diff --git a/package.json b/package.json index b339ded6..3efb8ae1 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@tanstack/svelte-query-devtools": "^6.0.2", "@types/node": "^22", "@vitest/browser": "^3.2.3", + "echarts": "^5.6.0", "eslint": "^9.18.0", "eslint-config-prettier": "^10.0.1", "eslint-plugin-storybook": "^10.1.2", @@ -52,6 +53,7 @@ "storybook": "^10.1.2", "svelte": "^5.0.0", "svelte-check": "^4.0.0", + "svelte-echarts": "^1.0.0", "svelte-preprocess": "^6.0.3", "typescript": "^5.0.0", "typescript-eslint": "^8.20.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d3095916..d7abb837 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -108,6 +108,9 @@ importers: '@vitest/browser': specifier: ^3.2.3 version: 3.2.4(playwright@1.55.0)(vite@7.1.5(@types/node@22.18.1)(sass@1.92.1))(vitest@3.2.4) + echarts: + specifier: ^5.6.0 + version: 5.6.0 eslint: specifier: ^9.18.0 version: 9.35.0 @@ -147,6 +150,9 @@ importers: svelte-check: specifier: ^4.0.0 version: 4.3.1(picomatch@4.0.3)(svelte@5.38.7)(typescript@5.9.2) + svelte-echarts: + specifier: ^1.0.0 + version: 1.0.0(echarts@5.6.0)(svelte@5.38.7) svelte-preprocess: specifier: ^6.0.3 version: 6.0.3(postcss-load-config@3.1.4(postcss@8.5.6))(postcss@8.5.6)(sass@1.92.1)(svelte@5.38.7)(typescript@5.9.2) @@ -1607,6 +1613,9 @@ packages: dom-accessibility-api@0.6.3: resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + echarts@5.6.0: + resolution: {integrity: sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -2519,6 +2528,12 @@ packages: svelte: ^4.0.0 || ^5.0.0-next.0 typescript: '>=5.0.0' + svelte-echarts@1.0.0: + resolution: {integrity: sha512-o0VgdxGJt+Km+IrxNo35qTJFqDsvj65p7JwAlIrk7CsWjBKKniJaUV6hKbMDNf0S34Su0idWbWEdymJNPX3anA==} + peerDependencies: + echarts: ^5.0.0 + svelte: '>=5' + svelte-eslint-parser@1.3.1: resolution: {integrity: sha512-0Iztj5vcOVOVkhy1pbo5uA9r+d3yaVoE5XPc9eABIWDOSJZ2mOsZ4D+t45rphWCOr0uMw3jtSG2fh2e7GvKnPg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2638,6 +2653,9 @@ packages: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -2885,6 +2903,9 @@ packages: zod@4.1.5: resolution: {integrity: sha512-rcUUZqlLJgBC33IT3PNMgsCq6TzLQEG/Ei/KTCU0PedSWRMAXoOUN+4t/0H+Q8bdnLPdqUYnvboJT0bn/229qg==} + zrender@5.6.1: + resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==} + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -4291,6 +4312,11 @@ snapshots: dom-accessibility-api@0.6.3: {} + echarts@5.6.0: + dependencies: + tslib: 2.3.0 + zrender: 5.6.1 + entities@4.5.0: {} es-module-lexer@1.7.0: {} @@ -5422,6 +5448,11 @@ snapshots: transitivePeerDependencies: - picomatch + svelte-echarts@1.0.0(echarts@5.6.0)(svelte@5.38.7): + dependencies: + echarts: 5.6.0 + svelte: 5.38.7 + svelte-eslint-parser@1.3.1(svelte@5.38.7): dependencies: eslint-scope: 8.4.0 @@ -5515,6 +5546,8 @@ snapshots: ts-dedent@2.2.0: {} + tslib@2.3.0: {} + tslib@2.8.1: {} type-check@0.4.0: @@ -5758,4 +5791,8 @@ snapshots: zod@4.1.5: {} + zrender@5.6.1: + dependencies: + tslib: 2.3.0 + zwitch@2.0.4: {} diff --git a/src/lib/components/charts/GwCrewBattleChart.svelte b/src/lib/components/charts/GwCrewBattleChart.svelte new file mode 100644 index 00000000..11262d87 --- /dev/null +++ b/src/lib/components/charts/GwCrewBattleChart.svelte @@ -0,0 +1,83 @@ + + + + +
+ +
+ + diff --git a/src/lib/components/charts/GwCrewHistoryChart.svelte b/src/lib/components/charts/GwCrewHistoryChart.svelte new file mode 100644 index 00000000..629fe757 --- /dev/null +++ b/src/lib/components/charts/GwCrewHistoryChart.svelte @@ -0,0 +1,129 @@ + + + + +
+
+ +
+

Drag to pan • Shift+scroll to zoom • Use slider below chart

+
+ + diff --git a/src/lib/components/charts/GwMultiPlayerChart.svelte b/src/lib/components/charts/GwMultiPlayerChart.svelte new file mode 100644 index 00000000..2971fdbb --- /dev/null +++ b/src/lib/components/charts/GwMultiPlayerChart.svelte @@ -0,0 +1,124 @@ + + + + +
+ +
+ + diff --git a/src/lib/components/charts/GwScoreLineChart.svelte b/src/lib/components/charts/GwScoreLineChart.svelte new file mode 100644 index 00000000..2b01a7b5 --- /dev/null +++ b/src/lib/components/charts/GwScoreLineChart.svelte @@ -0,0 +1,71 @@ + + + + +
+ +
+ + diff --git a/src/lib/components/charts/echarts-setup.ts b/src/lib/components/charts/echarts-setup.ts new file mode 100644 index 00000000..86889756 --- /dev/null +++ b/src/lib/components/charts/echarts-setup.ts @@ -0,0 +1,35 @@ +/** + * ECharts Setup Module + * + * Configures tree-shaking for ECharts by only importing the components we need. + * This keeps the bundle size reasonable while providing full chart functionality. + */ + +import { init, use } from 'echarts/core' +import { LineChart } from 'echarts/charts' +import { + GridComponent, + TooltipComponent, + LegendComponent, + TitleComponent, + DataZoomComponent, + ToolboxComponent +} from 'echarts/components' +import { CanvasRenderer } from 'echarts/renderers' + +// Register only the components we need +use([ + LineChart, + GridComponent, + TooltipComponent, + LegendComponent, + TitleComponent, + DataZoomComponent, + ToolboxComponent, + CanvasRenderer +]) + +// Shared font family matching the app's typography +export const CHART_FONT_FAMILY = "'AGrot', system-ui, sans-serif" + +export { init }