Spaces:
Running
Running
Commit ·
84b67b2
1
Parent(s): ba2eb6f
fix: Fixed missing visualization canvases, repaired ML Lab link, and fixed MathJax tab rendering logic.
Browse files- Visualization/app.js +278 -0
- Visualization/index.html +7 -0
- index.html +2 -1
- math-ds-complete/app.js +5 -0
Visualization/app.js
CHANGED
|
@@ -1733,6 +1733,258 @@
|
|
| 1733 |
ctx.fillText('+45% over Target!', finalX - 65, finalY + 45);
|
| 1734 |
}
|
| 1735 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1736 |
// ==================== EVENT LISTENERS ====================
|
| 1737 |
function bindEvents() {
|
| 1738 |
// Perception buttons
|
|
@@ -1740,6 +1992,25 @@
|
|
| 1740 |
$('btn-color')?.addEventListener('click', () => { perceptionMode = 'color'; drawPerception(); });
|
| 1741 |
$('btn-size')?.addEventListener('click', () => { perceptionMode = 'size'; drawPerception(); });
|
| 1742 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1743 |
// Chart choosing buttons
|
| 1744 |
$('btn-comparison')?.addEventListener('click', () => { chartPurpose = 'comparison'; drawChoosingCharts(); });
|
| 1745 |
$('btn-composition')?.addEventListener('click', () => { chartPurpose = 'composition'; drawChoosingCharts(); });
|
|
@@ -1806,6 +2077,13 @@
|
|
| 1806 |
bindEvents();
|
| 1807 |
|
| 1808 |
// Draw all initial visualizations
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1809 |
drawAnscombe();
|
| 1810 |
perceptionMode = 'position';
|
| 1811 |
drawPerception();
|
|
|
|
| 1733 |
ctx.fillText('+45% over Target!', finalX - 65, finalY + 45);
|
| 1734 |
}
|
| 1735 |
|
| 1736 |
+
|
| 1737 |
+
// ==================== SUBPLOTS & LAYOUTS ====================
|
| 1738 |
+
let subplotType = '2x2';
|
| 1739 |
+
function drawSubplots() {
|
| 1740 |
+
const canvas = $('canvas-subplots');
|
| 1741 |
+
if (!canvas) return;
|
| 1742 |
+
const ctx = canvas.getContext('2d');
|
| 1743 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| 1744 |
+
|
| 1745 |
+
ctx.fillStyle = COLORS.text;
|
| 1746 |
+
ctx.font = '14px Inter, sans-serif';
|
| 1747 |
+
ctx.textAlign = 'center';
|
| 1748 |
+
|
| 1749 |
+
if (subplotType === '2x2') {
|
| 1750 |
+
ctx.fillText('2x2 Grid Layout', canvas.width / 2, 30);
|
| 1751 |
+
drawRect(ctx, 50, 60, 300, 180, COLORS.primary, false);
|
| 1752 |
+
drawRect(ctx, 400, 60, 300, 180, COLORS.secondary, false);
|
| 1753 |
+
drawRect(ctx, 50, 270, 300, 180, COLORS.accent, false);
|
| 1754 |
+
drawRect(ctx, 400, 270, 300, 180, COLORS.success, false);
|
| 1755 |
+
ctx.fillText('ax1', 200, 150); ctx.fillText('ax2', 550, 150);
|
| 1756 |
+
ctx.fillText('ax3', 200, 360); ctx.fillText('ax4', 550, 360);
|
| 1757 |
+
} else if (subplotType === 'uneven') {
|
| 1758 |
+
ctx.fillText('Uneven Grid (1 top, 2 bottom)', canvas.width / 2, 30);
|
| 1759 |
+
drawRect(ctx, 50, 60, 650, 180, COLORS.primary, false);
|
| 1760 |
+
drawRect(ctx, 50, 270, 300, 180, COLORS.secondary, false);
|
| 1761 |
+
drawRect(ctx, 400, 270, 300, 180, COLORS.accent, false);
|
| 1762 |
+
ctx.fillText('ax1 (colspan=2)', 375, 150);
|
| 1763 |
+
ctx.fillText('ax2', 200, 360); ctx.fillText('ax3', 550, 360);
|
| 1764 |
+
} else if (subplotType === 'gridspec') {
|
| 1765 |
+
ctx.fillText('GridSpec Layout (Complex sizing)', canvas.width / 2, 30);
|
| 1766 |
+
drawRect(ctx, 50, 60, 450, 390, COLORS.primary, false);
|
| 1767 |
+
drawRect(ctx, 530, 60, 200, 180, COLORS.secondary, false);
|
| 1768 |
+
drawRect(ctx, 530, 270, 200, 180, COLORS.accent, false);
|
| 1769 |
+
ctx.fillText('Main Plot (3x3 grid, spans 2x3)', 275, 255);
|
| 1770 |
+
ctx.fillText('Side Plot 1', 630, 150);
|
| 1771 |
+
ctx.fillText('Side Plot 2', 630, 360);
|
| 1772 |
+
}
|
| 1773 |
+
}
|
| 1774 |
+
|
| 1775 |
+
// ==================== STYLING & THEMES ====================
|
| 1776 |
+
let styleType = 'default';
|
| 1777 |
+
function drawStyling() {
|
| 1778 |
+
const canvas = $('canvas-styling');
|
| 1779 |
+
if (!canvas) return;
|
| 1780 |
+
const ctx = canvas.getContext('2d');
|
| 1781 |
+
|
| 1782 |
+
// Background based on style
|
| 1783 |
+
let bg = '#ffffff';
|
| 1784 |
+
let fg = '#333333';
|
| 1785 |
+
let lineColors = ['#1f77b4', '#ff7f0e', '#2ca02c'];
|
| 1786 |
+
|
| 1787 |
+
if (styleType === 'dark') { bg = '#121212'; fg = '#eeeeee'; lineColors = ['#00d4ff', '#ff5555', '#55ff55']; }
|
| 1788 |
+
else if (styleType === 'seaborn') { bg = '#eaeaf2'; fg = '#222222'; lineColors = ['#4c72b0', '#55a868', '#c44e52']; }
|
| 1789 |
+
else if (styleType === 'ggplot') { bg = '#e5e5e5'; fg = '#555555'; lineColors = ['#f8766d', '#00ba38', '#619cff']; }
|
| 1790 |
+
else if (styleType === '538') { bg = '#f0f0f0'; fg = '#333333'; lineColors = ['#008fd5', '#fc4f30', '#e5ae38']; }
|
| 1791 |
+
|
| 1792 |
+
ctx.fillStyle = bg;
|
| 1793 |
+
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
| 1794 |
+
|
| 1795 |
+
ctx.fillStyle = fg;
|
| 1796 |
+
ctx.font = styleType === '538' ? 'bold 16px Arial' : '14px Inter, sans-serif';
|
| 1797 |
+
ctx.textAlign = 'center';
|
| 1798 |
+
ctx.fillText(`${styleType.toUpperCase()} Theme Preview`, canvas.width / 2, 30);
|
| 1799 |
+
|
| 1800 |
+
// Draw generic line chart
|
| 1801 |
+
const startX = 100, endX = 700, baseY = 300;
|
| 1802 |
+
|
| 1803 |
+
// Axes
|
| 1804 |
+
ctx.strokeStyle = (styleType === 'seaborn' || styleType === 'ggplot') ? '#ffffff' : fg;
|
| 1805 |
+
ctx.lineWidth = (styleType === 'seaborn' || styleType === 'ggplot') ? 2 : 1;
|
| 1806 |
+
ctx.beginPath();
|
| 1807 |
+
ctx.moveTo(startX, 50); ctx.lineTo(startX, baseY); ctx.lineTo(endX, baseY);
|
| 1808 |
+
ctx.stroke();
|
| 1809 |
+
|
| 1810 |
+
// Grid
|
| 1811 |
+
ctx.strokeStyle = (styleType === 'dark') ? '#333' : '#ddd';
|
| 1812 |
+
for (let i = 1; i <= 5; i++) {
|
| 1813 |
+
let y = baseY - (i * 50);
|
| 1814 |
+
ctx.beginPath(); ctx.moveTo(startX, y); ctx.lineTo(endX, y); ctx.stroke();
|
| 1815 |
+
}
|
| 1816 |
+
|
| 1817 |
+
// Lines
|
| 1818 |
+
for (let l = 0; l < 3; l++) {
|
| 1819 |
+
ctx.strokeStyle = lineColors[l];
|
| 1820 |
+
ctx.lineWidth = styleType === '538' ? 4 : 2;
|
| 1821 |
+
ctx.beginPath();
|
| 1822 |
+
for (let i = 0; i <= 10; i++) {
|
| 1823 |
+
let x = startX + (i * 60);
|
| 1824 |
+
let y = baseY - 50 - (Math.sin(i * 0.5 + l) * 50) - (l * 40);
|
| 1825 |
+
if (i === 0) ctx.moveTo(x, y);
|
| 1826 |
+
else ctx.lineTo(x, y);
|
| 1827 |
+
}
|
| 1828 |
+
ctx.stroke();
|
| 1829 |
+
}
|
| 1830 |
+
}
|
| 1831 |
+
|
| 1832 |
+
// ==================== SEABORN INTRO ====================
|
| 1833 |
+
function drawSeabornIntro() {
|
| 1834 |
+
const canvas = $('canvas-seaborn-intro');
|
| 1835 |
+
if (!canvas) return;
|
| 1836 |
+
const ctx = canvas.getContext('2d');
|
| 1837 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| 1838 |
+
|
| 1839 |
+
ctx.fillStyle = COLORS.text;
|
| 1840 |
+
ctx.font = '14px Inter, sans-serif';
|
| 1841 |
+
ctx.textAlign = 'center';
|
| 1842 |
+
ctx.fillText('Matplotlib vs Seaborn Comparison', canvas.width / 2, 30);
|
| 1843 |
+
|
| 1844 |
+
// Fake Matplotlib code
|
| 1845 |
+
drawRect(ctx, 50, 60, 300, 200, '#1e293b', true);
|
| 1846 |
+
ctx.fillStyle = '#fff'; ctx.font = '12px Courier'; ctx.textAlign = 'left';
|
| 1847 |
+
ctx.fillText('import matplotlib.pyplot as plt', 60, 80);
|
| 1848 |
+
ctx.fillText('fig, ax = plt.subplots()', 60, 100);
|
| 1849 |
+
ctx.fillText('ax.scatter(df[\'target\'], df[\'value\'])', 60, 120);
|
| 1850 |
+
ctx.fillText('ax.set_title(\'Complex to Style\')', 60, 140);
|
| 1851 |
+
|
| 1852 |
+
// Fake Seaborn
|
| 1853 |
+
drawRect(ctx, 400, 60, 300, 200, '#1e293b', true);
|
| 1854 |
+
ctx.fillStyle = '#fff'; ctx.fillText('import seaborn as sns', 410, 80);
|
| 1855 |
+
ctx.fillText('sns.scatterplot(', 410, 100);
|
| 1856 |
+
ctx.fillText(' data=df, x=\'target\', y=\'value\',', 410, 120);
|
| 1857 |
+
ctx.fillText(' hue=\'category\', style=\'type\')', 410, 140);
|
| 1858 |
+
ctx.fillStyle = COLORS.accent; ctx.fillText('// 1 line creates a styled mapped plot!', 410, 180);
|
| 1859 |
+
}
|
| 1860 |
+
|
| 1861 |
+
// ==================== CATEGORICAL PLOTS ====================
|
| 1862 |
+
let catPlotType = 'boxplot';
|
| 1863 |
+
function drawCategorical() {
|
| 1864 |
+
const canvas = $('canvas-categorical');
|
| 1865 |
+
if (!canvas) return;
|
| 1866 |
+
const ctx = canvas.getContext('2d');
|
| 1867 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| 1868 |
+
|
| 1869 |
+
const categories = ['Group A', 'Group B', 'Group C'];
|
| 1870 |
+
const colors = [COLORS.primary, COLORS.accent, COLORS.warning];
|
| 1871 |
+
|
| 1872 |
+
ctx.fillStyle = COLORS.text;
|
| 1873 |
+
ctx.textAlign = 'center';
|
| 1874 |
+
ctx.font = 'bold 14px Inter, sans-serif';
|
| 1875 |
+
ctx.fillText(catPlotType.toUpperCase() + ' PREVIEW', canvas.width / 2, 30);
|
| 1876 |
+
|
| 1877 |
+
const startX = 150;
|
| 1878 |
+
const spacing = 200;
|
| 1879 |
+
const baseY = 320;
|
| 1880 |
+
|
| 1881 |
+
// Axis
|
| 1882 |
+
ctx.strokeStyle = COLORS.textSecondary;
|
| 1883 |
+
ctx.beginPath(); ctx.moveTo(50, baseY); ctx.lineTo(750, baseY); ctx.stroke();
|
| 1884 |
+
|
| 1885 |
+
for (let c = 0; c < 3; c++) {
|
| 1886 |
+
let cx = startX + c * spacing;
|
| 1887 |
+
ctx.fillStyle = COLORS.text;
|
| 1888 |
+
ctx.fillText(categories[c], cx, baseY + 20);
|
| 1889 |
+
|
| 1890 |
+
ctx.fillStyle = colors[c];
|
| 1891 |
+
ctx.strokeStyle = colors[c];
|
| 1892 |
+
|
| 1893 |
+
if (catPlotType === 'boxplot') {
|
| 1894 |
+
// Box
|
| 1895 |
+
ctx.fillRect(cx - 30, baseY - 150 + c * 10, 60, 80);
|
| 1896 |
+
// Whiskers
|
| 1897 |
+
ctx.beginPath();
|
| 1898 |
+
ctx.moveTo(cx, baseY - 150 + c * 10); ctx.lineTo(cx, baseY - 200 + c * 20);
|
| 1899 |
+
ctx.moveTo(cx, baseY - 70 + c * 10); ctx.lineTo(cx, baseY - 30 - c * 10);
|
| 1900 |
+
// Caps
|
| 1901 |
+
ctx.moveTo(cx - 15, baseY - 200 + c * 20); ctx.lineTo(cx + 15, baseY - 200 + c * 20);
|
| 1902 |
+
ctx.moveTo(cx - 15, baseY - 30 - c * 10); ctx.lineTo(cx + 15, baseY - 30 - c * 10);
|
| 1903 |
+
ctx.stroke();
|
| 1904 |
+
// Median (black line)
|
| 1905 |
+
ctx.strokeStyle = '#000'; ctx.lineWidth = 2;
|
| 1906 |
+
ctx.beginPath(); ctx.moveTo(cx - 30, baseY - 110 + c * 10); ctx.lineTo(cx + 30, baseY - 110 + c * 10); ctx.stroke();
|
| 1907 |
+
} else if (catPlotType === 'violinplot') {
|
| 1908 |
+
ctx.beginPath();
|
| 1909 |
+
ctx.moveTo(cx, baseY - 50);
|
| 1910 |
+
ctx.bezierCurveTo(cx - 50, baseY - 100, cx - 70, baseY - 180, cx, baseY - 230);
|
| 1911 |
+
ctx.bezierCurveTo(cx + 70, baseY - 180, cx + 50, baseY - 100, cx, baseY - 50);
|
| 1912 |
+
ctx.globalAlpha = 0.5; ctx.fill(); ctx.globalAlpha = 1;
|
| 1913 |
+
ctx.stroke();
|
| 1914 |
+
} else if (catPlotType === 'barplot') {
|
| 1915 |
+
let h = 150 + c * 30;
|
| 1916 |
+
ctx.fillRect(cx - 40, baseY - h, 80, h);
|
| 1917 |
+
// Error bar
|
| 1918 |
+
ctx.strokeStyle = '#000'; ctx.lineWidth = 2;
|
| 1919 |
+
ctx.beginPath(); ctx.moveTo(cx, baseY - h - 20); ctx.lineTo(cx, baseY - h + 20);
|
| 1920 |
+
ctx.moveTo(cx - 10, baseY - h - 20); ctx.lineTo(cx + 10, baseY - h - 20);
|
| 1921 |
+
ctx.moveTo(cx - 10, baseY - h + 20); ctx.lineTo(cx + 10, baseY - h + 20);
|
| 1922 |
+
ctx.stroke();
|
| 1923 |
+
} else if (catPlotType === 'stripplot' || catPlotType === 'swarmplot') {
|
| 1924 |
+
ctx.globalAlpha = 0.6;
|
| 1925 |
+
for (let i = 0; i < 40; i++) {
|
| 1926 |
+
let y = baseY - 50 - Math.random() * 150;
|
| 1927 |
+
let x = (catPlotType === 'swarmplot') ? cx + (Math.sin(y) * 30 * Math.random()) : cx - 30 + Math.random() * 60;
|
| 1928 |
+
ctx.beginPath(); ctx.arc(x, y, 4, 0, Math.PI * 2); ctx.fill();
|
| 1929 |
+
}
|
| 1930 |
+
ctx.globalAlpha = 1;
|
| 1931 |
+
}
|
| 1932 |
+
}
|
| 1933 |
+
}
|
| 1934 |
+
|
| 1935 |
+
// ==================== PLOTLY & DASHBOARDS ====================
|
| 1936 |
+
function drawPlotly() {
|
| 1937 |
+
const canvas = $('canvas-plotly');
|
| 1938 |
+
if (!canvas) return;
|
| 1939 |
+
const ctx = canvas.getContext('2d');
|
| 1940 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| 1941 |
+
|
| 1942 |
+
ctx.fillStyle = '#1e293b';
|
| 1943 |
+
ctx.fillRect(40, 40, canvas.width - 80, canvas.height - 80);
|
| 1944 |
+
ctx.fillStyle = COLORS.cyan || '#06b6d4';
|
| 1945 |
+
ctx.font = '16px Inter'; ctx.textAlign = 'center';
|
| 1946 |
+
ctx.fillText('Plotly / Interactive Charts Visualization', canvas.width / 2, 80);
|
| 1947 |
+
ctx.font = '12px Inter';
|
| 1948 |
+
ctx.fillText('Hover tooltips, zooming, and panning enabled out of the box.', canvas.width / 2, 100);
|
| 1949 |
+
|
| 1950 |
+
// Draw a fake cursor and tooltip
|
| 1951 |
+
ctx.beginPath(); ctx.arc(400, 200, 8, 0, Math.PI * 2); ctx.fillStyle = COLORS.orange; ctx.fill();
|
| 1952 |
+
ctx.fillStyle = '#fff'; ctx.fillRect(415, 175, 100, 50);
|
| 1953 |
+
ctx.fillStyle = '#000'; ctx.fillText('X: 2024-01-01', 465, 195);
|
| 1954 |
+
ctx.fillText('Y: $450.2K', 465, 215);
|
| 1955 |
+
}
|
| 1956 |
+
|
| 1957 |
+
function drawDashboard() {
|
| 1958 |
+
const canvas = $('canvas-dashboard');
|
| 1959 |
+
if (!canvas) return;
|
| 1960 |
+
const ctx = canvas.getContext('2d');
|
| 1961 |
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| 1962 |
+
|
| 1963 |
+
ctx.fillStyle = COLORS.text;
|
| 1964 |
+
ctx.font = '16px Inter'; ctx.textAlign = 'center';
|
| 1965 |
+
ctx.fillText('Streamlit Dashboard Architecture', canvas.width / 2, 30);
|
| 1966 |
+
|
| 1967 |
+
drawRect(ctx, 100, 60, 200, 250, '#1e293b', true);
|
| 1968 |
+
ctx.fillStyle = '#fff'; ctx.fillText('Sidebar / Inputs', 200, 90);
|
| 1969 |
+
drawRect(ctx, 120, 120, 160, 30, '#334155', true);
|
| 1970 |
+
drawRect(ctx, 120, 170, 160, 30, '#334155', true);
|
| 1971 |
+
|
| 1972 |
+
drawRect(ctx, 350, 60, 400, 250, '#0f172a', true);
|
| 1973 |
+
ctx.fillStyle = COLORS.cyan || '#06b6d4'; ctx.fillText('Main Chart Area', 550, 90);
|
| 1974 |
+
ctx.beginPath(); ctx.arc(550, 180, 50, 0, Math.PI * 2); ctx.strokeStyle = COLORS.accent; ctx.lineWidth = 15; ctx.stroke();
|
| 1975 |
+
}
|
| 1976 |
+
|
| 1977 |
+
function drawRect(ctx, x, y, width, height, color, filled = true) {
|
| 1978 |
+
if (filled) {
|
| 1979 |
+
ctx.fillStyle = color;
|
| 1980 |
+
ctx.fillRect(x, y, width, height);
|
| 1981 |
+
} else {
|
| 1982 |
+
ctx.strokeStyle = color;
|
| 1983 |
+
ctx.lineWidth = 2;
|
| 1984 |
+
ctx.strokeRect(x, y, width, height);
|
| 1985 |
+
}
|
| 1986 |
+
}
|
| 1987 |
+
|
| 1988 |
// ==================== EVENT LISTENERS ====================
|
| 1989 |
function bindEvents() {
|
| 1990 |
// Perception buttons
|
|
|
|
| 1992 |
$('btn-color')?.addEventListener('click', () => { perceptionMode = 'color'; drawPerception(); });
|
| 1993 |
$('btn-size')?.addEventListener('click', () => { perceptionMode = 'size'; drawPerception(); });
|
| 1994 |
|
| 1995 |
+
|
| 1996 |
+
// Subplots
|
| 1997 |
+
$('btn-grid-2x2')?.addEventListener('click', () => { subplotType = '2x2'; drawSubplots(); });
|
| 1998 |
+
$('btn-grid-uneven')?.addEventListener('click', () => { subplotType = 'uneven'; drawSubplots(); });
|
| 1999 |
+
$('btn-gridspec')?.addEventListener('click', () => { subplotType = 'gridspec'; drawSubplots(); });
|
| 2000 |
+
|
| 2001 |
+
// Styling
|
| 2002 |
+
$('btn-style-default')?.addEventListener('click', () => { styleType = 'default'; drawStyling(); });
|
| 2003 |
+
$('btn-style-seaborn')?.addEventListener('click', () => { styleType = 'seaborn'; drawStyling(); });
|
| 2004 |
+
$('btn-style-ggplot')?.addEventListener('click', () => { styleType = 'ggplot'; drawStyling(); });
|
| 2005 |
+
$('btn-style-dark')?.addEventListener('click', () => { styleType = 'dark'; drawStyling(); });
|
| 2006 |
+
$('btn-style-538')?.addEventListener('click', () => { styleType = '538'; drawStyling(); });
|
| 2007 |
+
|
| 2008 |
+
// Categorical
|
| 2009 |
+
$('btn-stripplot')?.addEventListener('click', () => { catPlotType = 'stripplot'; drawCategorical(); });
|
| 2010 |
+
$('btn-swarmplot')?.addEventListener('click', () => { catPlotType = 'swarmplot'; drawCategorical(); });
|
| 2011 |
+
$('btn-boxplot')?.addEventListener('click', () => { catPlotType = 'boxplot'; drawCategorical(); });
|
| 2012 |
+
$('btn-violinplot')?.addEventListener('click', () => { catPlotType = 'violinplot'; drawCategorical(); });
|
| 2013 |
+
$('btn-barplot')?.addEventListener('click', () => { catPlotType = 'barplot'; drawCategorical(); });
|
| 2014 |
// Chart choosing buttons
|
| 2015 |
$('btn-comparison')?.addEventListener('click', () => { chartPurpose = 'comparison'; drawChoosingCharts(); });
|
| 2016 |
$('btn-composition')?.addEventListener('click', () => { chartPurpose = 'composition'; drawChoosingCharts(); });
|
|
|
|
| 2077 |
bindEvents();
|
| 2078 |
|
| 2079 |
// Draw all initial visualizations
|
| 2080 |
+
|
| 2081 |
+
drawSubplots();
|
| 2082 |
+
drawStyling();
|
| 2083 |
+
drawSeabornIntro();
|
| 2084 |
+
drawCategorical();
|
| 2085 |
+
drawPlotly();
|
| 2086 |
+
drawDashboard();
|
| 2087 |
drawAnscombe();
|
| 2088 |
perceptionMode = 'position';
|
| 2089 |
drawPerception();
|
Visualization/index.html
CHANGED
|
@@ -9,6 +9,13 @@
|
|
| 9 |
|
| 10 |
<!-- MathJax for rendering LaTeX formulas -->
|
| 11 |
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
| 13 |
</head>
|
| 14 |
|
|
|
|
| 9 |
|
| 10 |
<!-- MathJax for rendering LaTeX formulas -->
|
| 11 |
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
| 12 |
+
<script>
|
| 13 |
+
MathJax = {
|
| 14 |
+
tex: {
|
| 15 |
+
inlineMath: [['$', '$'], ['\\(', '\\)']]
|
| 16 |
+
}
|
| 17 |
+
};
|
| 18 |
+
</script>
|
| 19 |
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
|
| 20 |
</head>
|
| 21 |
|
index.html
CHANGED
|
@@ -681,7 +681,8 @@
|
|
| 681 |
</a>
|
| 682 |
|
| 683 |
<!-- ML Lab -->
|
| 684 |
-
<a href="
|
|
|
|
| 685 |
<div class="module-card-header">
|
| 686 |
<span class="badge badge-ml">Lab</span>
|
| 687 |
</div>
|
|
|
|
| 681 |
</a>
|
| 682 |
|
| 683 |
<!-- ML Lab -->
|
| 684 |
+
<a href="https://github.com/aashishgarg13/DataScience/tree/main/ML" target="_blank"
|
| 685 |
+
class="module-card module-ml">
|
| 686 |
<div class="module-card-header">
|
| 687 |
<span class="badge badge-ml">Lab</span>
|
| 688 |
</div>
|
math-ds-complete/app.js
CHANGED
|
@@ -113,6 +113,11 @@ function switchSubject(subject) {
|
|
| 113 |
}, 100);
|
| 114 |
}
|
| 115 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
}
|
| 117 |
|
| 118 |
// ===== NAVIGATION =====
|
|
|
|
| 113 |
}, 100);
|
| 114 |
}
|
| 115 |
}
|
| 116 |
+
|
| 117 |
+
// Force MathJax to re-typeset formulas in the newly visible section
|
| 118 |
+
if (window.MathJax && window.MathJax.typesetPromise) {
|
| 119 |
+
window.MathJax.typesetPromise().catch((err) => console.log('MathJax typeset failed: ', err));
|
| 120 |
+
}
|
| 121 |
}
|
| 122 |
|
| 123 |
// ===== NAVIGATION =====
|