@reshape-biotech/design-system 0.0.52 → 1.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 (184) hide show
  1. package/dist/components/activity/Activity.stories.svelte +21 -8
  2. package/dist/components/activity/Activity.svelte +49 -9
  3. package/dist/components/activity/Activity.svelte.d.ts +1 -1
  4. package/dist/components/avatar/Avatar.stories.svelte +7 -17
  5. package/dist/components/avatar/Avatar.svelte +2 -2
  6. package/dist/components/avatar/Avatar.svelte.d.ts +2 -2
  7. package/dist/components/banner/Banner.stories.svelte +5 -5
  8. package/dist/components/button/Button.stories.svelte +54 -21
  9. package/dist/components/button/Button.svelte +58 -11
  10. package/dist/components/button/Button.svelte.d.ts +4 -3
  11. package/dist/components/card/Card.stories.svelte +130 -0
  12. package/dist/components/card/Card.stories.svelte.d.ts +19 -0
  13. package/dist/components/card/Card.svelte +25 -0
  14. package/dist/components/card/Card.svelte.d.ts +10 -0
  15. package/dist/components/card/index.d.ts +1 -0
  16. package/dist/components/card/index.js +1 -0
  17. package/dist/components/checkbox/Checkbox.stories.svelte +22 -0
  18. package/dist/components/checkbox/Checkbox.stories.svelte.d.ts +19 -0
  19. package/dist/components/checkbox/Checkbox.svelte +24 -0
  20. package/dist/components/checkbox/Checkbox.svelte.d.ts +5 -0
  21. package/dist/components/checkbox/index.d.ts +1 -0
  22. package/dist/components/checkbox/index.js +1 -0
  23. package/dist/components/collapsible/Collapsible.stories.svelte +5 -4
  24. package/dist/components/collapsible/components/collapsible-trigger.svelte +1 -1
  25. package/dist/components/combobox/Combobox.stories.svelte +7 -5
  26. package/dist/components/combobox/components/combobox-add.svelte +2 -1
  27. package/dist/components/combobox/components/combobox-content.svelte +4 -0
  28. package/dist/components/combobox/types.d.ts +2 -0
  29. package/dist/components/datepicker/DatePicker.stories.svelte +8 -14
  30. package/dist/components/divider/Divider.stories.svelte +1 -3
  31. package/dist/components/divider/Divider.svelte +8 -2
  32. package/dist/components/divider/Divider.svelte.d.ts +2 -0
  33. package/dist/components/drawer/Drawer.stories.svelte +3 -3
  34. package/dist/components/dropdown/Dropdown.stories.svelte +8 -8
  35. package/dist/components/empty-content/EmptyContent.stories.svelte +2 -2
  36. package/dist/components/graphs/bar-chart/BarChart.stories.svelte +81 -0
  37. package/dist/components/graphs/bar-chart/BarChart.stories.svelte.d.ts +19 -0
  38. package/dist/components/graphs/bar-chart/BarChart.svelte +136 -0
  39. package/dist/components/graphs/bar-chart/BarChart.svelte.d.ts +15 -0
  40. package/dist/components/graphs/bar-chart/StackedBarChart.stories.svelte +42 -0
  41. package/dist/components/graphs/bar-chart/StackedBarChart.stories.svelte.d.ts +19 -0
  42. package/dist/components/graphs/bar-chart/StackedBarChart.svelte +177 -0
  43. package/dist/components/graphs/bar-chart/StackedBarChart.svelte.d.ts +16 -0
  44. package/dist/components/graphs/chart/Chart.stories.svelte +31 -23
  45. package/dist/components/graphs/chart/Chart.svelte +104 -32
  46. package/dist/components/graphs/chart/Chart.svelte.d.ts +15 -5
  47. package/dist/components/graphs/index.d.ts +3 -0
  48. package/dist/components/graphs/index.js +3 -0
  49. package/dist/components/graphs/line/LineChart.stories.svelte +107 -15
  50. package/dist/components/graphs/line/LineChart.svelte +90 -51
  51. package/dist/components/graphs/line/LineChart.svelte.d.ts +6 -13
  52. package/dist/components/graphs/matrix/Matrix.stories.svelte +156 -0
  53. package/dist/components/graphs/matrix/Matrix.stories.svelte.d.ts +19 -0
  54. package/dist/components/graphs/matrix/Matrix.svelte +149 -0
  55. package/dist/components/graphs/matrix/Matrix.svelte.d.ts +24 -0
  56. package/dist/components/graphs/matrix/index.d.ts +3 -0
  57. package/dist/components/graphs/matrix/index.js +3 -0
  58. package/dist/components/graphs/multiline/MultiLineChart.stories.svelte +130 -18
  59. package/dist/components/graphs/multiline/MultiLineChart.svelte +187 -50
  60. package/dist/components/graphs/multiline/MultiLineChart.svelte.d.ts +9 -12
  61. package/dist/components/graphs/scatterplot/Scatterplot.stories.svelte +68 -41
  62. package/dist/components/graphs/scatterplot/Scatterplot.svelte +312 -45
  63. package/dist/components/graphs/scatterplot/Scatterplot.svelte.d.ts +23 -13
  64. package/dist/components/graphs/utils/tooltipFormatter.d.ts +10 -0
  65. package/dist/components/graphs/utils/tooltipFormatter.js +52 -0
  66. package/dist/components/icon-button/IconButton.stories.svelte +6 -6
  67. package/dist/components/icon-button/IconButton.svelte +50 -9
  68. package/dist/components/icon-button/IconButton.svelte.d.ts +3 -5
  69. package/dist/components/icons/AnalysisIcon.stories.svelte +15 -21
  70. package/dist/components/icons/AnalysisIcon.svelte +53 -43
  71. package/dist/components/icons/Icon.stories.svelte +4 -4
  72. package/dist/components/icons/Icon.svelte +1 -1
  73. package/dist/components/icons/PrincipalIcon.svelte +96 -0
  74. package/dist/components/icons/PrincipalIcon.svelte.d.ts +10 -0
  75. package/dist/components/icons/custom/Halo.svelte +14 -8
  76. package/dist/components/icons/custom/Halo.svelte.d.ts +7 -25
  77. package/dist/components/icons/custom/Well.svelte +14 -6
  78. package/dist/components/icons/custom/Well.svelte.d.ts +7 -25
  79. package/dist/components/icons/index.d.ts +3 -2
  80. package/dist/components/icons/index.js +26 -0
  81. package/dist/components/input/Input.stories.svelte +16 -22
  82. package/dist/components/input/Input.svelte +140 -134
  83. package/dist/components/input/Input.svelte.d.ts +12 -13
  84. package/dist/components/label/Label.stories.svelte +28 -0
  85. package/dist/components/label/Label.stories.svelte.d.ts +19 -0
  86. package/dist/components/label/Label.svelte +17 -0
  87. package/dist/components/label/Label.svelte.d.ts +9 -0
  88. package/dist/components/list/List.stories.svelte +3 -3
  89. package/dist/components/logo/Logo.stories.svelte +1 -1
  90. package/dist/components/manual-cfu-counter/ManualCFUCounter.stories.svelte +125 -0
  91. package/dist/components/manual-cfu-counter/ManualCFUCounter.stories.svelte.d.ts +3 -0
  92. package/dist/components/manual-cfu-counter/ManualCFUCounter.svelte +577 -0
  93. package/dist/components/manual-cfu-counter/ManualCFUCounter.svelte.d.ts +16 -0
  94. package/dist/components/manual-cfu-counter/index.d.ts +1 -0
  95. package/dist/components/manual-cfu-counter/index.js +1 -0
  96. package/dist/components/manual-cfu-counter/test/ManualCFUCounterTestWrapper.svelte +22 -0
  97. package/dist/components/manual-cfu-counter/test/ManualCFUCounterTestWrapper.svelte.d.ts +19 -0
  98. package/dist/components/markdown/Markdown.stories.svelte +1 -1
  99. package/dist/components/markdown/Markdown.svelte +1 -1
  100. package/dist/components/modal/Modal.stories.svelte +2 -2
  101. package/dist/components/modal/Modal.svelte +27 -22
  102. package/dist/components/modal/Modal.svelte.d.ts +4 -1
  103. package/dist/components/notification-popup/NotificationPopup.stories.svelte +1 -1
  104. package/dist/components/pill/Pill.stories.svelte +13 -0
  105. package/dist/components/pill/Pill.stories.svelte.d.ts +19 -0
  106. package/dist/components/progress-circle/ProgressCircle.stories.svelte +15 -0
  107. package/dist/components/progress-circle/ProgressCircle.stories.svelte.d.ts +19 -0
  108. package/dist/components/required-status-indicator/RequiredStatusIndicator.stories.svelte +28 -0
  109. package/dist/components/required-status-indicator/RequiredStatusIndicator.stories.svelte.d.ts +19 -0
  110. package/dist/components/required-status-indicator/RequiredStatusIndicator.svelte +22 -0
  111. package/dist/components/required-status-indicator/RequiredStatusIndicator.svelte.d.ts +8 -0
  112. package/dist/components/required-status-indicator/index.d.ts +1 -0
  113. package/dist/components/required-status-indicator/index.js +1 -0
  114. package/dist/components/segmented-control-buttons/SegmentedControlButtons.stories.svelte +3 -3
  115. package/dist/components/select/Select.stories.svelte +12 -12
  116. package/dist/components/select/Select.svelte +0 -2
  117. package/dist/components/select-new/Select.stories.svelte +219 -0
  118. package/dist/components/select-new/Select.stories.svelte.d.ts +19 -0
  119. package/dist/components/select-new/components/Group.svelte +23 -0
  120. package/dist/components/select-new/components/Group.svelte.d.ts +10 -0
  121. package/dist/components/select-new/components/MultiSelectTrigger.svelte +66 -0
  122. package/dist/components/select-new/components/MultiSelectTrigger.svelte.d.ts +17 -0
  123. package/dist/components/select-new/components/SelectContent.svelte +33 -0
  124. package/dist/components/select-new/components/SelectContent.svelte.d.ts +10 -0
  125. package/dist/components/select-new/components/SelectGroupHeading.svelte +19 -0
  126. package/dist/components/select-new/components/SelectGroupHeading.svelte.d.ts +9 -0
  127. package/dist/components/select-new/components/SelectItem.svelte +41 -0
  128. package/dist/components/select-new/components/SelectItem.svelte.d.ts +9 -0
  129. package/dist/components/select-new/components/SelectTrigger.svelte +48 -0
  130. package/dist/components/select-new/components/SelectTrigger.svelte.d.ts +12 -0
  131. package/dist/components/select-new/index.d.ts +10 -0
  132. package/dist/components/select-new/index.js +12 -0
  133. package/dist/components/select-new/types.d.ts +25 -0
  134. package/dist/components/select-new/types.js +1 -0
  135. package/dist/components/sjsf-wrappers/SjsfNumberInputWrapper.svelte +92 -0
  136. package/dist/components/sjsf-wrappers/SjsfNumberInputWrapper.svelte.d.ts +3 -0
  137. package/dist/components/sjsf-wrappers/SjsfTextInputWrapper.svelte +65 -0
  138. package/dist/components/sjsf-wrappers/SjsfTextInputWrapper.svelte.d.ts +3 -0
  139. package/dist/components/sjsf-wrappers/index.d.ts +2 -0
  140. package/dist/components/sjsf-wrappers/index.js +2 -0
  141. package/dist/components/sjsf-wrappers/sjsfCustomTheme.d.ts +2 -0
  142. package/dist/components/sjsf-wrappers/sjsfCustomTheme.js +8 -0
  143. package/dist/components/skeleton-loader/SkeletonLoader.stories.svelte +4 -4
  144. package/dist/components/slider/Slider.stories.svelte +4 -4
  145. package/dist/components/spinner/Spinner.stories.svelte +13 -0
  146. package/dist/components/spinner/Spinner.stories.svelte.d.ts +19 -0
  147. package/dist/components/stat-card/StatCard.stories.svelte +27 -19
  148. package/dist/components/stat-card/StatCard.svelte +100 -6
  149. package/dist/components/stat-card/StatCard.svelte.d.ts +3 -0
  150. package/dist/components/status-badge/StatusBadge.stories.svelte +6 -6
  151. package/dist/components/status-badge/StatusBadge.svelte +5 -3
  152. package/dist/components/table/Table.stories.svelte +1 -1
  153. package/dist/components/table/components/Td.svelte +3 -2
  154. package/dist/components/table/components/Td.svelte.d.ts +1 -0
  155. package/dist/components/table/components/Tr.svelte +3 -2
  156. package/dist/components/table/components/Tr.svelte.d.ts +1 -0
  157. package/dist/components/tabs/Tabs.stories.svelte +1 -1
  158. package/dist/components/tag/Tag.stories.svelte +38 -7
  159. package/dist/components/tag/Tag.svelte +34 -21
  160. package/dist/components/tag/Tag.svelte.d.ts +1 -1
  161. package/dist/components/textarea/Textarea.stories.svelte +97 -0
  162. package/dist/components/textarea/Textarea.stories.svelte.d.ts +19 -0
  163. package/dist/components/textarea/Textarea.svelte +94 -0
  164. package/dist/components/textarea/Textarea.svelte.d.ts +17 -0
  165. package/dist/components/textarea/index.d.ts +1 -0
  166. package/dist/components/textarea/index.js +1 -0
  167. package/dist/components/toggle/Toggle.stories.svelte +1 -1
  168. package/dist/components/toggle/Toggle.svelte +3 -2
  169. package/dist/components/toggle/Toggle.svelte.d.ts +1 -0
  170. package/dist/components/toggle-icon-button/ToggleIconButton.stories.svelte +173 -0
  171. package/dist/components/toggle-icon-button/ToggleIconButton.stories.svelte.d.ts +19 -0
  172. package/dist/components/toggle-icon-button/ToggleIconButton.svelte +117 -0
  173. package/dist/components/toggle-icon-button/ToggleIconButton.svelte.d.ts +15 -0
  174. package/dist/components/toggle-icon-button/index.d.ts +3 -0
  175. package/dist/components/toggle-icon-button/index.js +3 -0
  176. package/dist/components/tooltip/Tooltip.stories.svelte +6 -6
  177. package/dist/components/tooltip/Tooltip.svelte +1 -1
  178. package/dist/index.d.ts +7 -0
  179. package/dist/index.js +7 -0
  180. package/dist/tailwind-safelist.js +2 -0
  181. package/dist/tailwind.preset.d.ts +2 -0
  182. package/dist/tokens.d.ts +4 -0
  183. package/dist/tokens.js +3 -1
  184. package/package.json +1 -2
