@fundar/data-chart-telling 1.16.0 → 1.18.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 +56 -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 +20 -6
- package/dist/configuration/themes/dark.js +1 -1
- package/dist/configuration/themes/editorial.js +1 -1
- package/dist/index.d.ts +12 -4
- package/dist/index.js +4 -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 +219 -44
- package/dist/layout/hover/HoverDefaults.d.ts +52 -0
- package/dist/layout/hover/HoverDefaults.js +96 -0
- package/dist/layout/hover/HoverLayers.d.ts +35 -0
- package/dist/layout/hover/HoverLayers.js +122 -0
- package/dist/layout/hover/HoverSettings.js +4 -1
- package/dist/layout/hover/HoverShapes.d.ts +44 -0
- package/dist/layout/hover/HoverShapes.js +103 -0
- package/dist/layout/hover/PlotHover.svelte.d.ts +18 -0
- package/dist/layout/hover/PlotHover.svelte.js +54 -1
- 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 +14 -2
- package/dist/layout/legend/LegendState.svelte.js +23 -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/Core.svelte +2 -2
- package/dist/layout/plot/Plot.svelte +4 -2
- package/dist/layout/plot/Plot.svelte.d.ts +2 -1
- package/dist/layout/plot/PublicPlotContext.d.ts +6 -0
- package/dist/layout/plot/PublicPlotContext.js +8 -0
- package/dist/layout/scales/ScalesLayout.svelte +1 -1
- package/dist/layout/styles/ValueLabels.d.ts +43 -4
- package/dist/layout/styles/ValueLabels.js +87 -19
- package/dist/layout/timeline/Timeline.svelte +5 -1
- package/dist/layout/tooltip/TooltipState.svelte.d.ts +8 -9
- package/dist/layout/tooltip/TooltipState.svelte.js +28 -29
- package/dist/markers/MarkerKinds.d.ts +5 -0
- package/dist/markers/MarkerKinds.js +1 -0
- package/dist/markers/area/AreaMarker.svelte +3 -0
- package/dist/markers/arrow/ArrowMarker.svelte +9 -5
- package/dist/markers/band/BandMarker.svelte +74 -0
- package/dist/markers/band/BandMarker.svelte.d.ts +7 -0
- package/dist/markers/band/Bands.d.ts +16 -0
- package/dist/markers/band/Bands.js +48 -0
- package/dist/markers/bar/BarMarker.svelte +50 -96
- 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 +7 -249
- package/dist/markers/hover/HoverMarker.svelte.d.ts +4 -27
- 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/PointPixel.d.ts +37 -0
- package/dist/markers/utils/PointPixel.js +44 -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 +10 -8
- package/dist/phases/Pipeline.js +13 -9
- package/dist/phases/context/ContextPhase.d.ts +22 -0
- package/dist/phases/context/ContextPhase.js +23 -0
- package/dist/phases/context/RowContext.d.ts +35 -0
- package/dist/phases/context/RowContext.js +95 -0
- package/dist/phases/data/DataPhase.d.ts +4 -4
- package/dist/phases/data/DataPhase.js +53 -12
- package/dist/phases/hover/HoverPhase.d.ts +6 -7
- package/dist/phases/hover/HoverPhase.js +28 -15
- package/dist/phases/mapping/MappingPhase.d.ts +4 -4
- package/dist/phases/mapping/MappingPhase.js +4 -3
- package/dist/phases/markers/MarkerStyles.d.ts +26 -0
- package/dist/phases/markers/MarkerStyles.js +126 -0
- package/dist/phases/markers/MarkersPhase.d.ts +5 -5
- package/dist/phases/markers/MarkersPhase.js +8 -6
- package/dist/phases/scales/ScalesPhase.d.ts +4 -4
- package/dist/phases/scales/ScalesPhase.js +4 -4
- package/dist/phases/sharedScales/SharedScalesPhase.d.ts +2 -2
- package/dist/phases/sharedScales/SharedScalesPhase.js +2 -2
- package/dist/phases/statistics/MarkerGrouping.d.ts +0 -9
- package/dist/phases/statistics/MarkerGrouping.js +0 -16
- package/dist/phases/statistics/StatisticsPhase.js +1 -1
- package/dist/phases/styles/StylesPhase.d.ts +3 -3
- package/dist/phases/styles/StylesPhase.js +2 -2
- package/dist/phases/tooltip/TooltipPhase.d.ts +4 -4
- package/dist/phases/tooltip/TooltipPhase.js +10 -7
- package/dist/phases/transforms/Transforms.js +3 -1
- package/dist/phases/transforms/TransformsPhase.d.ts +3 -3
- package/dist/phases/transforms/TransformsPhase.js +60 -6
- 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.d.ts +2 -2
- package/dist/plots/correlation/heatmap/defaults.js +23 -8
- package/dist/plots/correlation/heatmap/markers.d.ts +2 -10
- package/dist/plots/correlation/heatmap/markers.js +11 -37
- package/dist/plots/correlation/scatter/defaults.d.ts +2 -2
- package/dist/plots/correlation/scatter/defaults.js +9 -3
- package/dist/plots/correlation/scatter/markers.d.ts +3 -3
- package/dist/plots/correlation/scatter/markers.js +6 -5
- package/dist/plots/distribution/box/BoxSummaries.d.ts +17 -8
- package/dist/plots/distribution/box/BoxSummaries.js +90 -40
- package/dist/plots/distribution/box/defaults.d.ts +2 -2
- package/dist/plots/distribution/box/defaults.js +9 -6
- package/dist/plots/distribution/box/markers.d.ts +2 -2
- package/dist/plots/distribution/box/markers.js +3 -3
- package/dist/plots/distribution/density/defaults.d.ts +2 -2
- package/dist/plots/distribution/density/defaults.js +17 -1
- package/dist/plots/distribution/density/markers.d.ts +2 -2
- package/dist/plots/distribution/density/markers.js +4 -4
- package/dist/plots/distribution/histogram/defaults.d.ts +2 -2
- package/dist/plots/distribution/histogram/defaults.js +22 -27
- package/dist/plots/distribution/histogram/markers.d.ts +3 -12
- package/dist/plots/distribution/histogram/markers.js +21 -62
- package/dist/plots/distribution/pyramid/defaults.d.ts +2 -2
- package/dist/plots/distribution/pyramid/defaults.js +7 -4
- package/dist/plots/distribution/pyramid/markers.d.ts +2 -12
- package/dist/plots/distribution/pyramid/markers.js +16 -66
- package/dist/plots/distribution/violin/defaults.d.ts +2 -2
- package/dist/plots/distribution/violin/defaults.js +9 -7
- package/dist/plots/distribution/violin/markers.d.ts +2 -2
- package/dist/plots/distribution/violin/markers.js +4 -4
- package/dist/plots/evolution/area/defaults.d.ts +2 -2
- package/dist/plots/evolution/area/defaults.js +1 -1
- package/dist/plots/evolution/area/markers.d.ts +2 -2
- package/dist/plots/evolution/area/markers.js +4 -4
- package/dist/plots/evolution/line/defaults.d.ts +2 -2
- package/dist/plots/evolution/line/defaults.js +1 -1
- package/dist/plots/evolution/line/markers.d.ts +2 -2
- package/dist/plots/evolution/line/markers.js +3 -3
- package/dist/plots/evolution/slope/defaults.d.ts +2 -2
- package/dist/plots/evolution/slope/defaults.js +8 -4
- package/dist/plots/evolution/slope/markers.d.ts +2 -2
- package/dist/plots/evolution/slope/markers.js +3 -3
- package/dist/plots/evolution/sparkline/defaults.d.ts +2 -2
- package/dist/plots/evolution/sparkline/defaults.js +5 -2
- package/dist/plots/evolution/sparkline/markers.d.ts +2 -2
- package/dist/plots/evolution/sparkline/markers.js +3 -3
- package/dist/plots/map/geo/Core.svelte +3 -3
- package/dist/plots/map/geo/defaults.d.ts +2 -2
- package/dist/plots/map/geo/phases/data.d.ts +1 -1
- package/dist/plots/map/geo/phases/data.js +1 -1
- package/dist/plots/map/geo/phases/hover.d.ts +2 -2
- package/dist/plots/map/geo/phases/hover.js +3 -3
- package/dist/plots/map/geo/phases/markers.d.ts +2 -2
- package/dist/plots/map/geo/phases/markers.js +5 -4
- package/dist/plots/map/geo/phases/scales.d.ts +2 -2
- package/dist/plots/map/geo/phases/scales.js +2 -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 +183 -0
- package/dist/plots/ranking/bar/defaults.d.ts +2 -2
- package/dist/plots/ranking/bar/defaults.js +15 -9
- package/dist/plots/ranking/bar/markers.d.ts +4 -14
- package/dist/plots/ranking/bar/markers.js +45 -86
- package/dist/plots/ranking/bullet/defaults.d.ts +2 -2
- package/dist/plots/ranking/bullet/defaults.js +4 -4
- package/dist/plots/ranking/bullet/markers.d.ts +3 -3
- package/dist/plots/ranking/bullet/markers.js +11 -12
- package/dist/plots/ranking/cleveland/ClevelandMarkers.d.ts +3 -3
- package/dist/plots/ranking/cleveland/ClevelandMarkers.js +28 -23
- package/dist/plots/ranking/cleveland/defaults.d.ts +2 -2
- package/dist/plots/ranking/cleveland/defaults.js +7 -4
- package/dist/plots/ranking/dumbbell/defaults.d.ts +2 -2
- package/dist/plots/ranking/forest/defaults.d.ts +2 -2
- package/dist/plots/ranking/lollipop/defaults.d.ts +2 -2
- package/dist/types/configuration/styling.d.ts +31 -2
- package/dist/types/layout/context.d.ts +21 -0
- package/dist/types/layout/context.js +1 -0
- package/dist/types/layout/hover.d.ts +3 -0
- 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/styles/values.d.ts +8 -2
- package/dist/types/layout/tooltip.d.ts +11 -4
- package/dist/types/markers/axis/arrow.d.ts +2 -8
- package/dist/types/markers/axis/axisBasedMarkersConfig.d.ts +2 -1
- package/dist/types/markers/axis/band.d.ts +24 -0
- package/dist/types/markers/axis/band.js +1 -0
- package/dist/types/markers/axis/bar.d.ts +6 -10
- 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/hover.d.ts +60 -15
- 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 +8 -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/common.d.ts +1 -0
- package/dist/types/markers/common.js +1 -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/context/phase.d.ts +7 -0
- package/dist/types/phases/context/phase.js +1 -0
- package/dist/types/phases/data/phase.d.ts +7 -2
- package/dist/types/phases/hover/phase.d.ts +10 -5
- package/dist/types/phases/index.d.ts +2 -1
- package/dist/types/phases/kind.d.ts +11 -8
- package/dist/types/phases/mapping/phase.d.ts +2 -2
- package/dist/types/phases/markers/phase.d.ts +3 -3
- package/dist/types/phases/scales/phase.d.ts +4 -4
- package/dist/types/phases/stage.d.ts +3 -3
- package/dist/types/phases/state.d.ts +8 -1
- package/dist/types/phases/statistics/phase.d.ts +2 -1
- package/dist/types/phases/styles/phase.d.ts +3 -2
- package/dist/types/phases/transforms/phase.d.ts +13 -2
- package/dist/types/plots/constants.d.ts +17 -19
- package/dist/types/plots/correlation/heatmap/props.d.ts +3 -3
- package/dist/types/plots/correlation/heatmap/state.d.ts +2 -2
- package/dist/types/plots/correlation/scatter/props.d.ts +3 -3
- package/dist/types/plots/correlation/scatter/state.d.ts +2 -2
- 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 +25 -3
- package/dist/types/plots/distribution/box/state.d.ts +6 -17
- package/dist/types/plots/distribution/density/props.d.ts +3 -11
- package/dist/types/plots/distribution/density/state.d.ts +2 -2
- package/dist/types/plots/distribution/histogram/props.d.ts +16 -11
- package/dist/types/plots/distribution/histogram/state.d.ts +2 -2
- package/dist/types/plots/distribution/pyramid/props.d.ts +3 -3
- package/dist/types/plots/distribution/pyramid/state.d.ts +2 -2
- package/dist/types/plots/distribution/violin/props.d.ts +4 -3
- package/dist/types/plots/distribution/violin/state.d.ts +2 -2
- package/dist/types/plots/evolution/area/props.d.ts +3 -3
- package/dist/types/plots/evolution/area/state.d.ts +2 -2
- package/dist/types/plots/evolution/line/props.d.ts +3 -3
- package/dist/types/plots/evolution/line/state.d.ts +2 -2
- package/dist/types/plots/evolution/slope/state.d.ts +2 -2
- package/dist/types/plots/evolution/sparkline/state.d.ts +2 -2
- package/dist/types/plots/map/geo/state.d.ts +1 -1
- package/dist/types/plots/part-of-a-whole/treemap/props.d.ts +29 -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 +10 -4
- package/dist/types/plots/ranking/bar/props.d.ts +3 -3
- package/dist/types/plots/ranking/bar/state.d.ts +2 -2
- package/dist/types/plots/ranking/bullet/state.d.ts +2 -2
- package/dist/types/plots/ranking/cleveland/props.d.ts +3 -3
- package/dist/types/plots/ranking/cleveland/state.d.ts +2 -2
- package/dist/types/plots/ranking/dumbbell/props.d.ts +3 -3
- package/dist/types/plots/ranking/dumbbell/state.d.ts +2 -2
- package/dist/types/plots/ranking/forest/props.d.ts +3 -3
- package/dist/types/plots/ranking/forest/state.d.ts +2 -2
- package/dist/types/plots/ranking/lollipop/props.d.ts +3 -3
- package/dist/types/plots/ranking/lollipop/state.d.ts +2 -2
- 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 +110 -28
- package/docs/plots/evolution/line.md +1 -1
- package/docs/plots/evolution/slope.md +1 -1
- package/docs/plots/part-of-a-whole/treemap.md +103 -0
- package/docs/plots/ranking/bar.md +2 -1
- package/docs/plots/ranking/cleveland.md +1 -1
- package/docs/plots.md +21 -20
- package/docs/scales.md +3 -0
- package/docs/state.md +34 -1
- package/docs/styles-and-segments.md +20 -19
- package/docs/theming.md +6 -12
- package/docs/tooltip-and-hover.md +81 -3
- package/docs/transforms-and-statistics.md +17 -16
- package/examples/LineDates.svelte +1 -1
- package/examples/ResponsiveLine.svelte +3 -1
- package/examples/Treemap.svelte +13 -0
- package/examples/TreemapHover.svelte +25 -0
- package/examples/ValueLabels.svelte +1 -1
- package/examples/datasets/economic-activity.ts +40 -0
- package/examples/datasets/index.ts +1 -0
- package/llms-full.txt +11 -9
- package/llms.txt +4 -1
- package/package.json +3 -1
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import type { AxisPlotState,
|
|
1
|
+
import type { AxisPlotState, AxisPlotEnv, AxisPlotKind, AxisPlotDefaults, DataRunState, HoverStageOptions, PhaseStage, PlotPhase } from '../types/phases';
|
|
2
2
|
import type { PlotStylesConfig } from '../types/configuration/styling';
|
|
3
3
|
import type { FacetConfig } from '../types/layout/facet';
|
|
4
4
|
import type { LegendState } from '../layout/legend/LegendState.svelte';
|
|
5
5
|
import type { HoverStrategy } from '../types/layout/hover';
|
|
6
6
|
import type { Accessor } from '../types/plots/data/common';
|
|
7
|
+
import type { GroupingAccessor } from '../types/layout/mapping';
|
|
7
8
|
/** The core props an axis plot kind seeds its pipeline from. */
|
|
8
9
|
export type AxisPipelineProps<TData extends Record<string, unknown>> = {
|
|
9
10
|
series?: unknown[];
|
|
10
11
|
data?: TData[];
|
|
11
12
|
x?: Accessor<TData, unknown>;
|
|
12
13
|
y?: Accessor<TData, unknown>;
|
|
13
|
-
grouping?:
|
|
14
|
+
grouping?: GroupingAccessor<TData>;
|
|
14
15
|
color?: Accessor<TData, unknown>;
|
|
15
16
|
opacity?: unknown;
|
|
16
17
|
r?: unknown;
|
|
@@ -20,6 +21,7 @@ export type AxisPipelineProps<TData extends Record<string, unknown>> = {
|
|
|
20
21
|
error?: Accessor<TData, unknown>;
|
|
21
22
|
target?: unknown;
|
|
22
23
|
ranges?: unknown[];
|
|
24
|
+
value?: Accessor<TData, unknown>;
|
|
23
25
|
segments?: unknown;
|
|
24
26
|
styles?: {
|
|
25
27
|
gaps?: unknown;
|
|
@@ -53,7 +55,7 @@ export type PipelineOptions<TState> = {
|
|
|
53
55
|
* Stages declared out of phase order still run in it - with a warning, once,
|
|
54
56
|
* since the declared order would otherwise read as the one that runs.
|
|
55
57
|
*/
|
|
56
|
-
export declare class Pipeline<TState,
|
|
58
|
+
export declare class Pipeline<TState, TEnv = unknown> {
|
|
57
59
|
#private;
|
|
58
60
|
/**
|
|
59
61
|
* The phases that work on the plot's rows - everything before its scales,
|
|
@@ -63,25 +65,25 @@ export declare class Pipeline<TState, TCtx = unknown> {
|
|
|
63
65
|
static readonly DATA_PHASES: readonly PlotPhase[];
|
|
64
66
|
/** Every {@link PlotPhase}, in the order they run: the data phases, then each panel's own. */
|
|
65
67
|
static readonly ORDER: readonly PlotPhase[];
|
|
66
|
-
readonly stages: readonly PhaseStage<TState,
|
|
67
|
-
constructor(stages: PhaseStage<TState,
|
|
68
|
+
readonly stages: readonly PhaseStage<TState, TEnv>[];
|
|
69
|
+
constructor(stages: PhaseStage<TState, TEnv>[], options?: PipelineOptions<TState>);
|
|
68
70
|
/**
|
|
69
71
|
* An axis-based plot kind's pipeline: the shared stages, each set up with
|
|
70
72
|
* the kind's own options - its marks and value labels among them - started
|
|
71
73
|
* from a core's props. Built once per kind object.
|
|
72
74
|
*/
|
|
73
|
-
static ofAxisKind<TState extends AxisPlotState<any, any, any, any>,
|
|
75
|
+
static ofAxisKind<TState extends AxisPlotState<any, any, any, any>, TEnv extends AxisPlotEnv>(kind: AxisPlotKind<TState, TEnv> & Pick<AxisPlotDefaults<any, any>, 'timeline'>): Pipeline<TState, TEnv>;
|
|
74
76
|
/** A plot's pipeline from what its kind gives: its axis-kind defaults, or a pipeline of its own. */
|
|
75
77
|
static of(defaults: AxisPlotDefaults<any, any> | Pipeline<any, any>): Pipeline<any, any>;
|
|
76
78
|
/** The stage of `phase`, if the pipeline has one. */
|
|
77
|
-
stage(phase: PlotPhase): PhaseStage<TState,
|
|
79
|
+
stage(phase: PlotPhase): PhaseStage<TState, TEnv> | undefined;
|
|
78
80
|
/**
|
|
79
81
|
* A core's run: every stage over the state its `input` (an axis core's
|
|
80
82
|
* props) seeds - or, given `panelState` (one facet panel's part of
|
|
81
83
|
* {@link runData}), only the stages after the data phases, over that state
|
|
82
84
|
* with the input's own props (its box, margins and scales) on top.
|
|
83
85
|
*/
|
|
84
|
-
run: (input: unknown,
|
|
86
|
+
run: (input: unknown, env: TEnv, panelState?: object) => TState;
|
|
85
87
|
/** Whether the pipeline has data phases to run once over every facet panel ({@link runData}). */
|
|
86
88
|
get facets(): boolean;
|
|
87
89
|
/**
|
package/dist/phases/Pipeline.js
CHANGED
|
@@ -2,6 +2,7 @@ import { FacetPhase } from './facet/FacetPhase';
|
|
|
2
2
|
import { DataPhase } from './data/DataPhase';
|
|
3
3
|
import { MappingPhase } from './mapping/MappingPhase';
|
|
4
4
|
import { TransformsPhase } from './transforms/TransformsPhase';
|
|
5
|
+
import { ContextPhase } from './context/ContextPhase';
|
|
5
6
|
import { StatisticsPhase } from './statistics/StatisticsPhase';
|
|
6
7
|
import { ScalesPhase } from './scales/ScalesPhase';
|
|
7
8
|
import { SharedScalesPhase } from './sharedScales/SharedScalesPhase';
|
|
@@ -33,6 +34,7 @@ export class Pipeline {
|
|
|
33
34
|
'data',
|
|
34
35
|
'mapping',
|
|
35
36
|
'transforms',
|
|
37
|
+
'context',
|
|
36
38
|
'statistics',
|
|
37
39
|
'sharedScales'
|
|
38
40
|
];
|
|
@@ -79,6 +81,7 @@ export class Pipeline {
|
|
|
79
81
|
new DataPhase(kind.data),
|
|
80
82
|
new MappingPhase(kind.mapping),
|
|
81
83
|
new TransformsPhase(kind.transforms, kind.data?.segments?.connect),
|
|
84
|
+
new ContextPhase(kind.context),
|
|
82
85
|
new StatisticsPhase(kind.statistics),
|
|
83
86
|
new SharedScalesPhase(kind.sharedScales, scales),
|
|
84
87
|
scales,
|
|
@@ -112,12 +115,12 @@ export class Pipeline {
|
|
|
112
115
|
* {@link runData}), only the stages after the data phases, over that state
|
|
113
116
|
* with the input's own props (its box, margins and scales) on top.
|
|
114
117
|
*/
|
|
115
|
-
run = (input,
|
|
118
|
+
run = (input, env, panelState) => {
|
|
116
119
|
const seed = this.#seed(input);
|
|
117
120
|
if (!panelState)
|
|
118
|
-
return Pipeline.#through(this.stages, seed,
|
|
121
|
+
return Pipeline.#through(this.stages, seed, env);
|
|
119
122
|
this.#panel ??= this.stages.filter((stage) => !Pipeline.DATA_PHASES.includes(stage.phase));
|
|
120
|
-
return Pipeline.#through(this.#panel, { ...panelState, ...seed },
|
|
123
|
+
return Pipeline.#through(this.#panel, { ...panelState, ...seed }, env);
|
|
121
124
|
};
|
|
122
125
|
/** Whether the pipeline has data phases to run once over every facet panel ({@link runData}). */
|
|
123
126
|
get facets() {
|
|
@@ -131,7 +134,7 @@ export class Pipeline {
|
|
|
131
134
|
runData(props, rows, facet, legendInteraction, cfg) {
|
|
132
135
|
this.#data ??= this.stages.filter((stage) => Pipeline.DATA_PHASES.includes(stage.phase));
|
|
133
136
|
const seed = { ...this.#seed(props, rows), facet };
|
|
134
|
-
return Pipeline.#through(this.#data, seed, Pipeline.#
|
|
137
|
+
return Pipeline.#through(this.#data, seed, Pipeline.#envFor(cfg, legendInteraction));
|
|
135
138
|
}
|
|
136
139
|
/**
|
|
137
140
|
* The plot's hover strategy when neither its `tooltip` nor a hover marker
|
|
@@ -143,7 +146,7 @@ export class Pipeline {
|
|
|
143
146
|
if (fixed !== undefined)
|
|
144
147
|
return fixed;
|
|
145
148
|
const upToData = this.stages.filter((s) => s.phase === 'data');
|
|
146
|
-
const state = Pipeline.#through(upToData, this.#seed(props), Pipeline.#
|
|
149
|
+
const state = Pipeline.#through(upToData, this.#seed(props), Pipeline.#envFor(cfg, null));
|
|
147
150
|
return HoverSettings.strategyOf(state.axes);
|
|
148
151
|
}
|
|
149
152
|
/** The plot's default `timeline.filterMode`. */
|
|
@@ -162,7 +165,7 @@ export class Pipeline {
|
|
|
162
165
|
return undefined;
|
|
163
166
|
const upToMapping = this.stages.filter((s) => s.phase === 'data' || s.phase === 'mapping');
|
|
164
167
|
// Without a legend: the channels read the same whatever it turns off.
|
|
165
|
-
const state = Pipeline.#through(upToMapping, this.#seed(props), Pipeline.#
|
|
168
|
+
const state = Pipeline.#through(upToMapping, this.#seed(props), Pipeline.#envFor(cfg, null));
|
|
166
169
|
const channel = (ref) => {
|
|
167
170
|
const name = ref === 'value' || ref === 'category' ? state.axes?.[ref] : ref;
|
|
168
171
|
if (name === undefined)
|
|
@@ -186,11 +189,11 @@ export class Pipeline {
|
|
|
186
189
|
return this.#options.seed ? this.#options.seed(input, rows) : input;
|
|
187
190
|
}
|
|
188
191
|
/** `stages` over `state`, in order. */
|
|
189
|
-
static #through(stages, state,
|
|
190
|
-
return stages.reduce((acc, stage) => stage.run(acc,
|
|
192
|
+
static #through(stages, state, env) {
|
|
193
|
+
return stages.reduce((acc, stage) => stage.run(acc, env), state);
|
|
191
194
|
}
|
|
192
195
|
/** The context a plot-level run reads, outside any core: the configuration and the legend. */
|
|
193
|
-
static #
|
|
196
|
+
static #envFor(cfg, legendInteraction) {
|
|
194
197
|
const interaction = new PlotInteraction(() => cfg, { legend: legendInteraction });
|
|
195
198
|
return { cfg, interaction };
|
|
196
199
|
}
|
|
@@ -215,6 +218,7 @@ export class Pipeline {
|
|
|
215
218
|
error: props.error,
|
|
216
219
|
target: props.target,
|
|
217
220
|
ranges: props.ranges,
|
|
221
|
+
value: props.value,
|
|
218
222
|
segments: props.segments ?? {},
|
|
219
223
|
styles: props.styles,
|
|
220
224
|
gaps: props.styles?.gaps,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ContextStageOptions } from '../../types/phases/context/phase';
|
|
2
|
+
import type { PhaseStage, ProcessedData } from '../../types/phases';
|
|
3
|
+
import type { PlotAxes } from '../data/PlotAxes';
|
|
4
|
+
import type { Series } from '../../types/plots/data/common';
|
|
5
|
+
/** What the "context" phase reads. */
|
|
6
|
+
type ContextStageState = {
|
|
7
|
+
processedData?: ProcessedData;
|
|
8
|
+
resolvedSeries?: Series<any>[];
|
|
9
|
+
axes?: PlotAxes;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The "context" phase every axis-based plot shares: right after the transforms, it works out once what the plot
|
|
13
|
+
* knows of each processed row - the shared {@link RowContext}, with what the kind adds - and keeps it on the row,
|
|
14
|
+
* for the tooltip, the hover, the value labels and the author's own markers to read.
|
|
15
|
+
*/
|
|
16
|
+
export declare class ContextPhase<TState extends ContextStageState, TEnv = unknown> implements PhaseStage<TState, TEnv> {
|
|
17
|
+
#private;
|
|
18
|
+
readonly phase: "context";
|
|
19
|
+
constructor(kind?: ContextStageOptions<TState, TEnv>);
|
|
20
|
+
run: (state: TState, env: TEnv) => TState;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { RowContext } from './RowContext';
|
|
2
|
+
/**
|
|
3
|
+
* The "context" phase every axis-based plot shares: right after the transforms, it works out once what the plot
|
|
4
|
+
* knows of each processed row - the shared {@link RowContext}, with what the kind adds - and keeps it on the row,
|
|
5
|
+
* for the tooltip, the hover, the value labels and the author's own markers to read.
|
|
6
|
+
*/
|
|
7
|
+
export class ContextPhase {
|
|
8
|
+
phase = 'context';
|
|
9
|
+
#kind;
|
|
10
|
+
constructor(kind) {
|
|
11
|
+
this.#kind = kind;
|
|
12
|
+
}
|
|
13
|
+
run = (state, env) => {
|
|
14
|
+
const rows = state.processedData?.data;
|
|
15
|
+
if (!rows?.length)
|
|
16
|
+
return state;
|
|
17
|
+
const shared = RowContext.shared(state);
|
|
18
|
+
const own = this.#kind?.(state, env);
|
|
19
|
+
for (const row of rows)
|
|
20
|
+
RowContext.tag(row, { ...shared(row), ...own?.(row) });
|
|
21
|
+
return state;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { PlotAxes } from '../data/PlotAxes';
|
|
2
|
+
import type { PlotRowContext } from '../../types/layout/context';
|
|
3
|
+
import type { Series } from '../../types/plots/data/common';
|
|
4
|
+
import type { ProcessedData, ProcessedRow } from '../../types/phases';
|
|
5
|
+
/** What the shared context is worked out from. */
|
|
6
|
+
type ContextSource = {
|
|
7
|
+
processedData?: ProcessedData;
|
|
8
|
+
resolvedSeries?: Series<any>[];
|
|
9
|
+
axes?: PlotAxes;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* The context of the rows a plot draws ({@link PlotRowContext}): worked out once per row by the "context" phase,
|
|
13
|
+
* kept on the row itself, and read back from it - or from any copy of it - with {@link of}.
|
|
14
|
+
*/
|
|
15
|
+
export declare class RowContext {
|
|
16
|
+
#private;
|
|
17
|
+
/**
|
|
18
|
+
* What the plot knows of `row`: its series, where it sits, the value it shows and whatever its kind works out
|
|
19
|
+
* for it, with the row itself. A row no plot drew reads as its series alone.
|
|
20
|
+
*/
|
|
21
|
+
static of<TContext extends PlotRowContext = PlotRowContext>(row: unknown): TContext;
|
|
22
|
+
/** Keeps `context` on `row`, for {@link of} to read back. */
|
|
23
|
+
static tag(row: ProcessedRow, context: PlotRowContext): void;
|
|
24
|
+
/** Whether `row` carries a context already. */
|
|
25
|
+
static has(row: unknown): boolean;
|
|
26
|
+
/** A reader of the rows of `state`: the context each carries, else the shared one, for a row no phase tagged. */
|
|
27
|
+
static reader(state: ContextSource): (row: ProcessedRow) => PlotRowContext;
|
|
28
|
+
/**
|
|
29
|
+
* The context every plot gives a processed row: its series; its `x` and `y` - each its series' own value
|
|
30
|
+
* (a stacked row's own, not the running total), else where the transforms put it (a density's estimate, a
|
|
31
|
+
* bin's centre); and its value on the plot's value axis, when that is a number.
|
|
32
|
+
*/
|
|
33
|
+
static shared(state: ContextSource): (row: ProcessedRow) => PlotRowContext;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { SERIES_ID_KEY, SERIES_KEY } from '../transforms/TransformsPhase';
|
|
2
|
+
import { ProcessedPositions } from '../transforms/ProcessedPositions';
|
|
3
|
+
import { PlotAxes } from '../data/PlotAxes';
|
|
4
|
+
import { resolveAccessor } from '../../utils/accessors';
|
|
5
|
+
import { seriesIdOf } from '../../utils/grouping';
|
|
6
|
+
/** Where a row's context is kept on it: under a symbol, which survives the copies svelteplot makes of a row. */
|
|
7
|
+
const KEY = Symbol('dct-row-context');
|
|
8
|
+
/**
|
|
9
|
+
* The context of the rows a plot draws ({@link PlotRowContext}): worked out once per row by the "context" phase,
|
|
10
|
+
* kept on the row itself, and read back from it - or from any copy of it - with {@link of}.
|
|
11
|
+
*/
|
|
12
|
+
export class RowContext {
|
|
13
|
+
/**
|
|
14
|
+
* What the plot knows of `row`: its series, where it sits, the value it shows and whatever its kind works out
|
|
15
|
+
* for it, with the row itself. A row no plot drew reads as its series alone.
|
|
16
|
+
*/
|
|
17
|
+
static of(row) {
|
|
18
|
+
if (row == null || typeof row !== 'object')
|
|
19
|
+
return {};
|
|
20
|
+
const record = row;
|
|
21
|
+
const own = record[KEY];
|
|
22
|
+
if (own)
|
|
23
|
+
return { ...own, row };
|
|
24
|
+
const series = record[SERIES_KEY];
|
|
25
|
+
return { ...(typeof series === 'string' ? { series } : {}), row };
|
|
26
|
+
}
|
|
27
|
+
/** Keeps `context` on `row`, for {@link of} to read back. */
|
|
28
|
+
static tag(row, context) {
|
|
29
|
+
row[KEY] = context;
|
|
30
|
+
}
|
|
31
|
+
/** Whether `row` carries a context already. */
|
|
32
|
+
static has(row) {
|
|
33
|
+
return row != null && typeof row === 'object' && KEY in row;
|
|
34
|
+
}
|
|
35
|
+
/** A reader of the rows of `state`: the context each carries, else the shared one, for a row no phase tagged. */
|
|
36
|
+
static reader(state) {
|
|
37
|
+
let shared;
|
|
38
|
+
return (row) => {
|
|
39
|
+
if (RowContext.has(row))
|
|
40
|
+
return RowContext.of(row);
|
|
41
|
+
shared ??= RowContext.shared(state);
|
|
42
|
+
return { ...shared(row), row };
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The context every plot gives a processed row: its series; its `x` and `y` - each its series' own value
|
|
47
|
+
* (a stacked row's own, not the running total), else where the transforms put it (a density's estimate, a
|
|
48
|
+
* bin's centre); and its value on the plot's value axis, when that is a number.
|
|
49
|
+
*/
|
|
50
|
+
static shared(state) {
|
|
51
|
+
const processed = state.processedData;
|
|
52
|
+
if (!processed)
|
|
53
|
+
return () => ({});
|
|
54
|
+
const valueAxis = PlotAxes.valueOf(state);
|
|
55
|
+
const placed = ProcessedPositions.of(processed, valueAxis);
|
|
56
|
+
const x = RowContext.#along(state, 'x', RowContext.#stacked(processed, 'x') ?? placed.x);
|
|
57
|
+
const y = RowContext.#along(state, 'y', RowContext.#stacked(processed, 'y') ?? placed.y);
|
|
58
|
+
return (row) => {
|
|
59
|
+
const series = row[SERIES_KEY];
|
|
60
|
+
const at = { x: x(row), y: y(row) };
|
|
61
|
+
const raw = at[valueAxis];
|
|
62
|
+
const value = raw instanceof Date || raw === null || raw === '' ? NaN : Number(raw);
|
|
63
|
+
return {
|
|
64
|
+
...(typeof series === 'string' ? { series } : {}),
|
|
65
|
+
...at,
|
|
66
|
+
...(Number.isFinite(value) ? { value } : {})
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** A stacked row's own value along `axis` - its span, not the running total - or `undefined` with no stack there. */
|
|
71
|
+
static #stacked(processed, axis) {
|
|
72
|
+
const from = processed.channels[`${axis}1`];
|
|
73
|
+
const to = processed.channels[`${axis}2`];
|
|
74
|
+
const stack = axis === 'x' ? 'stackX' : 'stackY';
|
|
75
|
+
if (from === undefined || to === undefined)
|
|
76
|
+
return undefined;
|
|
77
|
+
if (!processed.transforms.some((t) => t.type === stack))
|
|
78
|
+
return undefined;
|
|
79
|
+
const low = resolveAccessor(from);
|
|
80
|
+
const high = resolveAccessor(to);
|
|
81
|
+
return (row) => Number(high(row)) - Number(low(row));
|
|
82
|
+
}
|
|
83
|
+
/** A row's value along `axis`: its series' own channel, else `placed`. */
|
|
84
|
+
static #along(state, axis, placed) {
|
|
85
|
+
const bySeries = new Map((state.resolvedSeries ?? []).flatMap((s) => {
|
|
86
|
+
const accessor = s[axis];
|
|
87
|
+
return accessor === undefined ? [] : [[seriesIdOf(s), resolveAccessor(accessor)]];
|
|
88
|
+
}));
|
|
89
|
+
return (row) => {
|
|
90
|
+
const own = bySeries.get(String(row[SERIES_ID_KEY]));
|
|
91
|
+
const value = own?.(row);
|
|
92
|
+
return value === undefined ? placed(row) : value;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AxisPlotState,
|
|
1
|
+
import type { AxisPlotState, AxisPlotEnv, DataStageOptions, PhaseStage } from '../../types/phases';
|
|
2
2
|
type AnyAxisState = AxisPlotState<any, any, any, any>;
|
|
3
3
|
/**
|
|
4
4
|
* The "data" phase every axis-based plot shares: its series (from `series`,
|
|
@@ -10,10 +10,10 @@ type AnyAxisState = AxisPlotState<any, any, any, any>;
|
|
|
10
10
|
* Colors and axes come from every series, before any is omitted or split by
|
|
11
11
|
* facet panel, so they stay put and every panel agrees.
|
|
12
12
|
*/
|
|
13
|
-
export declare class DataPhase<TState extends AnyAxisState,
|
|
13
|
+
export declare class DataPhase<TState extends AnyAxisState, TEnv extends AxisPlotEnv> implements PhaseStage<TState, TEnv> {
|
|
14
14
|
#private;
|
|
15
15
|
readonly phase: "data";
|
|
16
|
-
constructor(options?: DataStageOptions<TState,
|
|
17
|
-
run: (state: TState,
|
|
16
|
+
constructor(options?: DataStageOptions<TState, TEnv>);
|
|
17
|
+
run: (state: TState, env: TEnv) => TState;
|
|
18
18
|
}
|
|
19
19
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { buildSeries } from '../../utils/grouping';
|
|
2
|
-
import { ColorRamp } from '../../utils/color';
|
|
1
|
+
import { buildSeries, Grouping } from '../../utils/grouping';
|
|
2
|
+
import { ColorRamp, ColorTones } from '../../utils/color';
|
|
3
3
|
import { resolveAccessor } from '../../utils/accessors';
|
|
4
4
|
import { buildGroupedSeries, buildScopedMarkerGroups } from '../../plots/utils/segments';
|
|
5
5
|
import { buildGapFillMaps, isGapValue } from '../../plots/utils/gaps';
|
|
@@ -22,11 +22,11 @@ export class DataPhase {
|
|
|
22
22
|
constructor(options = {}) {
|
|
23
23
|
this.#options = options;
|
|
24
24
|
}
|
|
25
|
-
run = (state,
|
|
25
|
+
run = (state, env) => {
|
|
26
26
|
const options = this.#options;
|
|
27
27
|
const { series, data, segments, scales } = state;
|
|
28
28
|
const { connect = true, color: segmentColor } = options.segments ?? {};
|
|
29
|
-
const seriesGrouping = DataPhase.#buildGrouping(state);
|
|
29
|
+
const seriesGrouping = DataPhase.#buildGrouping(state, options.nested);
|
|
30
30
|
const built = series ?? buildSeries(data ?? [], state.x, state.y, seriesGrouping);
|
|
31
31
|
const fullSeries = options.orderSeries ? options.orderSeries(built, state) : built;
|
|
32
32
|
const axes = PlotAxes.build({
|
|
@@ -35,11 +35,18 @@ export class DataPhase {
|
|
|
35
35
|
given: { x: state.x !== undefined, y: state.y !== undefined },
|
|
36
36
|
discrete: options.discreteAxes
|
|
37
37
|
});
|
|
38
|
-
const
|
|
38
|
+
const seriesColors = ColorRamp.resolve(scales.color, (options.colorOrder ? options.colorOrder(fullSeries) : fullSeries).map((s) => s.name), env.cfg.palette);
|
|
39
|
+
const colorForPath = series ? undefined : DataPhase.#buildPathColors(state, env);
|
|
40
|
+
// A plot that splits its series by every level colors each one by its path; a nested one by its outermost.
|
|
41
|
+
const colorForSeries = colorForPath && !options.nested
|
|
42
|
+
? DataPhase.#byPath(state, colorForPath, seriesColors)
|
|
43
|
+
: seriesColors;
|
|
39
44
|
const panelSeries = state.panels && state.panelOf && !series
|
|
40
45
|
? FacetPanels.splitSeries(fullSeries, state.panels, state.panelOf)
|
|
41
46
|
: fullSeries;
|
|
42
|
-
const
|
|
47
|
+
const legend = env.interaction?.legend;
|
|
48
|
+
const resolvedSeries = legend?.withoutOmitted(panelSeries) ?? panelSeries;
|
|
49
|
+
const removedSeries = legend?.removed(panelSeries);
|
|
43
50
|
const baseFor = BasicStyles.of(state.styles, options.segments?.base);
|
|
44
51
|
const groupedSeries = buildGroupedSeries(resolvedSeries, segments, connect, baseFor);
|
|
45
52
|
const scopedGroups = buildScopedMarkerGroups({
|
|
@@ -57,6 +64,7 @@ export class DataPhase {
|
|
|
57
64
|
...state,
|
|
58
65
|
axes,
|
|
59
66
|
resolvedSeries,
|
|
67
|
+
...(removedSeries ? { removedSeries } : {}),
|
|
60
68
|
seriesGrouping,
|
|
61
69
|
allSeriesNames: fullSeries.map((s) => s.name),
|
|
62
70
|
groupedSeries,
|
|
@@ -64,20 +72,53 @@ export class DataPhase {
|
|
|
64
72
|
flat: resolvedSeries.flatMap((s) => s.data),
|
|
65
73
|
scopedGroups,
|
|
66
74
|
colorForSeries,
|
|
75
|
+
...(colorForPath ? { colorForPath } : {}),
|
|
67
76
|
...(gapFillMaps ? { gapFillMaps } : {})
|
|
68
77
|
};
|
|
69
|
-
return options.extend ? options.extend(next,
|
|
78
|
+
return options.extend ? options.extend(next, env) : next;
|
|
70
79
|
};
|
|
71
80
|
/**
|
|
72
|
-
* The
|
|
73
|
-
*
|
|
74
|
-
*
|
|
81
|
+
* The color of a path of the plot's `grouping` levels, when `scales.color.depth` reaches past the outermost
|
|
82
|
+
* one: each outermost value its categorical color, and every path down to `depth` a tone of it (see
|
|
83
|
+
* {@link ColorTones.hierarchy}). `undefined` for a grouping of one level, or a depth of 1.
|
|
75
84
|
*/
|
|
76
|
-
static #
|
|
85
|
+
static #buildPathColors(state, env) {
|
|
86
|
+
const depth = state.scales.color?.depth ?? 1;
|
|
87
|
+
const rows = state.data ?? [];
|
|
88
|
+
const levels = Grouping.levels(state.grouping, rows).map((level) => resolveAccessor(level));
|
|
89
|
+
if (depth <= 1 || levels.length <= 1)
|
|
90
|
+
return undefined;
|
|
91
|
+
const paths = rows.map((row) => levels.map((read) => String(read(row))));
|
|
92
|
+
const outermost = [...new Set(paths.map((path) => path[0]))];
|
|
93
|
+
const colorOf = ColorRamp.resolve(state.scales.color, outermost, env.cfg.palette);
|
|
94
|
+
return ColorTones.hierarchy(paths, depth, (value) => colorOf(value));
|
|
95
|
+
}
|
|
96
|
+
/** A series' color as the color of its path - its name is the key its levels make together. */
|
|
97
|
+
static #byPath(state, colorForPath, fallback) {
|
|
98
|
+
const rows = state.data ?? [];
|
|
99
|
+
const key = resolveAccessor(Grouping.key(state.grouping, rows));
|
|
100
|
+
const levels = Grouping.levels(state.grouping, rows).map((level) => resolveAccessor(level));
|
|
101
|
+
const pathOf = new Map();
|
|
102
|
+
for (const row of rows) {
|
|
103
|
+
const name = String(key(row));
|
|
104
|
+
if (!pathOf.has(name))
|
|
105
|
+
pathOf.set(name, levels.map((read) => String(read(row))));
|
|
106
|
+
}
|
|
107
|
+
return (name) => {
|
|
108
|
+
const path = pathOf.get(name);
|
|
109
|
+
return path ? colorForPath(path) : fallback(name);
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The key a plot's rows split into series by: its `grouping` (its levels together, or the outermost
|
|
114
|
+
* one alone for a `nested` kind), or its `color` when that names categories. A numeric `color` is a
|
|
115
|
+
* continuous value (a heatmap's cells), so it colors rows without grouping them.
|
|
116
|
+
*/
|
|
117
|
+
static #buildGrouping(state, nested = false
|
|
77
118
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
119
|
) {
|
|
79
120
|
if (state.grouping !== undefined)
|
|
80
|
-
return state.grouping;
|
|
121
|
+
return Grouping.key(state.grouping, state.data, nested);
|
|
81
122
|
const color = state.color;
|
|
82
123
|
if (color === undefined || !state.data)
|
|
83
124
|
return color;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HoverDisplayPoint, HoverPoint } from '../../types/layout/hover';
|
|
2
2
|
import { LegendState } from '../../layout/legend/LegendState.svelte';
|
|
3
|
-
import type {
|
|
3
|
+
import type { AxisPlotEnv, AxisPlotState, HoverPosition, HoverStageOptions, PhaseStage, ProcessedData } from '../../types/phases';
|
|
4
4
|
type AnyAxisState = AxisPlotState<any, any, any, any>;
|
|
5
5
|
/**
|
|
6
6
|
* The "hover" phase every axis-based plot shares: what the pointer can match
|
|
@@ -9,15 +9,16 @@ type AnyAxisState = AxisPlotState<any, any, any, any>;
|
|
|
9
9
|
* hover `rows`) of the series the legend shows, except gap rows and rows
|
|
10
10
|
* outside the legend's narrowed range.
|
|
11
11
|
*/
|
|
12
|
-
export declare class HoverPhase<TState extends AnyAxisState,
|
|
12
|
+
export declare class HoverPhase<TState extends AnyAxisState, TEnv extends AxisPlotEnv> implements PhaseStage<TState, TEnv> {
|
|
13
13
|
#private;
|
|
14
14
|
readonly phase: "hover";
|
|
15
|
-
constructor(options?: HoverStageOptions<TState,
|
|
16
|
-
run: (state: TState,
|
|
15
|
+
constructor(options?: HoverStageOptions<TState, TEnv>);
|
|
16
|
+
run: (state: TState, env: TEnv) => TState;
|
|
17
17
|
/**
|
|
18
18
|
* Hover candidates for a plot's own processed rows: each visible row at its
|
|
19
19
|
* position (a stacked row's top, a bin's centre), in its series' color. A
|
|
20
|
-
* series the legend
|
|
20
|
+
* series the legend hides, omits or rescales away is left out (a dimmed one
|
|
21
|
+
* stays), as is any row `include` rejects.
|
|
21
22
|
*/
|
|
22
23
|
static buildProcessedHoverPoints<TRow extends Record<string, unknown>>(args: {
|
|
23
24
|
processed: ProcessedData;
|
|
@@ -25,8 +26,6 @@ export declare class HoverPhase<TState extends AnyAxisState, TCtx extends AxisPl
|
|
|
25
26
|
legendInteraction?: LegendState | null;
|
|
26
27
|
label: (row: TRow) => string;
|
|
27
28
|
include?: (row: TRow) => boolean;
|
|
28
|
-
/** The row a hovered point reads as, e.g. with derived fields added. Defaults to the processed row. */
|
|
29
|
-
row?: (row: TRow) => TRow;
|
|
30
29
|
/** Fields to add to (or replace on) each point. */
|
|
31
30
|
decorate?: (row: TRow) => Partial<HoverDisplayPoint>;
|
|
32
31
|
/** Where a row sits, as is. Defaults to its processed position, with `y` as a number. */
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { ProcessedPositions } from '../transforms/ProcessedPositions';
|
|
2
2
|
import { GAP_VALUE, SERIES_KEY } from '../transforms/TransformsPhase';
|
|
3
3
|
import { HoverSettings } from '../../layout/hover/HoverSettings';
|
|
4
|
+
import { RowContext } from '../context/RowContext';
|
|
4
5
|
import { PlotAxes } from '../data/PlotAxes';
|
|
5
6
|
import { NumberFormat } from '../../utils/NumberFormat';
|
|
6
7
|
import { isGapValue } from '../../plots/utils/gaps';
|
|
7
8
|
import { LegendState } from '../../layout/legend/LegendState.svelte';
|
|
9
|
+
import { HoverDefaults } from '../../layout/hover/HoverDefaults';
|
|
8
10
|
/**
|
|
9
11
|
* The "hover" phase every axis-based plot shares: what the pointer can match
|
|
10
12
|
* (`hover`), the rows it hovers over (`hoverRows`) and where each sits
|
|
@@ -18,7 +20,7 @@ export class HoverPhase {
|
|
|
18
20
|
constructor(options = {}) {
|
|
19
21
|
this.#options = options;
|
|
20
22
|
}
|
|
21
|
-
run = (state,
|
|
23
|
+
run = (state, env) => {
|
|
22
24
|
const options = this.#options;
|
|
23
25
|
const valueAxis = PlotAxes.valueOf(state);
|
|
24
26
|
const raw = options.position?.(state) ??
|
|
@@ -28,20 +30,23 @@ export class HoverPhase {
|
|
|
28
30
|
const position = options.position || state.axes?.isDiscrete(valueAxis)
|
|
29
31
|
? raw
|
|
30
32
|
: { ...raw, [valueAxis]: (row) => Number(raw[valueAxis](row)) };
|
|
33
|
+
// A row's label is the value its context gives it, else its value channel's.
|
|
31
34
|
const label = options.label?.(state) ??
|
|
32
|
-
((row) =>
|
|
35
|
+
((row) => {
|
|
36
|
+
const { value } = RowContext.of(row);
|
|
37
|
+
return String(value ?? state.channels[valueAxis].accessor(row));
|
|
38
|
+
});
|
|
33
39
|
const processed = options.rows
|
|
34
40
|
? { ...state.processedData, data: options.rows(state) }
|
|
35
41
|
: state.processedData;
|
|
36
42
|
const points = HoverPhase.buildProcessedHoverPoints({
|
|
37
43
|
processed,
|
|
38
44
|
colorFor: state.colorForSeries,
|
|
39
|
-
legendInteraction:
|
|
45
|
+
legendInteraction: env.interaction?.legend,
|
|
40
46
|
label: label,
|
|
41
47
|
position,
|
|
42
|
-
include: HoverPhase.#hoverable(state,
|
|
43
|
-
|
|
44
|
-
decorate: options.decorate?.(state, ctx)
|
|
48
|
+
include: HoverPhase.#hoverable(state, env, raw, valueAxis),
|
|
49
|
+
decorate: options.decorate?.(state, env)
|
|
45
50
|
});
|
|
46
51
|
const hover = HoverSettings.buildConfig({
|
|
47
52
|
tooltip: state.tooltip,
|
|
@@ -52,12 +57,18 @@ export class HoverPhase {
|
|
|
52
57
|
label: label,
|
|
53
58
|
defaultStrategy: options.strategy ?? HoverSettings.strategyOf(state.axes),
|
|
54
59
|
pointMatching: options.pointMatching,
|
|
55
|
-
number: NumberFormat.of(NumberFormat.displayOf(state.tooltip),
|
|
60
|
+
number: NumberFormat.of(NumberFormat.displayOf(state.tooltip), env.cfg)
|
|
56
61
|
});
|
|
57
|
-
const hitAreas = options.hitAreas?.(state, hover,
|
|
62
|
+
const hitAreas = options.hitAreas?.(state, hover, env) ?? [];
|
|
63
|
+
const own = options.marker?.(state, env);
|
|
64
|
+
const look = typeof own === 'function'
|
|
65
|
+
? own
|
|
66
|
+
: own
|
|
67
|
+
? () => own
|
|
68
|
+
: (strategy) => HoverDefaults.of(strategy, hover.crosshair);
|
|
58
69
|
return {
|
|
59
70
|
...state,
|
|
60
|
-
hover,
|
|
71
|
+
hover: { ...hover, look },
|
|
61
72
|
hoverPosition: position,
|
|
62
73
|
hoverRows: processed.data,
|
|
63
74
|
...(hitAreas.length > 0 ? { markers: [...(state.markers ?? []), ...hitAreas] } : {})
|
|
@@ -66,10 +77,11 @@ export class HoverPhase {
|
|
|
66
77
|
/**
|
|
67
78
|
* Hover candidates for a plot's own processed rows: each visible row at its
|
|
68
79
|
* position (a stacked row's top, a bin's centre), in its series' color. A
|
|
69
|
-
* series the legend
|
|
80
|
+
* series the legend hides, omits or rescales away is left out (a dimmed one
|
|
81
|
+
* stays), as is any row `include` rejects.
|
|
70
82
|
*/
|
|
71
83
|
static buildProcessedHoverPoints(args) {
|
|
72
|
-
const { processed, colorFor, legendInteraction, label, include,
|
|
84
|
+
const { processed, colorFor, legendInteraction, label, include, decorate } = args;
|
|
73
85
|
const processedPosition = ProcessedPositions.of(processed);
|
|
74
86
|
const position = args.position ?? {
|
|
75
87
|
x: processedPosition.x,
|
|
@@ -78,7 +90,7 @@ export class HoverPhase {
|
|
|
78
90
|
const x = position.x;
|
|
79
91
|
const y = position.y;
|
|
80
92
|
return processed.data
|
|
81
|
-
.filter((d) => !legendInteraction?.
|
|
93
|
+
.filter((d) => !legendInteraction?.isUnhoverable(d[SERIES_KEY]))
|
|
82
94
|
.filter((d) => !include || include(d))
|
|
83
95
|
.map((d) => {
|
|
84
96
|
const row = d;
|
|
@@ -86,7 +98,8 @@ export class HoverPhase {
|
|
|
86
98
|
return {
|
|
87
99
|
x: x(d),
|
|
88
100
|
y: y(d),
|
|
89
|
-
row
|
|
101
|
+
row,
|
|
102
|
+
context: RowContext.of(row),
|
|
90
103
|
label: label(row),
|
|
91
104
|
series: seriesName,
|
|
92
105
|
color: colorFor(seriesName),
|
|
@@ -99,8 +112,8 @@ export class HoverPhase {
|
|
|
99
112
|
* filled in by `styles.gaps`), and, while the legend narrows a continuous
|
|
100
113
|
* color to a range, not outside it. A dimmed row stays drawn, never matched.
|
|
101
114
|
*/
|
|
102
|
-
static #hoverable(state,
|
|
103
|
-
const range =
|
|
115
|
+
static #hoverable(state, env, position, valueAxis) {
|
|
116
|
+
const range = env.interaction?.legend?.range;
|
|
104
117
|
const color = state.channels?.color?.accessor;
|
|
105
118
|
return (row) => {
|
|
106
119
|
if (isGapValue(position[valueAxis](row)) || row[GAP_VALUE] !== undefined)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AxisPlotState,
|
|
1
|
+
import type { AxisPlotState, AxisPlotEnv, MappingStageOptions, PhaseStage } from '../../types/phases';
|
|
2
2
|
type AnyAxisState = AxisPlotState<any, any, any, any>;
|
|
3
3
|
/**
|
|
4
4
|
* The "mapping" phase every axis-based plot shares: every channel resolved to
|
|
@@ -8,10 +8,10 @@ type AnyAxisState = AxisPlotState<any, any, any, any>;
|
|
|
8
8
|
* its prop is set, and a size channel given a number stays that literal size.
|
|
9
9
|
* An unset `x`/`y` reads each row itself, with no `source`.
|
|
10
10
|
*/
|
|
11
|
-
export declare class MappingPhase<TState extends AnyAxisState,
|
|
11
|
+
export declare class MappingPhase<TState extends AnyAxisState, TEnv extends AxisPlotEnv> implements PhaseStage<TState, TEnv> {
|
|
12
12
|
#private;
|
|
13
13
|
readonly phase: "mapping";
|
|
14
|
-
constructor(options?: MappingStageOptions<TState,
|
|
15
|
-
run: (state: TState,
|
|
14
|
+
constructor(options?: MappingStageOptions<TState, TEnv>);
|
|
15
|
+
run: (state: TState, env: TEnv) => TState;
|
|
16
16
|
}
|
|
17
17
|
export {};
|