@fundar/data-chart-telling 1.16.0 → 1.17.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.
- package/CHANGELOG.md +32 -0
- package/dist/configuration/ConfigVars.svelte +14 -0
- package/dist/configuration/ConfigVars.svelte.d.ts +3 -0
- package/dist/configuration/config.svelte.d.ts +5 -0
- package/dist/configuration/config.svelte.js +17 -4
- package/dist/configuration/themes/dark.js +1 -1
- package/dist/configuration/themes/editorial.js +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +2 -1
- package/dist/layout/base/BasePlotLayout.svelte +1 -1
- package/dist/layout/figure/Figure.svelte +5 -12
- package/dist/layout/figure/FigureChrome.svelte +2 -10
- package/dist/layout/geometry/GeometryLayout.svelte +42 -1
- package/dist/layout/hover/HoverSettings.d.ts +3 -1
- package/dist/layout/hover/HoverSettings.js +4 -2
- package/dist/layout/legend/DisabledStyle.d.ts +1 -1
- package/dist/layout/legend/DisabledStyle.js +1 -1
- package/dist/layout/legend/DiscreteBadgeItem.svelte +1 -1
- package/dist/layout/legend/DiscreteSection.svelte +1 -1
- package/dist/layout/legend/LegendState.svelte.d.ts +12 -2
- package/dist/layout/legend/LegendState.svelte.js +18 -4
- package/dist/layout/legend/LegendText.d.ts +4 -1
- package/dist/layout/legend/LegendText.js +7 -1
- package/dist/layout/margins/PlotMargins.svelte.d.ts +2 -2
- package/dist/layout/margins/PlotMargins.svelte.js +2 -2
- package/dist/layout/plot/Plot.svelte +4 -2
- package/dist/layout/plot/Plot.svelte.d.ts +2 -1
- package/dist/layout/scales/ScalesLayout.svelte +1 -1
- package/dist/layout/styles/ValueLabels.d.ts +33 -2
- package/dist/layout/styles/ValueLabels.js +67 -8
- package/dist/layout/timeline/Timeline.svelte +5 -1
- package/dist/markers/area/AreaMarker.svelte +3 -0
- package/dist/markers/arrow/ArrowMarker.svelte +9 -5
- package/dist/markers/bar/BarMarker.svelte +45 -48
- package/dist/markers/bollinger/BollingerMarker.svelte +3 -0
- package/dist/markers/box/BoxMarker.svelte +3 -1
- package/dist/markers/cell/CellMarker.svelte +11 -7
- package/dist/markers/contour/ContourMarker.svelte +3 -0
- package/dist/markers/delaunay/DelaunayLinkMarker.svelte +9 -5
- package/dist/markers/delaunay/DelaunayMeshMarker.svelte +3 -0
- package/dist/markers/density/DensityMarker.svelte +3 -0
- package/dist/markers/difference/DifferenceMarker.svelte +3 -0
- package/dist/markers/dot/DotMarker.svelte +11 -6
- package/dist/markers/geo/GraticuleMarker.svelte +3 -0
- package/dist/markers/geo/SphereMarker.svelte +3 -0
- package/dist/markers/hover/HoverMarker.svelte +22 -6
- package/dist/markers/hull/HullMarker.svelte +3 -0
- package/dist/markers/image/ImageMarker.svelte +3 -0
- package/dist/markers/line/LineMarker.svelte +3 -0
- package/dist/markers/link/LinkMarker.svelte +3 -0
- package/dist/markers/raster/RasterMarker.svelte +3 -0
- package/dist/markers/rect/RectMarker.svelte +25 -17
- package/dist/markers/regression/RegressionMarker.svelte +3 -0
- package/dist/markers/rule/RuleMarker.svelte +15 -5
- package/dist/markers/text/TextFit.d.ts +44 -0
- package/dist/markers/text/TextFit.js +86 -0
- package/dist/markers/text/TextMarker.svelte +186 -90
- package/dist/markers/text/TextMarker.svelte.d.ts +2 -0
- package/dist/markers/tick/TickMarker.svelte +9 -3
- package/dist/markers/trail/TrailMarker.svelte +3 -0
- package/dist/markers/utils/BoxLabel.d.ts +58 -0
- package/dist/markers/utils/BoxLabel.js +175 -0
- package/dist/markers/utils/MarkerEvents.d.ts +23 -0
- package/dist/markers/utils/MarkerEvents.js +44 -0
- package/dist/markers/utils/MarkerLabel.svelte +33 -0
- package/dist/markers/utils/MarkerLabel.svelte.d.ts +10 -0
- package/dist/markers/utils/RowStroke.d.ts +9 -21
- package/dist/markers/utils/RowStroke.js +10 -21
- package/dist/markers/utils/RowStyle.d.ts +26 -0
- package/dist/markers/utils/RowStyle.js +55 -0
- package/dist/markers/vector/VectorMarker.svelte +3 -0
- package/dist/markers/voronoi/VoronoiMarker.svelte +9 -5
- package/dist/markers/voronoi/VoronoiMeshMarker.svelte +3 -0
- package/dist/markers/waffle/WaffleMarker.svelte +9 -5
- package/dist/phases/Pipeline.d.ts +3 -1
- package/dist/phases/Pipeline.js +1 -0
- package/dist/phases/data/DataPhase.js +51 -10
- package/dist/phases/hover/HoverPhase.js +9 -1
- package/dist/phases/mapping/MappingPhase.js +2 -1
- package/dist/phases/markers/MarkerStyles.d.ts +18 -0
- package/dist/phases/markers/MarkerStyles.js +111 -0
- package/dist/phases/markers/MarkersPhase.d.ts +1 -1
- package/dist/phases/markers/MarkersPhase.js +7 -5
- package/dist/phases/statistics/StatisticsPhase.js +1 -1
- package/dist/phases/transforms/Transforms.js +3 -1
- package/dist/phases/transforms/TransformsPhase.js +58 -4
- package/dist/phases/transforms/methods/TreemapTransform.d.ts +28 -0
- package/dist/phases/transforms/methods/TreemapTransform.js +119 -0
- package/dist/plots/correlation/heatmap/defaults.js +2 -2
- package/dist/plots/correlation/heatmap/markers.d.ts +0 -8
- package/dist/plots/correlation/heatmap/markers.js +8 -35
- package/dist/plots/correlation/scatter/markers.d.ts +1 -1
- package/dist/plots/correlation/scatter/markers.js +2 -2
- package/dist/plots/distribution/histogram/defaults.js +2 -2
- package/dist/plots/distribution/histogram/markers.d.ts +1 -10
- package/dist/plots/distribution/histogram/markers.js +17 -59
- package/dist/plots/distribution/pyramid/defaults.js +3 -3
- package/dist/plots/distribution/pyramid/markers.d.ts +0 -10
- package/dist/plots/distribution/pyramid/markers.js +13 -64
- package/dist/plots/distribution/violin/markers.js +1 -1
- package/dist/plots/map/geo/phases/markers.js +3 -2
- package/dist/plots/part-of-a-whole/treemap/Plot.svelte +47 -0
- package/dist/plots/part-of-a-whole/treemap/Plot.svelte.d.ts +26 -0
- package/dist/plots/part-of-a-whole/treemap/defaults.d.ts +10 -0
- package/dist/plots/part-of-a-whole/treemap/defaults.js +167 -0
- package/dist/plots/ranking/bar/defaults.js +2 -2
- package/dist/plots/ranking/bar/markers.d.ts +1 -11
- package/dist/plots/ranking/bar/markers.js +38 -80
- package/dist/plots/ranking/bullet/markers.js +2 -3
- package/dist/plots/ranking/cleveland/ClevelandMarkers.js +17 -13
- package/dist/types/configuration/styling.d.ts +27 -2
- package/dist/types/layout/legend.d.ts +8 -1
- package/dist/types/layout/mapping.d.ts +12 -3
- package/dist/types/layout/scales.d.ts +6 -0
- package/dist/types/layout/tooltip.d.ts +16 -4
- package/dist/types/markers/axis/arrow.d.ts +2 -8
- package/dist/types/markers/axis/bar.d.ts +4 -8
- package/dist/types/markers/axis/cell.d.ts +5 -5
- package/dist/types/markers/axis/delaunayLink.d.ts +2 -2
- package/dist/types/markers/axis/rect.d.ts +4 -8
- package/dist/types/markers/axis/rule.d.ts +2 -16
- package/dist/types/markers/axis/tick.d.ts +2 -2
- package/dist/types/markers/axis/voronoi.d.ts +2 -2
- package/dist/types/markers/axis/waffle.d.ts +4 -3
- package/dist/types/markers/basic/dot.d.ts +2 -2
- package/dist/types/markers/basic/text.d.ts +56 -14
- package/dist/types/markers/channels/commonMarkerConfig.d.ts +4 -1
- package/dist/types/markers/channels/commonMarkerConfigWithArea.d.ts +1 -2
- package/dist/types/markers/channels/commonMarkerConfigWithLabel.d.ts +10 -0
- package/dist/types/markers/channels/commonMarkerConfigWithLabel.js +1 -0
- package/dist/types/markers/channels/commonMarkerEvents.d.ts +17 -0
- package/dist/types/markers/channels/commonMarkerEvents.js +13 -0
- package/dist/types/markers/geo/contour.d.ts +2 -1
- package/dist/types/markers/geo/graticule.d.ts +2 -1
- package/dist/types/markers/geo/link.d.ts +2 -1
- package/dist/types/markers/geo/sphere.d.ts +2 -1
- package/dist/types/markers/geo/vector.d.ts +2 -1
- package/dist/types/phases/data/phase.d.ts +5 -0
- package/dist/types/phases/hover/phase.d.ts +2 -0
- package/dist/types/phases/state.d.ts +7 -0
- package/dist/types/phases/statistics/phase.d.ts +2 -1
- package/dist/types/phases/transforms/phase.d.ts +11 -0
- package/dist/types/plots/constants.d.ts +14 -14
- package/dist/types/plots/correlation/heatmap/props.d.ts +3 -3
- package/dist/types/plots/correlation/scatter/props.d.ts +3 -3
- package/dist/types/plots/data/common.d.ts +19 -6
- package/dist/types/plots/data/geo.d.ts +1 -1
- package/dist/types/plots/distribution/box/props.d.ts +3 -3
- package/dist/types/plots/distribution/density/props.d.ts +3 -11
- package/dist/types/plots/distribution/histogram/props.d.ts +3 -11
- package/dist/types/plots/distribution/pyramid/props.d.ts +3 -3
- package/dist/types/plots/distribution/violin/props.d.ts +3 -3
- package/dist/types/plots/evolution/area/props.d.ts +3 -3
- package/dist/types/plots/evolution/line/props.d.ts +3 -3
- package/dist/types/plots/part-of-a-whole/treemap/props.d.ts +19 -0
- package/dist/types/plots/part-of-a-whole/treemap/props.js +1 -0
- package/dist/types/plots/part-of-a-whole/treemap/state.d.ts +6 -0
- package/dist/types/plots/part-of-a-whole/treemap/state.js +1 -0
- package/dist/types/plots/props.d.ts +7 -4
- package/dist/types/plots/ranking/bar/props.d.ts +3 -3
- package/dist/types/plots/ranking/cleveland/props.d.ts +3 -3
- package/dist/types/plots/ranking/dumbbell/props.d.ts +3 -3
- package/dist/types/plots/ranking/forest/props.d.ts +3 -3
- package/dist/types/plots/ranking/lollipop/props.d.ts +3 -3
- package/dist/types/plots/styling.d.ts +24 -0
- package/dist/types/transforms/index.d.ts +3 -1
- package/dist/types/transforms/treemap.d.ts +32 -0
- package/dist/types/transforms/treemap.js +5 -0
- package/dist/utils/color/ColorTones.d.ts +19 -0
- package/dist/utils/color/ColorTones.js +64 -0
- package/dist/utils/color/CssColor.d.ts +14 -5
- package/dist/utils/color/CssColor.js +69 -27
- package/dist/utils/color/index.d.ts +4 -0
- package/dist/utils/color/index.js +4 -0
- package/dist/utils/grouping.d.ts +18 -1
- package/dist/utils/grouping.js +31 -0
- package/docs/concepts.md +3 -2
- package/docs/legend.md +8 -5
- package/docs/markers.md +76 -26
- package/docs/plots/part-of-a-whole/treemap.md +69 -0
- package/docs/plots/ranking/bar.md +1 -1
- package/docs/plots.md +21 -20
- package/docs/scales.md +3 -0
- package/docs/state.md +1 -1
- package/docs/styles-and-segments.md +19 -18
- package/docs/theming.md +4 -11
- package/docs/tooltip-and-hover.md +1 -1
- package/docs/transforms-and-statistics.md +17 -16
- package/examples/Treemap.svelte +13 -0
- package/examples/datasets/economic-activity.ts +40 -0
- package/examples/datasets/index.ts +1 -0
- package/llms-full.txt +5 -5
- package/llms.txt +2 -0
- package/package.json +3 -1
|
@@ -1,66 +1,8 @@
|
|
|
1
1
|
import { ProcessedPositions } from '../../../phases/transforms/ProcessedPositions';
|
|
2
|
-
import {
|
|
2
|
+
import { ValueLabels } from '../../../layout/styles/ValueLabels';
|
|
3
3
|
import { Transforms } from '../../../phases/transforms/Transforms';
|
|
4
4
|
import { resolveAccessor } from '../../../utils/accessors';
|
|
5
5
|
import { PlotAxes } from '../../../phases/data/PlotAxes';
|
|
6
|
-
/**
|
|
7
|
-
* HistogramPlot's `styles.values` as one `'text'` marker over its non-empty
|
|
8
|
-
* bins (a `filter` on the count), each labelled with its count by `format`.
|
|
9
|
-
* `anchor` places each label along its bar: past its top (`'outside'`), just
|
|
10
|
-
* inside it (`'start'`), at its base (`'end'`), or centred (`'middle'`) -
|
|
11
|
-
* upward, or rightward on a horizontal histogram.
|
|
12
|
-
*/
|
|
13
|
-
export function buildValueLabels(labels, state, ctx) {
|
|
14
|
-
const { processedData: processed } = state;
|
|
15
|
-
if (!processed?.data.length)
|
|
16
|
-
return [];
|
|
17
|
-
const { font, anchor, format } = labels;
|
|
18
|
-
const nameOf = (d) => String(d[SERIES_KEY]);
|
|
19
|
-
const value = PlotAxes.valueOf(state);
|
|
20
|
-
const binned = PlotAxes.other(value);
|
|
21
|
-
const horizontal = value === 'x';
|
|
22
|
-
const position = ProcessedPositions.of(processed, value);
|
|
23
|
-
const read = (channel) => channel === undefined
|
|
24
|
-
? undefined
|
|
25
|
-
: resolveAccessor(channel);
|
|
26
|
-
const topOf = (d) => Number(position[value](d));
|
|
27
|
-
const bottomOf = read(processed.channels[`${value}1`]) ?? (() => 0);
|
|
28
|
-
const countRead = read(processed.channels[value]);
|
|
29
|
-
const countOf = (d) => countRead ? Number(countRead(d)) : topOf(d) - Number(bottomOf(d));
|
|
30
|
-
const along = anchor === 'end'
|
|
31
|
-
? bottomOf
|
|
32
|
-
: anchor === 'middle'
|
|
33
|
-
? (d) => (topOf(d) + Number(bottomOf(d))) / 2
|
|
34
|
-
: topOf;
|
|
35
|
-
// Outward from the bar's top: past it, just inside it, or out from its base.
|
|
36
|
-
const outward = anchor === 'outside' ? 6 : anchor === 'start' ? -4 : anchor === 'end' ? 4 : 0;
|
|
37
|
-
const outwardAnchor = anchor === 'start' ? 'end' : anchor === 'middle' ? 'middle' : 'start';
|
|
38
|
-
const marker = Transforms.resolve({
|
|
39
|
-
type: 'text',
|
|
40
|
-
data: processed.data,
|
|
41
|
-
[binned]: position[binned],
|
|
42
|
-
[value]: along,
|
|
43
|
-
transforms: [{ type: 'filter', filter: (d) => countOf(d) > 0 }],
|
|
44
|
-
text: (d) => format(countOf(d), nameOf(d), d),
|
|
45
|
-
styles: {
|
|
46
|
-
...font,
|
|
47
|
-
fill: font?.fill ?? ctx.cfg.axis.color,
|
|
48
|
-
fontSize: font?.fontSize ?? 12,
|
|
49
|
-
dx: font?.dx ?? (horizontal ? outward : 0),
|
|
50
|
-
dy: font?.dy ?? (horizontal ? 0 : -outward),
|
|
51
|
-
textAnchor: labels.textAnchor ?? (horizontal ? outwardAnchor : 'middle'),
|
|
52
|
-
lineAnchor: font?.lineAnchor ??
|
|
53
|
-
(horizontal
|
|
54
|
-
? 'middle'
|
|
55
|
-
: anchor === 'start'
|
|
56
|
-
? 'top'
|
|
57
|
-
: anchor === 'middle'
|
|
58
|
-
? 'middle'
|
|
59
|
-
: 'bottom')
|
|
60
|
-
}
|
|
61
|
-
}, processed.data);
|
|
62
|
-
return marker.data?.length ? [marker] : [];
|
|
63
|
-
}
|
|
64
6
|
/**
|
|
65
7
|
* HistogramPlot's "markers" phase: one `rect` per visual segment of each
|
|
66
8
|
* series, drawing that segment's bins, dimmed with its series. The markers
|
|
@@ -70,6 +12,21 @@ export function buildValueLabels(labels, state, ctx) {
|
|
|
70
12
|
export function buildMarks(state, ctx) {
|
|
71
13
|
const { channels, options, transforms } = state.processedData;
|
|
72
14
|
const fillOpacity = ctx.cfg.histogram.fillOpacity;
|
|
15
|
+
// Each bin writes its own count, along its bar: past its top (`'outside'`), against an edge, at its tip or its
|
|
16
|
+
// base - upward, or rightward on a horizontal histogram. A bin with nothing in it writes nothing.
|
|
17
|
+
const labels = state.valueLabels?.show ? state.valueLabels : undefined;
|
|
18
|
+
const value = PlotAxes.valueOf(state);
|
|
19
|
+
const position = ProcessedPositions.of(state.processedData, value);
|
|
20
|
+
const read = (channel) => channel === undefined
|
|
21
|
+
? undefined
|
|
22
|
+
: resolveAccessor(channel);
|
|
23
|
+
const bottomOf = read(channels[`${value}1`]) ?? (() => 0);
|
|
24
|
+
const countRead = read(channels[value]);
|
|
25
|
+
const countOf = (d) => countRead ? Number(countRead(d)) : Number(position[value](d)) - Number(bottomOf(d));
|
|
26
|
+
const labelFor = (name) => labels?.shapeLabel(ctx, (d) => (countOf(d) > 0 ? labels.format(countOf(d), name, d) : ''), {
|
|
27
|
+
fill: 'currentColor',
|
|
28
|
+
...ValueLabels.boxAnchor(labels.anchor, { isHorizontal: value === 'x' })
|
|
29
|
+
});
|
|
73
30
|
const rects = (state.processedGroups ?? []).flatMap((group) => {
|
|
74
31
|
const disabled = ctx.interaction?.fillFor(group.series.name);
|
|
75
32
|
// A stroke the segment sets is not a reason to lose the series' fill, as the marker would take it for the color.
|
|
@@ -78,6 +35,7 @@ export function buildMarks(state, ctx) {
|
|
|
78
35
|
type: 'rect',
|
|
79
36
|
series: group.series.name,
|
|
80
37
|
data: seg.data,
|
|
38
|
+
...(labels ? { label: labelFor(group.series.name) } : {}),
|
|
81
39
|
...channels,
|
|
82
40
|
...options,
|
|
83
41
|
styles: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ProcessedPositions } from '../../../phases/transforms/ProcessedPositions';
|
|
2
2
|
import { PlotAxes } from '../../../phases/data/PlotAxes';
|
|
3
|
-
import { buildMarks
|
|
3
|
+
import { buildMarks } from './markers';
|
|
4
4
|
import { ValueLabels } from '../../../layout/styles/ValueLabels';
|
|
5
5
|
import { seriesIdOf } from '../../../utils/grouping';
|
|
6
6
|
import { isGapValue } from '../../utils/gaps';
|
|
@@ -48,7 +48,7 @@ export function buildPyramidDefaults() {
|
|
|
48
48
|
values: {
|
|
49
49
|
// A label past its bar's end reaches out on its own side, the longest bar's to the edge.
|
|
50
50
|
reach: (labels, state) => {
|
|
51
|
-
if (labels.anchor
|
|
51
|
+
if (labels.anchor !== 'outside')
|
|
52
52
|
return [];
|
|
53
53
|
const axis = PlotAxes.valueOf(state);
|
|
54
54
|
const isHorizontal = state.axes?.isHorizontal ?? true;
|
|
@@ -63,7 +63,7 @@ export function buildPyramidDefaults() {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
|
-
markers: { marks: buildMarks
|
|
66
|
+
markers: { marks: buildMarks },
|
|
67
67
|
hover: {
|
|
68
68
|
// A bar sits at its signed magnitude - below or left of the baseline on the first
|
|
69
69
|
// side - and its category, and reads as its magnitude.
|
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
import type { TextMarkerConfig } from '../../../types/markers/common';
|
|
2
1
|
import type { PyramidPlotState, PyramidPlotCtx } from '../../../types/plots/distribution/pyramid/state';
|
|
3
|
-
import type { ValueLabels } from '../../../layout/styles/ValueLabels';
|
|
4
2
|
import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
|
|
5
|
-
/**
|
|
6
|
-
* PyramidPlot's `styles.values` as one `'text'` marker per series, over the
|
|
7
|
-
* same processed rows its bars draw (gap rows never get a label), mirrored to
|
|
8
|
-
* its own side of the shared zero baseline. `anchor` places each label along
|
|
9
|
-
* its bar: past its end (`'outside'`/`'start'`), at the baseline (`'end'`),
|
|
10
|
-
* or centred (`'middle'`). On a vertical pyramid the sides run down and up.
|
|
11
|
-
*/
|
|
12
|
-
export declare function buildValueLabels<TData extends Record<string, unknown>>(labels: ValueLabels, state: PyramidPlotState<TData>, ctx: PyramidPlotCtx): TextMarkerConfig[];
|
|
13
3
|
/**
|
|
14
4
|
* PyramidPlot's "markers" phase: one `role: 'segment'` bar per visual
|
|
15
5
|
* segment, along the category axis the "data" phase read (horizontal bars for
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { ValueLabels } from '../../../layout/styles/ValueLabels';
|
|
1
2
|
import { resolveAccessor } from '../../../utils/accessors';
|
|
2
|
-
import { SERIES_ID_KEY } from '../../../phases/transforms/TransformsPhase';
|
|
3
3
|
import { seriesIdOf } from '../../../utils/grouping';
|
|
4
4
|
import { PlotAxes } from '../../../phases/data/PlotAxes';
|
|
5
5
|
import { getConfiguration } from '../../../configuration/config.svelte';
|
|
@@ -8,69 +8,6 @@ const GAP_KINDS = ['start', 'middle', 'end'];
|
|
|
8
8
|
function signFor(s, magnitude) {
|
|
9
9
|
return s.side === 'left' ? -magnitude : magnitude;
|
|
10
10
|
}
|
|
11
|
-
/**
|
|
12
|
-
* PyramidPlot's `styles.values` as one `'text'` marker per series, over the
|
|
13
|
-
* same processed rows its bars draw (gap rows never get a label), mirrored to
|
|
14
|
-
* its own side of the shared zero baseline. `anchor` places each label along
|
|
15
|
-
* its bar: past its end (`'outside'`/`'start'`), at the baseline (`'end'`),
|
|
16
|
-
* or centred (`'middle'`). On a vertical pyramid the sides run down and up.
|
|
17
|
-
*/
|
|
18
|
-
export function buildValueLabels(labels, state, ctx) {
|
|
19
|
-
const { processedData } = state;
|
|
20
|
-
if (!processedData)
|
|
21
|
-
return [];
|
|
22
|
-
const { font, anchor, format } = labels;
|
|
23
|
-
const categoryAxis = PlotAxes.categoryOf(state);
|
|
24
|
-
const valueAxis = PlotAxes.valueOf(state);
|
|
25
|
-
const isHorizontal = state.axes?.isHorizontal ?? true;
|
|
26
|
-
return (state.processedGroups ?? []).flatMap(({ series }) => {
|
|
27
|
-
const id = seriesIdOf(series);
|
|
28
|
-
const side = state.resolvedSeries.find((s) => seriesIdOf(s) === id).side;
|
|
29
|
-
const isLeft = side === 'left';
|
|
30
|
-
const getMagnitude = resolveAccessor(series[valueAxis]);
|
|
31
|
-
const magnitude = (d) => Math.abs(Number(getMagnitude(d)));
|
|
32
|
-
const signed = (d) => (isLeft ? -magnitude(d) : magnitude(d));
|
|
33
|
-
const data = processedData.data.filter((d) => d[SERIES_ID_KEY] === id && !isGapValue(getMagnitude(d)));
|
|
34
|
-
if (data.length === 0)
|
|
35
|
-
return [];
|
|
36
|
-
const outward = isLeft ? -1 : 1;
|
|
37
|
-
const at = anchor === 'middle' ? (d) => signed(d) / 2 : anchor === 'end' ? 0 : signed;
|
|
38
|
-
const shift = anchor === 'middle' ? 0 : outward * (anchor === 'end' ? 4 : 6);
|
|
39
|
-
// Away from the baseline: left/right on a horizontal pyramid, down/up on a vertical one.
|
|
40
|
-
const awayAnchor = isHorizontal
|
|
41
|
-
? anchor === 'middle'
|
|
42
|
-
? 'middle'
|
|
43
|
-
: isLeft
|
|
44
|
-
? 'end'
|
|
45
|
-
: 'start'
|
|
46
|
-
: 'middle';
|
|
47
|
-
const awayLine = isHorizontal
|
|
48
|
-
? 'middle'
|
|
49
|
-
: anchor === 'middle'
|
|
50
|
-
? 'middle'
|
|
51
|
-
: isLeft
|
|
52
|
-
? 'top'
|
|
53
|
-
: 'bottom';
|
|
54
|
-
return [
|
|
55
|
-
{
|
|
56
|
-
type: 'text',
|
|
57
|
-
data,
|
|
58
|
-
[valueAxis]: at,
|
|
59
|
-
[categoryAxis]: series[categoryAxis],
|
|
60
|
-
text: (d) => format(magnitude(d), series.name, d),
|
|
61
|
-
styles: {
|
|
62
|
-
...font,
|
|
63
|
-
fill: font?.fill ?? ctx.cfg.axis.color,
|
|
64
|
-
fontSize: font?.fontSize ?? 12,
|
|
65
|
-
dx: font?.dx ?? (isHorizontal ? shift : 0),
|
|
66
|
-
dy: font?.dy ?? (isHorizontal ? 0 : -shift),
|
|
67
|
-
textAnchor: labels.textAnchor ?? awayAnchor,
|
|
68
|
-
lineAnchor: font?.lineAnchor ?? awayLine
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
];
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
11
|
/**
|
|
75
12
|
* PyramidPlot's "markers" phase: one `role: 'segment'` bar per visual
|
|
76
13
|
* segment, along the category axis the "data" phase read (horizontal bars for
|
|
@@ -85,6 +22,12 @@ export function buildMarks(state, ctx) {
|
|
|
85
22
|
const categoryAxis = PlotAxes.categoryOf(state);
|
|
86
23
|
const valueAxis = PlotAxes.valueOf(state);
|
|
87
24
|
const isHorizontal = state.axes?.isHorizontal ?? true;
|
|
25
|
+
const labels = state.valueLabels?.show ? state.valueLabels : undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Where a series' labels sit on its bars, which run out from the shared baseline to its own side: left and right
|
|
28
|
+
* of it on a horizontal pyramid, down and up on a vertical one.
|
|
29
|
+
*/
|
|
30
|
+
const anchorOf = (side) => ValueLabels.boxAnchor(labels?.anchor ?? 'outside', { isHorizontal, negative: side === 'left' });
|
|
88
31
|
/** One bar's own channels: its category, and its span from the baseline to its signed value. */
|
|
89
32
|
const span = (category, to) => ({
|
|
90
33
|
isHorizontal,
|
|
@@ -118,6 +61,12 @@ export function buildMarks(state, ctx) {
|
|
|
118
61
|
role: 'segment',
|
|
119
62
|
data: realData,
|
|
120
63
|
...span(processedCategory, signed),
|
|
64
|
+
// Each bar writes its own magnitude, on its side of the baseline.
|
|
65
|
+
...(labels
|
|
66
|
+
? {
|
|
67
|
+
label: labels.shapeLabel(ctx, (d) => labels.format(Math.abs(Number(getMagnitude(d))), group.series.name, d), { fill: 'currentColor', ...anchorOf(group.series.side) })
|
|
68
|
+
}
|
|
69
|
+
: {}),
|
|
121
70
|
styles: {
|
|
122
71
|
// An outline asked for without a color is the fill's.
|
|
123
72
|
...(seg.styles.strokeWidth !== undefined
|
|
@@ -29,7 +29,7 @@ export function buildMarks(state, ctx) {
|
|
|
29
29
|
: typeof styles?.box === 'number'
|
|
30
30
|
? styles.box
|
|
31
31
|
: cfg.violin.boxWidth;
|
|
32
|
-
const ink =
|
|
32
|
+
const ink = 'currentColor';
|
|
33
33
|
const violins = groups.flatMap((group, index) => {
|
|
34
34
|
const name = group.series.name;
|
|
35
35
|
const disabled = ctx.interaction?.fillFor(name);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { MarkerStyles } from '../../../../phases/markers/MarkerStyles';
|
|
1
2
|
import { LegendState } from '../../../../layout/legend/LegendState.svelte';
|
|
2
3
|
import { GeoSegments } from '../GeoSegments';
|
|
3
4
|
import { MarkerChannels } from '../../../../markers/utils/MarkerChannels';
|
|
@@ -58,7 +59,7 @@ export function buildMarkers(state, ctx) {
|
|
|
58
59
|
data: group.data,
|
|
59
60
|
fill: (d) => group.style.fill ?? resolveBaseFill(d),
|
|
60
61
|
fillOpacity: group.style.fillOpacity ?? group.opacity ?? fillOpacity ?? 1,
|
|
61
|
-
stroke: group.style.stroke ?? stroke ??
|
|
62
|
+
stroke: group.style.stroke ?? stroke ?? 'currentColor',
|
|
62
63
|
strokeWidth: group.style.strokeWidth ?? strokeWidth ?? 0.5,
|
|
63
64
|
hover: hoverable,
|
|
64
65
|
onclick: onFeatureClick ? (e, d) => onFeatureClick(d, e) : undefined
|
|
@@ -66,6 +67,6 @@ export function buildMarkers(state, ctx) {
|
|
|
66
67
|
const behindMarkers = authoredMarkers.filter(isBehindMarker);
|
|
67
68
|
const frontMarkers = authoredMarkers.filter((m) => !isBehindMarker(m) && m.type !== 'geo-hover');
|
|
68
69
|
const hoverMarker = authoredMarkers.find((m) => m.type === 'geo-hover');
|
|
69
|
-
const markers = MarkerChannels.inheritAll([...behindMarkers, ...featureMarkers, ...frontMarkers, ...(hoverMarker ? [hoverMarker] : [])], state.scales);
|
|
70
|
+
const markers = MarkerStyles.resolveAll(MarkerChannels.inheritAll([...behindMarkers, ...featureMarkers, ...frontMarkers, ...(hoverMarker ? [hoverMarker] : [])], state.scales), { cfg: ctx.cfg });
|
|
70
71
|
return { ...state, markers, styleGroups };
|
|
71
72
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script lang="ts" generics="TData extends Record<string, unknown>">
|
|
2
|
+
import Plot from '../../../layout/plot/Plot.svelte';
|
|
3
|
+
import { buildTreemapDefaults } from './defaults';
|
|
4
|
+
import type {
|
|
5
|
+
TreemapPlotProps,
|
|
6
|
+
TreemapPlotCoreProps
|
|
7
|
+
} from '../../../types/plots/part-of-a-whole/treemap/props';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A part-to-whole of rectangles: each row is a tile whose area is its `value`, nested by `grouping` - a field,
|
|
11
|
+
* or the fields of several levels joined by dots (`'sector.branch'`), outermost first, whose last names the
|
|
12
|
+
* tile. The outermost level colors the tiles and is what the legend lists; each tile is labelled with its name
|
|
13
|
+
* and its share of the whole, cut short or left out where it does not fit (`styles.values`). Optional chrome
|
|
14
|
+
* (`title`, `subtitle`, `caption`, `header`, `footer`, `legend`) frames it; `timeline` and `facet` slice its
|
|
15
|
+
* `data` rows.
|
|
16
|
+
*/
|
|
17
|
+
let {
|
|
18
|
+
title,
|
|
19
|
+
subtitle,
|
|
20
|
+
caption,
|
|
21
|
+
header,
|
|
22
|
+
footer,
|
|
23
|
+
legend,
|
|
24
|
+
order,
|
|
25
|
+
timeline,
|
|
26
|
+
facet,
|
|
27
|
+
tooltip,
|
|
28
|
+
margins = $bindable(),
|
|
29
|
+
...core
|
|
30
|
+
}: TreemapPlotProps<TData> = $props();
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<Plot
|
|
34
|
+
core={core as TreemapPlotCoreProps<TData>}
|
|
35
|
+
defaults={buildTreemapDefaults}
|
|
36
|
+
bind:margins
|
|
37
|
+
{title}
|
|
38
|
+
{subtitle}
|
|
39
|
+
{caption}
|
|
40
|
+
{header}
|
|
41
|
+
{footer}
|
|
42
|
+
{legend}
|
|
43
|
+
{order}
|
|
44
|
+
{timeline}
|
|
45
|
+
{facet}
|
|
46
|
+
{tooltip}
|
|
47
|
+
/>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Plot from '../../../layout/plot/Plot.svelte';
|
|
2
|
+
import type { TreemapPlotProps } from '../../../types/plots/part-of-a-whole/treemap/props';
|
|
3
|
+
declare function $$render<TData extends Record<string, unknown>>(): {
|
|
4
|
+
props: TreemapPlotProps<TData>;
|
|
5
|
+
exports: {};
|
|
6
|
+
bindings: "margins";
|
|
7
|
+
slots: {};
|
|
8
|
+
events: {};
|
|
9
|
+
};
|
|
10
|
+
declare class __sveltets_Render<TData extends Record<string, unknown>> {
|
|
11
|
+
props(): ReturnType<typeof $$render<TData>>['props'];
|
|
12
|
+
events(): ReturnType<typeof $$render<TData>>['events'];
|
|
13
|
+
slots(): ReturnType<typeof $$render<TData>>['slots'];
|
|
14
|
+
bindings(): "margins";
|
|
15
|
+
exports(): {};
|
|
16
|
+
}
|
|
17
|
+
interface $$IsomorphicComponent {
|
|
18
|
+
new <TData extends Record<string, unknown>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<TData>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<TData>['props']>, ReturnType<__sveltets_Render<TData>['events']>, ReturnType<__sveltets_Render<TData>['slots']>> & {
|
|
19
|
+
$$bindings?: ReturnType<__sveltets_Render<TData>['bindings']>;
|
|
20
|
+
} & ReturnType<__sveltets_Render<TData>['exports']>;
|
|
21
|
+
<TData extends Record<string, unknown>>(internal: unknown, props: ReturnType<__sveltets_Render<TData>['props']> & {}): ReturnType<__sveltets_Render<TData>['exports']>;
|
|
22
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
23
|
+
}
|
|
24
|
+
declare const Plot: $$IsomorphicComponent;
|
|
25
|
+
type Plot<TData extends Record<string, unknown>> = InstanceType<typeof Plot<TData>>;
|
|
26
|
+
export default Plot;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AxisPlotDefaults } from '../../../types/phases';
|
|
2
|
+
import type { TreemapPlotState, TreemapPlotCtx } from '../../../types/plots/part-of-a-whole/treemap/state';
|
|
3
|
+
/**
|
|
4
|
+
* TreemapPlot on the shared pipeline: its rows are the tiles of the `treemap` transform, laid out in a unit square
|
|
5
|
+
* the plot's two continuous axes span (hidden). Its series are the outermost level of its `grouping`, which colors
|
|
6
|
+
* the tiles and fills the legend. The tiles are `rect` markers, labelled by their own `label`. Hovering a tile is
|
|
7
|
+
* hovering its row: an invisible `rect` over each one drives the plot's hover, and its tooltip names the tile and
|
|
8
|
+
* gives its share.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildTreemapDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<TreemapPlotState<TData>, TreemapPlotCtx>;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { TREEMAP_ROW } from '../../../phases/transforms/methods/TreemapTransform';
|
|
2
|
+
import { NumberFormat } from '../../../utils/NumberFormat';
|
|
3
|
+
import { Grouping } from '../../../utils/grouping';
|
|
4
|
+
import { getConfiguration } from '../../../configuration/config.svelte';
|
|
5
|
+
/** A share is written with one decimal unless the author or the configuration's `numbers.decimals` says otherwise. */
|
|
6
|
+
const SHARE_DECIMALS = 1;
|
|
7
|
+
/** The width over the height of the box the tiles are shaped for, before the plot's own is known. */
|
|
8
|
+
const DEFAULT_ASPECT = 1.6;
|
|
9
|
+
/**
|
|
10
|
+
* What a treemap writes for a tile's share: `suffix` is a percent sign unless the author asks for something
|
|
11
|
+
* else, since a tile is a part of a whole.
|
|
12
|
+
*/
|
|
13
|
+
function shareDisplay(values) {
|
|
14
|
+
return { ...NumberFormat.displayOf(values), suffix: values?.suffix ?? '%' };
|
|
15
|
+
}
|
|
16
|
+
/** A tile's name, path and share (from `0` to `100`), as the transform left them on its row. */
|
|
17
|
+
function tileOf(row) {
|
|
18
|
+
return {
|
|
19
|
+
name: String(row[TREEMAP_ROW.name] ?? ''),
|
|
20
|
+
path: row[TREEMAP_ROW.path] ?? [],
|
|
21
|
+
share: Number(row[TREEMAP_ROW.share]) * 100
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The plot's tiles: a `treemap` of its `value`, nested by the levels of its `grouping` (its `color` when unset,
|
|
26
|
+
* as every plot groups by it then) and shaped for its box,
|
|
27
|
+
* with the options of the author's own `treemap` transforms over it (`tile`...), and their other transforms
|
|
28
|
+
* after it in order.
|
|
29
|
+
*/
|
|
30
|
+
function buildTransforms(state) {
|
|
31
|
+
const own = state.transforms ?? [];
|
|
32
|
+
const base = {
|
|
33
|
+
type: 'treemap',
|
|
34
|
+
value: state.value,
|
|
35
|
+
levels: Grouping.levels(state.grouping ?? state.color, state.data),
|
|
36
|
+
aspect: state.width && state.height ? state.width / state.height : DEFAULT_ASPECT
|
|
37
|
+
};
|
|
38
|
+
const treemap = own
|
|
39
|
+
.filter((t) => t.type === 'treemap')
|
|
40
|
+
.reduce((merged, t) => ({ ...merged, ...t }), base);
|
|
41
|
+
return [treemap, ...own.filter((t) => t.type !== 'treemap')];
|
|
42
|
+
}
|
|
43
|
+
/** The edges of the tiles, as the processed rows carry them. */
|
|
44
|
+
function edgesOf(state) {
|
|
45
|
+
const { x1, x2, y1, y2 } = state.processedData.channels;
|
|
46
|
+
return { x1, x2, y1, y2 };
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The keys of the segments a tile has below its series: its path down to each deeper level
|
|
50
|
+
* (`'Tertiary.Finance'`), outermost first, so the more specific wins. The series' own are in its style already.
|
|
51
|
+
*/
|
|
52
|
+
function pathKeysOf(state, row) {
|
|
53
|
+
const { path } = tileOf(row);
|
|
54
|
+
return path
|
|
55
|
+
.slice(1)
|
|
56
|
+
.map((_, i) => path.slice(0, i + 2).join(Grouping.SEPARATOR))
|
|
57
|
+
.filter((key) => state.segments?.[key]);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The tiles as `rect` markers, each with a `label`: the name of the tile over its share, fitted to it. A series'
|
|
61
|
+
* tiles take its style - its color, under `styles.area` and the segments keyed by it (and `default`) - and the
|
|
62
|
+
* segments keyed by a tile's path restyle it, so the tiles split into one marker per style. The legend's dimming
|
|
63
|
+
* goes over all of them.
|
|
64
|
+
*/
|
|
65
|
+
function buildMarks(state, ctx) {
|
|
66
|
+
if (!state.processedData?.data.length)
|
|
67
|
+
return [];
|
|
68
|
+
const look = ctx.cfg.treemap;
|
|
69
|
+
const edges = edgesOf(state);
|
|
70
|
+
const labels = state.valueLabels?.show ? state.valueLabels : undefined;
|
|
71
|
+
const number = NumberFormat.of(shareDisplay(state.values), ctx.cfg, SHARE_DECIMALS);
|
|
72
|
+
const shareText = (row, series) => {
|
|
73
|
+
const { share } = tileOf(row);
|
|
74
|
+
return state.values?.format ? state.values.format(share, series, row, number) : number(share);
|
|
75
|
+
};
|
|
76
|
+
/** The label of a series' tiles: the name over the share, fitted - or the share alone where the name does not fit. */
|
|
77
|
+
const labelOf = (labels, series) => {
|
|
78
|
+
const shape = labels.shapeLabel(ctx, (row) => `${tileOf(row).name}
|
|
79
|
+
${shareText(row, series)}`, { fontSize: look.fontSize });
|
|
80
|
+
return {
|
|
81
|
+
...shape,
|
|
82
|
+
styles: { lineHeight: look.lineHeight, ...shape.styles },
|
|
83
|
+
fit: { padding: look.padding, fallback: (row) => shareText(row, series) }
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
return (state.processedGroups ?? []).flatMap((group) => {
|
|
87
|
+
const series = group.series.name;
|
|
88
|
+
const dimmed = ctx.interaction?.fillFor(series);
|
|
89
|
+
const seriesColor = state.colorForSeries(series);
|
|
90
|
+
/** A tile's color: its series', or a tone of it by its path while `scales.color.depth` asks for one. */
|
|
91
|
+
const colorOf = (row) => state.colorForPath ? state.colorForPath(tileOf(row).path) : seriesColor;
|
|
92
|
+
return group.visualSegments.flatMap((segment) => {
|
|
93
|
+
const styled = new Map();
|
|
94
|
+
for (const row of segment.data) {
|
|
95
|
+
const keys = pathKeysOf(state, row);
|
|
96
|
+
const color = colorOf(row);
|
|
97
|
+
const id = JSON.stringify([keys, color]);
|
|
98
|
+
const bucket = styled.get(id) ?? styled.set(id, { keys, color, rows: [] }).get(id);
|
|
99
|
+
bucket.rows.push(row);
|
|
100
|
+
}
|
|
101
|
+
return [...styled.values()].map(({ keys, color, rows }) => {
|
|
102
|
+
const style = Object.assign({}, segment.styles, ...keys.flatMap((key) => state.segments[key].map((own) => own.styles ?? {})));
|
|
103
|
+
return {
|
|
104
|
+
type: 'rect',
|
|
105
|
+
data: rows,
|
|
106
|
+
...edges,
|
|
107
|
+
styles: {
|
|
108
|
+
...style,
|
|
109
|
+
fill: dimmed?.fill ?? style.fill ?? color,
|
|
110
|
+
fillOpacity: dimmed?.fillOpacity ?? style.fillOpacity,
|
|
111
|
+
stroke: style.stroke ?? look.stroke,
|
|
112
|
+
strokeWidth: style.strokeWidth ?? look.strokeWidth
|
|
113
|
+
},
|
|
114
|
+
label: labels && labelOf(labels, series)
|
|
115
|
+
};
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* TreemapPlot on the shared pipeline: its rows are the tiles of the `treemap` transform, laid out in a unit square
|
|
122
|
+
* the plot's two continuous axes span (hidden). Its series are the outermost level of its `grouping`, which colors
|
|
123
|
+
* the tiles and fills the legend. The tiles are `rect` markers, labelled by their own `label`. Hovering a tile is
|
|
124
|
+
* hovering its row: an invisible `rect` over each one drives the plot's hover, and its tooltip names the tile and
|
|
125
|
+
* gives its share.
|
|
126
|
+
*/
|
|
127
|
+
export function buildTreemapDefaults() {
|
|
128
|
+
return {
|
|
129
|
+
data: {
|
|
130
|
+
discreteAxes: 0,
|
|
131
|
+
nested: true,
|
|
132
|
+
segments: { color: (style) => style?.fill, connect: false, base: { flat: 'area' } }
|
|
133
|
+
},
|
|
134
|
+
// An omitted sector keeps its tiles' room, and every other tile its share; a rescaled one does not.
|
|
135
|
+
transforms: { transforms: buildTransforms, keepsOmitted: true },
|
|
136
|
+
scales: {
|
|
137
|
+
defaults: () => ({
|
|
138
|
+
x: { axisDisplay: 'none', grid: false },
|
|
139
|
+
y: { axisDisplay: 'none', grid: false, reverse: true }
|
|
140
|
+
}),
|
|
141
|
+
fit: () => ({ x: { domain: [0, 1], fitted: true }, y: { domain: [0, 1], fitted: true } })
|
|
142
|
+
},
|
|
143
|
+
styles: { values: { show: true } },
|
|
144
|
+
markers: { marks: buildMarks },
|
|
145
|
+
hover: {
|
|
146
|
+
strategy: 'punctual',
|
|
147
|
+
// A tile is hovered through its own hit area, not through whichever point the pointer is nearest.
|
|
148
|
+
pointMatching: 'contains',
|
|
149
|
+
hitAreas: (state, hover) => hover.points.map(({ row }) => ({
|
|
150
|
+
type: 'rect',
|
|
151
|
+
data: [row],
|
|
152
|
+
...edgesOf(state),
|
|
153
|
+
styles: { fill: 'transparent' },
|
|
154
|
+
hover: hover.active
|
|
155
|
+
})),
|
|
156
|
+
format: (state) => {
|
|
157
|
+
const number = NumberFormat.of(shareDisplay(state.values), getConfiguration(), SHARE_DECIMALS);
|
|
158
|
+
return ((row) => {
|
|
159
|
+
const tile = tileOf(row);
|
|
160
|
+
return `${tile.name}: ${number(tile.share)}`;
|
|
161
|
+
});
|
|
162
|
+
},
|
|
163
|
+
label: () => ((row) => tileOf(row).name),
|
|
164
|
+
context: () => ((row) => ({ share: tileOf(row).share }))
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ProcessedPositions } from '../../../phases/transforms/ProcessedPositions';
|
|
2
|
-
import { buildMarks,
|
|
2
|
+
import { buildMarks, buildHitAreas, buildBarGeometry } from './markers';
|
|
3
3
|
import { NiceTicks } from '../../../layout/scales/NiceTicks';
|
|
4
4
|
import { SERIES_KEY } from '../../../phases/transforms/TransformsPhase';
|
|
5
5
|
import { PlotAxes } from '../../../phases/data/PlotAxes';
|
|
@@ -90,7 +90,7 @@ export function buildBarDefaults() {
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
|
-
markers: { marks: buildMarks
|
|
93
|
+
markers: { marks: buildMarks },
|
|
94
94
|
hover: {
|
|
95
95
|
// Each bar matched by its own band (see `buildHitAreas`); a grouped bar's dot is
|
|
96
96
|
// drawn in its series' slice of the band.
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type { BarMarkerConfig
|
|
1
|
+
import type { BarMarkerConfig } from '../../../types/markers/common';
|
|
2
2
|
import type { BarPlotState, BarPlotCtx } from '../../../types/plots/ranking/bar/state';
|
|
3
3
|
import type { ProcessedRow } from '../../../types/phases';
|
|
4
4
|
import type { AxisValue } from '../../../types/layout/mapping';
|
|
5
5
|
import type { BandSlice } from '../../../types/layout/hover';
|
|
6
6
|
import type { HoverConfig } from '../../../types/plots/props';
|
|
7
|
-
import { ValueLabels } from '../../../layout/styles/ValueLabels';
|
|
8
7
|
import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
|
|
9
8
|
/**
|
|
10
9
|
* Where a bar plot's bars sit, read off the state its phases leave: each
|
|
@@ -27,15 +26,6 @@ export declare function buildBarGeometry<TData extends Record<string, unknown>>(
|
|
|
27
26
|
* plot's hover when it is active.
|
|
28
27
|
*/
|
|
29
28
|
export declare function buildHitAreas<TData extends Record<string, unknown>>(state: BarPlotState<TData>, hover: HoverConfig<any>, ctx: BarPlotCtx): BarMarkerConfig[];
|
|
30
|
-
/**
|
|
31
|
-
* BarPlot's `styles.values` as one `'text'` marker per series, over the same
|
|
32
|
-
* processed rows its bars draw (gap rows never get a label). `anchor` places
|
|
33
|
-
* each label along its bar: past its top (`'outside'`), just inside it
|
|
34
|
-
* (`'start'`), at its base (`'end'`), or centred (`'middle'`); a stacked bar's
|
|
35
|
-
* label always sits at the middle of its own span. A grouped bar's label
|
|
36
|
-
* shifts with its series' slice of the band.
|
|
37
|
-
*/
|
|
38
|
-
export declare function buildValueLabels<TData extends Record<string, unknown>>(labels: ValueLabels, state: BarPlotState<TData>, ctx: BarPlotCtx): TextMarkerConfig[];
|
|
39
29
|
/**
|
|
40
30
|
* BarPlot's "markers" phase: visible `role: 'segment'` bars - real data plus
|
|
41
31
|
* gap fills - drawing the rows the "transforms" phase left, prepended onto
|