@@ -1,14 +1,20 @@
1
1
  <script lang="ts">
2
- import * as echarts from 'echarts';
3
- import type { ECElementEvent } from 'echarts';
4
- import { onMount } from 'svelte';
2
+ import { init } from 'echarts';
3
+ import type { EChartsOption, ECElementEvent, ECharts, SeriesOption } from 'echarts';
4
+ import { onMount, type Snippet } from 'svelte';
5
5
  import { colors, textColor } from '../../../tokens';
6
- type Props = {
7
- options: echarts.EChartsOption;
6
+
7
+ type ChartProps = {
8
+ options: EChartsOption;
8
9
  theme?: string | object;
9
10
  renderer?: 'canvas' | 'svg';
10
11
  height?: string;
11
12
  width?: string;
13
+ xAxisName?: string;
14
+ yAxisName?: string;
15
+ yAxisUnit?: string;
16
+ xAxisOptions?: EChartsOption['xAxis'];
17
+ yAxisOptions?: EChartsOption['yAxis'];
12
18
  // Common event handlers
13
19
  onitemclick?: (params: ECElementEvent) => void;
14
20
  onmouseover?: (params: ECElementEvent) => void;
@@ -16,8 +22,12 @@
16
22
  // Additional options
17
23
  autoResize?: boolean;
18
24
  loading?: boolean;
25
+ timeIndex?: number;
26
+ children?: Snippet;
19
27
  };
20
28
 
29
+ export type GenericChartProps = Omit<ChartProps, 'options'>;
30
+
21
31
  const {
22
32
  options,
23
33
  theme,
@@ -28,24 +38,16 @@
28
38
  onmouseover,
29
39
  onmouseout,
30
40
  autoResize = true,
31
- loading = false
32
- }: Props = $props();
41
+ loading = false,
42
+ timeIndex,
43
+ children
44
+ }: ChartProps = $props();
33
45
 
