@classic-homes/charts-svelte 0.1.37 → 0.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/components/base/ChartContainer.svelte +4 -3
- package/dist/lib/components/base/ChartError.svelte +3 -1
- package/dist/lib/components/base/index.d.ts +9 -0
- package/dist/lib/components/core/AreaChart.svelte +30 -32
- package/dist/lib/components/core/DonutChart.svelte +6 -3
- package/dist/lib/components/core/LineChart.svelte +5 -2
- package/dist/lib/components/core/PieChart.svelte +1 -1
- package/dist/lib/components/core/ScatterChart.svelte +15 -6
- package/dist/lib/components/extended/CandlestickChart.svelte +10 -5
- package/dist/lib/components/extended/FunnelChart.svelte +2 -1
- package/dist/lib/components/extended/GaugeChart.svelte +15 -3
- package/dist/lib/components/extended/HeatmapChart.svelte +14 -4
- package/dist/lib/components/extended/TreemapChart.svelte +6 -2
- package/dist/lib/components/index.d.ts +1 -1
- package/dist/lib/components/index.js +1 -1
- package/dist/lib/composables/useChart.svelte.js +20 -3
- package/dist/lib/composables/useChartTheme.svelte.d.ts +2 -1
- package/dist/lib/composables/useChartTheme.svelte.js +2 -6
- package/dist/lib/index.d.ts +2 -2
- package/dist/lib/index.js +1 -1
- package/package.json +1 -1
|
@@ -33,10 +33,11 @@
|
|
|
33
33
|
children,
|
|
34
34
|
}: Props = $props();
|
|
35
35
|
|
|
36
|
+
// Unique per instance: two charts may share a title
|
|
37
|
+
const uid = $props.id();
|
|
38
|
+
|
|
36
39
|
const heightStyle = $derived(typeof height === 'number' ? `${height}px` : height);
|
|
37
|
-
const descriptionId = $derived(
|
|
38
|
-
description ? `${title.replace(/\s+/g, '-').toLowerCase()}-desc` : undefined
|
|
39
|
-
);
|
|
40
|
+
const descriptionId = $derived(description ? `${uid}-desc` : undefined);
|
|
40
41
|
</script>
|
|
41
42
|
|
|
42
43
|
{#if loading}
|
|
@@ -37,9 +37,11 @@
|
|
|
37
37
|
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"
|
|
38
38
|
/>
|
|
39
39
|
</svg>
|
|
40
|
-
|
|
40
|
+
<!-- text-destructive on the destructive tint fails AA; the icon and border carry the colour -->
|
|
41
|
+
<p class="mb-2 text-sm font-medium text-foreground">{message}</p>
|
|
41
42
|
{#if onRetry}
|
|
42
43
|
<button
|
|
44
|
+
type="button"
|
|
43
45
|
onclick={onRetry}
|
|
44
46
|
class="rounded-md bg-destructive px-3 py-1.5 text-xs font-medium text-destructive-foreground transition-colors hover:bg-destructive/90"
|
|
45
47
|
>
|
|
@@ -2,3 +2,12 @@ export { default as ChartContainer } from './ChartContainer.svelte';
|
|
|
2
2
|
export { default as ChartSkeleton } from './ChartSkeleton.svelte';
|
|
3
3
|
export { default as ChartError } from './ChartError.svelte';
|
|
4
4
|
export { default as ChartEmpty } from './ChartEmpty.svelte';
|
|
5
|
+
import type { ComponentProps } from 'svelte';
|
|
6
|
+
import type ChartContainer from './ChartContainer.svelte';
|
|
7
|
+
import type ChartSkeleton from './ChartSkeleton.svelte';
|
|
8
|
+
import type ChartError from './ChartError.svelte';
|
|
9
|
+
import type ChartEmpty from './ChartEmpty.svelte';
|
|
10
|
+
export type ChartContainerProps = ComponentProps<typeof ChartContainer>;
|
|
11
|
+
export type ChartSkeletonProps = ComponentProps<typeof ChartSkeleton>;
|
|
12
|
+
export type ChartErrorProps = ComponentProps<typeof ChartError>;
|
|
13
|
+
export type ChartEmptyProps = ComponentProps<typeof ChartEmpty>;
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import type { EChartsOption } from 'echarts';
|
|
12
12
|
|
|
13
13
|
import type { AreaChartProps, DataPointEventParams } from '@classic-homes/charts-core';
|
|
14
|
+
import { colorWithAlpha, getChartColors } from '@classic-homes/charts-core';
|
|
14
15
|
|
|
15
16
|
import { cn } from '../../utils.js';
|
|
16
17
|
import { useChart } from '../../composables/useChart.svelte.js';
|
|
@@ -54,6 +55,9 @@
|
|
|
54
55
|
!data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length)
|
|
55
56
|
);
|
|
56
57
|
|
|
58
|
+
// Per-element colours that follow the resolved chart theme
|
|
59
|
+
const chartColors = $derived.by(() => getChartColors(chart.theme));
|
|
60
|
+
|
|
57
61
|
const option: EChartsOption = $derived.by(() => {
|
|
58
62
|
if (isEmpty) return {};
|
|
59
63
|
|
|
@@ -70,7 +74,7 @@
|
|
|
70
74
|
axisPointer: {
|
|
71
75
|
type: 'cross',
|
|
72
76
|
label: {
|
|
73
|
-
backgroundColor:
|
|
77
|
+
backgroundColor: chartColors.axisPointerLabel,
|
|
74
78
|
},
|
|
75
79
|
},
|
|
76
80
|
}
|
|
@@ -92,37 +96,31 @@
|
|
|
92
96
|
show: showGrid,
|
|
93
97
|
},
|
|
94
98
|
},
|
|
95
|
-
series: data.series.map((series, index) =>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
itemStyle: series.color ? { color: series.color } : undefined,
|
|
121
|
-
emphasis: {
|
|
122
|
-
focus: 'series',
|
|
123
|
-
},
|
|
124
|
-
showSymbol: false,
|
|
125
|
-
})),
|
|
99
|
+
series: data.series.map((series, index) => {
|
|
100
|
+
// Fade the series colour (theme palette unless overridden) downwards
|
|
101
|
+
const base = series.color || chartColors.series[index % chartColors.series.length];
|
|
102
|
+
return {
|
|
103
|
+
name: series.name,
|
|
104
|
+
type: 'line',
|
|
105
|
+
data: series.data,
|
|
106
|
+
smooth,
|
|
107
|
+
stack: stacked ? 'Total' : undefined,
|
|
108
|
+
areaStyle: gradient
|
|
109
|
+
? {
|
|
110
|
+
opacity: 0.8,
|
|
111
|
+
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
112
|
+
{ offset: 0, color: colorWithAlpha(base, 0.8) },
|
|
113
|
+
{ offset: 1, color: colorWithAlpha(base, 0.1) },
|
|
114
|
+
]),
|
|
115
|
+
}
|
|
116
|
+
: { opacity: 0.5 },
|
|
117
|
+
itemStyle: series.color ? { color: series.color } : undefined,
|
|
118
|
+
emphasis: {
|
|
119
|
+
focus: 'series',
|
|
120
|
+
},
|
|
121
|
+
showSymbol: false,
|
|
122
|
+
};
|
|
123
|
+
}),
|
|
126
124
|
};
|
|
127
125
|
});
|
|
128
126
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import type { EChartsOption } from 'echarts';
|
|
7
7
|
|
|
8
8
|
import type { DonutChartProps, SliceEventParams } from '@classic-homes/charts-core';
|
|
9
|
-
import { generatePieChartDescription } from '@classic-homes/charts-core';
|
|
9
|
+
import { generatePieChartDescription, getChartColors } from '@classic-homes/charts-core';
|
|
10
10
|
|
|
11
11
|
import { cn } from '../../utils.js';
|
|
12
12
|
import { useChart } from '../../composables/useChart.svelte.js';
|
|
@@ -42,6 +42,9 @@
|
|
|
42
42
|
|
|
43
43
|
const isEmpty = $derived(!data?.length);
|
|
44
44
|
|
|
45
|
+
// Per-element colours that follow the resolved chart theme
|
|
46
|
+
const chartColors = $derived.by(() => getChartColors(chart.theme));
|
|
47
|
+
|
|
45
48
|
const option: EChartsOption = $derived.by(() => {
|
|
46
49
|
if (isEmpty) return {};
|
|
47
50
|
|
|
@@ -61,7 +64,7 @@
|
|
|
61
64
|
text: String(centerValue),
|
|
62
65
|
fontSize: 28,
|
|
63
66
|
fontWeight: 'bold',
|
|
64
|
-
fill:
|
|
67
|
+
fill: chartColors.foreground,
|
|
65
68
|
align: 'center',
|
|
66
69
|
},
|
|
67
70
|
top: 0,
|
|
@@ -76,7 +79,7 @@
|
|
|
76
79
|
style: {
|
|
77
80
|
text: centerLabel,
|
|
78
81
|
fontSize: 14,
|
|
79
|
-
fill:
|
|
82
|
+
fill: chartColors.mutedForeground,
|
|
80
83
|
align: 'center',
|
|
81
84
|
},
|
|
82
85
|
top: centerValue !== undefined ? 35 : 0,
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import type { EChartsOption } from 'echarts';
|
|
12
12
|
|
|
13
13
|
import type { LineChartProps, DataPointEventParams } from '@classic-homes/charts-core';
|
|
14
|
-
import { generateLineChartDescription } from '@classic-homes/charts-core';
|
|
14
|
+
import { generateLineChartDescription, getChartColors } from '@classic-homes/charts-core';
|
|
15
15
|
|
|
16
16
|
import { cn } from '../../utils.js';
|
|
17
17
|
import { useChart } from '../../composables/useChart.svelte.js';
|
|
@@ -57,6 +57,9 @@
|
|
|
57
57
|
!data?.categories?.length || !data?.series?.length || data.series.every((s) => !s.data?.length)
|
|
58
58
|
);
|
|
59
59
|
|
|
60
|
+
// Per-element colours that follow the resolved chart theme
|
|
61
|
+
const chartColors = $derived.by(() => getChartColors(chart.theme));
|
|
62
|
+
|
|
60
63
|
const option: EChartsOption = $derived.by(() => {
|
|
61
64
|
if (isEmpty) return {};
|
|
62
65
|
|
|
@@ -73,7 +76,7 @@
|
|
|
73
76
|
axisPointer: {
|
|
74
77
|
type: 'cross',
|
|
75
78
|
label: {
|
|
76
|
-
backgroundColor:
|
|
79
|
+
backgroundColor: chartColors.axisPointerLabel,
|
|
77
80
|
},
|
|
78
81
|
},
|
|
79
82
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import * as echarts from 'echarts/core';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ScatterChart as EChartsScatterChart,
|
|
5
|
+
LineChart as EChartsLineChart,
|
|
6
|
+
} from 'echarts/charts';
|
|
4
7
|
import {
|
|
5
8
|
GridComponent,
|
|
6
9
|
TooltipComponent,
|
|
@@ -11,7 +14,7 @@
|
|
|
11
14
|
import type { EChartsOption } from 'echarts';
|
|
12
15
|
|
|
13
16
|
import type { ScatterChartProps, DataPointEventParams } from '@classic-homes/charts-core';
|
|
14
|
-
import { generateScatterChartDescription } from '@classic-homes/charts-core';
|
|
17
|
+
import { escapeHtml, generateScatterChartDescription } from '@classic-homes/charts-core';
|
|
15
18
|
|
|
16
19
|
import { cn } from '../../utils.js';
|
|
17
20
|
import { useChart } from '../../composables/useChart.svelte.js';
|
|
@@ -20,6 +23,8 @@
|
|
|
20
23
|
// Register required ECharts modules
|
|
21
24
|
echarts.use([
|
|
22
25
|
EChartsScatterChart,
|
|
26
|
+
// Trend lines are line series
|
|
27
|
+
EChartsLineChart,
|
|
23
28
|
GridComponent,
|
|
24
29
|
TooltipComponent,
|
|
25
30
|
LegendComponent,
|
|
@@ -91,9 +96,13 @@
|
|
|
91
96
|
const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
|
|
92
97
|
const intercept = (sumY - slope * sumX) / n;
|
|
93
98
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
99
|
+
// A loop: spreading large arrays into Math.min/max overflows the stack
|
|
100
|
+
let minX = Infinity;
|
|
101
|
+
let maxX = -Infinity;
|
|
102
|
+
for (const [x] of s.data) {
|
|
103
|
+
if (x < minX) minX = x;
|
|
104
|
+
if (x > maxX) maxX = x;
|
|
105
|
+
}
|
|
97
106
|
|
|
98
107
|
(series as unknown[]).push({
|
|
99
108
|
name: `${s.name} Trend`,
|
|
@@ -129,7 +138,7 @@
|
|
|
129
138
|
formatter: (params: unknown) => {
|
|
130
139
|
const p = params as { seriesName?: string; value?: number[] };
|
|
131
140
|
if (!p.value) return '';
|
|
132
|
-
return `${p.seriesName}<br/>X: ${p.value[0]}<br/>Y: ${p.value[1]}`;
|
|
141
|
+
return `${escapeHtml(p.seriesName)}<br/>X: ${escapeHtml(p.value[0])}<br/>Y: ${escapeHtml(p.value[1])}`;
|
|
133
142
|
},
|
|
134
143
|
}
|
|
135
144
|
: undefined,
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import type { EChartsOption } from 'echarts';
|
|
15
15
|
|
|
16
16
|
import type { CandlestickChartProps, CandlestickEventParams } from '@classic-homes/charts-core';
|
|
17
|
+
import { getChartColors } from '@classic-homes/charts-core';
|
|
17
18
|
|
|
18
19
|
import { cn } from '../../utils.js';
|
|
19
20
|
import { useChart } from '../../composables/useChart.svelte.js';
|
|
@@ -51,6 +52,9 @@
|
|
|
51
52
|
|
|
52
53
|
const isEmpty = $derived(!data?.dates?.length || !data?.data?.length);
|
|
53
54
|
|
|
55
|
+
// Per-element colours that follow the resolved chart theme
|
|
56
|
+
const chartColors = $derived.by(() => getChartColors(chart.theme));
|
|
57
|
+
|
|
54
58
|
const option: EChartsOption = $derived.by(() => {
|
|
55
59
|
if (isEmpty) return {};
|
|
56
60
|
|
|
@@ -62,10 +66,10 @@
|
|
|
62
66
|
type: 'candlestick',
|
|
63
67
|
data: candlestickData,
|
|
64
68
|
itemStyle: {
|
|
65
|
-
color:
|
|
66
|
-
color0:
|
|
67
|
-
borderColor:
|
|
68
|
-
borderColor0:
|
|
69
|
+
color: chartColors.destructive,
|
|
70
|
+
color0: chartColors.success,
|
|
71
|
+
borderColor: chartColors.destructive,
|
|
72
|
+
borderColor0: chartColors.success,
|
|
69
73
|
},
|
|
70
74
|
},
|
|
71
75
|
];
|
|
@@ -115,7 +119,7 @@
|
|
|
115
119
|
xAxisIndex: 1,
|
|
116
120
|
yAxisIndex: 1,
|
|
117
121
|
data: data.volume,
|
|
118
|
-
itemStyle: { color:
|
|
122
|
+
itemStyle: { color: chartColors.mutedForeground },
|
|
119
123
|
});
|
|
120
124
|
}
|
|
121
125
|
|
|
@@ -148,6 +152,7 @@
|
|
|
148
152
|
instance.on('click', (params) => {
|
|
149
153
|
const dataIndex = params.dataIndex || 0;
|
|
150
154
|
const item = data.data[dataIndex];
|
|
155
|
+
if (!item) return;
|
|
151
156
|
onClick({
|
|
152
157
|
type: params.type || 'click',
|
|
153
158
|
componentType: params.componentType || 'series',
|
|
@@ -59,7 +59,8 @@
|
|
|
59
59
|
bottom: 60,
|
|
60
60
|
width: '80%',
|
|
61
61
|
min: 0,
|
|
62
|
-
|
|
62
|
+
// reduce, not Math.max(...): spreading large arrays overflows the stack
|
|
63
|
+
max: data.reduce((m, d) => (d.value > m ? d.value : m), -Infinity),
|
|
63
64
|
minSize: '0%',
|
|
64
65
|
maxSize: '100%',
|
|
65
66
|
sort,
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import type { EChartsOption } from 'echarts';
|
|
7
7
|
|
|
8
8
|
import type { GaugeChartProps } from '@classic-homes/charts-core';
|
|
9
|
+
import { getChartColors } from '@classic-homes/charts-core';
|
|
9
10
|
|
|
10
11
|
import { cn } from '../../utils.js';
|
|
11
12
|
import { useChart } from '../../composables/useChart.svelte.js';
|
|
@@ -42,6 +43,9 @@
|
|
|
42
43
|
animation: () => animation,
|
|
43
44
|
});
|
|
44
45
|
|
|
46
|
+
// Per-element colours that follow the resolved chart theme
|
|
47
|
+
const chartColors = $derived.by(() => getChartColors(chart.theme));
|
|
48
|
+
|
|
45
49
|
const option: EChartsOption = $derived({
|
|
46
50
|
series: [
|
|
47
51
|
{
|
|
@@ -53,9 +57,17 @@
|
|
|
53
57
|
splitNumber,
|
|
54
58
|
progress: showProgress ? { show: true, width: 18 } : undefined,
|
|
55
59
|
axisLine: { lineStyle: { width: 18 } },
|
|
56
|
-
axisTick: {
|
|
57
|
-
|
|
58
|
-
|
|
60
|
+
axisTick: {
|
|
61
|
+
distance: -30,
|
|
62
|
+
splitNumber: 5,
|
|
63
|
+
lineStyle: { width: 2, color: chartColors.mutedForeground },
|
|
64
|
+
},
|
|
65
|
+
splitLine: {
|
|
66
|
+
distance: -32,
|
|
67
|
+
length: 10,
|
|
68
|
+
lineStyle: { width: 3, color: chartColors.mutedForeground },
|
|
69
|
+
},
|
|
70
|
+
axisLabel: { distance: -20, color: chartColors.mutedForeground, fontSize: 12 },
|
|
59
71
|
anchor: { show: true, size: 20, itemStyle: { borderWidth: 2 } },
|
|
60
72
|
pointer: { width: 6, length: '60%' },
|
|
61
73
|
title: { show: true, offsetCenter: [0, '70%'], fontSize: 14 },
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import type { EChartsOption } from 'echarts';
|
|
12
12
|
|
|
13
13
|
import type { HeatmapChartProps, HeatmapEventParams } from '@classic-homes/charts-core';
|
|
14
|
+
import { escapeHtml } from '@classic-homes/charts-core';
|
|
14
15
|
|
|
15
16
|
import { cn } from '../../utils.js';
|
|
16
17
|
import { useChart } from '../../composables/useChart.svelte.js';
|
|
@@ -49,9 +50,18 @@
|
|
|
49
50
|
|
|
50
51
|
const isEmpty = $derived(!data?.data?.length || !xAxis?.length || !yAxis?.length);
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
53
|
+
// A loop: spreading large arrays into Math.min/max overflows the call stack
|
|
54
|
+
const extent = $derived.by(() => {
|
|
55
|
+
let min = Infinity;
|
|
56
|
+
let max = -Infinity;
|
|
57
|
+
for (const [, , value] of data?.data ?? []) {
|
|
58
|
+
if (value < min) min = value;
|
|
59
|
+
if (value > max) max = value;
|
|
60
|
+
}
|
|
61
|
+
return { min, max };
|
|
62
|
+
});
|
|
63
|
+
const minValue = $derived(data?.min ?? extent.min);
|
|
64
|
+
const maxValue = $derived(data?.max ?? extent.max);
|
|
55
65
|
|
|
56
66
|
const option: EChartsOption = $derived.by(() => {
|
|
57
67
|
if (isEmpty) return {};
|
|
@@ -64,7 +74,7 @@
|
|
|
64
74
|
const p = params as { value?: [number, number, number] };
|
|
65
75
|
if (!p.value) return '';
|
|
66
76
|
const [xIdx, yIdx, value] = p.value;
|
|
67
|
-
return `${xAxis[xIdx]} / ${yAxis[yIdx]}: ${value}`;
|
|
77
|
+
return `${escapeHtml(xAxis[xIdx])} / ${escapeHtml(yAxis[yIdx])}: ${escapeHtml(value)}`;
|
|
68
78
|
},
|
|
69
79
|
}
|
|
70
80
|
: undefined,
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import type { EChartsOption } from 'echarts';
|
|
7
7
|
|
|
8
8
|
import type { TreemapChartProps, TreemapEventParams } from '@classic-homes/charts-core';
|
|
9
|
+
import { escapeHtml, getChartColors } from '@classic-homes/charts-core';
|
|
9
10
|
|
|
10
11
|
import { cn } from '../../utils.js';
|
|
11
12
|
import { useChart } from '../../composables/useChart.svelte.js';
|
|
@@ -35,6 +36,9 @@
|
|
|
35
36
|
|
|
36
37
|
const isEmpty = $derived(!data?.length);
|
|
37
38
|
|
|
39
|
+
// Per-element colours that follow the resolved chart theme
|
|
40
|
+
const chartColors = $derived.by(() => getChartColors(chart.theme));
|
|
41
|
+
|
|
38
42
|
const option: EChartsOption = $derived.by(() => {
|
|
39
43
|
if (isEmpty) return {};
|
|
40
44
|
|
|
@@ -43,7 +47,7 @@
|
|
|
43
47
|
? {
|
|
44
48
|
formatter: (params: unknown) => {
|
|
45
49
|
const p = params as { name?: string; value?: number };
|
|
46
|
-
return `${p.name}: ${p.value}`;
|
|
50
|
+
return `${escapeHtml(p.name)}: ${escapeHtml(p.value)}`;
|
|
47
51
|
},
|
|
48
52
|
}
|
|
49
53
|
: undefined,
|
|
@@ -53,7 +57,7 @@
|
|
|
53
57
|
data,
|
|
54
58
|
roam: false,
|
|
55
59
|
levels: (levels || [
|
|
56
|
-
{ itemStyle: { borderColor:
|
|
60
|
+
{ itemStyle: { borderColor: chartColors.divider, borderWidth: 4, gapWidth: 4 } },
|
|
57
61
|
{
|
|
58
62
|
colorSaturation: [0.3, 0.6],
|
|
59
63
|
itemStyle: { borderColorSaturation: 0.7, gapWidth: 2, borderWidth: 2 },
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { ChartContainer, ChartSkeleton, ChartError, ChartEmpty } from './base/index.js';
|
|
1
|
+
export { ChartContainer, ChartSkeleton, ChartError, ChartEmpty, type ChartContainerProps, type ChartSkeletonProps, type ChartErrorProps, type ChartEmptyProps, } from './base/index.js';
|
|
2
2
|
export { LineChart, BarChart, PieChart, AreaChart, ScatterChart, DonutChart, } from './core/index.js';
|
|
3
3
|
export { RadarChart, FunnelChart, GaugeChart, HeatmapChart, TreemapChart, CandlestickChart, SankeyChart, } from './extended/index.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Base components
|
|
2
|
-
export { ChartContainer, ChartSkeleton, ChartError, ChartEmpty } from './base/index.js';
|
|
2
|
+
export { ChartContainer, ChartSkeleton, ChartError, ChartEmpty, } from './base/index.js';
|
|
3
3
|
// Core charts
|
|
4
4
|
export { LineChart, BarChart, PieChart, AreaChart, ScatterChart, DonutChart, } from './core/index.js';
|
|
5
5
|
// Extended charts
|
|
@@ -1,9 +1,26 @@
|
|
|
1
1
|
import { untrack } from 'svelte';
|
|
2
2
|
import * as echarts from 'echarts/core';
|
|
3
|
+
import { getReplaceMerge } from '@classic-homes/charts-core';
|
|
3
4
|
import { useChartTheme } from './useChartTheme.svelte.js';
|
|
4
5
|
import { useChartResize } from './useChartResize.svelte.js';
|
|
5
6
|
import { useReducedMotion } from './useReducedMotion.svelte.js';
|
|
6
|
-
const
|
|
7
|
+
const isComponentType = (mainType) => echarts.ComponentModel.hasClass(mainType);
|
|
8
|
+
// The option last applied to each instance; a fresh instance has none
|
|
9
|
+
const appliedOptions = new WeakMap();
|
|
10
|
+
/**
|
|
11
|
+
* Apply a complete option on top of the one last applied to this instance.
|
|
12
|
+
* Series, graphics and components that dropped out of the option are replaced
|
|
13
|
+
* so they disappear; everything else is merged so legend selection and
|
|
14
|
+
* dataZoom ranges survive data updates.
|
|
15
|
+
*/
|
|
16
|
+
function applyOption(chart, next) {
|
|
17
|
+
const prev = appliedOptions.get(chart) ?? null;
|
|
18
|
+
chart.setOption(next, {
|
|
19
|
+
replaceMerge: getReplaceMerge(prev, next, isComponentType),
|
|
20
|
+
lazyUpdate: true,
|
|
21
|
+
});
|
|
22
|
+
appliedOptions.set(chart, next);
|
|
23
|
+
}
|
|
7
24
|
/**
|
|
8
25
|
* Composable to manage ECharts instance lifecycle
|
|
9
26
|
* Matches behavior of React useChart hook
|
|
@@ -34,7 +51,7 @@ export function useChart(opts) {
|
|
|
34
51
|
// or callback changes update the chart instead of re-initializing it
|
|
35
52
|
untrack(() => {
|
|
36
53
|
if (!(opts.isEmpty?.() ?? false)) {
|
|
37
|
-
chart
|
|
54
|
+
applyOption(chart, resolveOption());
|
|
38
55
|
}
|
|
39
56
|
opts.onReady?.(chart);
|
|
40
57
|
});
|
|
@@ -55,7 +72,7 @@ export function useChart(opts) {
|
|
|
55
72
|
const empty = opts.isEmpty?.() ?? false;
|
|
56
73
|
if (!chart || chart.isDisposed() || empty)
|
|
57
74
|
return;
|
|
58
|
-
chart
|
|
75
|
+
applyOption(chart, option);
|
|
59
76
|
});
|
|
60
77
|
return {
|
|
61
78
|
get container() {
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export declare function registerClassicThemes(): void;
|
|
5
5
|
/**
|
|
6
|
-
* Create a reactive chart theme based on
|
|
6
|
+
* Create a reactive chart theme based on the document dark mode class. 'auto'
|
|
7
|
+
* follows the `.dark` class on <html>, the same switch the token CSS keys on.
|
|
7
8
|
* @param getPreference - A getter function that returns the current theme preference
|
|
8
9
|
*/
|
|
9
10
|
export declare function useChartTheme(getPreference: () => 'light' | 'dark' | 'auto'): {
|
|
@@ -12,7 +12,8 @@ export function registerClassicThemes() {
|
|
|
12
12
|
themesRegistered = true;
|
|
13
13
|
}
|
|
14
14
|
/**
|
|
15
|
-
* Create a reactive chart theme based on
|
|
15
|
+
* Create a reactive chart theme based on the document dark mode class. 'auto'
|
|
16
|
+
* follows the `.dark` class on <html>, the same switch the token CSS keys on.
|
|
16
17
|
* @param getPreference - A getter function that returns the current theme preference
|
|
17
18
|
*/
|
|
18
19
|
export function useChartTheme(getPreference) {
|
|
@@ -49,13 +50,8 @@ export function useChartTheme(getPreference) {
|
|
|
49
50
|
attributes: true,
|
|
50
51
|
attributeFilter: ['class'],
|
|
51
52
|
});
|
|
52
|
-
// Also listen for media query changes
|
|
53
|
-
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
54
|
-
const handleMediaChange = () => updateTheme();
|
|
55
|
-
mediaQuery.addEventListener('change', handleMediaChange);
|
|
56
53
|
return () => {
|
|
57
54
|
observer.disconnect();
|
|
58
|
-
mediaQuery.removeEventListener('change', handleMediaChange);
|
|
59
55
|
};
|
|
60
56
|
});
|
|
61
57
|
return {
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Svelte ECharts components for the Classic Theme design system
|
|
5
5
|
*/
|
|
6
|
-
export { ChartContainer, ChartSkeleton, ChartError, ChartEmpty, LineChart, BarChart, PieChart, AreaChart, ScatterChart, DonutChart, RadarChart, FunnelChart, GaugeChart, HeatmapChart, TreemapChart, CandlestickChart, SankeyChart, } from './components/index.js';
|
|
7
|
-
export { useChart, useChartTheme, registerClassicThemes, useReducedMotion, type UseChartOptions, type UseChartReturn, } from './composables/index.js';
|
|
6
|
+
export { ChartContainer, ChartSkeleton, ChartError, ChartEmpty, type ChartContainerProps, type ChartSkeletonProps, type ChartErrorProps, type ChartEmptyProps, LineChart, BarChart, PieChart, AreaChart, ScatterChart, DonutChart, RadarChart, FunnelChart, GaugeChart, HeatmapChart, TreemapChart, CandlestickChart, SankeyChart, } from './components/index.js';
|
|
7
|
+
export { useChart, useChartTheme, useChartResize, registerClassicThemes, useReducedMotion, type UseChartOptions, type UseChartReturn, } from './composables/index.js';
|
|
8
8
|
export { cn } from './utils.js';
|
|
9
9
|
export type { BaseChartProps, LineChartProps, BarChartProps, PieChartProps, DonutChartProps, AreaChartProps, ScatterChartProps, RadarChartProps, FunnelChartProps, GaugeChartProps, HeatmapChartProps, TreemapChartProps, CandlestickChartProps, SankeyChartProps, LineChartData, LineSeriesData, BarChartData, BarSeriesData, PieSliceData, AreaChartData, AreaSeriesData, ScatterChartData, ScatterSeriesData, RadarChartData, RadarSeriesData, RadarIndicator, FunnelSliceData, HeatmapData, TreemapNode, TreemapLevel, CandlestickData, CandlestickItem, SankeyData, SankeyNode, SankeyLink, BaseEventParams, DataPointEventParams, SliceEventParams, HeatmapEventParams, TreemapEventParams, CandlestickEventParams, SankeyEventParams, } from '@classic-homes/charts-core';
|
package/dist/lib/index.js
CHANGED
|
@@ -12,6 +12,6 @@ LineChart, BarChart, PieChart, AreaChart, ScatterChart, DonutChart,
|
|
|
12
12
|
// Extended charts
|
|
13
13
|
RadarChart, FunnelChart, GaugeChart, HeatmapChart, TreemapChart, CandlestickChart, SankeyChart, } from './components/index.js';
|
|
14
14
|
// Composables
|
|
15
|
-
export { useChart, useChartTheme, registerClassicThemes, useReducedMotion, } from './composables/index.js';
|
|
15
|
+
export { useChart, useChartTheme, useChartResize, registerClassicThemes, useReducedMotion, } from './composables/index.js';
|
|
16
16
|
// Utils
|
|
17
17
|
export { cn } from './utils.js';
|