@classic-homes/charts-svelte 0.1.1

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.
Files changed (53) hide show
  1. package/dist/lib/components/base/ChartContainer.svelte +63 -0
  2. package/dist/lib/components/base/ChartContainer.svelte.d.ts +17 -0
  3. package/dist/lib/components/base/ChartEmpty.svelte +39 -0
  4. package/dist/lib/components/base/ChartEmpty.svelte.d.ts +8 -0
  5. package/dist/lib/components/base/ChartError.svelte +49 -0
  6. package/dist/lib/components/base/ChartError.svelte.d.ts +9 -0
  7. package/dist/lib/components/base/ChartSkeleton.svelte +37 -0
  8. package/dist/lib/components/base/ChartSkeleton.svelte.d.ts +7 -0
  9. package/dist/lib/components/base/index.d.ts +4 -0
  10. package/dist/lib/components/base/index.js +4 -0
  11. package/dist/lib/components/core/AreaChart.svelte +198 -0
  12. package/dist/lib/components/core/AreaChart.svelte.d.ts +7 -0
  13. package/dist/lib/components/core/BarChart.svelte +186 -0
  14. package/dist/lib/components/core/BarChart.svelte.d.ts +7 -0
  15. package/dist/lib/components/core/DonutChart.svelte +207 -0
  16. package/dist/lib/components/core/DonutChart.svelte.d.ts +7 -0
  17. package/dist/lib/components/core/LineChart.svelte +203 -0
  18. package/dist/lib/components/core/LineChart.svelte.d.ts +7 -0
  19. package/dist/lib/components/core/PieChart.svelte +156 -0
  20. package/dist/lib/components/core/PieChart.svelte.d.ts +7 -0
  21. package/dist/lib/components/core/ScatterChart.svelte +224 -0
  22. package/dist/lib/components/core/ScatterChart.svelte.d.ts +7 -0
  23. package/dist/lib/components/core/index.d.ts +6 -0
  24. package/dist/lib/components/core/index.js +6 -0
  25. package/dist/lib/components/extended/CandlestickChart.svelte +200 -0
  26. package/dist/lib/components/extended/CandlestickChart.svelte.d.ts +7 -0
  27. package/dist/lib/components/extended/FunnelChart.svelte +142 -0
  28. package/dist/lib/components/extended/FunnelChart.svelte.d.ts +7 -0
  29. package/dist/lib/components/extended/GaugeChart.svelte +113 -0
  30. package/dist/lib/components/extended/GaugeChart.svelte.d.ts +7 -0
  31. package/dist/lib/components/extended/HeatmapChart.svelte +159 -0
  32. package/dist/lib/components/extended/HeatmapChart.svelte.d.ts +7 -0
  33. package/dist/lib/components/extended/RadarChart.svelte +131 -0
  34. package/dist/lib/components/extended/RadarChart.svelte.d.ts +7 -0
  35. package/dist/lib/components/extended/SankeyChart.svelte +129 -0
  36. package/dist/lib/components/extended/SankeyChart.svelte.d.ts +7 -0
  37. package/dist/lib/components/extended/TreemapChart.svelte +133 -0
  38. package/dist/lib/components/extended/TreemapChart.svelte.d.ts +7 -0
  39. package/dist/lib/components/extended/index.d.ts +7 -0
  40. package/dist/lib/components/extended/index.js +7 -0
  41. package/dist/lib/components/index.d.ts +3 -0
  42. package/dist/lib/components/index.js +6 -0
  43. package/dist/lib/composables/index.d.ts +2 -0
  44. package/dist/lib/composables/index.js +2 -0
  45. package/dist/lib/composables/useChartTheme.svelte.d.ts +11 -0
  46. package/dist/lib/composables/useChartTheme.svelte.js +66 -0
  47. package/dist/lib/composables/useReducedMotion.svelte.d.ts +6 -0
  48. package/dist/lib/composables/useReducedMotion.svelte.js +26 -0
  49. package/dist/lib/index.d.ts +9 -0
  50. package/dist/lib/index.js +17 -0
  51. package/dist/lib/utils.d.ts +2 -0
  52. package/dist/lib/utils.js +5 -0
  53. package/package.json +45 -0
