@sentropic/design-system-svelte 0.18.0 → 0.20.0

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 (43) hide show
  1. package/dist/BoxPlotChart.svelte +302 -0
  2. package/dist/BoxPlotChart.svelte.d.ts +40 -0
  3. package/dist/BoxPlotChart.svelte.d.ts.map +1 -0
  4. package/dist/BulletChart.svelte +479 -0
  5. package/dist/BulletChart.svelte.d.ts +32 -0
  6. package/dist/BulletChart.svelte.d.ts.map +1 -0
  7. package/dist/BumpChart.svelte +387 -0
  8. package/dist/BumpChart.svelte.d.ts +35 -0
  9. package/dist/BumpChart.svelte.d.ts.map +1 -0
  10. package/dist/CalendarHeatmapChart.svelte +345 -0
  11. package/dist/CalendarHeatmapChart.svelte.d.ts +28 -0
  12. package/dist/CalendarHeatmapChart.svelte.d.ts.map +1 -0
  13. package/dist/CandlestickChart.svelte +333 -0
  14. package/dist/CandlestickChart.svelte.d.ts +31 -0
  15. package/dist/CandlestickChart.svelte.d.ts.map +1 -0
  16. package/dist/HeatmapChart.svelte +337 -0
  17. package/dist/HeatmapChart.svelte.d.ts +35 -0
  18. package/dist/HeatmapChart.svelte.d.ts.map +1 -0
  19. package/dist/HistogramChart.svelte +294 -0
  20. package/dist/HistogramChart.svelte.d.ts +38 -0
  21. package/dist/HistogramChart.svelte.d.ts.map +1 -0
  22. package/dist/MarimekkoChart.svelte +319 -0
  23. package/dist/MarimekkoChart.svelte.d.ts +35 -0
  24. package/dist/MarimekkoChart.svelte.d.ts.map +1 -0
  25. package/dist/ParallelCoordinatesChart.svelte +315 -0
  26. package/dist/ParallelCoordinatesChart.svelte.d.ts +35 -0
  27. package/dist/ParallelCoordinatesChart.svelte.d.ts.map +1 -0
  28. package/dist/RadarChart.svelte +340 -0
  29. package/dist/RadarChart.svelte.d.ts +43 -0
  30. package/dist/RadarChart.svelte.d.ts.map +1 -0
  31. package/dist/SankeyChart.svelte +364 -0
  32. package/dist/SankeyChart.svelte.d.ts +45 -0
  33. package/dist/SankeyChart.svelte.d.ts.map +1 -0
  34. package/dist/SunburstChart.svelte +388 -0
  35. package/dist/SunburstChart.svelte.d.ts +39 -0
  36. package/dist/SunburstChart.svelte.d.ts.map +1 -0
  37. package/dist/chartContrast.d.ts +0 -4
  38. package/dist/chartContrast.d.ts.map +1 -1
  39. package/dist/chartContrast.js +4 -56
  40. package/dist/index.d.ts +24 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +12 -0
  43. package/package.json +1 -1
