@reshape-biotech/design-system 0.0.54 → 1.1.2
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/components/activity/Activity.stories.svelte +21 -8
- package/dist/components/activity/Activity.svelte +44 -6
- package/dist/components/activity/Activity.svelte.d.ts +1 -1
- package/dist/components/avatar/Avatar.stories.svelte +7 -17
- package/dist/components/avatar/Avatar.svelte +2 -2
- package/dist/components/avatar/Avatar.svelte.d.ts +2 -2
- package/dist/components/banner/Banner.stories.svelte +5 -5
- package/dist/components/banner/Banner.svelte +1 -1
- package/dist/components/button/Button.stories.svelte +54 -21
- package/dist/components/button/Button.svelte +58 -11
- package/dist/components/button/Button.svelte.d.ts +4 -3
- package/dist/components/card/Card.stories.svelte +130 -0
- package/dist/components/card/Card.stories.svelte.d.ts +19 -0
- package/dist/components/card/Card.svelte +25 -0
- package/dist/components/card/Card.svelte.d.ts +10 -0
- package/dist/components/card/index.d.ts +1 -0
- package/dist/components/card/index.js +1 -0
- package/dist/components/checkbox/Checkbox.stories.svelte +7 -15
- package/dist/components/checkbox/Checkbox.svelte +7 -7
- package/dist/components/checkbox/Checkbox.svelte.d.ts +3 -5
- package/dist/components/collapsible/Collapsible.stories.svelte +5 -4
- package/dist/components/combobox/Combobox.stories.svelte +7 -5
- package/dist/components/datepicker/DatePicker.stories.svelte +13 -18
- package/dist/components/datepicker/DatePicker.svelte +1 -0
- package/dist/components/divider/Divider.stories.svelte +1 -3
- package/dist/components/divider/Divider.svelte +8 -2
- package/dist/components/divider/Divider.svelte.d.ts +2 -0
- package/dist/components/drawer/Drawer.stories.svelte +3 -3
- package/dist/components/dropdown/Dropdown.stories.svelte +8 -8
- package/dist/components/empty-content/EmptyContent.stories.svelte +2 -2
- package/dist/components/graphs/bar-chart/BarChart.stories.svelte +81 -0
- package/dist/components/graphs/bar-chart/BarChart.stories.svelte.d.ts +19 -0
- package/dist/components/graphs/bar-chart/BarChart.svelte +136 -0
- package/dist/components/graphs/bar-chart/BarChart.svelte.d.ts +15 -0
- package/dist/components/graphs/bar-chart/StackedBarChart.stories.svelte +42 -0
- package/dist/components/graphs/bar-chart/StackedBarChart.stories.svelte.d.ts +19 -0
- package/dist/components/graphs/bar-chart/StackedBarChart.svelte +177 -0
- package/dist/components/graphs/bar-chart/StackedBarChart.svelte.d.ts +16 -0
- package/dist/components/graphs/chart/Chart.stories.svelte +30 -25
- package/dist/components/graphs/chart/Chart.svelte +104 -32
- package/dist/components/graphs/chart/Chart.svelte.d.ts +15 -5
- package/dist/components/graphs/index.d.ts +3 -0
- package/dist/components/graphs/index.js +3 -0
- package/dist/components/graphs/line/LineChart.stories.svelte +97 -17
- package/dist/components/graphs/line/LineChart.svelte +90 -51
- package/dist/components/graphs/line/LineChart.svelte.d.ts +6 -13
- package/dist/components/graphs/matrix/Matrix.stories.svelte +142 -0
- package/dist/components/graphs/matrix/Matrix.stories.svelte.d.ts +19 -0
- package/dist/components/graphs/matrix/Matrix.svelte +149 -0
- package/dist/components/graphs/matrix/Matrix.svelte.d.ts +24 -0
- package/dist/components/graphs/matrix/index.d.ts +3 -0
- package/dist/components/graphs/matrix/index.js +3 -0
- package/dist/components/graphs/multiline/MultiLineChart.stories.svelte +115 -28
- package/dist/components/graphs/multiline/MultiLineChart.svelte +187 -50
- package/dist/components/graphs/multiline/MultiLineChart.svelte.d.ts +9 -12
- package/dist/components/graphs/scatterplot/Scatterplot.stories.svelte +68 -41
- package/dist/components/graphs/scatterplot/Scatterplot.svelte +312 -45
- package/dist/components/graphs/scatterplot/Scatterplot.svelte.d.ts +23 -13
- package/dist/components/graphs/utils/tooltipFormatter.d.ts +10 -0
- package/dist/components/graphs/utils/tooltipFormatter.js +52 -0
- package/dist/components/icon-button/IconButton.stories.svelte +6 -6
- package/dist/components/icon-button/IconButton.svelte +50 -9
- package/dist/components/icon-button/IconButton.svelte.d.ts +3 -5
- package/dist/components/icons/AnalysisIcon.stories.svelte +15 -21
- package/dist/components/icons/AnalysisIcon.svelte +63 -44
- package/dist/components/icons/AnalysisIcon.svelte.d.ts +1 -0
- package/dist/components/icons/Icon.stories.svelte +4 -4
- package/dist/components/icons/Icon.svelte +1 -1
- package/dist/components/icons/PrincipalIcon.svelte +96 -0
- package/dist/components/icons/PrincipalIcon.svelte.d.ts +10 -0
- package/dist/components/icons/custom/Halo.svelte +14 -8
- package/dist/components/icons/custom/Halo.svelte.d.ts +7 -25
- package/dist/components/icons/custom/Well.svelte +14 -6
- package/dist/components/icons/custom/Well.svelte.d.ts +7 -25
- package/dist/components/icons/index.d.ts +3 -2
- package/dist/components/icons/index.js +34 -0
- package/dist/components/input/Input.stories.svelte +16 -22
- package/dist/components/input/Input.svelte +140 -134
- package/dist/components/input/Input.svelte.d.ts +12 -13
- package/dist/components/label/Label.stories.svelte +28 -0
- package/dist/components/label/Label.stories.svelte.d.ts +19 -0
- package/dist/components/label/Label.svelte +17 -0
- package/dist/components/label/Label.svelte.d.ts +9 -0
- package/dist/components/list/List.stories.svelte +3 -3
- package/dist/components/logo/Logo.stories.svelte +1 -1
- package/dist/components/manual-cfu-counter/ManualCFUCounter.stories.svelte +125 -0
- package/dist/components/manual-cfu-counter/ManualCFUCounter.stories.svelte.d.ts +3 -0
- package/dist/components/manual-cfu-counter/ManualCFUCounter.svelte +577 -0
- package/dist/components/manual-cfu-counter/ManualCFUCounter.svelte.d.ts +16 -0
- package/dist/components/manual-cfu-counter/index.d.ts +1 -0
- package/dist/components/manual-cfu-counter/index.js +1 -0
- package/dist/components/manual-cfu-counter/test/ManualCFUCounterTestWrapper.svelte +22 -0
- package/dist/components/manual-cfu-counter/test/ManualCFUCounterTestWrapper.svelte.d.ts +19 -0
- package/dist/components/markdown/Markdown.stories.svelte +1 -1
- package/dist/components/markdown/Markdown.svelte +1 -1
- package/dist/components/modal/Modal.stories.svelte +2 -2
- package/dist/components/modal/Modal.svelte +27 -22
- package/dist/components/modal/Modal.svelte.d.ts +4 -1
- package/dist/components/notification-popup/NotificationPopup.stories.svelte +1 -1
- package/dist/components/pill/Pill.stories.svelte +13 -0
- package/dist/components/pill/Pill.stories.svelte.d.ts +19 -0
- package/dist/components/progress-circle/ProgressCircle.stories.svelte +15 -0
- package/dist/components/progress-circle/ProgressCircle.stories.svelte.d.ts +19 -0
- package/dist/components/required-status-indicator/RequiredStatusIndicator.stories.svelte +28 -0
- package/dist/components/required-status-indicator/RequiredStatusIndicator.stories.svelte.d.ts +19 -0
- package/dist/components/required-status-indicator/RequiredStatusIndicator.svelte +22 -0
- package/dist/components/required-status-indicator/RequiredStatusIndicator.svelte.d.ts +8 -0
- package/dist/components/required-status-indicator/index.d.ts +1 -0
- package/dist/components/required-status-indicator/index.js +1 -0
- package/dist/components/segmented-control-buttons/SegmentedControlButtons.stories.svelte +3 -3
- package/dist/components/select/Select.stories.svelte +12 -12
- package/dist/components/select/Select.svelte +0 -2
- package/dist/components/select-new/Select.stories.svelte +219 -0
- package/dist/components/select-new/Select.stories.svelte.d.ts +19 -0
- package/dist/components/select-new/components/Group.svelte +24 -0
- package/dist/components/select-new/components/Group.svelte.d.ts +11 -0
- package/dist/components/select-new/components/MultiSelectTrigger.svelte +66 -0
- package/dist/components/select-new/components/MultiSelectTrigger.svelte.d.ts +17 -0
- package/dist/components/select-new/components/SelectContent.svelte +33 -0
- package/dist/components/select-new/components/SelectContent.svelte.d.ts +10 -0
- package/dist/components/select-new/components/SelectGroupHeading.svelte +19 -0
- package/dist/components/select-new/components/SelectGroupHeading.svelte.d.ts +9 -0
- package/dist/components/select-new/components/SelectItem.svelte +41 -0
- package/dist/components/select-new/components/SelectItem.svelte.d.ts +9 -0
- package/dist/components/select-new/components/SelectTrigger.svelte +48 -0
- package/dist/components/select-new/components/SelectTrigger.svelte.d.ts +12 -0
- package/dist/components/select-new/index.d.ts +10 -0
- package/dist/components/select-new/index.js +12 -0
- package/dist/components/select-new/types.d.ts +25 -0
- package/dist/components/select-new/types.js +1 -0
- package/dist/components/sjsf-wrappers/SjsfNumberInputWrapper.svelte +92 -0
- package/dist/components/sjsf-wrappers/SjsfNumberInputWrapper.svelte.d.ts +3 -0
- package/dist/components/sjsf-wrappers/SjsfTextInputWrapper.svelte +65 -0
- package/dist/components/sjsf-wrappers/SjsfTextInputWrapper.svelte.d.ts +3 -0
- package/dist/components/sjsf-wrappers/index.d.ts +2 -0
- package/dist/components/sjsf-wrappers/index.js +2 -0
- package/dist/components/sjsf-wrappers/sjsfCustomTheme.d.ts +2 -0
- package/dist/components/sjsf-wrappers/sjsfCustomTheme.js +8 -0
- package/dist/components/skeleton-loader/SkeletonLoader.stories.svelte +4 -4
- package/dist/components/slider/Slider.stories.svelte +4 -4
- package/dist/components/spinner/Spinner.stories.svelte +13 -0
- package/dist/components/spinner/Spinner.stories.svelte.d.ts +19 -0
- package/dist/components/stat-card/StatCard.stories.svelte +27 -19
- package/dist/components/stat-card/StatCard.svelte +100 -6
- package/dist/components/stat-card/StatCard.svelte.d.ts +3 -0
- package/dist/components/status-badge/StatusBadge.stories.svelte +6 -6
- package/dist/components/status-badge/StatusBadge.svelte +5 -3
- package/dist/components/stepper/Stepper.stories.svelte +243 -0
- package/dist/components/stepper/Stepper.stories.svelte.d.ts +19 -0
- package/dist/components/stepper/components/stepper-root.svelte +20 -0
- package/dist/components/stepper/components/stepper-root.svelte.d.ts +9 -0
- package/dist/components/stepper/components/stepper-step.svelte +100 -0
- package/dist/components/stepper/components/stepper-step.svelte.d.ts +11 -0
- package/dist/components/stepper/index.d.ts +15 -0
- package/dist/components/stepper/index.js +2 -0
- package/dist/components/table/Table.stories.svelte +1 -1
- package/dist/components/table/components/Td.svelte +3 -2
- package/dist/components/table/components/Td.svelte.d.ts +1 -0
- package/dist/components/table/components/Tr.svelte +3 -2
- package/dist/components/table/components/Tr.svelte.d.ts +1 -0
- package/dist/components/tabs/Tabs.stories.svelte +1 -1
- package/dist/components/tag/Tag.stories.svelte +9 -9
- package/dist/components/tag/Tag.svelte +0 -18
- package/dist/components/textarea/Textarea.stories.svelte +97 -0
- package/dist/components/textarea/Textarea.stories.svelte.d.ts +19 -0
- package/dist/components/textarea/Textarea.svelte +94 -0
- package/dist/components/textarea/Textarea.svelte.d.ts +17 -0
- package/dist/components/textarea/index.d.ts +1 -0
- package/dist/components/textarea/index.js +1 -0
- package/dist/components/toggle/Toggle.stories.svelte +1 -1
- package/dist/components/toggle/Toggle.svelte +3 -2
- package/dist/components/toggle/Toggle.svelte.d.ts +1 -0
- package/dist/components/toggle-icon-button/ToggleIconButton.stories.svelte +6 -6
- package/dist/components/tooltip/Tooltip.stories.svelte +6 -6
- package/dist/components/tooltip/Tooltip.svelte +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/tailwind.preset.d.ts +5 -0
- package/dist/tokens.d.ts +10 -0
- package/dist/tokens.js +6 -4
- package/package.json +1 -2
|
@@ -1,67 +1,334 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
import { backgroundColor } from '../../../tokens';
|
|
3
|
+
import Icon from '../../icons/Icon.svelte';
|
|
4
|
+
import Chart, { type GenericChartProps } from '../chart/Chart.svelte';
|
|
5
|
+
import type {
|
|
6
|
+
EChartsOption,
|
|
7
|
+
SeriesOption,
|
|
8
|
+
CustomSeriesRenderItemAPI,
|
|
9
|
+
CustomSeriesRenderItemParams
|
|
10
|
+
} from 'echarts';
|
|
11
|
+
import Tooltip from '../../tooltip/Tooltip.svelte';
|
|
12
|
+
import type { Snippet } from 'svelte';
|
|
13
|
+
|
|
14
|
+
export type DataPoint = { value: [number, number]; metadata: any; error_value?: number };
|
|
15
|
+
|
|
16
|
+
export type ScatterPlotEchartsEvent = echarts.ECElementEvent & {
|
|
17
|
+
data: DataPoint;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type LegendItem = {
|
|
21
|
+
label: string;
|
|
22
|
+
color: string;
|
|
23
|
+
type: 'point' | 'line' | 'area';
|
|
17
24
|
};
|
|
18
25
|
|
|
26
|
+
type ScatterPlotProps = {
|
|
27
|
+
data: DataPoint[];
|
|
28
|
+
lineData?: [[number, number], [number, number]];
|
|
29
|
+
showConfidenceBand?: boolean;
|
|
30
|
+
showLegend?: boolean;
|
|
31
|
+
legendItems?: LegendItem[];
|
|
32
|
+
children?: Snippet;
|
|
33
|
+
} & Omit<GenericChartProps, 'timeIndex'>;
|
|
34
|
+
|
|
19
35
|
const {
|
|
20
36
|
data,
|
|
21
|
-
|
|
22
|
-
|
|
37
|
+
xAxisName,
|
|
38
|
+
yAxisName,
|
|
23
39
|
loading = false,
|
|
40
|
+
showConfidenceBand = false,
|
|
24
41
|
onitemclick,
|
|
25
42
|
onmouseover,
|
|
26
43
|
onmouseout,
|
|
44
|
+
showLegend = false,
|
|
45
|
+
legendItems = [
|
|
46
|
+
{ label: 'Count', color: backgroundColor['blue-inverse'], type: 'point' },
|
|
47
|
+
{ label: 'Perfect agreement', color: backgroundColor['lilac-inverse'], type: 'line' }
|
|
48
|
+
],
|
|
49
|
+
children,
|
|
27
50
|
...props
|
|
28
|
-
}:
|
|
51
|
+
}: ScatterPlotProps = $props();
|
|
52
|
+
|
|
53
|
+
const displayedLegendItems: LegendItem[] = $derived([
|
|
54
|
+
...legendItems,
|
|
55
|
+
...(showConfidenceBand
|
|
56
|
+
? [
|
|
57
|
+
{
|
|
58
|
+
label: 'Error margin',
|
|
59
|
+
color: backgroundColor.lilac,
|
|
60
|
+
type: 'area' as const
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
: [])
|
|
64
|
+
]);
|
|
29
65
|
|
|
30
|
-
|
|
66
|
+
let chartComponent: any;
|
|
67
|
+
|
|
68
|
+
function handleClick(params: ScatterPlotEchartsEvent) {
|
|
31
69
|
onitemclick?.(params);
|
|
32
70
|
}
|
|
33
71
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
72
|
+
function handleMouseOver(params: ScatterPlotEchartsEvent) {
|
|
73
|
+
onmouseover?.(params);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function handleMouseOut() {
|
|
77
|
+
onmouseout?.();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// from https://echarts.apache.org/examples/en/editor.html?c=custom-error-bar
|
|
81
|
+
function renderErrorBarItem(
|
|
82
|
+
params: CustomSeriesRenderItemParams,
|
|
83
|
+
api: CustomSeriesRenderItemAPI
|
|
84
|
+
) {
|
|
85
|
+
const xValue = api.value(0) as number;
|
|
86
|
+
const yValue = api.value(1) as number;
|
|
87
|
+
const error = api.value(2) as number;
|
|
88
|
+
|
|
89
|
+
const highPoint = api.coord([xValue, yValue + error]);
|
|
90
|
+
const lowPoint = api.coord([xValue, yValue - error]);
|
|
91
|
+
|
|
92
|
+
if (!highPoint || !lowPoint) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// calculate a dynamic width for the caps based on the x-axis scale
|
|
97
|
+
const sizeValue = api.size?.([1, 0]);
|
|
98
|
+
const baseWidth = Array.isArray(sizeValue) ? sizeValue[0] : 10;
|
|
99
|
+
const halfWidth = Math.min((baseWidth ?? 10) * 1.5, 3);
|
|
100
|
+
const style = {
|
|
101
|
+
stroke: api.visual('color') as string,
|
|
102
|
+
fill: undefined
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
return {
|
|
106
|
+
type: 'group' as const,
|
|
107
|
+
children: [
|
|
108
|
+
{
|
|
109
|
+
type: 'line' as const,
|
|
110
|
+
transition: 'shape' as const,
|
|
111
|
+
shape: {
|
|
112
|
+
x1: highPoint[0] - halfWidth,
|
|
113
|
+
y1: highPoint[1],
|
|
114
|
+
x2: highPoint[0] + halfWidth,
|
|
115
|
+
y2: highPoint[1]
|
|
116
|
+
},
|
|
117
|
+
style
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
type: 'line' as const,
|
|
121
|
+
transition: 'shape' as const,
|
|
122
|
+
shape: {
|
|
123
|
+
x1: highPoint[0],
|
|
124
|
+
y1: highPoint[1],
|
|
125
|
+
x2: lowPoint[0],
|
|
126
|
+
y2: lowPoint[1]
|
|
127
|
+
},
|
|
128
|
+
style
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: 'line' as const,
|
|
132
|
+
transition: 'shape' as const,
|
|
133
|
+
shape: {
|
|
134
|
+
x1: lowPoint[0] - halfWidth,
|
|
135
|
+
y1: lowPoint[1],
|
|
136
|
+
x2: lowPoint[0] + halfWidth,
|
|
137
|
+
y2: lowPoint[1]
|
|
138
|
+
},
|
|
139
|
+
style
|
|
52
140
|
}
|
|
53
|
-
|
|
54
|
-
|
|
141
|
+
]
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const options = $derived(getChartOptions());
|
|
146
|
+
|
|
147
|
+
function getChartOptions(): EChartsOption {
|
|
148
|
+
const series: SeriesOption[] = [];
|
|
149
|
+
const errorBarData = data
|
|
150
|
+
.filter((d) => d.error_value != 0)
|
|
151
|
+
.map((d) => [...d.value, d.error_value]);
|
|
152
|
+
|
|
153
|
+
if (props.lineData && props.lineData.length > 0) {
|
|
154
|
+
const extendedLineData = [
|
|
155
|
+
props.lineData[0],
|
|
156
|
+
[
|
|
157
|
+
props.lineData[props.lineData.length - 1][0] + 10,
|
|
158
|
+
props.lineData[props.lineData.length - 1][1] + 10
|
|
159
|
+
]
|
|
160
|
+
];
|
|
161
|
+
series.push({
|
|
55
162
|
type: 'line',
|
|
56
|
-
data:
|
|
163
|
+
data: extendedLineData,
|
|
57
164
|
lineStyle: {
|
|
58
165
|
type: 'dashed',
|
|
59
|
-
color:
|
|
166
|
+
color: backgroundColor['lilac-inverse']
|
|
167
|
+
},
|
|
168
|
+
symbol: 'none',
|
|
169
|
+
emphasis: {
|
|
170
|
+
disabled: true
|
|
60
171
|
},
|
|
61
|
-
|
|
172
|
+
silent: true,
|
|
173
|
+
zlevel: 0
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
if (showConfidenceBand && props.lineData && props.lineData.length > 0) {
|
|
177
|
+
const lowerBandData = extendedLineData.map((point) => {
|
|
178
|
+
const yValue = point[1];
|
|
179
|
+
// 0-30 = ±3, 30+ = ±10%
|
|
180
|
+
return [point[0], yValue <= 30 ? yValue - 3 : yValue * 0.9];
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const upperBandData = extendedLineData.map((point) => {
|
|
184
|
+
const yValue = point[1];
|
|
185
|
+
// 0-30 = ±3, 30+ = ±10%
|
|
186
|
+
return [point[0], yValue <= 30 ? yValue + 3 : yValue * 1.1];
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
series.push({
|
|
190
|
+
name: 'Confidence Band',
|
|
191
|
+
type: 'line',
|
|
192
|
+
data: [...upperBandData, ...lowerBandData.reverse()],
|
|
193
|
+
symbol: 'none',
|
|
194
|
+
areaStyle: {
|
|
195
|
+
color: backgroundColor.lilac,
|
|
196
|
+
opacity: 0.5
|
|
197
|
+
},
|
|
198
|
+
lineStyle: {
|
|
199
|
+
opacity: 0
|
|
200
|
+
},
|
|
201
|
+
tooltip: {
|
|
202
|
+
show: false
|
|
203
|
+
},
|
|
204
|
+
emphasis: {
|
|
205
|
+
disabled: true
|
|
206
|
+
},
|
|
207
|
+
silent: true,
|
|
208
|
+
zlevel: 0
|
|
209
|
+
});
|
|
62
210
|
}
|
|
63
|
-
|
|
64
|
-
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
series.push({
|
|
214
|
+
symbolSize: 8,
|
|
215
|
+
data,
|
|
216
|
+
type: 'scatter',
|
|
217
|
+
itemStyle: {
|
|
218
|
+
color: backgroundColor['blue-inverse'],
|
|
219
|
+
opacity: 0.8
|
|
220
|
+
},
|
|
221
|
+
emphasis: {
|
|
222
|
+
itemStyle: {
|
|
223
|
+
color: backgroundColor['blue-inverse'],
|
|
224
|
+
opacity: 1
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
animation: false,
|
|
228
|
+
zlevel: 1
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
if (errorBarData.length > 0) {
|
|
232
|
+
series.push({
|
|
233
|
+
type: 'custom',
|
|
234
|
+
name: 'error',
|
|
235
|
+
silent: true,
|
|
236
|
+
itemStyle: {
|
|
237
|
+
borderWidth: 1.5,
|
|
238
|
+
color: backgroundColor['blue-inverse']
|
|
239
|
+
},
|
|
240
|
+
renderItem: renderErrorBarItem,
|
|
241
|
+
data: errorBarData,
|
|
242
|
+
zlevel: 0
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
xAxis: {
|
|
248
|
+
type: 'value',
|
|
249
|
+
name: xAxisName,
|
|
250
|
+
max: props.lineData
|
|
251
|
+
? Math.ceil(props.lineData[props.lineData.length - 1][0] / 10) * 10
|
|
252
|
+
: undefined,
|
|
253
|
+
...props.xAxisOptions
|
|
254
|
+
},
|
|
255
|
+
yAxis: {
|
|
256
|
+
type: 'value',
|
|
257
|
+
name: yAxisName,
|
|
258
|
+
min: 0,
|
|
259
|
+
max: props.lineData
|
|
260
|
+
? Math.ceil(props.lineData[props.lineData.length - 1][1] / 10) * 10
|
|
261
|
+
: undefined,
|
|
262
|
+
...props.yAxisOptions
|
|
263
|
+
},
|
|
264
|
+
animation: false,
|
|
265
|
+
tooltip: { show: false },
|
|
266
|
+
series
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
$effect(() => {
|
|
271
|
+
if (chartComponent && data) {
|
|
272
|
+
chartComponent.updateOptions(options);
|
|
273
|
+
}
|
|
274
|
+
});
|
|
65
275
|
</script>
|
|
66
276
|
|
|
67
|
-
|
|
277
|
+
{#snippet confBandTooltip()}
|
|
278
|
+
<div class="flex flex-col text-left">
|
|
279
|
+
<div class="w-max">
|
|
280
|
+
±3 <span class="text-sm text-secondary-inverse">colonies if count</span> ≤30
|
|
281
|
+
</div>
|
|
282
|
+
<div>
|
|
283
|
+
±10% <span class="text-sm text-secondary-inverse">if count</span> >30
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
286
|
+
{/snippet}
|
|
287
|
+
|
|
288
|
+
<div class="relative h-full" role="presentation">
|
|
289
|
+
<Chart
|
|
290
|
+
bind:this={chartComponent}
|
|
291
|
+
{options}
|
|
292
|
+
onitemclick={(e) => handleClick(e as ScatterPlotEchartsEvent)}
|
|
293
|
+
onmouseover={(e) => handleMouseOver(e as ScatterPlotEchartsEvent)}
|
|
294
|
+
onmouseout={handleMouseOut}
|
|
295
|
+
{loading}
|
|
296
|
+
{xAxisName}
|
|
297
|
+
{yAxisName}
|
|
298
|
+
>
|
|
299
|
+
{@render children?.()}
|
|
300
|
+
</Chart>
|
|
301
|
+
{#if showLegend}
|
|
302
|
+
<div
|
|
303
|
+
class="absolute left-14 top-6 flex h-auto rounded-lg border bg-surface transition-all duration-200"
|
|
304
|
+
>
|
|
305
|
+
<div class="ml-1 flex flex-col justify-center p-2">
|
|
306
|
+
{#each displayedLegendItems as item}
|
|
307
|
+
<div class="flex items-center gap-2">
|
|
308
|
+
{#if item.type === 'point'}
|
|
309
|
+
<div class="h-2 w-2 rounded-full" style="background-color: {item.color}"></div>
|
|
310
|
+
{:else if item.type === 'line'}
|
|
311
|
+
<div
|
|
312
|
+
class="h-[1px] w-2 border border-dashed"
|
|
313
|
+
style="border-color: {item.color}"
|
|
314
|
+
></div>
|
|
315
|
+
{:else if item.type === 'area'}
|
|
316
|
+
<div class="h-2 w-2" style="background-color: {item.color}"></div>
|
|
317
|
+
{/if}
|
|
318
|
+
<span class="text-sm text-secondary">{item.label}</span>
|
|
319
|
+
{#if item.label === 'Error margin'}
|
|
320
|
+
<Tooltip placement="right">
|
|
321
|
+
{#snippet trigger()}
|
|
322
|
+
<Icon iconName="Info" color="icon-tertiary" />
|
|
323
|
+
{/snippet}
|
|
324
|
+
{#snippet content()}
|
|
325
|
+
{@render confBandTooltip()}
|
|
326
|
+
{/snippet}
|
|
327
|
+
</Tooltip>
|
|
328
|
+
{/if}
|
|
329
|
+
</div>
|
|
330
|
+
{/each}
|
|
331
|
+
</div>
|
|
332
|
+
</div>
|
|
333
|
+
{/if}
|
|
334
|
+
</div>
|
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
import type
|
|
2
|
-
type
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
loading?: boolean;
|
|
8
|
-
xAxisOptions?: EChartsOption['xAxis'];
|
|
9
|
-
yAxisOptions?: EChartsOption['yAxis'];
|
|
10
|
-
onitemclick?: (params: echarts.ECElementEvent) => void;
|
|
11
|
-
onmouseover?: (params: echarts.ECElementEvent) => void;
|
|
12
|
-
onmouseout?: () => void;
|
|
1
|
+
import { type GenericChartProps } from '../chart/Chart.svelte';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
export type DataPoint = {
|
|
4
|
+
value: [number, number];
|
|
5
|
+
metadata: any;
|
|
6
|
+
error_value?: number;
|
|
13
7
|
};
|
|
14
|
-
|
|
8
|
+
export type ScatterPlotEchartsEvent = echarts.ECElementEvent & {
|
|
9
|
+
data: DataPoint;
|
|
10
|
+
};
|
|
11
|
+
type LegendItem = {
|
|
12
|
+
label: string;
|
|
13
|
+
color: string;
|
|
14
|
+
type: 'point' | 'line' | 'area';
|
|
15
|
+
};
|
|
16
|
+
type ScatterPlotProps = {
|
|
17
|
+
data: DataPoint[];
|
|
18
|
+
lineData?: [[number, number], [number, number]];
|
|
19
|
+
showConfidenceBand?: boolean;
|
|
20
|
+
showLegend?: boolean;
|
|
21
|
+
legendItems?: LegendItem[];
|
|
22
|
+
children?: Snippet;
|
|
23
|
+
} & Omit<GenericChartProps, 'timeIndex'>;
|
|
24
|
+
declare const Scatterplot: import("svelte").Component<ScatterPlotProps, {}, "">;
|
|
15
25
|
type Scatterplot = ReturnType<typeof Scatterplot>;
|
|
16
26
|
export default Scatterplot;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CallbackDataParams } from 'echarts/types/dist/shared';
|
|
2
|
+
interface TooltipFormatterConfig {
|
|
3
|
+
yAxisName?: string;
|
|
4
|
+
yAxisUnit?: string;
|
|
5
|
+
focusedSeriesAccessor?: () => string | undefined;
|
|
6
|
+
getSeriesColor?: (seriesName: string, seriesIndex: number) => string;
|
|
7
|
+
maxSeriesToShow?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const createTooltipFormatter: (config: TooltipFormatterConfig) => (params: CallbackDataParams | CallbackDataParams[]) => string;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { textColor } from '../../../tokens';
|
|
2
|
+
const toFixedLocaleString = (value, fractionDigits = 0, locale = undefined) => value?.toLocaleString(locale, {
|
|
3
|
+
minimumFractionDigits: fractionDigits,
|
|
4
|
+
maximumFractionDigits: fractionDigits
|
|
5
|
+
}) ?? '';
|
|
6
|
+
export const createTooltipFormatter = (config) => {
|
|
7
|
+
const { maxSeriesToShow = 10 } = config;
|
|
8
|
+
return (params) => {
|
|
9
|
+
if (typeof params !== 'object' || params === null) {
|
|
10
|
+
return '';
|
|
11
|
+
}
|
|
12
|
+
let paramArray = Array.isArray(params) ? params : [params];
|
|
13
|
+
if (paramArray.length === 0)
|
|
14
|
+
return '';
|
|
15
|
+
const currentFocusedSeries = config.focusedSeriesAccessor?.();
|
|
16
|
+
if (currentFocusedSeries !== undefined) {
|
|
17
|
+
paramArray = paramArray.filter((p) => currentFocusedSeries.includes(p.seriesName ?? ''));
|
|
18
|
+
if (paramArray.length === 0)
|
|
19
|
+
return '';
|
|
20
|
+
}
|
|
21
|
+
const firstParam = paramArray[0];
|
|
22
|
+
const categoryName = firstParam.name ?? ''; // X-axis value (category)
|
|
23
|
+
const unit = config.yAxisUnit ?? '';
|
|
24
|
+
let tooltipContent = `<div style="font-weight:bold; margin-bottom: 5px;">${categoryName}</div>`;
|
|
25
|
+
const originalSeriesCount = paramArray.length;
|
|
26
|
+
let seriesToShow = paramArray;
|
|
27
|
+
if (originalSeriesCount > maxSeriesToShow) {
|
|
28
|
+
seriesToShow = paramArray.slice(0, maxSeriesToShow);
|
|
29
|
+
}
|
|
30
|
+
seriesToShow.forEach((p, index) => {
|
|
31
|
+
if (p.value == null || p.value === undefined)
|
|
32
|
+
return; // Skip null/undefined values
|
|
33
|
+
const seriesName = p.seriesName ?? config.yAxisName ?? ''; // Use series name or configured yAxisName
|
|
34
|
+
const value = p.value; // Assume number after null check
|
|
35
|
+
let color = p.color;
|
|
36
|
+
// Resolve color for multiline if needed and getter provided
|
|
37
|
+
if (!color && config.getSeriesColor && p.seriesName) {
|
|
38
|
+
color = config.getSeriesColor(p.seriesName, p.seriesIndex ?? index);
|
|
39
|
+
}
|
|
40
|
+
// Fallback color if still unresolved (should ideally not happen if configured correctly)
|
|
41
|
+
color = color || textColor['icon-blue'];
|
|
42
|
+
const marker = `<span style="display:inline-block;margin-right:5px;border-radius:2px;width:8px;height:8px;background-color:${color}; vertical-align: baseline;"></span>`;
|
|
43
|
+
const valueString = `<span style="font-weight:500;">${toFixedLocaleString(value, 2)} ${unit}</span>`;
|
|
44
|
+
tooltipContent += `<div>${marker}${seriesName}: ${valueString}</div>`;
|
|
45
|
+
});
|
|
46
|
+
if (originalSeriesCount > maxSeriesToShow) {
|
|
47
|
+
const remainingCount = originalSeriesCount - maxSeriesToShow;
|
|
48
|
+
tooltipContent += `<div style="margin-top: 5px; font-style: italic;">... and ${remainingCount} more series</div>`;
|
|
49
|
+
}
|
|
50
|
+
return tooltipContent;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
});
|
|
11
11
|
</script>
|
|
12
12
|
|
|
13
|
-
<Story name="Base">
|
|
13
|
+
<Story name="Base" asChild>
|
|
14
14
|
<div class="flex flex-col gap-2">
|
|
15
15
|
<IconButton variant="primary">
|
|
16
16
|
<Icon iconName="Plus" />
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
</div>
|
|
28
28
|
</Story>
|
|
29
29
|
|
|
30
|
-
<Story name="Sizes">
|
|
30
|
+
<Story name="Sizes" asChild>
|
|
31
31
|
<div class="flex flex-col gap-2">
|
|
32
32
|
<IconButton variant="secondary" size="xs">
|
|
33
33
|
<Icon iconName="Plus" />
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
</IconButton>
|
|
41
41
|
</div>
|
|
42
42
|
</Story>
|
|
43
|
-
<Story name="Not rounded base">
|
|
43
|
+
<Story name="Not rounded base" asChild>
|
|
44
44
|
<div class="flex flex-col gap-2">
|
|
45
45
|
<IconButton variant="primary" rounded={false}>
|
|
46
46
|
<Icon iconName="Plus" />
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
</div>
|
|
58
58
|
</Story>
|
|
59
59
|
|
|
60
|
-
<Story name="Not rounded sizes">
|
|
60
|
+
<Story name="Not rounded sizes" asChild>
|
|
61
61
|
<div class="flex flex-col gap-2">
|
|
62
62
|
<IconButton variant="secondary" size="xs" rounded={false}>
|
|
63
63
|
<Icon iconName="Plus" />
|
|
@@ -70,12 +70,12 @@
|
|
|
70
70
|
</IconButton>
|
|
71
71
|
</div>
|
|
72
72
|
</Story>
|
|
73
|
-
<Story name="Disabled">
|
|
73
|
+
<Story name="Disabled" asChild>
|
|
74
74
|
<IconButton disabled>
|
|
75
75
|
<Icon iconName="Plus" />
|
|
76
76
|
</IconButton>
|
|
77
77
|
</Story>
|
|
78
|
-
<Story name="Loading">
|
|
78
|
+
<Story name="Loading" asChild>
|
|
79
79
|
<IconButton loading>
|
|
80
80
|
<Icon iconName="Plus" />
|
|
81
81
|
</IconButton>
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import { Spinner } from '../spinner/';
|
|
4
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
4
5
|
|
|
5
|
-
type Variant =
|
|
6
|
-
|
|
6
|
+
type Variant =
|
|
7
|
+
| 'primary'
|
|
8
|
+
| 'secondary'
|
|
9
|
+
| 'transparent'
|
|
10
|
+
| 'danger'
|
|
11
|
+
| 'secondary-inverse'
|
|
12
|
+
| 'transparent-inverse';
|
|
13
|
+
|
|
14
|
+
// Combine custom props with standard HTML button attributes,
|
|
15
|
+
// omitting ones we handle explicitly (like 'class', 'onclick')
|
|
16
|
+
interface Props extends HTMLButtonAttributes {
|
|
7
17
|
variant?: Variant;
|
|
8
18
|
type?: 'button' | 'submit' | 'reset' | null | undefined;
|
|
9
19
|
loading?: boolean;
|
|
10
|
-
disabled?: boolean;
|
|
11
20
|
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
12
21
|
children?: Snippet;
|
|
13
|
-
onclick?: (e: MouseEvent) => void;
|
|
14
|
-
tabindex?: number | undefined;
|
|
15
22
|
rounded?: boolean;
|
|
16
23
|
}
|
|
17
24
|
|
|
25
|
+
// Destructure only the component's specific props
|
|
18
26
|
let {
|
|
19
27
|
variant = 'transparent',
|
|
20
28
|
type = 'button',
|
|
@@ -24,7 +32,9 @@
|
|
|
24
32
|
children,
|
|
25
33
|
onclick,
|
|
26
34
|
tabindex,
|
|
27
|
-
rounded = true
|
|
35
|
+
rounded = true,
|
|
36
|
+
class: className,
|
|
37
|
+
...rest
|
|
28
38
|
}: Props = $props();
|
|
29
39
|
|
|
30
40
|
let sizeClass = $derived(`size-${size}`);
|
|
@@ -38,8 +48,9 @@
|
|
|
38
48
|
}}
|
|
39
49
|
{type}
|
|
40
50
|
{disabled}
|
|
41
|
-
class="{sizeClass} {variantClass} disabled"
|
|
51
|
+
class="{sizeClass} {variantClass} disabled {className}"
|
|
42
52
|
class:rounded
|
|
53
|
+
{...rest}
|
|
43
54
|
>
|
|
44
55
|
{#if loading}
|
|
45
56
|
<Spinner />
|
|
@@ -48,7 +59,15 @@
|
|
|
48
59
|
{/if}
|
|
49
60
|
</button>
|
|
50
61
|
{:else}
|
|
51
|
-
<button
|
|
62
|
+
<button
|
|
63
|
+
{onclick}
|
|
64
|
+
{type}
|
|
65
|
+
{disabled}
|
|
66
|
+
{tabindex}
|
|
67
|
+
class="{sizeClass} {variantClass} {className}"
|
|
68
|
+
class:rounded
|
|
69
|
+
{...rest}
|
|
70
|
+
>
|
|
52
71
|
{@render children?.()}
|
|
53
72
|
</button>
|
|
54
73
|
{/if}
|
|
@@ -66,7 +85,7 @@
|
|
|
66
85
|
border-radius: 9999px
|
|
67
86
|
}
|
|
68
87
|
.disabled {
|
|
69
|
-
cursor:
|
|
88
|
+
cursor: not-allowed
|
|
70
89
|
}
|
|
71
90
|
.disabled:disabled {
|
|
72
91
|
background-color: #12192a0d;
|
|
@@ -148,5 +167,27 @@
|
|
|
148
167
|
.color-danger:hover {
|
|
149
168
|
--tw-bg-opacity: 1;
|
|
150
169
|
background-color: rgb(191 57 58 / var(--tw-bg-opacity, 1))
|
|
170
|
+
}
|
|
171
|
+
.color-secondary-inverse {
|
|
172
|
+
background-color: #FFFFFF0D;
|
|
173
|
+
--tw-text-opacity: 1;
|
|
174
|
+
color: rgb(255 255 255 / var(--tw-text-opacity, 1))
|
|
175
|
+
}
|
|
176
|
+
.color-secondary-inverse:hover {
|
|
177
|
+
background-color: #FFFFFF26
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.color-transparent-inverse {
|
|
181
|
+
background-color: transparent;
|
|
182
|
+
--tw-text-opacity: 1;
|
|
183
|
+
color: rgb(255 255 255 / var(--tw-text-opacity, 1))
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.color-transparent-inverse:hover {
|
|
187
|
+
background-color: #FFFFFF26
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.color-transparent-inverse:hover:disabled {
|
|
191
|
+
background-color: transparent
|
|
151
192
|
}
|
|
152
193
|
</style>
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
type
|
|
3
|
-
|
|
2
|
+
import type { HTMLButtonAttributes } from 'svelte/elements';
|
|
3
|
+
type Variant = 'primary' | 'secondary' | 'transparent' | 'danger' | 'secondary-inverse' | 'transparent-inverse';
|
|
4
|
+
interface Props extends HTMLButtonAttributes {
|
|
4
5
|
variant?: Variant;
|
|
5
6
|
type?: 'button' | 'submit' | 'reset' | null | undefined;
|
|
6
7
|
loading?: boolean;
|
|
7
|
-
disabled?: boolean;
|
|
8
8
|
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
9
9
|
children?: Snippet;
|
|
10
|
-
onclick?: (e: MouseEvent) => void;
|
|
11
|
-
tabindex?: number | undefined;
|
|
12
10
|
rounded?: boolean;
|
|
13
11
|
}
|
|
14
12
|
declare const IconButton: import("svelte").Component<Props, {}, "">;
|