@internetstiftelsen/charts 0.13.0 → 0.13.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.
- package/dist/line.d.ts +3 -1
- package/dist/line.js +35 -2
- package/dist/tooltip.js +7 -3
- package/dist/types.d.ts +9 -1
- package/docs/xy-chart.md +16 -0
- package/package.json +1 -1
package/dist/line.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Selection } from 'd3';
|
|
2
|
-
import type { LineConfig, DataItem, D3Scale, ScaleType, ChartTheme, LineValueLabelConfig, ExportHooks, LineConfigBase } from './types.js';
|
|
2
|
+
import type { LineConfig, DataItem, D3Scale, ScaleType, ChartTheme, LineValueLabelConfig, ExportHooks, LineConfigBase, LineCurveType, LinePointsConfig } from './types.js';
|
|
3
3
|
import type { ChartComponent } from './chart-interface.js';
|
|
4
4
|
import type { XYPointAnimationContext, XYPointSnapshot, XYSeriesRenderResult } from './xy-motion/types.js';
|
|
5
5
|
export declare class Line implements ChartComponent<LineConfigBase> {
|
|
@@ -7,6 +7,8 @@ export declare class Line implements ChartComponent<LineConfigBase> {
|
|
|
7
7
|
readonly dataKey: string;
|
|
8
8
|
readonly stroke: string;
|
|
9
9
|
readonly strokeWidth?: number;
|
|
10
|
+
readonly curve: LineCurveType;
|
|
11
|
+
readonly points: Required<LinePointsConfig>;
|
|
10
12
|
readonly valueLabel?: LineValueLabelConfig;
|
|
11
13
|
readonly exportHooks?: ExportHooks<LineConfigBase>;
|
|
12
14
|
constructor(config: LineConfig);
|
package/dist/line.js
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
import { line } from 'd3';
|
|
1
|
+
import { curveBasis, curveCardinal, curveLinear, curveMonotoneX, curveNatural, curveStep, line, } from 'd3';
|
|
2
2
|
import { sanitizeForCSS, mergeDeep } from './utils.js';
|
|
3
3
|
import { getScalePosition } from './scale-utils.js';
|
|
4
4
|
import { buildXYDatumSnapshotKeys, createTransitionCompletionPromise, createLeftToRightRevealTransition, getEnterStaggerTiming, } from './xy-motion/helpers.js';
|
|
5
|
+
const DEFAULT_LINE_POINTS = {
|
|
6
|
+
show: 'always',
|
|
7
|
+
};
|
|
8
|
+
const LINE_CURVE_FACTORIES = {
|
|
9
|
+
linear: curveLinear,
|
|
10
|
+
monotone: curveMonotoneX,
|
|
11
|
+
step: curveStep,
|
|
12
|
+
natural: curveNatural,
|
|
13
|
+
basis: curveBasis,
|
|
14
|
+
cardinal: curveCardinal,
|
|
15
|
+
};
|
|
5
16
|
export class Line {
|
|
6
17
|
constructor(config) {
|
|
7
18
|
Object.defineProperty(this, "type", {
|
|
@@ -28,6 +39,18 @@ export class Line {
|
|
|
28
39
|
writable: true,
|
|
29
40
|
value: void 0
|
|
30
41
|
});
|
|
42
|
+
Object.defineProperty(this, "curve", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
configurable: true,
|
|
45
|
+
writable: true,
|
|
46
|
+
value: void 0
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(this, "points", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
configurable: true,
|
|
51
|
+
writable: true,
|
|
52
|
+
value: void 0
|
|
53
|
+
});
|
|
31
54
|
Object.defineProperty(this, "valueLabel", {
|
|
32
55
|
enumerable: true,
|
|
33
56
|
configurable: true,
|
|
@@ -43,6 +66,10 @@ export class Line {
|
|
|
43
66
|
this.dataKey = config.dataKey;
|
|
44
67
|
this.stroke = config.stroke || '#8884d8';
|
|
45
68
|
this.strokeWidth = config.strokeWidth;
|
|
69
|
+
this.curve = config.curve || 'linear';
|
|
70
|
+
this.points = {
|
|
71
|
+
show: config.points?.show ?? DEFAULT_LINE_POINTS.show,
|
|
72
|
+
};
|
|
46
73
|
this.valueLabel = config.valueLabel;
|
|
47
74
|
this.exportHooks = config.exportHooks;
|
|
48
75
|
}
|
|
@@ -51,6 +78,8 @@ export class Line {
|
|
|
51
78
|
dataKey: this.dataKey,
|
|
52
79
|
stroke: this.stroke,
|
|
53
80
|
strokeWidth: this.strokeWidth,
|
|
81
|
+
curve: this.curve,
|
|
82
|
+
points: this.points,
|
|
54
83
|
valueLabel: this.valueLabel,
|
|
55
84
|
};
|
|
56
85
|
}
|
|
@@ -80,7 +109,9 @@ export class Line {
|
|
|
80
109
|
});
|
|
81
110
|
const transitions = [
|
|
82
111
|
...this.renderLinePath(plotGroup, lineData, animatedLineData, theme, sanitizeForCSS(this.dataKey), animation),
|
|
83
|
-
...this.
|
|
112
|
+
...(this.points.show === 'always'
|
|
113
|
+
? this.renderLinePoints(plotGroup, validLineData, validAnimatedLineData, theme, animation)
|
|
114
|
+
: []),
|
|
84
115
|
];
|
|
85
116
|
const snapshot = this.createSnapshot(validLineData);
|
|
86
117
|
// Render value labels if enabled (only for valid values)
|
|
@@ -129,8 +160,10 @@ export class Line {
|
|
|
129
160
|
}
|
|
130
161
|
renderLinePath(plotGroup, lineData, animatedLineData, theme, sanitizedKey, animation) {
|
|
131
162
|
const lineStrokeWidth = this.strokeWidth ?? theme.line.strokeWidth;
|
|
163
|
+
const curveFactory = LINE_CURVE_FACTORIES[this.curve] || curveLinear;
|
|
132
164
|
const lineGenerator = line()
|
|
133
165
|
.defined((entry) => entry.valid)
|
|
166
|
+
.curve(curveFactory)
|
|
134
167
|
.x((entry) => entry.x)
|
|
135
168
|
.y((entry) => entry.y);
|
|
136
169
|
const finalPath = lineGenerator(lineData);
|
package/dist/tooltip.js
CHANGED
|
@@ -269,7 +269,11 @@ export class Tooltip {
|
|
|
269
269
|
.attr('aria-hidden', 'true')
|
|
270
270
|
.style('fill', 'none')
|
|
271
271
|
.style('pointer-events', 'all');
|
|
272
|
-
const
|
|
272
|
+
const focusCircleSeries = series.filter((currentSeries) => {
|
|
273
|
+
if (currentSeries.type === 'line' &&
|
|
274
|
+
currentSeries.points.show === 'never') {
|
|
275
|
+
return false;
|
|
276
|
+
}
|
|
273
277
|
return (currentSeries.type === 'line' ||
|
|
274
278
|
currentSeries.type === 'area' ||
|
|
275
279
|
currentSeries.type === 'scatter');
|
|
@@ -278,7 +282,7 @@ export class Tooltip {
|
|
|
278
282
|
return currentSeries.type === 'bar';
|
|
279
283
|
});
|
|
280
284
|
const hasBarSeries = barSeries.length > 0;
|
|
281
|
-
const focusCircles =
|
|
285
|
+
const focusCircles = focusCircleSeries.map((currentSeries) => {
|
|
282
286
|
const seriesColor = getSeriesColor(currentSeries);
|
|
283
287
|
return svg
|
|
284
288
|
.append('circle')
|
|
@@ -303,7 +307,7 @@ export class Tooltip {
|
|
|
303
307
|
const updateVisualStateAtIndex = (closestIndex) => {
|
|
304
308
|
const dataPoint = data[closestIndex];
|
|
305
309
|
const dataPointPosition = dataPointPositions[closestIndex];
|
|
306
|
-
|
|
310
|
+
focusCircleSeries.forEach((currentSeries, seriesIndex) => {
|
|
307
311
|
const value = resolveSeriesValue(currentSeries, dataPoint, closestIndex);
|
|
308
312
|
if (!Number.isFinite(value)) {
|
|
309
313
|
focusCircles[seriesIndex].style('opacity', 0);
|
package/dist/types.d.ts
CHANGED
|
@@ -184,16 +184,25 @@ export type ValueLabelConfig = {
|
|
|
184
184
|
export type LineValueLabelConfig = ValueLabelConfig & {
|
|
185
185
|
show?: boolean;
|
|
186
186
|
};
|
|
187
|
+
export type LinePointVisibility = 'always' | 'hover' | 'never';
|
|
188
|
+
export type LinePointsConfig = {
|
|
189
|
+
show?: LinePointVisibility;
|
|
190
|
+
};
|
|
187
191
|
export type BarValueLabelConfig = ValueLabelConfig & {
|
|
188
192
|
show?: boolean;
|
|
189
193
|
position?: 'inside' | 'outside';
|
|
190
194
|
insidePosition?: 'top' | 'middle' | 'bottom';
|
|
191
195
|
};
|
|
192
196
|
export type BarSide = 'left' | 'right';
|
|
197
|
+
export type CurveType = 'linear' | 'monotone' | 'step' | 'natural' | 'basis' | 'cardinal';
|
|
198
|
+
export type LineCurveType = CurveType;
|
|
199
|
+
export type AreaCurveType = CurveType;
|
|
193
200
|
export type LineConfigBase = {
|
|
194
201
|
dataKey: string;
|
|
195
202
|
stroke?: string;
|
|
196
203
|
strokeWidth?: number;
|
|
204
|
+
curve?: LineCurveType;
|
|
205
|
+
points?: LinePointsConfig;
|
|
197
206
|
valueLabel?: LineValueLabelConfig;
|
|
198
207
|
};
|
|
199
208
|
export type LineConfig = LineConfigBase & {
|
|
@@ -219,7 +228,6 @@ export type BarConfigBase = {
|
|
|
219
228
|
export type BarConfig = BarConfigBase & {
|
|
220
229
|
exportHooks?: ExportHooks<BarConfigBase>;
|
|
221
230
|
};
|
|
222
|
-
export type AreaCurveType = 'linear' | 'monotone' | 'step' | 'natural' | 'basis' | 'cardinal';
|
|
223
231
|
export type AreaConfigBase = {
|
|
224
232
|
dataKey: string;
|
|
225
233
|
fill?: string;
|
package/docs/xy-chart.md
CHANGED
|
@@ -338,6 +338,10 @@ new Line({
|
|
|
338
338
|
dataKey: string, // Key in data objects for Y values (required)
|
|
339
339
|
stroke?: string, // Line color (auto-assigned if omitted)
|
|
340
340
|
strokeWidth?: number, // Line width in pixels (default: 2)
|
|
341
|
+
curve?: 'linear' | 'monotone' | 'step' | 'natural' | 'basis' | 'cardinal',
|
|
342
|
+
points?: {
|
|
343
|
+
show?: 'always' | 'hover' | 'never'
|
|
344
|
+
}, // Data point visibility (default: 'always')
|
|
341
345
|
valueLabel?: {
|
|
342
346
|
show?: boolean,
|
|
343
347
|
formatter?: (dataKey, value, data) => string
|
|
@@ -355,8 +359,20 @@ chart.addChild(new Line({ dataKey: 'expenses' }));
|
|
|
355
359
|
// Manual colors
|
|
356
360
|
chart.addChild(new Line({ dataKey: 'revenue', stroke: '#00ff00' }));
|
|
357
361
|
chart.addChild(new Line({ dataKey: 'expenses', stroke: '#ff0000' }));
|
|
362
|
+
|
|
363
|
+
// Smooth line interpolation
|
|
364
|
+
chart.addChild(new Line({ dataKey: 'revenue', curve: 'monotone' }));
|
|
365
|
+
|
|
366
|
+
// Show point circles only while hovering or focusing a tooltip target
|
|
367
|
+
chart
|
|
368
|
+
.addChild(new Line({ dataKey: 'revenue', points: { show: 'hover' } }))
|
|
369
|
+
.addChild(new Tooltip());
|
|
358
370
|
```
|
|
359
371
|
|
|
372
|
+
`points.show: 'hover'` uses `Tooltip` focus markers, so add a `Tooltip`
|
|
373
|
+
component when hover-only points should be visible. Use `'never'` to suppress
|
|
374
|
+
both static line points and tooltip focus markers for that line.
|
|
375
|
+
|
|
360
376
|
---
|
|
361
377
|
|
|
362
378
|
## Scatter
|
package/package.json
CHANGED