@@ -0,0 +1,38 @@
1
+ /**
2
+ * HistogramChart - API canonique (référence Svelte, React/Vue doivent s'aligner)
3
+ *
4
+ * Props obligatoires :
5
+ * data HistogramChartDatum[] | number[]
6
+ * - si tableau de nombres : bins numériques calculés automatiquement
7
+ * - si tableau de {label, value, tone?} : bins pré-calculés (passthrough)
8
+ * label string - aria-label du graphique
9
+ *
10
+ * Props optionnelles :
11
+ * bins number (défaut 10) - nombre de bins pour le mode numérique.
12
+ * Défaut fixe = 10 (pas ceil(√n)) pour parité
13
+ * Svelte/React/Vue et prédictibilité.
14
+ * width number (défaut 480) - largeur du viewBox en px
15
+ * height number (défaut 240) - hauteur du viewBox en px
16
+ * class string - classe CSS supplémentaire
17
+ *
18
+ * NaN/vide : les valeurs non-finies sont exclues avant le binning (filter
19
+ * Number.isFinite). Tableau vide → rendu vide sans crash.
20
+ */
21
+ export type HistogramChartTone = "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
22
+ export type HistogramChartDatum = {
23
+ label: string;
24
+ value: number;
25
+ tone?: HistogramChartTone;
26
+ };
27
+ type HistogramChartProps = {
28
+ data: HistogramChartDatum[] | number[];
29
+ bins?: number;
30
+ label: string;
31
+ width?: number;
32
+ height?: number;
33
+ class?: string;
34
+ };
35
+ declare const HistogramChart: import("svelte").Component<HistogramChartProps, {}, "">;
36
+ type HistogramChart = ReturnType<typeof HistogramChart>;
37
+ export default HistogramChart;
38
+ //# sourceMappingURL=HistogramChart.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HistogramChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/HistogramChart.svelte.ts"],"names":[],"mappings":"AAGE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,kBAAkB,CAAC;CAC3B,CAAC;AAMF,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,mBAAmB,EAAE,GAAG,MAAM,EAAE,CAAC;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA4JJ,QAAA,MAAM,cAAc,yDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,319 @@
1
+ <script lang="ts" module>
2
+ /**
3
+ * MarimekkoChart - rectangles largeur (part catégorie) × hauteur (segments %).
4
+ * API canonique (référence Svelte, React/Vue doivent s'aligner)
5
+ *
6
+ * Props obligatoires :
7
+ * data MarimekkoChartDatum[] - tableau {label, width, segments[]}
8
+ * label string
9
+ *
10
+ * Props optionnelles :
11
+ * width number (défaut 480)
12
+ * height number (défaut 300)
13
+ * class string
14
+ */
15
+ export type MarimekkoChartTone =
16
+ | "category1"
17
+ | "category2"
18
+ | "category3"
19
+ | "category4"
20
+ | "category5"
21
+ | "category6"
22
+ | "category7"
23
+ | "category8";
24
+
25
+ export type MarimekkoChartSegment = {
26
+ label: string;
27
+ value: number;
28
+ tone?: MarimekkoChartTone;
29
+ };
30
+
31
+ export type MarimekkoChartDatum = {
32
+ label: string;
33
+ width: number;
34
+ segments: MarimekkoChartSegment[];
35
+ };
36
+ </script>
37
+
38
+ <script lang="ts">
39
+ import ChartDataList from "./ChartDataList.svelte";
40
+ import { contrastTextForTone } from "./chartContrast";
41
+
42
+ const TONES: MarimekkoChartTone[] = [
43
+ "category1","category2","category3","category4",
44
+ "category5","category6","category7","category8"
45
+ ];
46
+
47
+ type MarimekkoChartProps = {
48
+ data: MarimekkoChartDatum[];
49
+ label: string;
50
+ width?: number;
51
+ height?: number;
52
+ class?: string;
53
+ };
54
+
55
+ let {
56
+ data = [],
57
+ label,
58
+ width = 480,
59
+ height = 300,
60
+ class: className
61
+ }: MarimekkoChartProps = $props();
62
+
63
+ const MARGIN = { top: 12, right: 16, bottom: 32, left: 8 };
64
+
65
+ let hoveredKey: string | null = $state(null);
66
+
67
+ const plotWidth = $derived(Math.max(width - MARGIN.left - MARGIN.right, 1));
68
+ const plotHeight = $derived(Math.max(height - MARGIN.top - MARGIN.bottom, 1));
69
+
70
+ // FIX #4 : ignorer (skip) largeurs non-finies ou <=0, PAS de Math.abs
71
+ const totalWidth = $derived.by(() => {
72
+ const sum = data.reduce((acc, d) => {
73
+ const w = d.width;
74
+ return acc + (Number.isFinite(w) && w > 0 ? w : 0);
75
+ }, 0);
76
+ return sum > 0 ? sum : 1;
77
+ });
78
+
79
+ const cells = $derived.by(() => {
80
+ let xCursor = MARGIN.left;
81
+ const result: {
82
+ key: string;
83
+ catLabel: string;
84
+ segLabel: string;
85
+ tone: MarimekkoChartTone;
86
+ x: number;
87
+ y: number;
88
+ w: number;
89
+ h: number;
90
+ cx: number;
91
+ cy: number;
92
+ pct: number;
93
+ colPct: number;
94
+ }[] = [];
95
+
96
+ for (const datum of data) {
97
+ const safeW = (Number.isFinite(datum.width) && datum.width > 0) ? datum.width : 0;
98
+ // FIX #4 : skip colonnes invalides (largeur 0 ou non-finie)
99
+ if (safeW <= 0) continue;
100
+ const colW = (safeW / totalWidth) * plotWidth;
101
+ const colPct = safeW / totalWidth;
102
+
103
+ // FIX #4 : ignorer segments non-finis ou <=0 (PAS de Math.abs, PAS de plancher 0.5px)
104
+ const validSegs = datum.segments.filter((s) => Number.isFinite(s.value) && s.value > 0);
105
+ const segSum = validSegs.reduce((acc, s) => acc + s.value, 0);
106
+ const safeSum = segSum > 0 ? segSum : 1;
107
+
108
+ let yCursor = MARGIN.top;
109
+ for (let si = 0; si < validSegs.length; si++) {
110
+ const seg = validSegs[si];
111
+ const pct = seg.value / safeSum;
112
+ const segH = pct * plotHeight;
113
+ const tone = seg.tone ?? TONES[si % TONES.length];
114
+ result.push({
115
+ key: `${datum.label}-${seg.label}`,
116
+ catLabel: datum.label,
117
+ segLabel: seg.label,
118
+ tone,
119
+ x: xCursor,
120
+ y: yCursor,
121
+ // FIX #4 : pas de plancher min 0.5px pour les zéros (ils sont filtrés)
122
+ w: Math.max(colW - 1, 1),
123
+ h: Math.max(segH, 1),
124
+ cx: xCursor + colW / 2,
125
+ cy: yCursor + segH / 2,
126
+ pct,
127
+ colPct
128
+ });
129
+ yCursor += segH;
130
+ }
131
+ xCursor += colW;
132
+ }
133
+ return result;
134
+ });
135
+
136
+ // FIX #4 a11y : SR inclut la part de LARGEUR (colPct) en plus du % de segment
137
+ const dataValueItems = $derived(
138
+ cells.map((c) => `${c.catLabel}, ${c.segLabel}: ${Math.round(c.pct * 100)}% (colonne ${Math.round(c.colPct * 100)}%)`)
139
+ );
140
+
141
+ function handlePointerMove(event: PointerEvent) {
142
+ const target = event.target;
143
+ if (!(target instanceof Element)) { hoveredKey = null; return; }
144
+ hoveredKey = target.getAttribute("data-chart-key") ?? null;
145
+ }
146
+
147
+ const hoveredCell = $derived(hoveredKey !== null ? cells.find((c) => c.key === hoveredKey) ?? null : null);
148
+
149
+ const classes = () => ["st-marimekkoChart", className].filter(Boolean).join(" ");
150
+ </script>
151
+
152
+ <div class={classes()}>
153
+ <div
154
+ class="st-marimekkoChart__visual"
155
+ role="img"
156
+ aria-label={label}
157
+ onpointermove={handlePointerMove}
158
+ onpointerleave={() => (hoveredKey = null)}
159
+ >
160
+ <svg
161
+ viewBox="0 0 {width} {height}"
162
+ preserveAspectRatio="xMidYMid meet"
163
+ width="100%"
164
+ height="100%"
165
+ focusable="false"
166
+ aria-hidden="true"
167
+ >
168
+ <!-- axis -->
169
+ <line
170
+ class="st-marimekkoChart__axis"
171
+ x1={MARGIN.left}
172
+ x2={width - MARGIN.right}
173
+ y1={height - MARGIN.bottom}
174
+ y2={height - MARGIN.bottom}
175
+ />
176
+
177
+ <!-- cells -->
178
+ {#each cells as cell (cell.key)}
179
+ <rect
180
+ class="st-marimekkoChart__cell st-marimekkoChart__cell--{cell.tone}"
181
+ class:st-marimekkoChart__cell--dim={hoveredKey !== null && hoveredKey !== cell.key}
182
+ x={cell.x}
183
+ y={cell.y}
184
+ width={cell.w}
185
+ height={cell.h}
186
+ data-chart-key={cell.key}
187
+ />
188
+ {#if cell.w > 28 && cell.h > 14}
189
+ <text
190
+ class="st-marimekkoChart__cellLabel"
191
+ x={cell.cx}
192
+ y={cell.cy}
193
+ text-anchor="middle"
194
+ dominant-baseline="middle"
195
+ style="fill: {contrastTextForTone(cell.tone)}"
196
+ pointer-events="none"
197
+ >
198
+ {Math.round(cell.pct * 100)}%
199
+ </text>
200
+ {/if}
201
+ {/each}
202
+
203
+ <!-- category labels below axis -->
204
+ {#each data as datum, i (datum.label)}
205
+ {#if Number.isFinite(datum.width) && datum.width > 0}
206
+ {@const safeW = datum.width}
207
+ {@const colW = (safeW / totalWidth) * plotWidth}
208
+ {@const startX = cells.find(c => c.catLabel === datum.label)?.x ?? MARGIN.left}
209
+ <text
210
+ class="st-marimekkoChart__catLabel"
211
+ x={startX + colW / 2}
212
+ y={height - MARGIN.bottom + 16}
213
+ text-anchor="middle"
214
+ >
215
+ {datum.label}
216
+ </text>
217
+ {/if}
218
+ {/each}
219
+ </svg>
220
+ </div>
221
+
222
+ <ChartDataList {label} items={dataValueItems} />
223
+
224
+ {#if hoveredCell !== null}
225
+ <div
226
+ class="st-marimekkoChart__tooltip"
227
+ role="presentation"
228
+ style="left: {(hoveredCell.cx / width) * 100}%; top: {(hoveredCell.cy / height) * 100}%"
229
+ >
230
+ <span class="st-marimekkoChart__tooltipLabel">{hoveredCell.catLabel} / {hoveredCell.segLabel}</span>
231
+ <span class="st-marimekkoChart__tooltipValue">{Math.round(hoveredCell.pct * 100)}%</span>
232
+ </div>
233
+ {/if}
234
+ </div>
235
+
236
+ <style>
237
+ .st-marimekkoChart {
238
+ color: var(--st-semantic-text-secondary);
239
+ display: block;
240
+ font-family: inherit;
241
+ position: relative;
242
+ width: 100%;
243
+ }
244
+
245
+ .st-marimekkoChart svg {
246
+ display: block;
247
+ overflow: visible;
248
+ }
249
+
250
+ .st-marimekkoChart__visual {
251
+ display: block;
252
+ }
253
+
254
+ .st-marimekkoChart__axis {
255
+ stroke: var(--st-semantic-border-subtle);
256
+ stroke-width: 1;
257
+ }
258
+
259
+ .st-marimekkoChart__cell {
260
+ cursor: pointer;
261
+ stroke: var(--st-semantic-surface-default, Canvas);
262
+ stroke-width: 1;
263
+ transition: opacity 120ms ease;
264
+ }
265
+
266
+ .st-marimekkoChart__cell--dim {
267
+ opacity: 0.4;
268
+ }
269
+
270
+ @media (prefers-reduced-motion: reduce) {
271
+ .st-marimekkoChart__cell {
272
+ transition: none;
273
+ }
274
+ }
275
+
276
+ .st-marimekkoChart__cell--category1 { fill: var(--st-semantic-data-category1); }
277
+ .st-marimekkoChart__cell--category2 { fill: var(--st-semantic-data-category2); }
278
+ .st-marimekkoChart__cell--category3 { fill: var(--st-semantic-data-category3); }
279
+ .st-marimekkoChart__cell--category4 { fill: var(--st-semantic-data-category4); }
280
+ .st-marimekkoChart__cell--category5 { fill: var(--st-semantic-data-category5); }
281
+ .st-marimekkoChart__cell--category6 { fill: var(--st-semantic-data-category6); }
282
+ .st-marimekkoChart__cell--category7 { fill: var(--st-semantic-data-category7); }
283
+ .st-marimekkoChart__cell--category8 { fill: var(--st-semantic-data-category8); }
284
+
285
+ .st-marimekkoChart__cellLabel {
286
+ font-size: 0.625rem;
287
+ pointer-events: none;
288
+ }
289
+
290
+ .st-marimekkoChart__catLabel {
291
+ fill: var(--st-semantic-text-secondary);
292
+ font-size: 0.6875rem;
293
+ }
294
+
295
+ .st-marimekkoChart__tooltip {
296
+ background: var(--st-semantic-surface-inverse);
297
+ border-radius: var(--st-radius-sm, 0.25rem);
298
+ color: var(--st-semantic-text-inverse);
299
+ display: inline-flex;
300
+ flex-direction: column;
301
+ font-size: 0.75rem;
302
+ gap: 0.125rem;
303
+ line-height: 1.2;
304
+ padding: 0.375rem 0.5rem;
305
+ pointer-events: none;
306
+ position: absolute;
307
+ transform: translate(-50%, calc(-100% - 8px));
308
+ white-space: nowrap;
309
+ z-index: 1;
310
+ }
311
+
312
+ .st-marimekkoChart__tooltipLabel {
313
+ font-weight: 600;
314
+ }
315
+
316
+ .st-marimekkoChart__tooltipValue {
317
+ opacity: 0.85;
318
+ }
319
+ </style>
@@ -0,0 +1,35 @@
1
+ /**
2
+ * MarimekkoChart - rectangles largeur (part catégorie) × hauteur (segments %).
3
+ * API canonique (référence Svelte, React/Vue doivent s'aligner)
4
+ *
5
+ * Props obligatoires :
6
+ * data MarimekkoChartDatum[] - tableau {label, width, segments[]}
7
+ * label string
8
+ *
9
+ * Props optionnelles :
10
+ * width number (défaut 480)
11
+ * height number (défaut 300)
12
+ * class string
13
+ */
14
+ export type MarimekkoChartTone = "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
15
+ export type MarimekkoChartSegment = {
16
+ label: string;
17
+ value: number;
18
+ tone?: MarimekkoChartTone;
19
+ };
20
+ export type MarimekkoChartDatum = {
21
+ label: string;
22
+ width: number;
23
+ segments: MarimekkoChartSegment[];
24
+ };
25
+ type MarimekkoChartProps = {
26
+ data: MarimekkoChartDatum[];
27
+ label: string;
28
+ width?: number;
29
+ height?: number;
30
+ class?: string;
31
+ };
32
+ declare const MarimekkoChart: import("svelte").Component<MarimekkoChartProps, {}, "">;
33
+ type MarimekkoChart = ReturnType<typeof MarimekkoChart>;
34
+ export default MarimekkoChart;
35
+ //# sourceMappingURL=MarimekkoChart.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarimekkoChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/MarimekkoChart.svelte.ts"],"names":[],"mappings":"AAGE;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,qBAAqB,GAAG;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,kBAAkB,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,qBAAqB,EAAE,CAAC;CACnC,CAAC;AAOF,KAAK,mBAAmB,GAAG;IACzB,IAAI,EAAE,mBAAmB,EAAE,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA0JJ,QAAA,MAAM,cAAc,yDAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}