@fundar/data-chart-telling 1.17.0 → 1.19.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 +59 -0
- package/README.md +2 -1
- package/dist/configuration/config.svelte.js +4 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +4 -1
- package/dist/layout/coordinates/CoordinatesLayout.svelte +3 -1
- package/dist/layout/geometry/GeometryLayout.svelte +222 -53
- package/dist/layout/geometry/ScaleFreeContext.d.ts +31 -0
- package/dist/layout/geometry/ScaleFreeContext.js +65 -0
- package/dist/layout/geometry/ScaleFreeMarks.svelte +14 -0
- package/dist/layout/geometry/ScaleFreeMarks.svelte.d.ts +7 -0
- package/dist/layout/geometry/ScaleGate.svelte.d.ts +8 -0
- package/dist/layout/geometry/ScaleGate.svelte.js +95 -0
- package/dist/layout/geometry/ScaleGateMarks.svelte +15 -0
- package/dist/layout/geometry/ScaleGateMarks.svelte.d.ts +7 -0
- 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.d.ts +1 -3
- package/dist/layout/hover/HoverSettings.js +3 -2
- package/dist/layout/hover/HoverShapes.d.ts +56 -0
- package/dist/layout/hover/HoverShapes.js +163 -0
- package/dist/layout/hover/PlotHover.svelte.d.ts +18 -0
- package/dist/layout/hover/PlotHover.svelte.js +54 -1
- package/dist/layout/legend/LegendState.svelte.d.ts +2 -0
- package/dist/layout/legend/LegendState.svelte.js +5 -0
- package/dist/layout/margins/Box.d.ts +4 -0
- package/dist/layout/margins/Box.js +14 -0
- package/dist/layout/margins/PlotMargins.svelte.js +26 -1
- package/dist/layout/plot/{Plot.svelte.d.ts → AbstractPlot.svelte.d.ts} +3 -3
- package/dist/layout/plot/Core.svelte +2 -2
- package/dist/layout/plot/PublicPlotContext.d.ts +6 -0
- package/dist/layout/plot/PublicPlotContext.js +8 -0
- package/dist/layout/styles/ValueLabels.d.ts +118 -59
- package/dist/layout/styles/ValueLabels.js +313 -146
- 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 +84 -1
- package/dist/markers/MarkerKinds.js +150 -23
- package/dist/markers/area/AreaMarker.svelte +1 -1
- 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 +29 -70
- package/dist/markers/bollinger/BollingerMarker.svelte +1 -1
- package/dist/markers/box/BoxMarker.svelte +1 -1
- package/dist/markers/dot/DotRadius.d.ts +11 -0
- package/dist/markers/dot/DotRadius.js +21 -0
- package/dist/markers/hover/HoverMarker.svelte +7 -265
- package/dist/markers/hover/HoverMarker.svelte.d.ts +4 -27
- package/dist/markers/labels/CurveLabel.svelte +56 -0
- package/dist/markers/labels/CurveLabel.svelte.d.ts +9 -0
- package/dist/markers/labels/LabelMerge.d.ts +11 -0
- package/dist/markers/labels/LabelMerge.js +87 -0
- package/dist/markers/labels/MarkerLabel.svelte +36 -0
- package/dist/markers/labels/MarkerLabel.svelte.d.ts +10 -0
- package/dist/markers/labels/MarkerLabels.d.ts +52 -0
- package/dist/markers/labels/MarkerLabels.js +97 -0
- package/dist/markers/labels/geometry/BoxGeometry.d.ts +8 -0
- package/dist/markers/labels/geometry/BoxGeometry.js +101 -0
- package/dist/markers/labels/geometry/CurveGeometry.d.ts +34 -0
- package/dist/markers/labels/geometry/CurveGeometry.js +193 -0
- package/dist/markers/labels/geometry/PointGeometry.d.ts +9 -0
- package/dist/markers/labels/geometry/PointGeometry.js +22 -0
- package/dist/markers/labels/layouts/BoxLayout.d.ts +10 -0
- package/dist/markers/labels/layouts/BoxLayout.js +49 -0
- package/dist/markers/labels/layouts/PathLayout.d.ts +11 -0
- package/dist/markers/labels/layouts/PathLayout.js +91 -0
- package/dist/markers/labels/layouts/PointLayout.d.ts +19 -0
- package/dist/markers/labels/layouts/PointLayout.js +94 -0
- package/dist/markers/regression/RegressionMarker.svelte +1 -1
- package/dist/markers/text/Covering.d.ts +13 -0
- package/dist/markers/text/Covering.js +29 -0
- package/dist/markers/text/Declutter.d.ts +24 -3
- package/dist/markers/text/Declutter.js +46 -3
- package/dist/markers/text/TextMarker.svelte +90 -17
- package/dist/markers/text/TextMarker.svelte.d.ts +1 -1
- package/dist/markers/tick/TickMarker.svelte +1 -1
- package/dist/markers/utils/MarkerChannels.d.ts +1 -1
- package/dist/markers/utils/MarkerChannels.js +3 -2
- package/dist/markers/utils/PointPixel.d.ts +37 -0
- package/dist/markers/utils/PointPixel.js +44 -0
- package/dist/markers/violin/ViolinMarker.svelte +1 -1
- package/dist/markers/waffle/WaffleMarker.svelte +1 -1
- package/dist/phases/Pipeline.d.ts +7 -7
- package/dist/phases/Pipeline.js +12 -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 +37 -0
- package/dist/phases/context/RowContext.js +97 -0
- package/dist/phases/data/DataPhase.d.ts +4 -4
- package/dist/phases/data/DataPhase.js +7 -7
- package/dist/phases/hover/HoverPhase.d.ts +6 -7
- package/dist/phases/hover/HoverPhase.js +28 -23
- package/dist/phases/mapping/MappingPhase.d.ts +4 -4
- package/dist/phases/mapping/MappingPhase.js +2 -2
- package/dist/phases/markers/MarkerStyles.d.ts +8 -0
- package/dist/phases/markers/MarkerStyles.js +24 -6
- package/dist/phases/markers/MarkersPhase.d.ts +6 -7
- package/dist/phases/markers/MarkersPhase.js +18 -12
- 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 +5 -48
- package/dist/phases/statistics/MarkerInheritance.d.ts +11 -0
- package/dist/phases/statistics/MarkerInheritance.js +25 -0
- package/dist/phases/statistics/MarkerOrientation.d.ts +26 -0
- package/dist/phases/statistics/MarkerOrientation.js +29 -0
- package/dist/phases/statistics/StatisticsPhase.js +15 -15
- 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/TransformsPhase.d.ts +3 -3
- package/dist/phases/transforms/TransformsPhase.js +7 -5
- package/dist/plots/correlation/heatmap/Plot.svelte +2 -2
- package/dist/plots/correlation/heatmap/Plot.svelte.d.ts +0 -1
- package/dist/plots/correlation/heatmap/defaults.d.ts +2 -2
- package/dist/plots/correlation/heatmap/defaults.js +35 -7
- package/dist/plots/correlation/heatmap/markers.d.ts +2 -8
- package/dist/plots/correlation/heatmap/markers.js +8 -11
- package/dist/plots/correlation/scatter/Plot.svelte +2 -2
- package/dist/plots/correlation/scatter/Plot.svelte.d.ts +0 -1
- package/dist/plots/correlation/scatter/defaults.d.ts +2 -2
- package/dist/plots/correlation/scatter/defaults.js +18 -6
- package/dist/plots/correlation/scatter/markers.d.ts +2 -11
- package/dist/plots/correlation/scatter/markers.js +24 -30
- package/dist/plots/distribution/box/BoxSummaries.d.ts +22 -8
- package/dist/plots/distribution/box/BoxSummaries.js +99 -40
- package/dist/plots/distribution/box/Plot.svelte +2 -2
- package/dist/plots/distribution/box/Plot.svelte.d.ts +0 -1
- package/dist/plots/distribution/box/defaults.d.ts +2 -2
- package/dist/plots/distribution/box/defaults.js +20 -6
- package/dist/plots/distribution/box/markers.d.ts +2 -2
- package/dist/plots/distribution/box/markers.js +13 -4
- package/dist/plots/distribution/density/Plot.svelte +2 -2
- package/dist/plots/distribution/density/Plot.svelte.d.ts +0 -1
- package/dist/plots/distribution/density/defaults.d.ts +2 -2
- package/dist/plots/distribution/density/defaults.js +33 -1
- package/dist/plots/distribution/density/markers.d.ts +2 -2
- package/dist/plots/distribution/density/markers.js +9 -5
- package/dist/plots/distribution/histogram/Plot.svelte +2 -2
- package/dist/plots/distribution/histogram/Plot.svelte.d.ts +0 -1
- package/dist/plots/distribution/histogram/defaults.d.ts +2 -2
- package/dist/plots/distribution/histogram/defaults.js +36 -36
- package/dist/plots/distribution/histogram/markers.d.ts +2 -2
- package/dist/plots/distribution/histogram/markers.js +7 -6
- package/dist/plots/distribution/pyramid/Plot.svelte +2 -2
- package/dist/plots/distribution/pyramid/Plot.svelte.d.ts +0 -1
- package/dist/plots/distribution/pyramid/defaults.d.ts +2 -2
- package/dist/plots/distribution/pyramid/defaults.js +13 -3
- package/dist/plots/distribution/pyramid/markers.d.ts +2 -10
- package/dist/plots/distribution/pyramid/markers.js +9 -18
- package/dist/plots/distribution/violin/Plot.svelte +2 -2
- package/dist/plots/distribution/violin/Plot.svelte.d.ts +0 -1
- package/dist/plots/distribution/violin/defaults.d.ts +2 -2
- package/dist/plots/distribution/violin/defaults.js +20 -7
- package/dist/plots/distribution/violin/markers.d.ts +2 -2
- package/dist/plots/distribution/violin/markers.js +30 -6
- package/dist/plots/evolution/area/Plot.svelte +2 -2
- package/dist/plots/evolution/area/Plot.svelte.d.ts +0 -1
- package/dist/plots/evolution/area/defaults.d.ts +2 -2
- package/dist/plots/evolution/area/defaults.js +5 -8
- package/dist/plots/evolution/area/markers.d.ts +2 -2
- package/dist/plots/evolution/area/markers.js +7 -5
- package/dist/plots/evolution/line/Plot.svelte +2 -2
- package/dist/plots/evolution/line/Plot.svelte.d.ts +0 -1
- package/dist/plots/evolution/line/defaults.d.ts +2 -2
- package/dist/plots/evolution/line/defaults.js +5 -7
- package/dist/plots/evolution/line/markers.d.ts +2 -2
- package/dist/plots/evolution/line/markers.js +6 -4
- package/dist/plots/evolution/slope/Plot.svelte +2 -2
- package/dist/plots/evolution/slope/Plot.svelte.d.ts +0 -1
- package/dist/plots/evolution/slope/defaults.d.ts +2 -2
- package/dist/plots/evolution/slope/defaults.js +11 -6
- package/dist/plots/evolution/slope/markers.d.ts +6 -5
- package/dist/plots/evolution/slope/markers.js +19 -12
- package/dist/plots/evolution/sparkline/Plot.svelte +2 -2
- package/dist/plots/evolution/sparkline/Plot.svelte.d.ts +0 -1
- 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 +6 -4
- package/dist/plots/generic/Plot.svelte +42 -0
- package/dist/plots/generic/Plot.svelte.d.ts +25 -0
- package/dist/plots/generic/defaults.d.ts +4 -0
- package/dist/plots/generic/defaults.js +7 -0
- package/dist/plots/map/geo/Core.svelte +3 -3
- package/dist/plots/map/geo/Plot.svelte +2 -2
- package/dist/plots/map/geo/Plot.svelte.d.ts +0 -1
- 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 +3 -3
- 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 +2 -2
- package/dist/plots/part-of-a-whole/treemap/Plot.svelte.d.ts +0 -1
- package/dist/plots/part-of-a-whole/treemap/defaults.d.ts +2 -2
- package/dist/plots/part-of-a-whole/treemap/defaults.js +38 -22
- package/dist/plots/ranking/bar/Plot.svelte +2 -2
- package/dist/plots/ranking/bar/Plot.svelte.d.ts +0 -1
- package/dist/plots/ranking/bar/defaults.d.ts +2 -2
- package/dist/plots/ranking/bar/defaults.js +26 -10
- package/dist/plots/ranking/bar/markers.d.ts +3 -3
- package/dist/plots/ranking/bar/markers.js +17 -33
- package/dist/plots/ranking/bullet/Plot.svelte +2 -2
- package/dist/plots/ranking/bullet/Plot.svelte.d.ts +0 -1
- package/dist/plots/ranking/bullet/defaults.d.ts +2 -2
- package/dist/plots/ranking/bullet/defaults.js +24 -4
- package/dist/plots/ranking/bullet/markers.d.ts +3 -3
- package/dist/plots/ranking/bullet/markers.js +16 -10
- package/dist/plots/ranking/cleveland/ClevelandMarkers.d.ts +4 -11
- package/dist/plots/ranking/cleveland/ClevelandMarkers.js +73 -54
- package/dist/plots/ranking/cleveland/Plot.svelte +2 -2
- package/dist/plots/ranking/cleveland/Plot.svelte.d.ts +0 -1
- package/dist/plots/ranking/cleveland/defaults.d.ts +2 -2
- package/dist/plots/ranking/cleveland/defaults.js +39 -5
- package/dist/plots/ranking/dumbbell/Plot.svelte +2 -2
- package/dist/plots/ranking/dumbbell/Plot.svelte.d.ts +0 -1
- package/dist/plots/ranking/dumbbell/defaults.d.ts +2 -2
- package/dist/plots/ranking/forest/Plot.svelte +2 -2
- package/dist/plots/ranking/forest/Plot.svelte.d.ts +0 -1
- package/dist/plots/ranking/forest/defaults.d.ts +2 -2
- package/dist/plots/ranking/lollipop/Plot.svelte +2 -2
- package/dist/plots/ranking/lollipop/Plot.svelte.d.ts +0 -1
- package/dist/plots/ranking/lollipop/defaults.d.ts +2 -2
- package/dist/types/configuration/styling.d.ts +4 -0
- package/dist/types/layout/context.d.ts +23 -0
- package/dist/types/layout/context.js +1 -0
- package/dist/types/layout/hover.d.ts +3 -0
- package/dist/types/layout/styles/bullet.d.ts +4 -1
- package/dist/types/layout/styles/values.d.ts +59 -13
- package/dist/types/layout/tooltip.d.ts +5 -10
- package/dist/types/markers/axis/area.d.ts +5 -1
- 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 +7 -4
- package/dist/types/markers/axis/bollinger.d.ts +2 -1
- package/dist/types/markers/axis/box.d.ts +2 -1
- package/dist/types/markers/axis/cell.d.ts +4 -1
- package/dist/types/markers/axis/hover.d.ts +60 -15
- package/dist/types/markers/axis/line.d.ts +4 -1
- package/dist/types/markers/axis/rect.d.ts +4 -1
- package/dist/types/markers/axis/regression.d.ts +2 -1
- package/dist/types/markers/axis/tick.d.ts +2 -1
- package/dist/types/markers/axis/trail.d.ts +4 -1
- package/dist/types/markers/axis/violin.d.ts +2 -1
- package/dist/types/markers/axis/waffle.d.ts +5 -1
- package/dist/types/markers/basic/dot.d.ts +4 -1
- package/dist/types/markers/basic/text.d.ts +25 -21
- package/dist/types/markers/channels/commonMarkerConfig.d.ts +6 -2
- package/dist/types/markers/channels/commonMarkerConfigWithLabel.d.ts +5 -9
- package/dist/types/markers/channels/commonMarkerConfigWithOrientation.d.ts +5 -0
- package/dist/types/markers/channels/commonMarkerConfigWithOrientation.js +1 -0
- package/dist/types/markers/common.d.ts +1 -0
- package/dist/types/markers/common.js +1 -0
- package/dist/types/markers/labels/box.d.ts +57 -0
- package/dist/types/markers/labels/box.js +1 -0
- package/dist/types/markers/labels/common.d.ts +15 -0
- package/dist/types/markers/labels/common.js +1 -0
- package/dist/types/markers/labels/path.d.ts +52 -0
- package/dist/types/markers/labels/path.js +1 -0
- package/dist/types/markers/labels/point.d.ts +40 -0
- package/dist/types/markers/labels/point.js +1 -0
- package/dist/types/markers/traits.d.ts +10 -0
- 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 +2 -2
- package/dist/types/phases/hover/phase.d.ts +10 -7
- 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 -10
- 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 +1 -1
- package/dist/types/phases/statistics/phase.d.ts +8 -3
- package/dist/types/phases/styles/phase.d.ts +18 -5
- package/dist/types/phases/transforms/phase.d.ts +4 -2
- package/dist/types/plots/constants.d.ts +3 -17
- package/dist/types/plots/correlation/heatmap/props.d.ts +3 -2
- package/dist/types/plots/correlation/heatmap/state.d.ts +2 -2
- package/dist/types/plots/correlation/scatter/props.d.ts +3 -2
- package/dist/types/plots/correlation/scatter/state.d.ts +2 -2
- package/dist/types/plots/distribution/box/props.d.ts +28 -2
- package/dist/types/plots/distribution/box/state.d.ts +6 -17
- package/dist/types/plots/distribution/density/props.d.ts +2 -1
- package/dist/types/plots/distribution/density/state.d.ts +2 -2
- package/dist/types/plots/distribution/histogram/props.d.ts +16 -2
- package/dist/types/plots/distribution/histogram/state.d.ts +2 -2
- package/dist/types/plots/distribution/pyramid/props.d.ts +3 -2
- package/dist/types/plots/distribution/pyramid/state.d.ts +2 -2
- package/dist/types/plots/distribution/violin/props.d.ts +6 -2
- package/dist/types/plots/distribution/violin/state.d.ts +2 -2
- package/dist/types/plots/evolution/area/props.d.ts +3 -2
- package/dist/types/plots/evolution/area/state.d.ts +2 -2
- package/dist/types/plots/evolution/line/props.d.ts +3 -2
- 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/generic/props.d.ts +16 -0
- package/dist/types/plots/generic/props.js +1 -0
- package/dist/types/plots/generic/state.d.ts +4 -0
- package/dist/types/plots/generic/state.js +1 -0
- package/dist/types/plots/map/geo/state.d.ts +1 -1
- package/dist/types/plots/part-of-a-whole/treemap/props.d.ts +18 -6
- package/dist/types/plots/part-of-a-whole/treemap/state.d.ts +2 -2
- package/dist/types/plots/props.d.ts +3 -0
- package/dist/types/plots/ranking/bar/props.d.ts +3 -2
- 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 -2
- package/dist/types/plots/ranking/cleveland/state.d.ts +2 -2
- package/dist/types/plots/ranking/dumbbell/props.d.ts +3 -2
- package/dist/types/plots/ranking/dumbbell/state.d.ts +2 -2
- package/dist/types/plots/ranking/forest/props.d.ts +5 -2
- package/dist/types/plots/ranking/forest/state.d.ts +2 -2
- package/dist/types/plots/ranking/lollipop/props.d.ts +3 -2
- package/dist/types/plots/ranking/lollipop/state.d.ts +2 -2
- package/docs/architecture.md +9 -9
- package/docs/markers.md +36 -6
- 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 +36 -2
- package/docs/plots/ranking/bar.md +1 -0
- package/docs/plots/ranking/cleveland.md +1 -1
- package/docs/state.md +33 -0
- package/docs/styles-and-segments.md +2 -15
- package/docs/theming.md +2 -1
- package/docs/tooltip-and-hover.md +81 -3
- package/docs/value-labels.md +159 -0
- package/examples/BarValues.svelte +1 -1
- package/examples/LineDates.svelte +1 -1
- package/examples/ResponsiveLine.svelte +3 -1
- package/examples/TreemapHover.svelte +25 -0
- package/examples/ValueLabels.svelte +1 -1
- package/llms-full.txt +9 -7
- package/llms.txt +3 -1
- package/package.json +3 -1
- package/dist/markers/utils/BoxLabel.d.ts +0 -58
- package/dist/markers/utils/BoxLabel.js +0 -175
- package/dist/markers/utils/MarkerLabel.svelte +0 -33
- package/dist/markers/utils/MarkerLabel.svelte.d.ts +0 -10
- /package/dist/layout/plot/{Plot.svelte → AbstractPlot.svelte} +0 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { BandSlice } from '../../types/layout/hover';
|
|
2
|
+
type Scale = {
|
|
3
|
+
type?: string;
|
|
4
|
+
fn?: (value: never) => unknown;
|
|
5
|
+
} | undefined;
|
|
6
|
+
/** Where a point is drawn, in pixels of its plot: its `x` and `y` through the plot's scales. */
|
|
7
|
+
export declare class PointPixel {
|
|
8
|
+
#private;
|
|
9
|
+
/**
|
|
10
|
+
* `point`'s pixel position - the middle of its band on a band scale, of its slice when it has one (a grouped
|
|
11
|
+
* bar's series) - or `null` when a scale cannot place it.
|
|
12
|
+
*/
|
|
13
|
+
static of(scales: {
|
|
14
|
+
x?: Scale;
|
|
15
|
+
y?: Scale;
|
|
16
|
+
}, point: {
|
|
17
|
+
x: unknown;
|
|
18
|
+
y: unknown;
|
|
19
|
+
areaInset?: BandSlice;
|
|
20
|
+
}): {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
} | null;
|
|
24
|
+
/** The index of the one of `points` nearest `cursor`, or `-1` when none can be placed. */
|
|
25
|
+
static nearest(scales: {
|
|
26
|
+
x?: Scale;
|
|
27
|
+
y?: Scale;
|
|
28
|
+
}, points: readonly {
|
|
29
|
+
x: unknown;
|
|
30
|
+
y: unknown;
|
|
31
|
+
areaInset?: BandSlice;
|
|
32
|
+
}[], cursor: {
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
}): number;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { BandNudge } from './BandNudge';
|
|
2
|
+
/** Where a point is drawn, in pixels of its plot: its `x` and `y` through the plot's scales. */
|
|
3
|
+
export class PointPixel {
|
|
4
|
+
/**
|
|
5
|
+
* `point`'s pixel position - the middle of its band on a band scale, of its slice when it has one (a grouped
|
|
6
|
+
* bar's series) - or `null` when a scale cannot place it.
|
|
7
|
+
*/
|
|
8
|
+
static of(scales, point) {
|
|
9
|
+
const x = PointPixel.#along(scales.x, point.x);
|
|
10
|
+
const y = PointPixel.#along(scales.y, point.y);
|
|
11
|
+
if (x == null || y == null)
|
|
12
|
+
return null;
|
|
13
|
+
const nudge = BandNudge.of(scales, point.areaInset);
|
|
14
|
+
return { x: x + nudge.dx, y: y + nudge.dy };
|
|
15
|
+
}
|
|
16
|
+
/** The index of the one of `points` nearest `cursor`, or `-1` when none can be placed. */
|
|
17
|
+
static nearest(scales, points, cursor) {
|
|
18
|
+
let best = -1;
|
|
19
|
+
let bestDistance = Infinity;
|
|
20
|
+
points.forEach((point, index) => {
|
|
21
|
+
const pixel = PointPixel.of(scales, point);
|
|
22
|
+
if (!pixel)
|
|
23
|
+
return;
|
|
24
|
+
const distance = Math.hypot(pixel.x - cursor.x, pixel.y - cursor.y);
|
|
25
|
+
if (distance < bestDistance) {
|
|
26
|
+
best = index;
|
|
27
|
+
bestDistance = distance;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return best;
|
|
31
|
+
}
|
|
32
|
+
/** `value`'s pixel along one scale, in the middle of its band on a band scale. */
|
|
33
|
+
static #along(scale, value) {
|
|
34
|
+
if (!scale?.fn || value == null)
|
|
35
|
+
return null;
|
|
36
|
+
const raw = Number(scale.fn(value));
|
|
37
|
+
if (!Number.isFinite(raw))
|
|
38
|
+
return null;
|
|
39
|
+
if (scale.type !== 'band')
|
|
40
|
+
return raw;
|
|
41
|
+
const bandwidth = scale.fn.bandwidth?.() ?? 0;
|
|
42
|
+
return raw + bandwidth / 2;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
const plot = usePlot();
|
|
18
18
|
const cfg = $derived(getConfiguration());
|
|
19
|
-
const isHorizontal = $derived(plot.axes?.isHorizontal ?? false);
|
|
19
|
+
const isHorizontal = $derived(marker.isHorizontal ?? plot.axes?.isHorizontal ?? false);
|
|
20
20
|
const categoryScale = $derived(
|
|
21
21
|
isHorizontal ? plot.svelteplot.scales.y : plot.svelteplot.scales.x
|
|
22
22
|
);
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
const events = MarkerEvents.use(() => marker);
|
|
13
13
|
|
|
14
14
|
const plot = usePlot();
|
|
15
|
-
const isHorizontal = $derived(plot.axes?.isHorizontal ?? false);
|
|
15
|
+
const isHorizontal = $derived(marker.isHorizontal ?? plot.axes?.isHorizontal ?? false);
|
|
16
16
|
const WaffleMark = $derived(isHorizontal ? WaffleX : WaffleY);
|
|
17
17
|
|
|
18
18
|
const cfg = $derived(getConfiguration());
|
|
@@ -1,4 +1,4 @@
|
|
|
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';
|
|
@@ -55,7 +55,7 @@ export type PipelineOptions<TState> = {
|
|
|
55
55
|
* Stages declared out of phase order still run in it - with a warning, once,
|
|
56
56
|
* since the declared order would otherwise read as the one that runs.
|
|
57
57
|
*/
|
|
58
|
-
export declare class Pipeline<TState,
|
|
58
|
+
export declare class Pipeline<TState, TEnv = unknown> {
|
|
59
59
|
#private;
|
|
60
60
|
/**
|
|
61
61
|
* The phases that work on the plot's rows - everything before its scales,
|
|
@@ -65,25 +65,25 @@ export declare class Pipeline<TState, TCtx = unknown> {
|
|
|
65
65
|
static readonly DATA_PHASES: readonly PlotPhase[];
|
|
66
66
|
/** Every {@link PlotPhase}, in the order they run: the data phases, then each panel's own. */
|
|
67
67
|
static readonly ORDER: readonly PlotPhase[];
|
|
68
|
-
readonly stages: readonly PhaseStage<TState,
|
|
69
|
-
constructor(stages: PhaseStage<TState,
|
|
68
|
+
readonly stages: readonly PhaseStage<TState, TEnv>[];
|
|
69
|
+
constructor(stages: PhaseStage<TState, TEnv>[], options?: PipelineOptions<TState>);
|
|
70
70
|
/**
|
|
71
71
|
* An axis-based plot kind's pipeline: the shared stages, each set up with
|
|
72
72
|
* the kind's own options - its marks and value labels among them - started
|
|
73
73
|
* from a core's props. Built once per kind object.
|
|
74
74
|
*/
|
|
75
|
-
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>;
|
|
76
76
|
/** A plot's pipeline from what its kind gives: its axis-kind defaults, or a pipeline of its own. */
|
|
77
77
|
static of(defaults: AxisPlotDefaults<any, any> | Pipeline<any, any>): Pipeline<any, any>;
|
|
78
78
|
/** The stage of `phase`, if the pipeline has one. */
|
|
79
|
-
stage(phase: PlotPhase): PhaseStage<TState,
|
|
79
|
+
stage(phase: PlotPhase): PhaseStage<TState, TEnv> | undefined;
|
|
80
80
|
/**
|
|
81
81
|
* A core's run: every stage over the state its `input` (an axis core's
|
|
82
82
|
* props) seeds - or, given `panelState` (one facet panel's part of
|
|
83
83
|
* {@link runData}), only the stages after the data phases, over that state
|
|
84
84
|
* with the input's own props (its box, margins and scales) on top.
|
|
85
85
|
*/
|
|
86
|
-
run: (input: unknown,
|
|
86
|
+
run: (input: unknown, env: TEnv, panelState?: object) => TState;
|
|
87
87
|
/** Whether the pipeline has data phases to run once over every facet panel ({@link runData}). */
|
|
88
88
|
get facets(): boolean;
|
|
89
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
|
}
|
|
@@ -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,37 @@
|
|
|
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
|
+
/** The key a row's context is kept under: no scale reads it, so a copy of a row with a new context is no new row to them. */
|
|
23
|
+
static readonly key: symbol;
|
|
24
|
+
/** Keeps `context` on `row`, for {@link of} to read back. */
|
|
25
|
+
static tag(row: ProcessedRow, context: PlotRowContext): void;
|
|
26
|
+
/** Whether `row` carries a context already. */
|
|
27
|
+
static has(row: unknown): boolean;
|
|
28
|
+
/** A reader of the rows of `state`: the context each carries, else the shared one, for a row no phase tagged. */
|
|
29
|
+
static reader(state: ContextSource): (row: ProcessedRow) => PlotRowContext;
|
|
30
|
+
/**
|
|
31
|
+
* The context every plot gives a processed row: its series; its `x` and `y` - each its series' own value
|
|
32
|
+
* (a stacked row's own, not the running total), else where the transforms put it (a density's estimate, a
|
|
33
|
+
* bin's centre); and its value on the plot's value axis, when that is a number.
|
|
34
|
+
*/
|
|
35
|
+
static shared(state: ContextSource): (row: ProcessedRow) => PlotRowContext;
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
/** The key a row's context is kept under: no scale reads it, so a copy of a row with a new context is no new row to them. */
|
|
28
|
+
static key = KEY;
|
|
29
|
+
/** Keeps `context` on `row`, for {@link of} to read back. */
|
|
30
|
+
static tag(row, context) {
|
|
31
|
+
row[KEY] = context;
|
|
32
|
+
}
|
|
33
|
+
/** Whether `row` carries a context already. */
|
|
34
|
+
static has(row) {
|
|
35
|
+
return row != null && typeof row === 'object' && KEY in row;
|
|
36
|
+
}
|
|
37
|
+
/** A reader of the rows of `state`: the context each carries, else the shared one, for a row no phase tagged. */
|
|
38
|
+
static reader(state) {
|
|
39
|
+
let shared;
|
|
40
|
+
return (row) => {
|
|
41
|
+
if (RowContext.has(row))
|
|
42
|
+
return RowContext.of(row);
|
|
43
|
+
shared ??= RowContext.shared(state);
|
|
44
|
+
return { ...shared(row), row };
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The context every plot gives a processed row: its series; its `x` and `y` - each its series' own value
|
|
49
|
+
* (a stacked row's own, not the running total), else where the transforms put it (a density's estimate, a
|
|
50
|
+
* bin's centre); and its value on the plot's value axis, when that is a number.
|
|
51
|
+
*/
|
|
52
|
+
static shared(state) {
|
|
53
|
+
const processed = state.processedData;
|
|
54
|
+
if (!processed)
|
|
55
|
+
return () => ({});
|
|
56
|
+
const valueAxis = PlotAxes.valueOf(state);
|
|
57
|
+
const placed = ProcessedPositions.of(processed, valueAxis);
|
|
58
|
+
const x = RowContext.#along(state, 'x', RowContext.#stacked(processed, 'x') ?? placed.x);
|
|
59
|
+
const y = RowContext.#along(state, 'y', RowContext.#stacked(processed, 'y') ?? placed.y);
|
|
60
|
+
return (row) => {
|
|
61
|
+
const series = row[SERIES_KEY];
|
|
62
|
+
const at = { x: x(row), y: y(row) };
|
|
63
|
+
const raw = at[valueAxis];
|
|
64
|
+
const value = raw instanceof Date || raw === null || raw === '' ? NaN : Number(raw);
|
|
65
|
+
return {
|
|
66
|
+
...(typeof series === 'string' ? { series } : {}),
|
|
67
|
+
...at,
|
|
68
|
+
...(Number.isFinite(value) ? { value } : {})
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** A stacked row's own value along `axis` - its span, not the running total - or `undefined` with no stack there. */
|
|
73
|
+
static #stacked(processed, axis) {
|
|
74
|
+
const from = processed.channels[`${axis}1`];
|
|
75
|
+
const to = processed.channels[`${axis}2`];
|
|
76
|
+
const stack = axis === 'x' ? 'stackX' : 'stackY';
|
|
77
|
+
if (from === undefined || to === undefined)
|
|
78
|
+
return undefined;
|
|
79
|
+
if (!processed.transforms.some((t) => t.type === stack))
|
|
80
|
+
return undefined;
|
|
81
|
+
const low = resolveAccessor(from);
|
|
82
|
+
const high = resolveAccessor(to);
|
|
83
|
+
return (row) => Number(high(row)) - Number(low(row));
|
|
84
|
+
}
|
|
85
|
+
/** A row's value along `axis`: its series' own channel, else `placed`. */
|
|
86
|
+
static #along(state, axis, placed) {
|
|
87
|
+
const bySeries = new Map((state.resolvedSeries ?? []).flatMap((s) => {
|
|
88
|
+
const accessor = s[axis];
|
|
89
|
+
return accessor === undefined ? [] : [[seriesIdOf(s), resolveAccessor(accessor)]];
|
|
90
|
+
}));
|
|
91
|
+
return (row) => {
|
|
92
|
+
const own = bySeries.get(String(row[SERIES_ID_KEY]));
|
|
93
|
+
const value = own?.(row);
|
|
94
|
+
return value === undefined ? placed(row) : value;
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -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 {};
|
|
@@ -22,7 +22,7 @@ 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 ?? {};
|
|
@@ -35,8 +35,8 @@ export class DataPhase {
|
|
|
35
35
|
given: { x: state.x !== undefined, y: state.y !== undefined },
|
|
36
36
|
discrete: options.discreteAxes
|
|
37
37
|
});
|
|
38
|
-
const seriesColors = ColorRamp.resolve(scales.color, (options.colorOrder ? options.colorOrder(fullSeries) : fullSeries).map((s) => s.name),
|
|
39
|
-
const colorForPath = series ? undefined : DataPhase.#buildPathColors(state,
|
|
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
40
|
// A plot that splits its series by every level colors each one by its path; a nested one by its outermost.
|
|
41
41
|
const colorForSeries = colorForPath && !options.nested
|
|
42
42
|
? DataPhase.#byPath(state, colorForPath, seriesColors)
|
|
@@ -44,7 +44,7 @@ export class DataPhase {
|
|
|
44
44
|
const panelSeries = state.panels && state.panelOf && !series
|
|
45
45
|
? FacetPanels.splitSeries(fullSeries, state.panels, state.panelOf)
|
|
46
46
|
: fullSeries;
|
|
47
|
-
const legend =
|
|
47
|
+
const legend = env.interaction?.legend;
|
|
48
48
|
const resolvedSeries = legend?.withoutOmitted(panelSeries) ?? panelSeries;
|
|
49
49
|
const removedSeries = legend?.removed(panelSeries);
|
|
50
50
|
const baseFor = BasicStyles.of(state.styles, options.segments?.base);
|
|
@@ -75,14 +75,14 @@ export class DataPhase {
|
|
|
75
75
|
...(colorForPath ? { colorForPath } : {}),
|
|
76
76
|
...(gapFillMaps ? { gapFillMaps } : {})
|
|
77
77
|
};
|
|
78
|
-
return options.extend ? options.extend(next,
|
|
78
|
+
return options.extend ? options.extend(next, env) : next;
|
|
79
79
|
};
|
|
80
80
|
/**
|
|
81
81
|
* The color of a path of the plot's `grouping` levels, when `scales.color.depth` reaches past the outermost
|
|
82
82
|
* one: each outermost value its categorical color, and every path down to `depth` a tone of it (see
|
|
83
83
|
* {@link ColorTones.hierarchy}). `undefined` for a grouping of one level, or a depth of 1.
|
|
84
84
|
*/
|
|
85
|
-
static #buildPathColors(state,
|
|
85
|
+
static #buildPathColors(state, env) {
|
|
86
86
|
const depth = state.scales.color?.depth ?? 1;
|
|
87
87
|
const rows = state.data ?? [];
|
|
88
88
|
const levels = Grouping.levels(state.grouping, rows).map((level) => resolveAccessor(level));
|
|
@@ -90,7 +90,7 @@ export class DataPhase {
|
|
|
90
90
|
return undefined;
|
|
91
91
|
const paths = rows.map((row) => levels.map((read) => String(read(row))));
|
|
92
92
|
const outermost = [...new Set(paths.map((path) => path[0]))];
|
|
93
|
-
const colorOf = ColorRamp.resolve(state.scales.color, outermost,
|
|
93
|
+
const colorOf = ColorRamp.resolve(state.scales.color, outermost, env.cfg.palette);
|
|
94
94
|
return ColorTones.hierarchy(paths, depth, (value) => colorOf(value));
|
|
95
95
|
}
|
|
96
96
|
/** A series' color as the color of its path - its name is the key its levels make together. */
|
|
@@ -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,13 +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),
|
|
56
|
-
context: HoverPhase.#contextOf(options.context?.(state))
|
|
60
|
+
number: NumberFormat.of(NumberFormat.displayOf(state.tooltip), env.cfg)
|
|
57
61
|
});
|
|
58
|
-
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);
|
|
59
69
|
return {
|
|
60
70
|
...state,
|
|
61
|
-
hover,
|
|
71
|
+
hover: { ...hover, look },
|
|
62
72
|
hoverPosition: position,
|
|
63
73
|
hoverRows: processed.data,
|
|
64
74
|
...(hitAreas.length > 0 ? { markers: [...(state.markers ?? []), ...hitAreas] } : {})
|
|
@@ -67,10 +77,11 @@ export class HoverPhase {
|
|
|
67
77
|
/**
|
|
68
78
|
* Hover candidates for a plot's own processed rows: each visible row at its
|
|
69
79
|
* position (a stacked row's top, a bin's centre), in its series' color. A
|
|
70
|
-
* 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.
|
|
71
82
|
*/
|
|
72
83
|
static buildProcessedHoverPoints(args) {
|
|
73
|
-
const { processed, colorFor, legendInteraction, label, include,
|
|
84
|
+
const { processed, colorFor, legendInteraction, label, include, decorate } = args;
|
|
74
85
|
const processedPosition = ProcessedPositions.of(processed);
|
|
75
86
|
const position = args.position ?? {
|
|
76
87
|
x: processedPosition.x,
|
|
@@ -79,7 +90,7 @@ export class HoverPhase {
|
|
|
79
90
|
const x = position.x;
|
|
80
91
|
const y = position.y;
|
|
81
92
|
return processed.data
|
|
82
|
-
.filter((d) => !legendInteraction?.
|
|
93
|
+
.filter((d) => !legendInteraction?.isUnhoverable(d[SERIES_KEY]))
|
|
83
94
|
.filter((d) => !include || include(d))
|
|
84
95
|
.map((d) => {
|
|
85
96
|
const row = d;
|
|
@@ -87,7 +98,8 @@ export class HoverPhase {
|
|
|
87
98
|
return {
|
|
88
99
|
x: x(d),
|
|
89
100
|
y: y(d),
|
|
90
|
-
row
|
|
101
|
+
row,
|
|
102
|
+
context: RowContext.of(row),
|
|
91
103
|
label: label(row),
|
|
92
104
|
series: seriesName,
|
|
93
105
|
color: colorFor(seriesName),
|
|
@@ -95,20 +107,13 @@ export class HoverPhase {
|
|
|
95
107
|
};
|
|
96
108
|
});
|
|
97
109
|
}
|
|
98
|
-
/** What the plot knows of a hovered row: its series, and whatever its kind adds. */
|
|
99
|
-
static #contextOf(kind) {
|
|
100
|
-
return (row) => {
|
|
101
|
-
const series = row[SERIES_KEY];
|
|
102
|
-
return { ...(typeof series === 'string' ? { series } : {}), ...kind?.(row) };
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
110
|
/**
|
|
106
111
|
* Which processed rows can be hovered: not a gap (no value where it sits, or
|
|
107
112
|
* filled in by `styles.gaps`), and, while the legend narrows a continuous
|
|
108
113
|
* color to a range, not outside it. A dimmed row stays drawn, never matched.
|
|
109
114
|
*/
|
|
110
|
-
static #hoverable(state,
|
|
111
|
-
const range =
|
|
115
|
+
static #hoverable(state, env, position, valueAxis) {
|
|
116
|
+
const range = env.interaction?.legend?.range;
|
|
112
117
|
const color = state.channels?.color?.accessor;
|
|
113
118
|
return (row) => {
|
|
114
119
|
if (isGapValue(position[valueAxis](row)) || row[GAP_VALUE] !== undefined)
|