34
- let chart = $state<echarts.ECharts | null>(null);
46
+ let chart = $state<ECharts | null>(null);
35
47
  let container: HTMLElement;
36
48
 
37
- function deepMerge(target: any, source: any) {
38
- for (const key in source) {
39
- if (source[key] instanceof Object && key in target) {
40
- deepMerge(target[key], source[key]);
41
- } else {
42
- target[key] = source[key];
43
- }
44
- }
45
- return target;
46
- }
47
-
48
- const defaultOptions = {
49
+ const defaultOptions: EChartsOption = {
50
+ animation: false,
49
51
  grid: {
50
52
  left: '48px',
51
53
  right: '16px',
@@ -56,13 +58,13 @@
56
58
  nameLocation: 'middle',
57
59
  nameGap: 32,
58
60
  axisLabel: {
59
- fontSize: 10,
61
+ fontSize: 11,
62
+ fontFamily: 'af Another Sans',
60
63
  lineHeight: 14,
61
64
  align: 'center',
62
65
  fontWeight: 450,
63
66
  color: textColor.secondary,
64
- margin: 16,
65
- fontFamily: 'monospace'
67
+ margin: 16
66
68
  },
67
69
  axisLine: {
68
70
  lineStyle: {
@@ -71,6 +73,7 @@
71
73
  },
72
74
  nameTextStyle: {
73
75
  fontSize: 12,
76
+ fontFamily: 'af Another Sans',
74
77
  color: textColor.secondary
75
78
  }
76
79
  },
@@ -79,13 +82,13 @@
79
82
  nameGap: 32,
80
83
  nameRotate: 90,
81
84
  axisLabel: {
82
- fontSize: 10,
85
+ fontSize: 11,
86
+ fontFamily: 'af Another Sans',
83
87
  lineHeight: 14,
84
88
  align: 'center',
85
89
  fontWeight: 450,
86
90
  color: textColor.secondary,
87
- margin: 16,
88
- fontFamily: 'monospace'
91
+ margin: 16
89
92
  },
90
93
  axisLine: {
91
94
  lineStyle: {
@@ -94,18 +97,17 @@
94
97
  },
95
98
  nameTextStyle: {
96
99
  fontSize: 12,
100
+ fontFamily: 'af Another Sans',
97
101
  color: textColor.secondary
98
102
  }
99
103
  }
100
104
  } as const;
101
105
 
102
- const finalOptions = deepMerge(structuredClone(defaultOptions), options);
103
-
104
106
  function initChart() {
105
107
  if (container) {
106
- chart = echarts.init(container, theme, { renderer });
107
- chart.setOption(finalOptions);
108
-
108
+ chart = init(container, theme, { renderer });
109
+ chart.setOption(defaultOptions);
110
+ chart.setOption(options, { notMerge: false });
109
111
  if (onitemclick) chart.on('click', onitemclick);
110
112
  if (onmouseover) chart.on('mouseover', onmouseover);
111
113
  if (onmouseout) chart.on('mouseout', onmouseout);
@@ -114,6 +116,73 @@
114
116
  }
115
117
  }
116
118
 
119
+ export function updateOptions(newOptions: EChartsOption) {
120
+ if (chart) {
121
+ chart.setOption(newOptions, { notMerge: false });
122
+ }
123
+ }
124
+
125
+ $effect(() => {
126
+ if (chart) {
127
+ chart.setOption(options, { notMerge: false });
128
+ }
129
+ });
130
+
131
+ // This effect is used to add a mark line to the chart when the timeIndex prop is provided
132
+ $effect(() => {
133
+ if (!chart || !timeIndex) return;
134
+
135
+ const seriesArray = Array.isArray(options.series)
136
+ ? options.series
137
+ : options.series
138
+ ? [options.series]
139
+ : [];
140
+
141
+ if (seriesArray.length === 0) return;
142
+
143
+ const seriesUpdate: SeriesOption[] = seriesArray.map((s: SeriesOption, index: number) => {
144
+ let newSeries = { ...s };
145
+
146
+ if (index === 0) {
147
+ if (typeof timeIndex === 'number') {
148
+ const existingMarkLine =
149
+ typeof newSeries.markLine === 'object' && newSeries.markLine !== null
150
+ ? newSeries.markLine
151
+ : {};
152
+
153
+ newSeries.markLine = {
154
+ ...existingMarkLine,
155
+ id: 'currentLocationMarkLine',
156
+ symbol: ['none', 'none'],
157
+ silent: true,
158
+ lineStyle: {
159
+ color: colors.gray[2],
160
+ type: 'dashed',
161
+ width: 1
162
+ },
163
+ data: [{ xAxis: timeIndex }],
164
+ label: {
165
+ position: 'insideEndTop',
166
+ show: false
167
+ }
168
+ };
169
+ } else {
170
+ if (
171
+ newSeries.markLine &&
172
+ typeof newSeries.markLine === 'object' &&
173
+ 'id' in newSeries.markLine &&
174
+ newSeries.markLine.id === 'currentLocationMarkLine'
175
+ ) {
176
+ delete newSeries.markLine;
177
+ }
178
+ }
179
+ }
180
+ return newSeries;
181
+ });
182
+
183
+ chart.setOption({ series: seriesUpdate }, { notMerge: false });
184
+ });
185
+
117
186
  $effect(() => {
118
187
  if (loading) {
119
188
  chart?.showLoading();
@@ -136,10 +205,13 @@
136
205
  });
137
206
  </script>
138
207
 
139
- <div bind:this={container} style="width: {width}; height: {height};" class="chart-container"></div>
208
+ <div bind:this={container} style="width: {width}; height: {height};" class="chart-container">
209
+ {@render children?.()}
210
+ </div>
140
211
 
141
212
  <style>
142
213
  .chart-container {
143
214
  position: relative;
215
+ overflow: visible;
144
216
  }
145
217
  </style>
@@ -1,17 +1,27 @@
1
- import * as echarts from 'echarts';
2
- import type { ECElementEvent } from 'echarts';
3
- type Props = {
4
- options: echarts.EChartsOption;
1
+ import type { EChartsOption, ECElementEvent } from 'echarts';
2
+ import { type Snippet } from 'svelte';
3
+ type ChartProps = {
4
+ options: EChartsOption;
5
5
  theme?: string | object;
6
6
  renderer?: 'canvas' | 'svg';
7
7
  height?: string;
8
8
  width?: string;
9
+ xAxisName?: string;
10
+ yAxisName?: string;
11
+ yAxisUnit?: string;
12
+ xAxisOptions?: EChartsOption['xAxis'];
13
+ yAxisOptions?: EChartsOption['yAxis'];
9
14
  onitemclick?: (params: ECElementEvent) => void;
10
15
  onmouseover?: (params: ECElementEvent) => void;
11
16
  onmouseout?: () => void;
12
17
  autoResize?: boolean;
13
18
  loading?: boolean;
19
+ timeIndex?: number;
20
+ children?: Snippet;
14
21
  };
15
- declare const Chart: import("svelte").Component<Props, {}, "">;
22
+ export type GenericChartProps = Omit<ChartProps, 'options'>;
23
+ declare const Chart: import("svelte").Component<ChartProps, {
24
+ updateOptions: (newOptions: EChartsOption) => void;
25
+ }, "">;
16
26
  type Chart = ReturnType<typeof Chart>;
17
27
  export default Chart;
@@ -2,3 +2,6 @@ export { default as Scatterplot } from './scatterplot/Scatterplot.svelte';
2
2
  export { default as Chart } from './chart/Chart.svelte';
3
3
  export { default as LineChart } from './line/LineChart.svelte';
4
4
  export { default as MultiLineChart } from './multiline/MultiLineChart.svelte';
5
+ export { default as Matrix } from './matrix/Matrix.svelte';
6
+ export { default as BarChart } from './bar-chart/BarChart.svelte';
7
+ export { default as StackedBarChart } from './bar-chart/StackedBarChart.svelte';
@@ -2,3 +2,6 @@ export { default as Scatterplot } from './scatterplot/Scatterplot.svelte';
2
2
  export { default as Chart } from './chart/Chart.svelte';
3
3
  export { default as LineChart } from './line/LineChart.svelte';
4
4
  export { default as MultiLineChart } from './multiline/MultiLineChart.svelte';
5
+ export { default as Matrix } from './matrix/Matrix.svelte';
6
+ export { default as BarChart } from './bar-chart/BarChart.svelte';
7
+ export { default as StackedBarChart } from './bar-chart/StackedBarChart.svelte';
@@ -1,6 +1,7 @@
1
1
  <script module lang="ts">
2
2
  import { defineMeta } from '@storybook/addon-svelte-csf';
3
-
3
+ import type { ECElementEvent } from 'echarts';
4
+ import { within, userEvent } from '@storybook/test';
4
5
  import LineChart from './LineChart.svelte';
5
6
 
6
7
  const { Story } = defineMeta({
@@ -9,8 +10,8 @@
9
10
  tags: ['autodocs']
10
11
  });
11
12
 
12
- const xAxis = '€€€';
13
- const yAxis = '$$$';
13
+ const xAxisName = 'Time';
14
+ const yAxisName = 'Count';
14
15
 
15
16
  const data = [
16
17
  10.0, 8.04, 8.07, 6.95, 13.0, 7.58, 9.05, 8.81, 11.0, 8.33, 14.0, 7.66, 13.4, 6.81, 10.0, 6.33,
@@ -20,24 +21,29 @@
20
21
 
21
22
  const bigData = Array.from({ length: 1000 }, (_, i) => i);
22
23
 
23
- function handleItemClick(params: echarts.ECElementEvent) {
24
+ function handleItemClick(params: ECElementEvent) {
24
25
  console.log(params);
25
26
  }
26
27
 
27
- function handleMouseOver(params: echarts.ECElementEvent) {
28
+ function handleMouseOver(params: ECElementEvent) {
28
29
  console.log(params);
29
30
  }
30
31
 
31
32
  function handleMouseOut() {
32
33
  console.log('mouse out');
33
34
  }
35
+
36
+ // State for interactive current location story
37
+ let interactivetimeIndex = $state(3);
38
+ const interactiveChartData = [10, 8, 13, 7, 9, 6, 11];
34
39
  </script>
35
40
 
36
- <Story name="Base">
41
+ <Story name="Base" asChild>
37
42
  <div class="h-[400px] w-full">
38
43
  <LineChart
39
- {xAxis}
40
- {yAxis}
44
+ {xAxisName}
45
+ {yAxisName}
46
+ yAxisUnit="mm²"
41
47
  {data}
42
48
  onitemclick={handleItemClick}
43
49
  onmouseover={handleMouseOver}
@@ -45,11 +51,11 @@
45
51
  />
46
52
  </div>
47
53
  </Story>
48
- <Story name="Loading">
54
+ <Story name="Loading" asChild>
49
55
  <div class="h-[400px] w-full">
50
56
  <LineChart
51
- {xAxis}
52
- {yAxis}
57
+ {xAxisName}
58
+ {yAxisName}
53
59
  {data}
54
60
  loading
55
61
  onitemclick={handleItemClick}
@@ -58,16 +64,102 @@
58
64
  />
59
65
  </div>
60
66
  </Story>
61
- <Story name="Large datasets with capture intervals">
67
+ <Story name="Large datasets with capture intervals" asChild>
62
68
  <div class="h-[400px] w-full">
63
69
  <LineChart
64
- {xAxis}
65
- {yAxis}
70
+ {xAxisName}
71
+ {yAxisName}
66
72
  data={bigData}
67
- captureInterval={1000}
68
73
  onitemclick={handleItemClick}
69
74
  onmouseover={handleMouseOver}
70
75
  onmouseout={handleMouseOut}
71
76
  />
72
77
  </div>
73
78
  </Story>
79
+ <Story name="With Area Gradient" asChild>
80
+ <div class="h-[400px] w-full">
81
+ <LineChart
82
+ {xAxisName}
83
+ {yAxisName}
84
+ {data}
85
+ withArea
86
+ onitemclick={handleItemClick}
87
+ onmouseover={handleMouseOver}
88
+ onmouseout={handleMouseOut}
89
+ />
90
+ </div>
91
+ </Story>
92
+ <Story name="Custom Color" asChild>
93
+ <div class="h-[400px] w-full">
94
+ <LineChart
95
+ {xAxisName}
96
+ {yAxisName}
97
+ {data}
98
+ color="#e01b5c"
99
+ onitemclick={handleItemClick}
100
+ onmouseover={handleMouseOver}
101
+ onmouseout={handleMouseOut}
102
+ />
103
+ </div>
104
+ </Story>
105
+ <Story name="Custom Color with Area" asChild>
106
+ <div class="h-[400px] w-full">
107
+ <LineChart
108
+ {xAxisName}
109
+ {yAxisName}
110
+ {data}
111
+ color="#3ba272"
112
+ withArea
113
+ onitemclick={handleItemClick}
114
+ onmouseover={handleMouseOver}
115
+ onmouseout={handleMouseOut}
116
+ />
117
+ </div>
118
+ </Story>
119
+ <Story name="With Current Location" asChild>
120
+ <div class="h-[400px] w-full">
121
+ <LineChart {xAxisName} yAxisName="Value" data={[10, 8, 13, 7, 9, 6, 11]} timeIndex={3} />
122
+ </div>
123
+ </Story>
124
+ <Story
125
+ name="Interactive Current Location"
126
+ asChild
127
+ play={async ({ canvasElement }) => {
128
+ const canvas = within(canvasElement);
129
+
130
+ // Find the input field by its label
131
+ const input = canvas.getByLabelText('Current Location X:');
132
+
133
+ // Clear the input and type a new value
134
+ await userEvent.clear(input);
135
+ await userEvent.type(input, '5');
136
+ await new Promise((resolve) => setTimeout(resolve, 1000));
137
+
138
+ await userEvent.clear(input);
139
+ await userEvent.type(input, '2');
140
+
141
+ // Add a small delay to observe the change if running interactively
142
+ await new Promise((resolve) => setTimeout(resolve, 500));
143
+ }}
144
+ >
145
+ <div class="flex h-[450px] w-full flex-col gap-4">
146
+ <label class="flex items-center gap-2">
147
+ Current Location X:
148
+ <input
149
+ type="number"
150
+ bind:value={interactivetimeIndex}
151
+ min="0"
152
+ max={interactiveChartData.length - 1}
153
+ class="w-20 rounded border p-1"
154
+ />
155
+ </label>
156
+ <div class="h-full w-full">
157
+ <LineChart
158
+ {xAxisName}
159
+ yAxisName="Value"
160
+ data={interactiveChartData}
161
+ timeIndex={interactivetimeIndex}
162
+ />
163
+ </div>
164
+ </div>
165
+ </Story>
@@ -1,24 +1,32 @@
1
1
  <script lang="ts">
2
- import { textColor, backgroundColor } from '../../../tokens';
2
+ import { textColor } from '../../../tokens';
3
3
  import Chart from '../chart/Chart.svelte';
4
4
  import type { EChartsOption } from 'echarts';
5
- import { Duration } from 'luxon';
5
+ import * as echarts from 'echarts/core';
6
+ import type { GenericChartProps } from '../chart/Chart.svelte';
7
+ import { createTooltipFormatter } from '../utils/tooltipFormatter';
6
8
 
7
- interface Props {
9
+ interface LineChartProps extends GenericChartProps {
8
10
  data: (number | null)[];
9
- captureInterval?: number;
10
- loading?: boolean;
11
- xAxis?: string;
12
- yAxis?: string;
13
- height?: string;
14
- width?: string;
15
- xAxisOptions?: EChartsOption['xAxis'];
16
- yAxisOptions?: EChartsOption['yAxis'];
17
- onitemclick?: (params: echarts.ECElementEvent) => void;
18
- onmouseover?: (params: echarts.ECElementEvent) => void;
19
- onmouseout?: () => void;
11
+ withArea?: boolean;
12
+ color?: string;
13
+ grid?: EChartsOption['grid'];
20
14
  }
21
15
 
16
+ let {
17
+ data,
18
+ xAxisName,
19
+ yAxisName,
20
+ withArea = false,
21
+ color = textColor['icon-blue'],
22
+ ...props
23
+ }: LineChartProps = $props();
24
+
25
+ const formatTooltip = createTooltipFormatter({
26
+ yAxisName: yAxisName,
27
+ yAxisUnit: props.yAxisUnit
28
+ });
29
+
22
30
  const toFixedLocaleString = (
23
31
  value?: number | undefined,
24
32
  fractionDigits: number | undefined = 0,
@@ -29,31 +37,14 @@
29
37
  maximumFractionDigits: fractionDigits
30
38
  }) ?? '';
31
39
 
32
- let { data, xAxis, xAxisOptions, yAxis, yAxisOptions, captureInterval, ...props }: Props =
33
- $props();
34
-
35
- const captureIntervals = captureInterval
36
- ? Array(data.length)
37
- .fill(null)
38
- .map((_, timeIndex) => {
39
- const seconds = timeIndex * captureInterval;
40
- const duration = Duration.fromObject({ seconds }).shiftTo('days', 'hours', 'minutes');
41
- return duration.days >= 1 ? duration.toFormat('dd:hh:mm') : duration.toFormat('hh:mm');
42
- })
43
- : undefined;
44
-
45
- $effect(() => {
46
- console.log(captureIntervals);
47
- });
48
-
49
- let options: EChartsOption = {
50
- color: ['#5750EE', '#FF7100', '#50EEA6', '#E7EE50', '#EE5098'],
40
+ let options: EChartsOption = $derived({
51
41
  grid: {
52
42
  top: 10,
53
43
  bottom: 10,
54
44
  left: 10,
55
45
  right: 10,
56
- containLabel: true
46
+ containLabel: true,
47
+ ...props.grid
57
48
  },
58
49
  textStyle: {
59
50
  color: textColor['secondary']
@@ -64,10 +55,28 @@
64
55
  axisLine: {
65
56
  onZero: false
66
57
  },
67
- name: xAxis,
68
- data: captureIntervals,
69
- ...xAxisOptions
70
- },
58
+ axisLabel: {
59
+ interval: (index: number, value: string) => {
60
+ const dataLength = data.length;
61
+ if (dataLength <= 1) return true; // Show label if only one point
62
+
63
+ const targetLabelCount = 10; // Aim for about 10 labels
64
+ // Calculate interval, ensuring it's at least 1
65
+ const calculatedInterval = Math.max(1, Math.ceil(dataLength / targetLabelCount));
66
+
67
+ // Show the first label (index 0)
68
+ if (index === 0) return true;
69
+ // Show the last label if data exists
70
+ if (dataLength > 0 && index === dataLength - 1) return true;
71
+ // Show labels at the calculated interval, but not the last one if it was already shown
72
+ if (index % calculatedInterval === 0 && index !== dataLength - 1) return true;
73
+ // Hide others
74
+ return false;
75
+ },
76
+ hideOverlap: true
77
+ },
78
+ ...props.xAxisOptions
79
+ } as any as EChartsOption['xAxis'],
71
80
  yAxis: {
72
81
  type: 'value',
73
82
  alignTicks: true,
@@ -79,24 +88,54 @@
79
88
  formatter: (value: any) => toFixedLocaleString(value.value, 2)
80
89
  }
81
90
  },
82
- name: yAxis,
83
- ...yAxisOptions
91
+ ...props.yAxisOptions
84
92
  },
85
93
  selectedMode: 'multiple',
94
+ tooltip: {
95
+ axisPointer: {
96
+ type: 'line',
97
+ lineStyle: {
98
+ type: 'solid'
99
+ }
100
+ },
101
+ trigger: 'axis',
102
+ formatter: formatTooltip
103
+ },
86
104
  series: {
87
- animation: false,
88
- seriesLayoutBy: 'row',
89
- emphasis: {
90
- focus: 'series'
105
+ type: 'line',
106
+ symbol: 'circle',
107
+ name: yAxisName,
108
+ symbolSize: 1,
109
+ data: data,
110
+ lineStyle: {
111
+ color: color
91
112
  },
92
- tooltip: {
93
- show: false
113
+ itemStyle: {
114
+ color: color
94
115
  },
95
- type: 'line',
96
- symbol: data.length > 1 ? 'none' : 'circle',
97
- data
116
+ areaStyle: withArea
117
+ ? {
118
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
119
+ {
120
+ offset: 0,
121
+ color: echarts.color.modifyAlpha(color, 0.4)
122
+ },
123
+ {
124
+ offset: 1,
125
+ color: echarts.color.modifyAlpha(color, 0)
126
+ }
127
+ ])
128
+ }
129
+ : undefined
98
130
  }
99
- };
131
+ });
100
132
  </script>
101
133
 
102
- <Chart {options} {...props} />
134
+ <Chart
135
+ {options}
136
+ {...{
137
+ ...props,
138
+ xAxisName,
139
+ yAxisName
140
+ }}
141
+ />
@@ -1,18 +1,11 @@
1
1
  import type { EChartsOption } from 'echarts';
2
- interface Props {
2
+ import type { GenericChartProps } from '../chart/Chart.svelte';
3
+ interface LineChartProps extends GenericChartProps {
3
4
  data: (number | null)[];
4
- captureInterval?: number;
5
- loading?: boolean;
6
- xAxis?: string;
7
- yAxis?: string;
8
- height?: string;
9
- width?: string;
10
- xAxisOptions?: EChartsOption['xAxis'];
11
- yAxisOptions?: EChartsOption['yAxis'];
12
- onitemclick?: (params: echarts.ECElementEvent) => void;
13
- onmouseover?: (params: echarts.ECElementEvent) => void;
14
- onmouseout?: () => void;
5
+ withArea?: boolean;
6
+ color?: string;
7
+ grid?: EChartsOption['grid'];
15
8
  }
16
- declare const LineChart: import("svelte").Component<Props, {}, "">;
9
+ declare const LineChart: import("svelte").Component<LineChartProps, {}, "">;
17
10
  type LineChart = ReturnType<typeof LineChart>;
18
11
  export default LineChart;