@@ -0,0 +1,224 @@
1
+ <script lang="ts">
2
+ import * as echarts from 'echarts/core';
3
+ import { ScatterChart as EChartsScatterChart } from 'echarts/charts';
4
+ import {
5
+ GridComponent,
6
+ TooltipComponent,
7
+ LegendComponent,
8
+ TitleComponent,
9
+ } from 'echarts/components';
10
+ import { CanvasRenderer } from 'echarts/renderers';
11
+ import type { EChartsOption } from 'echarts';
12
+
13
+ import type { ScatterChartProps, DataPointEventParams } from '@classic-homes/charts-core';
14
+ import { generateScatterChartDescription } from '@classic-homes/charts-core';
15
+
16
+ import { cn } from '../../utils.js';
17
+ import { useChartTheme } from '../../composables/useChartTheme.svelte.js';
18
+ import { useReducedMotion } from '../../composables/useReducedMotion.svelte.js';
19
+ import ChartContainer from '../base/ChartContainer.svelte';
20
+
21
+ // Register required ECharts modules
22
+ echarts.use([
23
+ EChartsScatterChart,
24
+ GridComponent,
25
+ TooltipComponent,
26
+ LegendComponent,
27
+ TitleComponent,
28
+ CanvasRenderer,
29
+ ]);
30
+
31
+ interface Props extends Omit<ScatterChartProps, 'class'> {
32
+ class?: string;
33
+ }
34
+
35
+ let {
36
+ title,
37
+ description,
38
+ data,
39
+ height = 400,
40
+ loading,
41
+ error,
42
+ emptyMessage,
43
+ theme = 'auto',
44
+ animation = true,
45
+ showLegend = true,
46
+ showTooltip = true,
47
+ showGrid = true,
48
+ showTrendLine = false,
49
+ symbolSize = 10,
50
+ onClick,
51
+ class: className,
52
+ }: Props = $props();
53
+
54
+ let containerEl: HTMLDivElement | null = $state(null);
55
+ let chart: echarts.ECharts | null = null;
56
+
57
+ const chartTheme = useChartTheme(() => theme);
58
+ const reducedMotion = useReducedMotion();
59
+
60
+ const isEmpty = $derived(!data?.series?.length || data.series.every((s) => !s.data?.length));
61
+
62
+ const option: EChartsOption = $derived.by(() => {
63
+ if (isEmpty) return {};
64
+
65
+ const series: EChartsOption['series'] = data.series.map((s) => ({
66
+ name: s.name,
67
+ type: 'scatter',
68
+ data: s.data,
69
+ symbolSize: typeof symbolSize === 'function' ? symbolSize : symbolSize,
70
+ itemStyle: s.color ? { color: s.color } : undefined,
71
+ emphasis: {
72
+ focus: 'series',
73
+ itemStyle: {
74
+ shadowBlur: 10,
75
+ shadowColor: 'rgba(0, 0, 0, 0.5)',
76
+ },
77
+ },
78
+ }));
79
+
80
+ // Add trend lines if enabled
81
+ if (showTrendLine) {
82
+ data.series.forEach((s, index) => {
83
+ if (s.data.length < 2) return;
84
+
85
+ const n = s.data.length;
86
+ let sumX = 0,
87
+ sumY = 0,
88
+ sumXY = 0,
89
+ sumX2 = 0;
90
+
91
+ s.data.forEach(([x, y]) => {
92
+ sumX += x;
93
+ sumY += y;
94
+ sumXY += x * y;
95
+ sumX2 += x * x;
96
+ });
97
+
98
+ const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
99
+ const intercept = (sumY - slope * sumX) / n;
100
+
101
+ const xValues = s.data.map(([x]) => x);
102
+ const minX = Math.min(...xValues);
103
+ const maxX = Math.max(...xValues);
104
+
105
+ (series as unknown[]).push({
106
+ name: `${s.name} Trend`,
107
+ type: 'line',
108
+ data: [
109
+ [minX, slope * minX + intercept],
110
+ [maxX, slope * maxX + intercept],
111
+ ],
112
+ smooth: false,
113
+ showSymbol: false,
114
+ lineStyle: {
115
+ type: 'dashed',
116
+ opacity: 0.7,
117
+ },
118
+ emphasis: {
119
+ disabled: true,
120
+ },
121
+ z: index,
122
+ });
123
+ });
124
+ }
125
+
126
+ return {
127
+ grid: {
128
+ left: '3%',
129
+ right: '4%',
130
+ bottom: '3%',
131
+ containLabel: true,
132
+ },
133
+ tooltip: showTooltip
134
+ ? {
135
+ trigger: 'item' as const,
136
+ formatter: (params: unknown) => {
137
+ const p = params as { seriesName?: string; value?: number[] };
138
+ if (!p.value) return '';
139
+ return `${p.seriesName}<br/>X: ${p.value[0]}<br/>Y: ${p.value[1]}`;
140
+ },
141
+ }
142
+ : undefined,
143
+ legend: showLegend
144
+ ? {
145
+ data: data.series.map((s) => s.name),
146
+ bottom: 0,
147
+ }
148
+ : undefined,
149
+ xAxis: {
150
+ type: 'value',
151
+ splitLine: {
152
+ show: showGrid,
153
+ },
154
+ },
155
+ yAxis: {
156
+ type: 'value',
157
+ splitLine: {
158
+ show: showGrid,
159
+ },
160
+ },
161
+ series,
162
+ animation: animation && !reducedMotion.value,
163
+ };
164
+ });
165
+
166
+ const accessibilityDescription = $derived(
167
+ description || (!isEmpty ? generateScatterChartDescription(title, data) : undefined)
168
+ );
169
+
170
+ // Initialize chart instance (only depends on container and theme)
171
+ $effect(() => {
172
+ if (!containerEl) return;
173
+
174
+ if (chart) {
175
+ chart.dispose();
176
+ }
177
+
178
+ chart = echarts.init(containerEl, chartTheme.theme);
179
+
180
+ if (onClick) {
181
+ chart.on('click', (params) => {
182
+ onClick({
183
+ type: params.type || 'click',
184
+ componentType: params.componentType || 'series',
185
+ seriesIndex: params.seriesIndex,
186
+ seriesName: params.seriesName || '',
187
+ dataIndex: params.dataIndex || 0,
188
+ name: params.name || '',
189
+ value: params.value as number[],
190
+ color: params.color as string,
191
+ } as DataPointEventParams);
192
+ });
193
+ }
194
+
195
+ const handleResize = () => chart?.resize();
196
+ window.addEventListener('resize', handleResize);
197
+
198
+ return () => {
199
+ window.removeEventListener('resize', handleResize);
200
+ chart?.dispose();
201
+ chart = null;
202
+ };
203
+ });
204
+
205
+ // Update options when they change (handles both initial and subsequent updates)
206
+ $effect(() => {
207
+ if (chart && !isEmpty) {
208
+ chart.setOption(option, { notMerge: true, lazyUpdate: true });
209
+ }
210
+ });
211
+ </script>
212
+
213
+ <ChartContainer
214
+ {title}
215
+ description={accessibilityDescription}
216
+ {height}
217
+ {loading}
218
+ {error}
219
+ empty={isEmpty}
220
+ {emptyMessage}
221
+ class={cn(className)}
222
+ >
223
+ <div bind:this={containerEl} class="h-full w-full"></div>
224
+ </ChartContainer>
@@ -0,0 +1,7 @@
1
+ import type { ScatterChartProps } from '@classic-homes/charts-core';
2
+ interface Props extends Omit<ScatterChartProps, 'class'> {
3
+ class?: string;
4
+ }
5
+ declare const ScatterChart: import("svelte").Component<Props, {}, "">;
6
+ type ScatterChart = ReturnType<typeof ScatterChart>;
7
+ export default ScatterChart;
@@ -0,0 +1,6 @@
1
+ export { default as LineChart } from './LineChart.svelte';
2
+ export { default as BarChart } from './BarChart.svelte';
3
+ export { default as PieChart } from './PieChart.svelte';
4
+ export { default as AreaChart } from './AreaChart.svelte';
5
+ export { default as ScatterChart } from './ScatterChart.svelte';
6
+ export { default as DonutChart } from './DonutChart.svelte';
@@ -0,0 +1,6 @@
1
+ export { default as LineChart } from './LineChart.svelte';
2
+ export { default as BarChart } from './BarChart.svelte';
3
+ export { default as PieChart } from './PieChart.svelte';
4
+ export { default as AreaChart } from './AreaChart.svelte';
5
+ export { default as ScatterChart } from './ScatterChart.svelte';
6
+ export { default as DonutChart } from './DonutChart.svelte';
@@ -0,0 +1,200 @@
1
+ <script lang="ts">
2
+ import * as echarts from 'echarts/core';
3
+ import {
4
+ CandlestickChart as EChartsCandlestickChart,
5
+ BarChart as EChartsBarChart,
6
+ } from 'echarts/charts';
7
+ import {
8
+ GridComponent,
9
+ TooltipComponent,
10
+ TitleComponent,
11
+ DataZoomComponent,
12
+ } from 'echarts/components';
13
+ import { CanvasRenderer } from 'echarts/renderers';
14
+ import type { EChartsOption } from 'echarts';
15
+
16
+ import type { CandlestickChartProps, CandlestickEventParams } from '@classic-homes/charts-core';
17
+
18
+ import { cn } from '../../utils.js';
19
+ import { useChartTheme } from '../../composables/useChartTheme.svelte.js';
20
+ import { useReducedMotion } from '../../composables/useReducedMotion.svelte.js';
21
+ import ChartContainer from '../base/ChartContainer.svelte';
22
+
23
+ echarts.use([
24
+ EChartsCandlestickChart,
25
+ EChartsBarChart,
26
+ GridComponent,
27
+ TooltipComponent,
28
+ TitleComponent,
29
+ DataZoomComponent,
30
+ CanvasRenderer,
31
+ ]);
32
+
33
+ interface Props extends Omit<CandlestickChartProps, 'class'> {
34
+ class?: string;
35
+ }
36
+
37
+ let {
38
+ title,
39
+ description,
40
+ data,
41
+ height = 400,
42
+ loading,
43
+ error,
44
+ emptyMessage,
45
+ theme = 'auto',
46
+ animation = true,
47
+ showTooltip = true,
48
+ showVolume = false,
49
+ onClick,
50
+ class: className,
51
+ }: Props = $props();
52
+
53
+ let containerEl: HTMLDivElement | null = $state(null);
54
+ let chart: echarts.ECharts | null = null;
55
+
56
+ const chartTheme = useChartTheme(() => theme);
57
+ const reducedMotion = useReducedMotion();
58
+
59
+ const isEmpty = $derived(!data?.dates?.length || !data?.data?.length);
60
+
61
+ const option: EChartsOption = $derived.by(() => {
62
+ if (isEmpty) return {};
63
+
64
+ const candlestickData = data.data.map((item) => [item.open, item.close, item.low, item.high]);
65
+
66
+ const seriesArr: EChartsOption['series'] = [
67
+ {
68
+ name: title,
69
+ type: 'candlestick',
70
+ data: candlestickData,
71
+ itemStyle: {
72
+ color: '#ef4444',
73
+ color0: '#22c55e',
74
+ borderColor: '#ef4444',
75
+ borderColor0: '#22c55e',
76
+ },
77
+ },
78
+ ];
79
+
80
+ const gridArr: { left: string; right: string; top: number | string; height: string }[] = [
81
+ { left: '10%', right: '10%', top: 60, height: showVolume ? '50%' : '70%' },
82
+ ];
83
+ const xAxisArr: unknown[] = [
84
+ {
85
+ type: 'category',
86
+ data: data.dates,
87
+ boundaryGap: false,
88
+ axisLine: { onZero: false },
89
+ splitLine: { show: false },
90
+ min: 'dataMin',
91
+ max: 'dataMax',
92
+ },
93
+ ];
94
+ const yAxisArr: unknown[] = [{ scale: true, splitArea: { show: true } }];
95
+
96
+ if (showVolume && data.volume) {
97
+ gridArr.push({ left: '10%', right: '10%', top: '73%', height: '12%' });
98
+ xAxisArr.push({
99
+ type: 'category',
100
+ gridIndex: 1,
101
+ data: data.dates,
102
+ boundaryGap: false,
103
+ axisLine: { onZero: false },
104
+ axisTick: { show: false },
105
+ splitLine: { show: false },
106
+ axisLabel: { show: false },
107
+ min: 'dataMin',
108
+ max: 'dataMax',
109
+ });
110
+ yAxisArr.push({
111
+ scale: true,
112
+ gridIndex: 1,
113
+ splitNumber: 2,
114
+ axisLabel: { show: false },
115
+ axisLine: { show: false },
116
+ axisTick: { show: false },
117
+ splitLine: { show: false },
118
+ });
119
+ (seriesArr as unknown[]).push({
120
+ name: 'Volume',
121
+ type: 'bar',
122
+ xAxisIndex: 1,
123
+ yAxisIndex: 1,
124
+ data: data.volume,
125
+ itemStyle: { color: '#6b7280' },
126
+ });
127
+ }
128
+
129
+ return {
130
+ tooltip: showTooltip ? { trigger: 'axis', axisPointer: { type: 'cross' } } : undefined,
131
+ grid: gridArr,
132
+ xAxis: xAxisArr as EChartsOption['xAxis'],
133
+ yAxis: yAxisArr as EChartsOption['yAxis'],
134
+ dataZoom: [
135
+ { type: 'inside', start: 80, end: 100 },
136
+ { show: true, type: 'slider', top: '90%', start: 80, end: 100 },
137
+ ],
138
+ series: seriesArr,
139
+ animation: animation && !reducedMotion.value,
140
+ };
141
+ });
142
+
143
+ const accessibilityDescription = $derived(
144
+ description ||
145
+ (!isEmpty ? `${title}. Candlestick chart with ${data.dates.length} data points.` : undefined)
146
+ );
147
+
148
+ // Initialize chart instance (only depends on container and theme)
149
+ $effect(() => {
150
+ if (!containerEl) return;
151
+ if (chart) chart.dispose();
152
+ chart = echarts.init(containerEl, chartTheme.theme);
153
+
154
+ if (onClick) {
155
+ chart.on('click', (params) => {
156
+ const dataIndex = params.dataIndex || 0;
157
+ const item = data.data[dataIndex];
158
+ onClick({
159
+ type: params.type || 'click',
160
+ componentType: params.componentType || 'series',
161
+ date: data.dates[dataIndex],
162
+ open: item.open,
163
+ close: item.close,
164
+ high: item.high,
165
+ low: item.low,
166
+ volume: data.volume?.[dataIndex],
167
+ } as CandlestickEventParams);
168
+ });
169
+ }
170
+
171
+ const handleResize = () => chart?.resize();
172
+ window.addEventListener('resize', handleResize);
173
+
174
+ return () => {
175
+ window.removeEventListener('resize', handleResize);
176
+ chart?.dispose();
177
+ chart = null;
178
+ };
179
+ });
180
+
181
+ // Update options when they change (handles both initial and subsequent updates)
182
+ $effect(() => {
183
+ if (chart && !isEmpty) {
184
+ chart.setOption(option, { notMerge: true, lazyUpdate: true });
185
+ }
186
+ });
187
+ </script>
188
+
189
+ <ChartContainer
190
+ {title}
191
+ description={accessibilityDescription}
192
+ {height}
193
+ {loading}
194
+ {error}
195
+ empty={isEmpty}
196
+ {emptyMessage}
197
+ class={cn(className)}
198
+ >
199
+ <div bind:this={containerEl} class="h-full w-full"></div>
200
+ </ChartContainer>
@@ -0,0 +1,7 @@
1
+ import type { CandlestickChartProps } from '@classic-homes/charts-core';
2
+ interface Props extends Omit<CandlestickChartProps, 'class'> {
3
+ class?: string;
4
+ }
5
+ declare const CandlestickChart: import("svelte").Component<Props, {}, "">;
6
+ type CandlestickChart = ReturnType<typeof CandlestickChart>;
7
+ export default CandlestickChart;
@@ -0,0 +1,142 @@
1
+ <script lang="ts">
2
+ import * as echarts from 'echarts/core';
3
+ import { FunnelChart as EChartsFunnelChart } from 'echarts/charts';
4
+ import { TooltipComponent, LegendComponent, TitleComponent } from 'echarts/components';
5
+ import { CanvasRenderer } from 'echarts/renderers';
6
+ import type { EChartsOption } from 'echarts';
7
+
8
+ import type { FunnelChartProps, SliceEventParams } from '@classic-homes/charts-core';
9
+
10
+ import { cn } from '../../utils.js';
11
+ import { useChartTheme } from '../../composables/useChartTheme.svelte.js';
12
+ import { useReducedMotion } from '../../composables/useReducedMotion.svelte.js';
13
+ import ChartContainer from '../base/ChartContainer.svelte';
14
+
15
+ echarts.use([
16
+ EChartsFunnelChart,
17
+ TooltipComponent,
18
+ LegendComponent,
19
+ TitleComponent,
20
+ CanvasRenderer,
21
+ ]);
22
+
23
+ interface Props extends Omit<FunnelChartProps, 'class'> {
24
+ class?: string;
25
+ }
26
+
27
+ let {
28
+ title,
29
+ description,
30
+ data,
31
+ height = 400,
32
+ loading,
33
+ error,
34
+ emptyMessage,
35
+ theme = 'auto',
36
+ animation = true,
37
+ showLegend = true,
38
+ showTooltip = true,
39
+ sort = 'descending',
40
+ orientation = 'vertical',
41
+ showLabels = true,
42
+ onClick,
43
+ class: className,
44
+ }: Props = $props();
45
+
46
+ let containerEl: HTMLDivElement | null = $state(null);
47
+ let chart: echarts.ECharts | null = null;
48
+
49
+ const chartTheme = useChartTheme(() => theme);
50
+ const reducedMotion = useReducedMotion();
51
+
52
+ const isEmpty = $derived(!data?.length);
53
+
54
+ const option: EChartsOption = $derived.by(() => {
55
+ if (isEmpty) return {};
56
+
57
+ return {
58
+ tooltip: showTooltip ? { trigger: 'item', formatter: '{a} <br/>{b}: {c}' } : undefined,
59
+ legend: showLegend ? { data: data.map((d) => d.name), bottom: 0 } : undefined,
60
+ series: [
61
+ {
62
+ name: title,
63
+ type: 'funnel',
64
+ left: '10%',
65
+ top: 60,
66
+ bottom: 60,
67
+ width: '80%',
68
+ min: 0,
69
+ max: Math.max(...data.map((d) => d.value)),
70
+ minSize: '0%',
71
+ maxSize: '100%',
72
+ sort,
73
+ orient: orientation,
74
+ gap: 2,
75
+ label: showLabels
76
+ ? { show: true, position: 'inside', formatter: '{b}: {c}' }
77
+ : { show: false },
78
+ labelLine: { show: false },
79
+ emphasis: { label: { fontSize: 16 } },
80
+ data: data.map((item) => ({
81
+ name: item.name,
82
+ value: item.value,
83
+ itemStyle: item.color ? { color: item.color } : undefined,
84
+ })),
85
+ },
86
+ ],
87
+ animation: animation && !reducedMotion.value,
88
+ };
89
+ });
90
+
91
+ const accessibilityDescription = $derived(
92
+ description || (!isEmpty ? `${title}. Funnel chart with ${data.length} stages.` : undefined)
93
+ );
94
+
95
+ // Initialize chart instance (only depends on container and theme)
96
+ $effect(() => {
97
+ if (!containerEl) return;
98
+ if (chart) chart.dispose();
99
+ chart = echarts.init(containerEl, chartTheme.theme);
100
+
101
+ if (onClick) {
102
+ chart.on('click', (params) => {
103
+ onClick({
104
+ type: params.type || 'click',
105
+ componentType: params.componentType || 'series',
106
+ name: params.name || '',
107
+ value: params.value as number,
108
+ color: params.color as string,
109
+ } as SliceEventParams);
110
+ });
111
+ }
112
+
113
+ const handleResize = () => chart?.resize();
114
+ window.addEventListener('resize', handleResize);
115
+
116
+ return () => {
117
+ window.removeEventListener('resize', handleResize);
118
+ chart?.dispose();
119
+ chart = null;
120
+ };
121
+ });
122
+
123
+ // Update options when they change (handles both initial and subsequent updates)
124
+ $effect(() => {
125
+ if (chart && !isEmpty) {
126
+ chart.setOption(option, { notMerge: true, lazyUpdate: true });
127
+ }
128
+ });
129
+ </script>
130
+
131
+ <ChartContainer
132
+ {title}
133
+ description={accessibilityDescription}
134
+ {height}
135
+ {loading}
136
+ {error}
137
+ empty={isEmpty}
138
+ {emptyMessage}
139
+ class={cn(className)}
140
+ >
141
+ <div bind:this={containerEl} class="h-full w-full"></div>
142
+ </ChartContainer>
@@ -0,0 +1,7 @@
1
+ import type { FunnelChartProps } from '@classic-homes/charts-core';
2
+ interface Props extends Omit<FunnelChartProps, 'class'> {
3
+ class?: string;
4
+ }
5
+ declare const FunnelChart: import("svelte").Component<Props, {}, "">;
6
+ type FunnelChart = ReturnType<typeof FunnelChart>;
7
+ export default FunnelChart;