@sentropic/design-system-svelte 0.34.0 → 0.34.21
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/AppChrome.svelte +660 -0
- package/dist/AppChrome.svelte.d.ts +74 -0
- package/dist/AppChrome.svelte.d.ts.map +1 -0
- package/dist/AppChrome.test.d.ts +2 -0
- package/dist/AppChrome.test.d.ts.map +1 -0
- package/dist/AppChrome.test.js +122 -0
- package/dist/AppHeader.svelte +159 -1
- package/dist/AppHeader.svelte.d.ts +18 -1
- package/dist/AppHeader.svelte.d.ts.map +1 -1
- package/dist/ArcDiagramChart.svelte +380 -0
- package/dist/ArcDiagramChart.svelte.d.ts +43 -0
- package/dist/ArcDiagramChart.svelte.d.ts.map +1 -0
- package/dist/AreaRangeChart.svelte +487 -0
- package/dist/AreaRangeChart.svelte.d.ts +38 -0
- package/dist/AreaRangeChart.svelte.d.ts.map +1 -0
- package/dist/AreaSplineRangeChart.svelte +478 -0
- package/dist/AreaSplineRangeChart.svelte.d.ts +37 -0
- package/dist/AreaSplineRangeChart.svelte.d.ts.map +1 -0
- package/dist/BellCurveChart.svelte +487 -0
- package/dist/BellCurveChart.svelte.d.ts +40 -0
- package/dist/BellCurveChart.svelte.d.ts.map +1 -0
- package/dist/Calendar.svelte +11 -0
- package/dist/ChatThread.svelte +32 -1
- package/dist/ChatThread.svelte.d.ts +14 -0
- package/dist/ChatThread.svelte.d.ts.map +1 -1
- package/dist/ColumnPyramidChart.svelte +332 -0
- package/dist/ColumnPyramidChart.svelte.d.ts +35 -0
- package/dist/ColumnPyramidChart.svelte.d.ts.map +1 -0
- package/dist/ColumnRangeChart.svelte +432 -0
- package/dist/ColumnRangeChart.svelte.d.ts +42 -0
- package/dist/ColumnRangeChart.svelte.d.ts.map +1 -0
- package/dist/Combobox.svelte +3 -0
- package/dist/ConfigItemCard.svelte +303 -0
- package/dist/ConfigItemCard.svelte.d.ts +37 -0
- package/dist/ConfigItemCard.svelte.d.ts.map +1 -0
- package/dist/ContentSwitcher.svelte +1 -1
- package/dist/DatePicker.svelte +3 -0
- package/dist/DependencyWheelChart.svelte +413 -0
- package/dist/DependencyWheelChart.svelte.d.ts +42 -0
- package/dist/DependencyWheelChart.svelte.d.ts.map +1 -0
- package/dist/DumbbellChart.svelte +403 -0
- package/dist/DumbbellChart.svelte.d.ts +44 -0
- package/dist/DumbbellChart.svelte.d.ts.map +1 -0
- package/dist/ErrorBarChart.svelte +428 -0
- package/dist/ErrorBarChart.svelte.d.ts +40 -0
- package/dist/ErrorBarChart.svelte.d.ts.map +1 -0
- package/dist/FieldCard.svelte +220 -0
- package/dist/FieldCard.svelte.d.ts +28 -0
- package/dist/FieldCard.svelte.d.ts.map +1 -0
- package/dist/GanttChart.svelte +410 -0
- package/dist/GanttChart.svelte.d.ts +39 -0
- package/dist/GanttChart.svelte.d.ts.map +1 -0
- package/dist/HLCChart.svelte +330 -0
- package/dist/HLCChart.svelte.d.ts +32 -0
- package/dist/HLCChart.svelte.d.ts.map +1 -0
- package/dist/HeikinAshiChart.svelte +365 -0
- package/dist/HeikinAshiChart.svelte.d.ts +37 -0
- package/dist/HeikinAshiChart.svelte.d.ts.map +1 -0
- package/dist/HollowCandlestickChart.svelte +357 -0
- package/dist/HollowCandlestickChart.svelte.d.ts +34 -0
- package/dist/HollowCandlestickChart.svelte.d.ts.map +1 -0
- package/dist/Input.svelte +3 -0
- package/dist/ItemChart.svelte +389 -0
- package/dist/ItemChart.svelte.d.ts +67 -0
- package/dist/ItemChart.svelte.d.ts.map +1 -0
- package/dist/LollipopChart.svelte +1 -1
- package/dist/MultiSelect.svelte +3 -0
- package/dist/NumberInput.svelte +3 -0
- package/dist/OHLCChart.svelte +343 -0
- package/dist/OHLCChart.svelte.d.ts +33 -0
- package/dist/OHLCChart.svelte.d.ts.map +1 -0
- package/dist/OrganizationChart.svelte +284 -0
- package/dist/OrganizationChart.svelte.d.ts +19 -0
- package/dist/OrganizationChart.svelte.d.ts.map +1 -0
- package/dist/PasswordInput.svelte +3 -0
- package/dist/PolygonChart.svelte +189 -0
- package/dist/PolygonChart.svelte.d.ts +17 -0
- package/dist/PolygonChart.svelte.d.ts.map +1 -0
- package/dist/ScoreCard.svelte +172 -0
- package/dist/ScoreCard.svelte.d.ts +27 -0
- package/dist/ScoreCard.svelte.d.ts.map +1 -0
- package/dist/Search.svelte +7 -5
- package/dist/Select.svelte +3 -0
- package/dist/StreamgraphChart.svelte +283 -0
- package/dist/StreamgraphChart.svelte.d.ts +23 -0
- package/dist/StreamgraphChart.svelte.d.ts.map +1 -0
- package/dist/StreamingMessage.svelte +44 -2
- package/dist/StreamingMessage.svelte.d.ts +18 -1
- package/dist/StreamingMessage.svelte.d.ts.map +1 -1
- package/dist/TileMapChart.svelte +314 -0
- package/dist/TileMapChart.svelte.d.ts +45 -0
- package/dist/TileMapChart.svelte.d.ts.map +1 -0
- package/dist/TimePicker.svelte +3 -0
- package/dist/TimelineChart.svelte +362 -0
- package/dist/TimelineChart.svelte.d.ts +22 -0
- package/dist/TimelineChart.svelte.d.ts.map +1 -0
- package/dist/TreegraphChart.svelte +281 -0
- package/dist/TreegraphChart.svelte.d.ts +19 -0
- package/dist/TreegraphChart.svelte.d.ts.map +1 -0
- package/dist/VariablePieChart.svelte +313 -0
- package/dist/VariablePieChart.svelte.d.ts +52 -0
- package/dist/VariablePieChart.svelte.d.ts.map +1 -0
- package/dist/VennChart.svelte +348 -0
- package/dist/VennChart.svelte.d.ts +72 -0
- package/dist/VennChart.svelte.d.ts.map +1 -0
- package/dist/WordCloudChart.svelte +279 -0
- package/dist/WordCloudChart.svelte.d.ts +18 -0
- package/dist/WordCloudChart.svelte.d.ts.map +1 -0
- package/dist/index.d.ts +56 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -0
- package/package.json +5 -3
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
/**
|
|
3
|
+
* ItemChart (« parlement » / hémicycle) — API canonique (référence Svelte,
|
|
4
|
+
* React/Vue doivent s'aligner).
|
|
5
|
+
*
|
|
6
|
+
* Chaque groupe apporte `value` POINTS (sièges). La somme des points est
|
|
7
|
+
* disposée en plusieurs RANGÉES CONCENTRIQUES formant un demi-anneau du haut
|
|
8
|
+
* (hémicycle). Les points d'un même groupe sont CONTIGUS et colorés par un ton
|
|
9
|
+
* catégoriel (`categoryN`). On lit donc la taille relative des groupes à la
|
|
10
|
+
* longueur de l'arc qu'ils occupent — façon répartition des sièges.
|
|
11
|
+
*
|
|
12
|
+
* Géométrie :
|
|
13
|
+
* - nombre de rangées = clamp(round(sqrt(total / 12)), 3, 5) tant qu'il reste
|
|
14
|
+
* des points (au moins 1 rangée).
|
|
15
|
+
* - les rangées ont des rayons régulièrement espacés ; le nombre de points
|
|
16
|
+
* par rangée est ∝ au rayon (les rangées extérieures portent plus de
|
|
17
|
+
* sièges), de sorte que l'espacement angulaire reste homogène.
|
|
18
|
+
* - chaque siège est posé sur un demi-cercle (de gauche π à droite 0, via le
|
|
19
|
+
* haut), tous les sièges étant ordonnés rangée par rangée puis attribués
|
|
20
|
+
* aux groupes dans l'ordre fourni → blocs contigus.
|
|
21
|
+
*
|
|
22
|
+
* Props obligatoires :
|
|
23
|
+
* data ItemChartDatum[] - {label, value, tone?}
|
|
24
|
+
* label string - aria-label du graphique (role=img)
|
|
25
|
+
*
|
|
26
|
+
* Props optionnelles :
|
|
27
|
+
* width number (défaut 480)
|
|
28
|
+
* height number (défaut 280)
|
|
29
|
+
* class string
|
|
30
|
+
*
|
|
31
|
+
* NaN/négatif : `value` non-finie ou < 0 → 0 siège pour ce groupe. Total 0 →
|
|
32
|
+
* rendu vide sans crash. `value` est arrondie à l'entier le plus proche pour
|
|
33
|
+
* compter des sièges.
|
|
34
|
+
*/
|
|
35
|
+
export type ItemChartTone =
|
|
36
|
+
| "category1"
|
|
37
|
+
| "category2"
|
|
38
|
+
| "category3"
|
|
39
|
+
| "category4"
|
|
40
|
+
| "category5"
|
|
41
|
+
| "category6"
|
|
42
|
+
| "category7"
|
|
43
|
+
| "category8";
|
|
44
|
+
|
|
45
|
+
export type ItemChartDatum = {
|
|
46
|
+
label: string;
|
|
47
|
+
value: number;
|
|
48
|
+
tone?: ItemChartTone;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type ItemChartSeat = {
|
|
52
|
+
x: number;
|
|
53
|
+
y: number;
|
|
54
|
+
r: number;
|
|
55
|
+
tone: ItemChartTone;
|
|
56
|
+
groupIndex: number;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const TONES: ItemChartTone[] = [
|
|
60
|
+
"category1",
|
|
61
|
+
"category2",
|
|
62
|
+
"category3",
|
|
63
|
+
"category4",
|
|
64
|
+
"category5",
|
|
65
|
+
"category6",
|
|
66
|
+
"category7",
|
|
67
|
+
"category8"
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
export function seatCount(value: number): number {
|
|
71
|
+
if (!Number.isFinite(value) || value < 0) return 0;
|
|
72
|
+
return Math.round(value);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Construit la liste ordonnée des sièges de l'hémicycle, puis affecte chaque
|
|
77
|
+
* siège à un groupe dans l'ordre fourni (blocs contigus). Pur, sans état.
|
|
78
|
+
*/
|
|
79
|
+
export function buildSeats(
|
|
80
|
+
counts: number[],
|
|
81
|
+
width: number,
|
|
82
|
+
height: number
|
|
83
|
+
): { seats: ItemChartSeat[]; cx: number; cy: number } {
|
|
84
|
+
const total = counts.reduce((sum, c) => sum + c, 0);
|
|
85
|
+
const cx = width / 2;
|
|
86
|
+
const cy = height - 8;
|
|
87
|
+
if (total <= 0) return { seats: [], cx, cy };
|
|
88
|
+
|
|
89
|
+
const rows = Math.max(1, Math.min(5, Math.round(Math.sqrt(total / 12)) || 1));
|
|
90
|
+
const outerR = Math.max(Math.min(cx, cy) - 14, 1);
|
|
91
|
+
const innerR = outerR * 0.42;
|
|
92
|
+
const rowGap = rows > 1 ? (outerR - innerR) / (rows - 1) : 0;
|
|
93
|
+
|
|
94
|
+
// Poids de chaque rangée ∝ son rayon (rangées extérieures = plus de sièges).
|
|
95
|
+
const radii: number[] = [];
|
|
96
|
+
let weightSum = 0;
|
|
97
|
+
for (let r = 0; r < rows; r++) {
|
|
98
|
+
const radius = rows > 1 ? innerR + rowGap * r : (innerR + outerR) / 2;
|
|
99
|
+
radii.push(radius);
|
|
100
|
+
weightSum += radius;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Répartit `total` sièges sur les rangées au prorata du rayon (reste au plus
|
|
104
|
+
// grand résidu) pour conserver exactement `total` sièges.
|
|
105
|
+
const perRowFloat = radii.map((radius) => (total * radius) / weightSum);
|
|
106
|
+
const perRow = perRowFloat.map((v) => Math.floor(v));
|
|
107
|
+
let assigned = perRow.reduce((sum, c) => sum + c, 0);
|
|
108
|
+
const residuals = perRowFloat
|
|
109
|
+
.map((v, i) => ({ i, frac: v - Math.floor(v) }))
|
|
110
|
+
.sort((a, b) => b.frac - a.frac);
|
|
111
|
+
let ri = 0;
|
|
112
|
+
while (assigned < total) {
|
|
113
|
+
perRow[residuals[ri % residuals.length].i] += 1;
|
|
114
|
+
assigned += 1;
|
|
115
|
+
ri += 1;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Rayon du point ≈ moitié de l'espacement de rangée, borné par l'arc.
|
|
119
|
+
const seatR = Math.max(2, Math.min(rowGap > 0 ? rowGap * 0.34 : outerR * 0.12, outerR * 0.12));
|
|
120
|
+
|
|
121
|
+
const ordered: { x: number; y: number; r: number }[] = [];
|
|
122
|
+
for (let r = 0; r < rows; r++) {
|
|
123
|
+
const radius = radii[r];
|
|
124
|
+
const n = perRow[r];
|
|
125
|
+
if (n <= 0) continue;
|
|
126
|
+
// Demi-cercle de la GAUCHE (π) vers la DROITE (0) en passant par le HAUT.
|
|
127
|
+
for (let s = 0; s < n; s++) {
|
|
128
|
+
const t = n === 1 ? 0.5 : s / (n - 1);
|
|
129
|
+
const angle = Math.PI - t * Math.PI;
|
|
130
|
+
ordered.push({
|
|
131
|
+
x: cx + radius * Math.cos(angle),
|
|
132
|
+
y: cy - radius * Math.sin(angle),
|
|
133
|
+
r: seatR
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Attribution des sièges ordonnés aux groupes (blocs contigus).
|
|
139
|
+
const seats: ItemChartSeat[] = [];
|
|
140
|
+
let cursor = 0;
|
|
141
|
+
for (let g = 0; g < counts.length; g++) {
|
|
142
|
+
const tone = TONES[g % TONES.length];
|
|
143
|
+
for (let k = 0; k < counts[g] && cursor < ordered.length; k++) {
|
|
144
|
+
const seat = ordered[cursor++];
|
|
145
|
+
seats.push({ x: seat.x, y: seat.y, r: seat.r, tone, groupIndex: g });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return { seats, cx, cy };
|
|
149
|
+
}
|
|
150
|
+
</script>
|
|
151
|
+
|
|
152
|
+
<script lang="ts">
|
|
153
|
+
import ChartDataList from "./ChartDataList.svelte";
|
|
154
|
+
|
|
155
|
+
type ItemChartProps = {
|
|
156
|
+
data: ItemChartDatum[];
|
|
157
|
+
label: string;
|
|
158
|
+
width?: number;
|
|
159
|
+
height?: number;
|
|
160
|
+
class?: string;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
let {
|
|
164
|
+
data,
|
|
165
|
+
label,
|
|
166
|
+
width = 480,
|
|
167
|
+
height = 280,
|
|
168
|
+
class: className
|
|
169
|
+
}: ItemChartProps = $props();
|
|
170
|
+
|
|
171
|
+
let hoveredIndex: number | null = $state(null);
|
|
172
|
+
|
|
173
|
+
const groups = $derived(
|
|
174
|
+
data.map((datum, index) => ({
|
|
175
|
+
datum,
|
|
176
|
+
count: seatCount(datum.value),
|
|
177
|
+
tone: datum.tone ?? TONES[index % TONES.length]
|
|
178
|
+
}))
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
const layout = $derived(buildSeats(groups.map((g) => g.count), width, height));
|
|
182
|
+
|
|
183
|
+
// Sièges avec le ton EFFECTIF du groupe (respecte un `tone` explicite).
|
|
184
|
+
const seats = $derived(
|
|
185
|
+
layout.seats.map((seat) => ({
|
|
186
|
+
...seat,
|
|
187
|
+
tone: groups[seat.groupIndex]?.tone ?? seat.tone
|
|
188
|
+
}))
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
const dataValueItems = $derived(
|
|
192
|
+
groups.map((g) => `${g.datum.label}: ${g.count}`)
|
|
193
|
+
);
|
|
194
|
+
|
|
195
|
+
const total = $derived(groups.reduce((sum, g) => sum + g.count, 0));
|
|
196
|
+
|
|
197
|
+
function handleVisualPointerMove(event: PointerEvent) {
|
|
198
|
+
const target = event.target;
|
|
199
|
+
if (!(target instanceof Element)) {
|
|
200
|
+
hoveredIndex = null;
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const index = Number(target.getAttribute("data-chart-index"));
|
|
204
|
+
hoveredIndex = Number.isInteger(index) ? index : null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const classes = () => ["st-itemChart", className].filter(Boolean).join(" ");
|
|
208
|
+
</script>
|
|
209
|
+
|
|
210
|
+
<div class={classes()}>
|
|
211
|
+
<div
|
|
212
|
+
class="st-itemChart__visual"
|
|
213
|
+
role="img"
|
|
214
|
+
aria-label={label}
|
|
215
|
+
onpointermove={handleVisualPointerMove}
|
|
216
|
+
onpointerleave={() => (hoveredIndex = null)}
|
|
217
|
+
>
|
|
218
|
+
<svg
|
|
219
|
+
viewBox="0 0 {width} {height}"
|
|
220
|
+
preserveAspectRatio="xMidYMid meet"
|
|
221
|
+
width="100%"
|
|
222
|
+
height="100%"
|
|
223
|
+
focusable="false"
|
|
224
|
+
aria-hidden="true"
|
|
225
|
+
>
|
|
226
|
+
{#each seats as seat, i (i)}
|
|
227
|
+
<circle
|
|
228
|
+
class="st-itemChart__seat st-itemChart__seat--{seat.tone}"
|
|
229
|
+
class:st-itemChart__seat--dim={hoveredIndex !== null && hoveredIndex !== seat.groupIndex}
|
|
230
|
+
cx={seat.x}
|
|
231
|
+
cy={seat.y}
|
|
232
|
+
r={seat.r}
|
|
233
|
+
data-chart-index={seat.groupIndex}
|
|
234
|
+
/>
|
|
235
|
+
{/each}
|
|
236
|
+
{#if total > 0}
|
|
237
|
+
<text
|
|
238
|
+
class="st-itemChart__total"
|
|
239
|
+
x={layout.cx}
|
|
240
|
+
y={layout.cy - 6}
|
|
241
|
+
text-anchor="middle"
|
|
242
|
+
>
|
|
243
|
+
{total}
|
|
244
|
+
</text>
|
|
245
|
+
{/if}
|
|
246
|
+
</svg>
|
|
247
|
+
</div>
|
|
248
|
+
|
|
249
|
+
<ul class="st-itemChart__legend" aria-hidden="true">
|
|
250
|
+
{#each groups as group, i (group.datum.label)}
|
|
251
|
+
<li
|
|
252
|
+
class="st-itemChart__legendItem"
|
|
253
|
+
class:st-itemChart__legendItem--dim={hoveredIndex !== null && hoveredIndex !== i}
|
|
254
|
+
>
|
|
255
|
+
<span class="st-itemChart__swatch st-itemChart__swatch--{group.tone}"></span>
|
|
256
|
+
<span class="st-itemChart__legendLabel">{group.datum.label}</span>
|
|
257
|
+
<span class="st-itemChart__legendValue">{group.count}</span>
|
|
258
|
+
</li>
|
|
259
|
+
{/each}
|
|
260
|
+
</ul>
|
|
261
|
+
|
|
262
|
+
<ChartDataList {label} items={dataValueItems} />
|
|
263
|
+
|
|
264
|
+
{#if hoveredIndex !== null && groups[hoveredIndex]}
|
|
265
|
+
{@const group = groups[hoveredIndex]}
|
|
266
|
+
<div class="st-itemChart__tooltip" role="presentation">
|
|
267
|
+
<span class="st-itemChart__tooltipLabel">{group.datum.label}</span>
|
|
268
|
+
<span class="st-itemChart__tooltipValue">{group.count}</span>
|
|
269
|
+
</div>
|
|
270
|
+
{/if}
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<style>
|
|
274
|
+
.st-itemChart {
|
|
275
|
+
color: var(--st-semantic-text-secondary);
|
|
276
|
+
display: block;
|
|
277
|
+
font-family: inherit;
|
|
278
|
+
max-width: 100%;
|
|
279
|
+
position: relative;
|
|
280
|
+
width: 100%;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.st-itemChart svg,
|
|
284
|
+
.st-itemChart__visual {
|
|
285
|
+
display: block;
|
|
286
|
+
overflow: visible;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
.st-itemChart__seat {
|
|
290
|
+
cursor: pointer;
|
|
291
|
+
stroke: var(--st-semantic-surface-default);
|
|
292
|
+
stroke-width: 1;
|
|
293
|
+
transition: opacity 120ms ease;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.st-itemChart__seat--dim {
|
|
297
|
+
opacity: 0.32;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
@media (prefers-reduced-motion: reduce) {
|
|
301
|
+
.st-itemChart__seat {
|
|
302
|
+
transition: none;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
.st-itemChart__seat--category1 { fill: var(--st-semantic-data-category1); }
|
|
307
|
+
.st-itemChart__seat--category2 { fill: var(--st-semantic-data-category2); }
|
|
308
|
+
.st-itemChart__seat--category3 { fill: var(--st-semantic-data-category3); }
|
|
309
|
+
.st-itemChart__seat--category4 { fill: var(--st-semantic-data-category4); }
|
|
310
|
+
.st-itemChart__seat--category5 { fill: var(--st-semantic-data-category5); }
|
|
311
|
+
.st-itemChart__seat--category6 { fill: var(--st-semantic-data-category6); }
|
|
312
|
+
.st-itemChart__seat--category7 { fill: var(--st-semantic-data-category7); }
|
|
313
|
+
.st-itemChart__seat--category8 { fill: var(--st-semantic-data-category8); }
|
|
314
|
+
|
|
315
|
+
.st-itemChart__total {
|
|
316
|
+
fill: var(--st-semantic-text-primary);
|
|
317
|
+
font-size: 1.5rem;
|
|
318
|
+
font-weight: 700;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.st-itemChart__legend {
|
|
322
|
+
display: flex;
|
|
323
|
+
flex-wrap: wrap;
|
|
324
|
+
gap: 0.25rem 0.875rem;
|
|
325
|
+
list-style: none;
|
|
326
|
+
margin: 0.5rem 0 0;
|
|
327
|
+
padding: 0;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
.st-itemChart__legendItem {
|
|
331
|
+
align-items: center;
|
|
332
|
+
display: inline-flex;
|
|
333
|
+
font-size: 0.8125rem;
|
|
334
|
+
gap: 0.375rem;
|
|
335
|
+
transition: opacity 120ms ease;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
.st-itemChart__legendItem--dim {
|
|
339
|
+
opacity: 0.4;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
.st-itemChart__swatch {
|
|
343
|
+
border-radius: 999px;
|
|
344
|
+
display: inline-block;
|
|
345
|
+
height: 0.625rem;
|
|
346
|
+
width: 0.625rem;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.st-itemChart__swatch--category1 { background: var(--st-semantic-data-category1); }
|
|
350
|
+
.st-itemChart__swatch--category2 { background: var(--st-semantic-data-category2); }
|
|
351
|
+
.st-itemChart__swatch--category3 { background: var(--st-semantic-data-category3); }
|
|
352
|
+
.st-itemChart__swatch--category4 { background: var(--st-semantic-data-category4); }
|
|
353
|
+
.st-itemChart__swatch--category5 { background: var(--st-semantic-data-category5); }
|
|
354
|
+
.st-itemChart__swatch--category6 { background: var(--st-semantic-data-category6); }
|
|
355
|
+
.st-itemChart__swatch--category7 { background: var(--st-semantic-data-category7); }
|
|
356
|
+
.st-itemChart__swatch--category8 { background: var(--st-semantic-data-category8); }
|
|
357
|
+
|
|
358
|
+
.st-itemChart__legendLabel {
|
|
359
|
+
color: var(--st-semantic-text-primary);
|
|
360
|
+
font-weight: 500;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.st-itemChart__legendValue {
|
|
364
|
+
color: var(--st-semantic-text-secondary);
|
|
365
|
+
font-variant-numeric: tabular-nums;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.st-itemChart__tooltip {
|
|
369
|
+
background: var(--st-semantic-surface-inverse);
|
|
370
|
+
border-radius: var(--st-radius-sm);
|
|
371
|
+
color: var(--st-semantic-text-inverse);
|
|
372
|
+
display: inline-flex;
|
|
373
|
+
flex-direction: column;
|
|
374
|
+
font-size: 0.75rem;
|
|
375
|
+
gap: 0.125rem;
|
|
376
|
+
left: 50%;
|
|
377
|
+
line-height: 1.2;
|
|
378
|
+
padding: 0.375rem 0.5rem;
|
|
379
|
+
pointer-events: none;
|
|
380
|
+
position: absolute;
|
|
381
|
+
top: 0.5rem;
|
|
382
|
+
transform: translateX(-50%);
|
|
383
|
+
white-space: nowrap;
|
|
384
|
+
z-index: 1;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
.st-itemChart__tooltipLabel { font-weight: 600; }
|
|
388
|
+
.st-itemChart__tooltipValue { opacity: 0.85; }
|
|
389
|
+
</style>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ItemChart (« parlement » / hémicycle) — API canonique (référence Svelte,
|
|
3
|
+
* React/Vue doivent s'aligner).
|
|
4
|
+
*
|
|
5
|
+
* Chaque groupe apporte `value` POINTS (sièges). La somme des points est
|
|
6
|
+
* disposée en plusieurs RANGÉES CONCENTRIQUES formant un demi-anneau du haut
|
|
7
|
+
* (hémicycle). Les points d'un même groupe sont CONTIGUS et colorés par un ton
|
|
8
|
+
* catégoriel (`categoryN`). On lit donc la taille relative des groupes à la
|
|
9
|
+
* longueur de l'arc qu'ils occupent — façon répartition des sièges.
|
|
10
|
+
*
|
|
11
|
+
* Géométrie :
|
|
12
|
+
* - nombre de rangées = clamp(round(sqrt(total / 12)), 3, 5) tant qu'il reste
|
|
13
|
+
* des points (au moins 1 rangée).
|
|
14
|
+
* - les rangées ont des rayons régulièrement espacés ; le nombre de points
|
|
15
|
+
* par rangée est ∝ au rayon (les rangées extérieures portent plus de
|
|
16
|
+
* sièges), de sorte que l'espacement angulaire reste homogène.
|
|
17
|
+
* - chaque siège est posé sur un demi-cercle (de gauche π à droite 0, via le
|
|
18
|
+
* haut), tous les sièges étant ordonnés rangée par rangée puis attribués
|
|
19
|
+
* aux groupes dans l'ordre fourni → blocs contigus.
|
|
20
|
+
*
|
|
21
|
+
* Props obligatoires :
|
|
22
|
+
* data ItemChartDatum[] - {label, value, tone?}
|
|
23
|
+
* label string - aria-label du graphique (role=img)
|
|
24
|
+
*
|
|
25
|
+
* Props optionnelles :
|
|
26
|
+
* width number (défaut 480)
|
|
27
|
+
* height number (défaut 280)
|
|
28
|
+
* class string
|
|
29
|
+
*
|
|
30
|
+
* NaN/négatif : `value` non-finie ou < 0 → 0 siège pour ce groupe. Total 0 →
|
|
31
|
+
* rendu vide sans crash. `value` est arrondie à l'entier le plus proche pour
|
|
32
|
+
* compter des sièges.
|
|
33
|
+
*/
|
|
34
|
+
export type ItemChartTone = "category1" | "category2" | "category3" | "category4" | "category5" | "category6" | "category7" | "category8";
|
|
35
|
+
export type ItemChartDatum = {
|
|
36
|
+
label: string;
|
|
37
|
+
value: number;
|
|
38
|
+
tone?: ItemChartTone;
|
|
39
|
+
};
|
|
40
|
+
export type ItemChartSeat = {
|
|
41
|
+
x: number;
|
|
42
|
+
y: number;
|
|
43
|
+
r: number;
|
|
44
|
+
tone: ItemChartTone;
|
|
45
|
+
groupIndex: number;
|
|
46
|
+
};
|
|
47
|
+
export declare function seatCount(value: number): number;
|
|
48
|
+
/**
|
|
49
|
+
* Construit la liste ordonnée des sièges de l'hémicycle, puis affecte chaque
|
|
50
|
+
* siège à un groupe dans l'ordre fourni (blocs contigus). Pur, sans état.
|
|
51
|
+
*/
|
|
52
|
+
export declare function buildSeats(counts: number[], width: number, height: number): {
|
|
53
|
+
seats: ItemChartSeat[];
|
|
54
|
+
cx: number;
|
|
55
|
+
cy: number;
|
|
56
|
+
};
|
|
57
|
+
type ItemChartProps = {
|
|
58
|
+
data: ItemChartDatum[];
|
|
59
|
+
label: string;
|
|
60
|
+
width?: number;
|
|
61
|
+
height?: number;
|
|
62
|
+
class?: string;
|
|
63
|
+
};
|
|
64
|
+
declare const ItemChart: import("svelte").Component<ItemChartProps, {}, "">;
|
|
65
|
+
type ItemChart = ReturnType<typeof ItemChart>;
|
|
66
|
+
export default ItemChart;
|
|
67
|
+
//# sourceMappingURL=ItemChart.svelte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ItemChart.svelte.d.ts","sourceRoot":"","sources":["../src/lib/ItemChart.svelte.ts"],"names":[],"mappings":"AAGE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,MAAM,aAAa,GACrB,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,cAAc,GAAG;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,IAAI,EAAE,aAAa,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAaF,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb;IAAE,KAAK,EAAE,aAAa,EAAE,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAkEpD;AAMD,KAAK,cAAc,GAAG;IACpB,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AA6FJ,QAAA,MAAM,SAAS,oDAAwC,CAAC;AACxD,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC;AAC9C,eAAe,SAAS,CAAC"}
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
class: className
|
|
62
62
|
}: LollipopChartProps = $props();
|
|
63
63
|
|
|
64
|
-
const MARGIN = { top:
|
|
64
|
+
const MARGIN = { top: 24, right: 16, bottom: 32, left: 44 };
|
|
65
65
|
const DOT_RADIUS = 5;
|
|
66
66
|
|
|
67
67
|
function niceTicks(min: number, max: number, target = 5): number[] {
|
package/dist/MultiSelect.svelte
CHANGED
|
@@ -238,14 +238,17 @@
|
|
|
238
238
|
|
|
239
239
|
.st-multiSelect--sm .st-multiSelect__trigger {
|
|
240
240
|
min-height: var(--st-component-control-smHeight, 2rem);
|
|
241
|
+
font-size: 0.8125rem;
|
|
241
242
|
}
|
|
242
243
|
|
|
243
244
|
.st-multiSelect--md .st-multiSelect__trigger {
|
|
244
245
|
min-height: var(--st-component-control-mdHeight, 2.5rem);
|
|
246
|
+
font-size: 0.875rem;
|
|
245
247
|
}
|
|
246
248
|
|
|
247
249
|
.st-multiSelect--lg .st-multiSelect__trigger {
|
|
248
250
|
min-height: var(--st-component-control-lgHeight, 3rem);
|
|
251
|
+
font-size: 1rem;
|
|
249
252
|
}
|
|
250
253
|
|
|
251
254
|
/* Field box = resolved field anatomy (v1.2.0), same as Input. */
|
package/dist/NumberInput.svelte
CHANGED
|
@@ -168,14 +168,17 @@
|
|
|
168
168
|
|
|
169
169
|
.st-numberInput--sm {
|
|
170
170
|
min-height: var(--st-component-control-smHeight, 2rem);
|
|
171
|
+
font-size: 0.8125rem;
|
|
171
172
|
}
|
|
172
173
|
|
|
173
174
|
.st-numberInput--md {
|
|
174
175
|
min-height: var(--st-component-control-mdHeight, 2.5rem);
|
|
176
|
+
font-size: 0.875rem;
|
|
175
177
|
}
|
|
176
178
|
|
|
177
179
|
.st-numberInput--lg {
|
|
178
180
|
min-height: var(--st-component-control-lgHeight, 3rem);
|
|
181
|
+
font-size: 1rem;
|
|
179
182
|
}
|
|
180
183
|
|
|
181
184
|
.st-numberInput:hover:not(:has(input:disabled)) {
|