@fundar/data-chart-telling 0.0.40 → 0.0.42
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.
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
validateSegments,
|
|
22
22
|
buildScopedMarkerGroups
|
|
23
23
|
} from '../utils/segments';
|
|
24
|
-
import type { BasePlotProps } from '../../types/plots/props';
|
|
24
|
+
import type { BasePlotProps, MarginConfig } from '../../types/plots/props';
|
|
25
25
|
import type { AxisValue, AxisBasedScalesConfig } from '../../types/layout/scales';
|
|
26
26
|
import type { Series, SeriesProps, DataProps } from '../../types/plots/data/common';
|
|
27
27
|
import type { GapsAwarePlotStylesConfig } from '../../types/layout/styles';
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
segments = {},
|
|
51
51
|
markers = [],
|
|
52
52
|
scales = {},
|
|
53
|
-
margins,
|
|
53
|
+
margins = $bindable(),
|
|
54
54
|
tooltip = undefined
|
|
55
55
|
}: Props = $props();
|
|
56
56
|
|
|
@@ -129,7 +129,9 @@
|
|
|
129
129
|
buildGapMarkers<TData>({
|
|
130
130
|
seriesList: resolvedSeries,
|
|
131
131
|
gaps,
|
|
132
|
-
colorFor: (seriesIndex) => paletteColor(seriesIndex, cfg.palette)
|
|
132
|
+
colorFor: (seriesIndex) => paletteColor(seriesIndex, cfg.palette),
|
|
133
|
+
disabledStrokeFor: (name) => disabledStrokeOverride(effectiveDisabledFor(name)),
|
|
134
|
+
disabledDotsFor: (name) => disabledDotsOverride(effectiveDisabledFor(name))
|
|
133
135
|
})
|
|
134
136
|
);
|
|
135
137
|
|
|
@@ -169,6 +171,26 @@
|
|
|
169
171
|
() => margins,
|
|
170
172
|
() => resolvedSeries
|
|
171
173
|
);
|
|
174
|
+
|
|
175
|
+
// Writes the resolved margin back into the bindable `margins` prop once it
|
|
176
|
+
// settles, so a caller binding it (`bind:margins`) can capture and reuse a
|
|
177
|
+
// fixed margin later. `lastWritten` is a plain variable (not `$state`) so
|
|
178
|
+
// the effect only depends on `resolvedMargins`, never on `margins` itself.
|
|
179
|
+
let lastWritten: MarginConfig | undefined;
|
|
180
|
+
$effect(() => {
|
|
181
|
+
const next = labelMargin.resolvedMargins;
|
|
182
|
+
if (!next) return;
|
|
183
|
+
const changed =
|
|
184
|
+
!lastWritten ||
|
|
185
|
+
next.top !== lastWritten.top ||
|
|
186
|
+
next.right !== lastWritten.right ||
|
|
187
|
+
next.bottom !== lastWritten.bottom ||
|
|
188
|
+
next.left !== lastWritten.left;
|
|
189
|
+
if (changed) {
|
|
190
|
+
lastWritten = { top: next.top, right: next.right, bottom: next.bottom, left: next.left };
|
|
191
|
+
margins = next;
|
|
192
|
+
}
|
|
193
|
+
});
|
|
172
194
|
</script>
|
|
173
195
|
|
|
174
196
|
<BasePlotLayout
|
|
@@ -7,7 +7,7 @@ import type { LineMarkersConfig } from '../../types/markers/line';
|
|
|
7
7
|
declare function $$render<TData extends Record<string, unknown>>(): {
|
|
8
8
|
props: BasePlotProps<SeriesProps<TData> | DataProps<TData>, TData, GapsAwarePlotStylesConfig<LineSegmentStyle>, LineSegmentStyle, LineMarkersConfig, AxisBasedScalesConfig<TData>>;
|
|
9
9
|
exports: {};
|
|
10
|
-
bindings: "";
|
|
10
|
+
bindings: "margins";
|
|
11
11
|
slots: {};
|
|
12
12
|
events: {};
|
|
13
13
|
};
|
|
@@ -15,7 +15,7 @@ declare class __sveltets_Render<TData extends Record<string, unknown>> {
|
|
|
15
15
|
props(): ReturnType<typeof $$render<TData>>['props'];
|
|
16
16
|
events(): ReturnType<typeof $$render<TData>>['events'];
|
|
17
17
|
slots(): ReturnType<typeof $$render<TData>>['slots'];
|
|
18
|
-
bindings(): "";
|
|
18
|
+
bindings(): "margins";
|
|
19
19
|
exports(): {};
|
|
20
20
|
}
|
|
21
21
|
interface $$IsomorphicComponent {
|
|
@@ -2,6 +2,7 @@ import type { Series } from '../../types/plots/data/common';
|
|
|
2
2
|
import type { GapsConfig } from '../../types/plots/gaps';
|
|
3
3
|
import type { LineSegmentStyle } from '../../types/plots/segments/common';
|
|
4
4
|
import type { LineMarkerConfig, DotMarkerConfig } from '../../types/markers/common';
|
|
5
|
+
import type { StrokeStyle, DotStyle } from '../../types/plots/styling';
|
|
5
6
|
/**
|
|
6
7
|
* One `'line'` (+ `'dot'`, when its zone sets `style.dots`) marker per
|
|
7
8
|
* detected, configured gap run across every series — the interpolated
|
|
@@ -12,10 +13,16 @@ import type { LineMarkerConfig, DotMarkerConfig } from '../../types/markers/comm
|
|
|
12
13
|
* muted out of the box), so a gap-fill reads as estimated rather than real
|
|
13
14
|
* data unless a zone or the global configuration overrides it. Dots (when
|
|
14
15
|
* requested) are drawn only at a run's two endpoints, not along every
|
|
15
|
-
* sampled bridge point.
|
|
16
|
+
* sampled bridge point. `disabledStrokeFor`/`disabledDotsFor` mirror
|
|
17
|
+
* `buildLineMarkers`'s own params — a legend-disabled (or hover-isolated)
|
|
18
|
+
* series must dim its gap bridge exactly like it dims the real line it's
|
|
19
|
+
* bridging, so both take the same precedence: disabled override, then the
|
|
20
|
+
* gap zone's own style, then the shared gap default.
|
|
16
21
|
*/
|
|
17
22
|
export declare function buildGapMarkers<TData extends Record<string, unknown>>(args: {
|
|
18
23
|
seriesList: Series<TData>[];
|
|
19
24
|
gaps: GapsConfig<LineSegmentStyle>;
|
|
20
25
|
colorFor: (seriesIndex: number) => string;
|
|
26
|
+
disabledStrokeFor: (seriesName: string) => StrokeStyle | undefined;
|
|
27
|
+
disabledDotsFor: (seriesName: string) => DotStyle | undefined;
|
|
21
28
|
}): (LineMarkerConfig | DotMarkerConfig)[];
|
|
@@ -12,10 +12,14 @@ const gy = (p) => p.y;
|
|
|
12
12
|
* muted out of the box), so a gap-fill reads as estimated rather than real
|
|
13
13
|
* data unless a zone or the global configuration overrides it. Dots (when
|
|
14
14
|
* requested) are drawn only at a run's two endpoints, not along every
|
|
15
|
-
* sampled bridge point.
|
|
15
|
+
* sampled bridge point. `disabledStrokeFor`/`disabledDotsFor` mirror
|
|
16
|
+
* `buildLineMarkers`'s own params — a legend-disabled (or hover-isolated)
|
|
17
|
+
* series must dim its gap bridge exactly like it dims the real line it's
|
|
18
|
+
* bridging, so both take the same precedence: disabled override, then the
|
|
19
|
+
* gap zone's own style, then the shared gap default.
|
|
16
20
|
*/
|
|
17
21
|
export function buildGapMarkers(args) {
|
|
18
|
-
const { seriesList, gaps, colorFor } = args;
|
|
22
|
+
const { seriesList, gaps, colorFor, disabledStrokeFor, disabledDotsFor } = args;
|
|
19
23
|
const cfg = getConfiguration();
|
|
20
24
|
const gapDefaults = cfg.line.gap;
|
|
21
25
|
const markers = [];
|
|
@@ -25,6 +29,8 @@ export function buildGapMarkers(args) {
|
|
|
25
29
|
if (runs.length === 0)
|
|
26
30
|
return;
|
|
27
31
|
const defaultColor = colorFor(seriesIndex);
|
|
32
|
+
const disabledStroke = disabledStrokeFor(series.name);
|
|
33
|
+
const disabledDots = disabledDotsFor(series.name);
|
|
28
34
|
for (const run of runs) {
|
|
29
35
|
const strokeStyle = run.zone.style?.stroke;
|
|
30
36
|
const dotStyle = run.zone.style?.dots;
|
|
@@ -34,12 +40,12 @@ export function buildGapMarkers(args) {
|
|
|
34
40
|
x: gx,
|
|
35
41
|
y: gy,
|
|
36
42
|
style: {
|
|
37
|
-
stroke: strokeStyle?.stroke ?? defaultColor,
|
|
38
|
-
strokeWidth: strokeStyle?.strokeWidth ?? gapDefaults.stroke.strokeWidth ?? cfg.line.strokeWidth,
|
|
39
|
-
strokeOpacity: strokeStyle?.strokeOpacity ?? gapDefaults.stroke.strokeOpacity,
|
|
40
|
-
strokeDasharray: strokeStyle?.strokeDasharray ?? gapDefaults.stroke.strokeDasharray,
|
|
41
|
-
strokeLinejoin: strokeStyle?.strokeLinejoin ?? gapDefaults.stroke.strokeLinejoin,
|
|
42
|
-
strokeLinecap: strokeStyle?.strokeLinecap ?? gapDefaults.stroke.strokeLinecap,
|
|
43
|
+
stroke: disabledStroke?.stroke ?? strokeStyle?.stroke ?? defaultColor,
|
|
44
|
+
strokeWidth: disabledStroke?.strokeWidth ?? strokeStyle?.strokeWidth ?? gapDefaults.stroke.strokeWidth ?? cfg.line.strokeWidth,
|
|
45
|
+
strokeOpacity: disabledStroke?.strokeOpacity ?? strokeStyle?.strokeOpacity ?? gapDefaults.stroke.strokeOpacity,
|
|
46
|
+
strokeDasharray: disabledStroke?.strokeDasharray ?? strokeStyle?.strokeDasharray ?? gapDefaults.stroke.strokeDasharray,
|
|
47
|
+
strokeLinejoin: disabledStroke?.strokeLinejoin ?? strokeStyle?.strokeLinejoin ?? gapDefaults.stroke.strokeLinejoin,
|
|
48
|
+
strokeLinecap: disabledStroke?.strokeLinecap ?? strokeStyle?.strokeLinecap ?? gapDefaults.stroke.strokeLinecap,
|
|
43
49
|
},
|
|
44
50
|
});
|
|
45
51
|
if (!dotStyle)
|
|
@@ -52,14 +58,14 @@ export function buildGapMarkers(args) {
|
|
|
52
58
|
x: gx,
|
|
53
59
|
y: gy,
|
|
54
60
|
style: {
|
|
55
|
-
dotRadius: dotStyle.dotRadius ?? dotDefaults.dotRadius ?? cfg.line.dotRadius,
|
|
56
|
-
dotFill: dotStyle.dotFill ?? strokeStyle?.stroke ?? dotDefaults.dotFill ?? defaultColor,
|
|
57
|
-
dotSymbol: dotStyle.dotSymbol ?? dotDefaults.dotSymbol ?? 'circle',
|
|
58
|
-
dotStroke: dotStyle.dotStroke ?? strokeStyle?.stroke ?? dotDefaults.dotStroke ?? defaultColor,
|
|
59
|
-
dotStrokeWidth: dotStyle.dotStrokeWidth ?? dotDefaults.dotStrokeWidth ?? 1,
|
|
60
|
-
dotFillOpacity: dotStyle.dotFillOpacity ?? dotDefaults.dotFillOpacity ?? 1,
|
|
61
|
-
dotStrokeOpacity: dotStyle.dotStrokeOpacity ?? dotDefaults.dotStrokeOpacity ?? 1,
|
|
62
|
-
dotStrokeDasharray: dotStyle.dotStrokeDasharray ?? dotDefaults.dotStrokeDasharray,
|
|
61
|
+
dotRadius: disabledDots?.dotRadius ?? dotStyle.dotRadius ?? dotDefaults.dotRadius ?? cfg.line.dotRadius,
|
|
62
|
+
dotFill: disabledDots?.dotFill ?? dotStyle.dotFill ?? strokeStyle?.stroke ?? dotDefaults.dotFill ?? defaultColor,
|
|
63
|
+
dotSymbol: disabledDots?.dotSymbol ?? dotStyle.dotSymbol ?? dotDefaults.dotSymbol ?? 'circle',
|
|
64
|
+
dotStroke: disabledDots?.dotStroke ?? dotStyle.dotStroke ?? strokeStyle?.stroke ?? dotDefaults.dotStroke ?? defaultColor,
|
|
65
|
+
dotStrokeWidth: disabledDots?.dotStrokeWidth ?? dotStyle.dotStrokeWidth ?? dotDefaults.dotStrokeWidth ?? 1,
|
|
66
|
+
dotFillOpacity: disabledDots?.dotFillOpacity ?? dotStyle.dotFillOpacity ?? dotDefaults.dotFillOpacity ?? 1,
|
|
67
|
+
dotStrokeOpacity: disabledDots?.dotStrokeOpacity ?? dotStyle.dotStrokeOpacity ?? dotDefaults.dotStrokeOpacity ?? 1,
|
|
68
|
+
dotStrokeDasharray: disabledDots?.dotStrokeDasharray ?? dotStyle.dotStrokeDasharray ?? dotDefaults.dotStrokeDasharray,
|
|
63
69
|
},
|
|
64
70
|
});
|
|
65
71
|
}
|
|
@@ -160,15 +160,18 @@ export function createLabelMarginTracker(margins, resetKey) {
|
|
|
160
160
|
out.bottom = AUTO_MARGIN_ESTIMATE.bottom + measured.bottom;
|
|
161
161
|
return out;
|
|
162
162
|
});
|
|
163
|
-
// Bundles `resolvedMargins` with a remount key
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
//
|
|
167
|
-
//
|
|
168
|
-
//
|
|
163
|
+
// Bundles `resolvedMargins` with a remount key, ready to spread straight
|
|
164
|
+
// onto `<BasePlotLayout>` as its `margins`/`marginRemountKey` props (see
|
|
165
|
+
// that prop's doc comment for *why* a remount key is needed here at all)
|
|
166
|
+
// — keeps the caller from re-deriving the same key by hand. Tracks both
|
|
167
|
+
// `measured` (this tracker's own auto-grown overflow) and the caller's
|
|
168
|
+
// own `margins()` — a caller that changes its explicit margins prop
|
|
169
|
+
// after mount (e.g. locking in a previously-measured value) needs that
|
|
170
|
+
// picked up just as cleanly as internal growth does; keying only on
|
|
171
|
+
// `measured` would silently miss it.
|
|
169
172
|
const plotProps = $derived.by(() => ({
|
|
170
173
|
margins: resolvedMargins,
|
|
171
|
-
marginRemountKey: JSON.stringify(measured)
|
|
174
|
+
marginRemountKey: JSON.stringify({ base: margins(), measured })
|
|
172
175
|
}));
|
|
173
176
|
return {
|
|
174
177
|
report,
|