@communitiesuk/svelte-component-library 0.1.19-beta.20 → 0.1.19-beta.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/components/data-vis/Histogram.svelte +94 -57
- package/dist/components/data-vis/Histogram.svelte.d.ts +4 -0
- package/dist/components/data-vis/axis/Axis.svelte +6 -1
- package/dist/components/data-vis/axis/Axis.svelte.d.ts +1 -1
- package/dist/components/data-vis/axis/Ticks.svelte +11 -3
- package/dist/components/data-vis/axis/Ticks.svelte.d.ts +2 -1
- package/dist/components/data-vis/position-chart/PositionChart.svelte +44 -14
- package/dist/components/data-vis/position-chart/PositionChart.svelte.d.ts +2 -0
- package/dist/components/data-vis/position-chart/PositionChartAxis.svelte +1 -0
- package/package.json +1 -1
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
tickStrokeWidth = 0.25,
|
|
39
39
|
barStrokeWidth = 0,
|
|
40
40
|
barStrokeColor = "white",
|
|
41
|
+
topLabel = true,
|
|
42
|
+
includeOutliers = true,
|
|
41
43
|
} = $props();
|
|
42
44
|
|
|
43
45
|
let xTicks = $state([]);
|
|
@@ -74,11 +76,18 @@
|
|
|
74
76
|
const binner = $derived(
|
|
75
77
|
bin().domain([domainXMin, domainXMax]).thresholds(binThresholds),
|
|
76
78
|
);
|
|
79
|
+
const clampedDistribution = $derived(
|
|
80
|
+
distribution.map((d) => Math.min(Math.max(d, domainXMin), domainXMax)),
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const binnedDistribution = $derived(
|
|
84
|
+
binner(includeOutliers ? clampedDistribution : distribution),
|
|
85
|
+
);
|
|
77
86
|
|
|
78
87
|
const bins = $derived(
|
|
79
88
|
polarity === "reverse"
|
|
80
|
-
?
|
|
81
|
-
:
|
|
89
|
+
? binnedDistribution.toReversed()
|
|
90
|
+
: binnedDistribution,
|
|
82
91
|
);
|
|
83
92
|
|
|
84
93
|
const proportionsInBins = $derived(
|
|
@@ -138,24 +147,48 @@
|
|
|
138
147
|
);
|
|
139
148
|
|
|
140
149
|
$inspect({ colorScale });
|
|
150
|
+
|
|
151
|
+
const layout = $derived.by(() => {
|
|
152
|
+
let y = 0;
|
|
153
|
+
|
|
154
|
+
const topLabelY = topLabel ? y : null;
|
|
155
|
+
if (topLabel) y += 20;
|
|
156
|
+
|
|
157
|
+
const annotationY = annotationText ? y : null;
|
|
158
|
+
if (annotationText) y += 25;
|
|
159
|
+
|
|
160
|
+
const chartY = y;
|
|
161
|
+
y += height;
|
|
162
|
+
|
|
163
|
+
const xAxisY = showXAxis ? y : null;
|
|
164
|
+
if (showXAxis) y += 25;
|
|
165
|
+
|
|
166
|
+
return {
|
|
167
|
+
topLabelY,
|
|
168
|
+
annotationY,
|
|
169
|
+
chartY,
|
|
170
|
+
xAxisY,
|
|
171
|
+
totalHeight: y,
|
|
172
|
+
};
|
|
173
|
+
});
|
|
141
174
|
</script>
|
|
142
175
|
|
|
143
176
|
{#key containerWidth}
|
|
144
177
|
<div class="scale-container" bind:clientWidth={containerWidth}>
|
|
145
|
-
<svg
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
178
|
+
<svg width={containerWidth} height={layout.totalHeight}>
|
|
179
|
+
<g transform="translate({padding / 2}, 0)">
|
|
180
|
+
{#if topLabel && layout.topLabelY !== null}
|
|
181
|
+
<text x={0} y={layout.topLabelY + 14} fill="#666" font-size="0.75em">
|
|
182
|
+
Number of areas
|
|
183
|
+
</text>
|
|
184
|
+
{/if}
|
|
185
|
+
|
|
186
|
+
{#if annotationText && layout.annotationY !== null}
|
|
187
|
+
<g
|
|
188
|
+
transform="translate({xScale(
|
|
189
|
+
annotationValue,
|
|
190
|
+
)}, {layout.annotationY})"
|
|
191
|
+
>
|
|
159
192
|
<text
|
|
160
193
|
fill="#555555"
|
|
161
194
|
font-size="0.8em"
|
|
@@ -168,57 +201,61 @@
|
|
|
168
201
|
</g>
|
|
169
202
|
{/if}
|
|
170
203
|
|
|
171
|
-
<g transform="translate(0,{
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
{#if showYAxis}
|
|
191
|
-
<Axis
|
|
192
|
-
bind:ticksArray={yTicks}
|
|
193
|
-
chartHeight={height}
|
|
194
|
-
chartWidth={containerWidth - padding}
|
|
195
|
-
orientation={{ axis: "y", position: "left" }}
|
|
196
|
-
min={minY}
|
|
197
|
-
max={maxY}
|
|
198
|
-
domain={[0, yTickLast]}
|
|
199
|
-
range={[0, height]}
|
|
200
|
-
fontSize={0}
|
|
201
|
-
numberOfTicks={4}
|
|
202
|
-
{showGridlines}
|
|
203
|
-
{showTickMarks}
|
|
204
|
-
strokeWidth={tickStrokeWidth}
|
|
205
|
-
></Axis>
|
|
206
|
-
{/if}
|
|
207
|
-
</g>
|
|
204
|
+
<g transform="translate(0, {layout.chartY})">
|
|
205
|
+
{#if showYAxis}
|
|
206
|
+
<Axis
|
|
207
|
+
bind:ticksArray={yTicks}
|
|
208
|
+
chartHeight={height}
|
|
209
|
+
chartWidth={containerWidth - padding}
|
|
210
|
+
orientation={{ axis: "y", position: "left" }}
|
|
211
|
+
min={minY}
|
|
212
|
+
max={maxY}
|
|
213
|
+
domain={[yTickLast, 0]}
|
|
214
|
+
range={[0, height]}
|
|
215
|
+
fontSize={0}
|
|
216
|
+
numberOfTicks={3}
|
|
217
|
+
{showGridlines}
|
|
218
|
+
{showTickMarks}
|
|
219
|
+
strokeWidth={tickStrokeWidth}
|
|
220
|
+
/>
|
|
221
|
+
{/if}
|
|
222
|
+
|
|
208
223
|
{#each bins as bin, i}
|
|
209
224
|
{#key bin.x0}
|
|
225
|
+
{@const fullWidth = Math.abs(xScale(bin.x1) - xScale(bin.x0))}
|
|
226
|
+
{@const barWidth = fullWidth * 0.97}
|
|
227
|
+
{@const offset = (fullWidth - barWidth) / 2}
|
|
210
228
|
<rect
|
|
211
|
-
x={polarity === "reverse" ? xScale(bin.x1) : xScale(bin.x0)
|
|
229
|
+
x={(polarity === "reverse" ? xScale(bin.x1) : xScale(bin.x0)) +
|
|
230
|
+
offset}
|
|
212
231
|
y={height - yScale(bin.length)}
|
|
213
|
-
width={
|
|
232
|
+
width={barWidth}
|
|
214
233
|
height={yScale(bin.length)}
|
|
215
234
|
fill={fill ?? colorScale[i]}
|
|
216
|
-
stroke-width={barStrokeWidth}
|
|
217
|
-
stroke={barStrokeColor}
|
|
218
235
|
></rect>
|
|
219
236
|
{/key}
|
|
220
237
|
{/each}
|
|
221
238
|
</g>
|
|
239
|
+
|
|
240
|
+
{#if showXAxis && layout.xAxisY !== null}
|
|
241
|
+
<g transform="translate(0, {layout.xAxisY})">
|
|
242
|
+
<Axis
|
|
243
|
+
bind:ticksArray={xTicks}
|
|
244
|
+
chartHeight={height}
|
|
245
|
+
chartWidth={containerWidth - padding}
|
|
246
|
+
orientation={{ axis: "x", position: "bottom" }}
|
|
247
|
+
domain={[xTickFirst, xTickLast]}
|
|
248
|
+
min={minX}
|
|
249
|
+
max={maxX}
|
|
250
|
+
range={useRange}
|
|
251
|
+
fontSize={13}
|
|
252
|
+
{floor}
|
|
253
|
+
{ceiling}
|
|
254
|
+
{labelFormatter}
|
|
255
|
+
{numberOfTicks}
|
|
256
|
+
/>
|
|
257
|
+
</g>
|
|
258
|
+
{/if}
|
|
222
259
|
</g>
|
|
223
260
|
</svg>
|
|
224
261
|
</div>
|
|
@@ -35,6 +35,8 @@ declare const Histogram: import("svelte").Component<{
|
|
|
35
35
|
tickStrokeWidth?: number;
|
|
36
36
|
barStrokeWidth?: number;
|
|
37
37
|
barStrokeColor?: string;
|
|
38
|
+
topLabel?: boolean;
|
|
39
|
+
includeOutliers?: boolean;
|
|
38
40
|
}, {}, "containerWidth">;
|
|
39
41
|
type $$ComponentProps = {
|
|
40
42
|
averageValue?: any;
|
|
@@ -68,4 +70,6 @@ type $$ComponentProps = {
|
|
|
68
70
|
tickStrokeWidth?: number;
|
|
69
71
|
barStrokeWidth?: number;
|
|
70
72
|
barStrokeColor?: string;
|
|
73
|
+
topLabel?: boolean;
|
|
74
|
+
includeOutliers?: boolean;
|
|
71
75
|
};
|
|
@@ -10,7 +10,12 @@
|
|
|
10
10
|
type AxisPosition = "bottom" | "top" | "left" | "right";
|
|
11
11
|
type Orientation = { axis: AxisName; position: AxisPosition };
|
|
12
12
|
type AxisProjector = (value: number) => number;
|
|
13
|
-
type LabelFormatter = (
|
|
13
|
+
type LabelFormatter = (
|
|
14
|
+
tick: number,
|
|
15
|
+
index: number,
|
|
16
|
+
ticksArrayLength: number,
|
|
17
|
+
) => string | number;
|
|
18
|
+
|
|
14
19
|
type Polarity = "standard" | "reverse";
|
|
15
20
|
|
|
16
21
|
let {
|
|
@@ -5,7 +5,7 @@ type Orientation = {
|
|
|
5
5
|
axis: AxisName;
|
|
6
6
|
position: AxisPosition;
|
|
7
7
|
};
|
|
8
|
-
type LabelFormatter = (tick: number, index: number) => string | number;
|
|
8
|
+
type LabelFormatter = (tick: number, index: number, ticksArrayLength: number) => string | number;
|
|
9
9
|
type Polarity = "standard" | "reverse";
|
|
10
10
|
type $$ComponentProps = {
|
|
11
11
|
chartHeight?: number;
|
|
@@ -11,6 +11,12 @@
|
|
|
11
11
|
}
|
|
12
12
|
type Polarity = "standard" | "reverse";
|
|
13
13
|
|
|
14
|
+
type LabelFormatter = (
|
|
15
|
+
tick: number,
|
|
16
|
+
index: number,
|
|
17
|
+
ticksArrayLength: number,
|
|
18
|
+
) => string | number;
|
|
19
|
+
|
|
14
20
|
// Props with defaults (Svelte 5 runes)
|
|
15
21
|
let {
|
|
16
22
|
ticksArray = $bindable<number[]>(),
|
|
@@ -23,13 +29,13 @@
|
|
|
23
29
|
floor,
|
|
24
30
|
ceiling,
|
|
25
31
|
orientation,
|
|
26
|
-
labelFormatter,
|
|
27
32
|
fontSize = 19,
|
|
28
33
|
polarity = "standard",
|
|
29
34
|
showGridlines = false,
|
|
30
35
|
showTickMarks = false,
|
|
31
36
|
|
|
32
37
|
strokeWidth = 2,
|
|
38
|
+
labelFormatter = undefined as LabelFormatter | undefined,
|
|
33
39
|
}: {
|
|
34
40
|
ticksArray?: number[]; // bindable
|
|
35
41
|
chartWidth: number;
|
|
@@ -41,13 +47,13 @@
|
|
|
41
47
|
floor?: number;
|
|
42
48
|
ceiling?: number;
|
|
43
49
|
orientation: Orientation;
|
|
44
|
-
labelFormatter?: (tick: number, index: number) => string;
|
|
45
50
|
fontSize?: number;
|
|
46
51
|
polarity?: Polarity;
|
|
47
52
|
showGridlines?: Boolean;
|
|
48
53
|
showTickMarks?: Boolean;
|
|
49
54
|
|
|
50
55
|
strokeWidth?: number;
|
|
56
|
+
labelFormatter?: LabelFormatter;
|
|
51
57
|
} = $props();
|
|
52
58
|
function axisValue(fn: any, tick: number): number {
|
|
53
59
|
// Try single-call first: axisFunction(tick)
|
|
@@ -201,7 +207,9 @@
|
|
|
201
207
|
: "start"}
|
|
202
208
|
fill="grey"
|
|
203
209
|
>
|
|
204
|
-
{labelFormatter
|
|
210
|
+
{labelFormatter
|
|
211
|
+
? labelFormatter(tick, index, ticksArray.length)
|
|
212
|
+
: defaultLabel(tick)}
|
|
205
213
|
</text>
|
|
206
214
|
</g>
|
|
207
215
|
{/each}
|
|
@@ -5,6 +5,7 @@ interface Orientation {
|
|
|
5
5
|
position: Position;
|
|
6
6
|
}
|
|
7
7
|
type Polarity = "standard" | "reverse";
|
|
8
|
+
type LabelFormatter = (tick: number, index: number, ticksArrayLength: number) => string | number;
|
|
8
9
|
type $$ComponentProps = {
|
|
9
10
|
ticksArray?: number[];
|
|
10
11
|
chartWidth: number;
|
|
@@ -16,12 +17,12 @@ type $$ComponentProps = {
|
|
|
16
17
|
floor?: number;
|
|
17
18
|
ceiling?: number;
|
|
18
19
|
orientation: Orientation;
|
|
19
|
-
labelFormatter?: (tick: number, index: number) => string;
|
|
20
20
|
fontSize?: number;
|
|
21
21
|
polarity?: Polarity;
|
|
22
22
|
showGridlines?: Boolean;
|
|
23
23
|
showTickMarks?: Boolean;
|
|
24
24
|
strokeWidth?: number;
|
|
25
|
+
labelFormatter?: LabelFormatter;
|
|
25
26
|
};
|
|
26
27
|
declare const Ticks: import("svelte").Component<$$ComponentProps, {}, "ticksArray">;
|
|
27
28
|
type Ticks = ReturnType<typeof Ticks>;
|
|
@@ -93,6 +93,9 @@
|
|
|
93
93
|
skew = false,
|
|
94
94
|
showTickMarks = true,
|
|
95
95
|
showGridlines = false,
|
|
96
|
+
labelFormatter = (tick, index, ticksArrayLength) => {
|
|
97
|
+
return tick;
|
|
98
|
+
},
|
|
96
99
|
} = $props();
|
|
97
100
|
|
|
98
101
|
let xTicks = $state([]);
|
|
@@ -272,6 +275,17 @@
|
|
|
272
275
|
),
|
|
273
276
|
);
|
|
274
277
|
}
|
|
278
|
+
|
|
279
|
+
let totalHeight = $derived(
|
|
280
|
+
chartHeight +
|
|
281
|
+
(showAxis ? 25 : 0) +
|
|
282
|
+
(showAverage ? 35 : 0) +
|
|
283
|
+
(showArrows ? 25 : 0),
|
|
284
|
+
);
|
|
285
|
+
|
|
286
|
+
let svgHeight = $derived(
|
|
287
|
+
chartHeight + (showAxis ? 25 : 0) + (showAverage ? 35 : 0),
|
|
288
|
+
);
|
|
275
289
|
</script>
|
|
276
290
|
|
|
277
291
|
{#if annotations.length}
|
|
@@ -331,9 +345,10 @@
|
|
|
331
345
|
class="grid-container"
|
|
332
346
|
bind:this={container}
|
|
333
347
|
style="
|
|
334
|
-
|
|
348
|
+
position: relative;
|
|
335
349
|
grid-template-columns: {gridTemplateColumns};
|
|
336
350
|
grid-template-rows: {gridTemplateRows};
|
|
351
|
+
height: {totalHeight}px;
|
|
337
352
|
"
|
|
338
353
|
>
|
|
339
354
|
{#each allDataNormalized as positionChart, i}
|
|
@@ -357,18 +372,8 @@
|
|
|
357
372
|
></Button>
|
|
358
373
|
</div>
|
|
359
374
|
{/if}
|
|
360
|
-
<div
|
|
361
|
-
|
|
362
|
-
style="height:{chartHeight +
|
|
363
|
-
(showAxis ? 30 : 30) +
|
|
364
|
-
(showArrows ? 30 : 0) +
|
|
365
|
-
(showAverage ? 40 : 0)}px"
|
|
366
|
-
bind:clientWidth={chartWidth}
|
|
367
|
-
>
|
|
368
|
-
<svg
|
|
369
|
-
width={chartWidth}
|
|
370
|
-
height={chartHeight + (showAxis ? 40 : 0) + (showAverage ? 40 : 0)}
|
|
371
|
-
>
|
|
375
|
+
<div class="chart" bind:clientWidth={chartWidth}>
|
|
376
|
+
<svg width={chartWidth} height={svgHeight} overflow="visible">
|
|
372
377
|
{#each range as number}
|
|
373
378
|
<g
|
|
374
379
|
transform="translate({markerRadius +
|
|
@@ -472,6 +477,7 @@
|
|
|
472
477
|
{polarity}
|
|
473
478
|
{showTickMarks}
|
|
474
479
|
{showGridlines}
|
|
480
|
+
{labelFormatter}
|
|
475
481
|
></Axis>
|
|
476
482
|
{/if}
|
|
477
483
|
{#if showAverage}
|
|
@@ -479,7 +485,8 @@
|
|
|
479
485
|
transform="translate({xFunction(
|
|
480
486
|
xTickFirst,
|
|
481
487
|
xTickLast,
|
|
482
|
-
)(averageValue) + markerRadius}, {chartHeight
|
|
488
|
+
)(averageValue) + markerRadius}, {chartHeight +
|
|
489
|
+
(showAxis ? 20 : 0)})"
|
|
483
490
|
>
|
|
484
491
|
<text
|
|
485
492
|
fill="#444"
|
|
@@ -550,6 +557,29 @@
|
|
|
550
557
|
{/if}
|
|
551
558
|
</div>
|
|
552
559
|
|
|
560
|
+
<div style="content-visibility: hidden;">
|
|
561
|
+
{#if !showAxis}
|
|
562
|
+
<Axis
|
|
563
|
+
bind:ticksArray={xTicks}
|
|
564
|
+
{chartHeight}
|
|
565
|
+
chartWidth={chartWidth - markerRadius * 2}
|
|
566
|
+
orientation={{ axis: "x", position: "bottom" }}
|
|
567
|
+
range={[markerRadius, chartWidth - markerRadius]}
|
|
568
|
+
domain={[xTickFirst, xTickLast]}
|
|
569
|
+
{min}
|
|
570
|
+
{max}
|
|
571
|
+
fontSize={14}
|
|
572
|
+
{floor}
|
|
573
|
+
{ceiling}
|
|
574
|
+
{numberOfTicks}
|
|
575
|
+
{polarity}
|
|
576
|
+
{showTickMarks}
|
|
577
|
+
{showGridlines}
|
|
578
|
+
{labelFormatter}
|
|
579
|
+
></Axis>
|
|
580
|
+
{/if}
|
|
581
|
+
</div>
|
|
582
|
+
|
|
553
583
|
<style>
|
|
554
584
|
.grid-container {
|
|
555
585
|
display: grid;
|
|
@@ -53,6 +53,7 @@ declare const PositionChart: import("svelte").Component<{
|
|
|
53
53
|
skew?: boolean;
|
|
54
54
|
showTickMarks?: boolean;
|
|
55
55
|
showGridlines?: boolean;
|
|
56
|
+
labelFormatter?: Function;
|
|
56
57
|
}, {}, "chartWidth">;
|
|
57
58
|
type $$ComponentProps = {
|
|
58
59
|
value?: any;
|
|
@@ -104,4 +105,5 @@ type $$ComponentProps = {
|
|
|
104
105
|
skew?: boolean;
|
|
105
106
|
showTickMarks?: boolean;
|
|
106
107
|
showGridlines?: boolean;
|
|
108
|
+
labelFormatter?: Function;
|
|
107
109
|
};
|