@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,15 +1,17 @@
|
|
|
1
1
|
import { Box } from '../margins/Box';
|
|
2
2
|
import { PlotAxes } from '../../phases/data/PlotAxes';
|
|
3
|
+
import type { PlotRowContext } from '../../types/layout/context';
|
|
3
4
|
import type { PlotStylesConfig } from '../../types/configuration/styling';
|
|
4
5
|
import type { ValuesStyle } from '../../types/layout/styles';
|
|
5
6
|
import type { ValueLabelsOptions } from '../../types/phases/styles/phase';
|
|
6
7
|
import type { Series } from '../../types/plots/data/common';
|
|
7
8
|
import type { FontStyle, StrokeStyle } from '../../types/plots/styling';
|
|
8
|
-
import type { TextAnchor, ValueAnchor } from '../../types/plots/constants';
|
|
9
|
+
import type { LabelAnchor, TextAnchor, ValueAnchor } from '../../types/plots/constants';
|
|
9
10
|
import type { BoxAnchors, EdgeBox } from '../../types/layout/box';
|
|
10
11
|
import type { MarginSide } from '../../types/plots/props';
|
|
11
|
-
import type {
|
|
12
|
+
import type { AxisPlotEnv, AxisPlotState, ProcessedData, ProcessedRow } from '../../types/phases';
|
|
12
13
|
import type { TextMarkerConfig } from '../../types/markers/common';
|
|
14
|
+
import type { TextLabelConfig } from '../../types/markers/basic/text';
|
|
13
15
|
/**
|
|
14
16
|
* A plot's value labels: the author's `styles.values` over the plot kind's
|
|
15
17
|
* own defaults, how their text measures, where they are expected to sit
|
|
@@ -20,7 +22,12 @@ export declare class ValueLabels {
|
|
|
20
22
|
#private;
|
|
21
23
|
readonly show: boolean;
|
|
22
24
|
readonly anchor: ValueAnchor;
|
|
23
|
-
|
|
25
|
+
/**
|
|
26
|
+
* A label's text for `value`: the author's `format`, else the kind's, else the value as the display fields ask.
|
|
27
|
+
* `row` is the row it labels, whose context the format reads; `series` names its series where there is no row
|
|
28
|
+
* (a label measured ahead of the rows).
|
|
29
|
+
*/
|
|
30
|
+
readonly format: (value: number, row?: object, series?: string) => string;
|
|
24
31
|
readonly hoverIsolate: boolean;
|
|
25
32
|
readonly font: FontStyle | undefined;
|
|
26
33
|
readonly fontSize: number;
|
|
@@ -33,6 +40,8 @@ export declare class ValueLabels {
|
|
|
33
40
|
/** Where the labels are expected to sit: boxes around their points, on the edges those can reach. */
|
|
34
41
|
readonly reach: EdgeBox[];
|
|
35
42
|
constructor(values: ValuesStyle | undefined, cfg: PlotStylesConfig, options?: Omit<ValueLabelsOptions<never>, 'reach'>, reach?: (labels: ValueLabels) => EdgeBox[]);
|
|
43
|
+
/** The context a label's `format` reads: its row's, with `series` when the row gives none. */
|
|
44
|
+
static contextOf(row: object | undefined, series?: string): PlotRowContext;
|
|
36
45
|
/** A plot's value labels: `values` over `options`, the kind's own defaults, their reach read off `state`. */
|
|
37
46
|
static build<TState>(values: ValuesStyle | undefined, cfg: PlotStylesConfig, options: ValueLabelsOptions<TState>, state: TState): ValueLabels;
|
|
38
47
|
/** The configuration the labels were built under, for a plot kind's own label defaults. */
|
|
@@ -78,7 +87,37 @@ export declare class ValueLabels {
|
|
|
78
87
|
* dims with its row's series, and with `hoverIsolate`, hovering it
|
|
79
88
|
* isolates that series. A row without a series gets the margins only.
|
|
80
89
|
*/
|
|
81
|
-
hooks(
|
|
90
|
+
hooks(env: AxisPlotEnv): Pick<TextMarkerConfig, 'fitMargins' | 'onpointerenter' | 'onpointerleave' | 'styles'>;
|
|
91
|
+
/**
|
|
92
|
+
* Where in a bar a label goes, from the `anchor` of `styles.values`: its `label` anchor, and whether it is beyond
|
|
93
|
+
* the bar. `negative` tells a bar that runs to the left (or down) from its base from one that runs right (or up),
|
|
94
|
+
* which `'tip'`, `'base'` and `'outside'` follow; the others are the edges of the page. A `stacked` bar's label is
|
|
95
|
+
* always in the middle. An anchor the shapes do not read (`'start'`, `'end'`) is taken for `'outside'`, the default.
|
|
96
|
+
*/
|
|
97
|
+
static boxAnchor(anchor: ValueAnchor, shape: {
|
|
98
|
+
isHorizontal: boolean;
|
|
99
|
+
negative?: boolean;
|
|
100
|
+
stacked?: boolean;
|
|
101
|
+
}): {
|
|
102
|
+
anchor: LabelAnchor;
|
|
103
|
+
outside?: boolean;
|
|
104
|
+
};
|
|
105
|
+
/** Whether a label at `anchor` goes to one side or the other of a bar with the sign of its value. */
|
|
106
|
+
static followsSign(anchor: ValueAnchor): boolean;
|
|
107
|
+
/**
|
|
108
|
+
* The `label` the shapes of a plot kind write their value in: this plot's `styles.values` over the `defaults` the kind
|
|
109
|
+
* sets, with what every label shares ({@link hooks}) - its dimming and isolating of a series. A label inside its shape
|
|
110
|
+
* never reaches out of the plot, so only one `outside` has the margins grow to hold it; and it takes the default
|
|
111
|
+
* `fill` only `outside`, for inside it is written in the color that contrasts with its shape.
|
|
112
|
+
*/
|
|
113
|
+
shapeLabel(env: AxisPlotEnv, text: (row: ProcessedRow) => string, defaults?: {
|
|
114
|
+
fill?: string;
|
|
115
|
+
fontSize?: number;
|
|
116
|
+
fontWeight?: FontStyle['fontWeight'];
|
|
117
|
+
anchor?: LabelAnchor;
|
|
118
|
+
outside?: boolean;
|
|
119
|
+
gap?: number;
|
|
120
|
+
}): TextLabelConfig;
|
|
82
121
|
/**
|
|
83
122
|
* A processed row's own value, read through its series' own value channel
|
|
84
123
|
* (`y`, or `x` on a horizontal plot) - what a label shows, even where a
|
|
@@ -6,6 +6,7 @@ import { seriesIdOf } from '../../utils/grouping';
|
|
|
6
6
|
import { isGapValue } from '../../plots/utils/gaps';
|
|
7
7
|
import { PlotAxes } from '../../phases/data/PlotAxes';
|
|
8
8
|
import { NumberFormat } from '../../utils/NumberFormat';
|
|
9
|
+
import { RowContext } from '../../phases/context/RowContext';
|
|
9
10
|
/**
|
|
10
11
|
* A plot's value labels: the author's `styles.values` over the plot kind's
|
|
11
12
|
* own defaults, how their text measures, where they are expected to sit
|
|
@@ -15,6 +16,11 @@ import { NumberFormat } from '../../utils/NumberFormat';
|
|
|
15
16
|
export class ValueLabels {
|
|
16
17
|
show;
|
|
17
18
|
anchor;
|
|
19
|
+
/**
|
|
20
|
+
* A label's text for `value`: the author's `format`, else the kind's, else the value as the display fields ask.
|
|
21
|
+
* `row` is the row it labels, whose context the format reads; `series` names its series where there is no row
|
|
22
|
+
* (a label measured ahead of the rows).
|
|
23
|
+
*/
|
|
18
24
|
format;
|
|
19
25
|
hoverIsolate;
|
|
20
26
|
font;
|
|
@@ -33,12 +39,10 @@ export class ValueLabels {
|
|
|
33
39
|
this.anchor = values?.anchor ?? options.anchor ?? 'outside';
|
|
34
40
|
// The value as the display fields ask (else as it is), which a plot kind's own text builds on.
|
|
35
41
|
const number = NumberFormat.maybe(NumberFormat.displayOf(values), cfg) ?? ((v) => `${v}`);
|
|
36
|
-
const
|
|
37
|
-
this.format =
|
|
38
|
-
? (v,
|
|
39
|
-
:
|
|
40
|
-
? (v, name) => kindFormat(v, name, number)
|
|
41
|
-
: (v) => number(v);
|
|
42
|
+
const own = values?.format ?? options.format;
|
|
43
|
+
this.format = own
|
|
44
|
+
? (v, row, series) => own(v, number, ValueLabels.contextOf(row, series))
|
|
45
|
+
: (v) => number(v);
|
|
42
46
|
this.hoverIsolate = values?.hoverIsolate ?? false;
|
|
43
47
|
this.font = values?.fontStyle;
|
|
44
48
|
this.fontSize = typeof this.font?.fontSize === 'number' ? this.font.fontSize : 12;
|
|
@@ -48,6 +52,11 @@ export class ValueLabels {
|
|
|
48
52
|
this.#cfg = cfg;
|
|
49
53
|
this.reach = (this.show && reach?.(this)) || [];
|
|
50
54
|
}
|
|
55
|
+
/** The context a label's `format` reads: its row's, with `series` when the row gives none. */
|
|
56
|
+
static contextOf(row, series) {
|
|
57
|
+
const context = RowContext.of(row);
|
|
58
|
+
return context.series === undefined && series !== undefined ? { ...context, series } : context;
|
|
59
|
+
}
|
|
51
60
|
/** A plot's value labels: `values` over `options`, the kind's own defaults, their reach read off `state`. */
|
|
52
61
|
static build(values, cfg, options, state) {
|
|
53
62
|
const { reach } = options;
|
|
@@ -134,20 +143,80 @@ export class ValueLabels {
|
|
|
134
143
|
* dims with its row's series, and with `hoverIsolate`, hovering it
|
|
135
144
|
* isolates that series. A row without a series gets the margins only.
|
|
136
145
|
*/
|
|
137
|
-
hooks(
|
|
138
|
-
const interaction =
|
|
146
|
+
hooks(env) {
|
|
147
|
+
const interaction = env.interaction;
|
|
139
148
|
const seriesOf = (d) => d?.[SERIES_KEY] === undefined ? undefined : String(d[SERIES_KEY]);
|
|
140
149
|
const isolate = this.hoverIsolate && interaction;
|
|
141
150
|
return {
|
|
142
151
|
fitMargins: true,
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
152
|
+
styles: {
|
|
153
|
+
fillOpacity: (d) => {
|
|
154
|
+
const series = seriesOf(d);
|
|
155
|
+
return series === undefined ? 1 : (interaction?.fillFor(series)?.fillOpacity ?? 1);
|
|
156
|
+
}
|
|
146
157
|
},
|
|
147
|
-
|
|
148
|
-
? (d) => interaction.isolate(seriesOf(d) ?? null)
|
|
158
|
+
onpointerenter: isolate
|
|
159
|
+
? (_event, d) => interaction.isolate(seriesOf(d) ?? null)
|
|
149
160
|
: undefined,
|
|
150
|
-
|
|
161
|
+
onpointerleave: isolate ? () => interaction.isolate(null) : undefined
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Where in a bar a label goes, from the `anchor` of `styles.values`: its `label` anchor, and whether it is beyond
|
|
166
|
+
* the bar. `negative` tells a bar that runs to the left (or down) from its base from one that runs right (or up),
|
|
167
|
+
* which `'tip'`, `'base'` and `'outside'` follow; the others are the edges of the page. A `stacked` bar's label is
|
|
168
|
+
* always in the middle. An anchor the shapes do not read (`'start'`, `'end'`) is taken for `'outside'`, the default.
|
|
169
|
+
*/
|
|
170
|
+
static boxAnchor(anchor, shape) {
|
|
171
|
+
if (shape.stacked || anchor === 'middle')
|
|
172
|
+
return { anchor: 'middle' };
|
|
173
|
+
// A place in the shape as it is drawn on the page, which no sign moves.
|
|
174
|
+
if (anchor !== 'outside' &&
|
|
175
|
+
anchor !== 'start' &&
|
|
176
|
+
anchor !== 'end' &&
|
|
177
|
+
anchor !== 'tip' &&
|
|
178
|
+
anchor !== 'base') {
|
|
179
|
+
return { anchor };
|
|
180
|
+
}
|
|
181
|
+
const [tip, base] = shape.isHorizontal
|
|
182
|
+
? shape.negative
|
|
183
|
+
? ['left', 'right']
|
|
184
|
+
: ['right', 'left']
|
|
185
|
+
: shape.negative
|
|
186
|
+
? ['bottom', 'top']
|
|
187
|
+
: ['top', 'bottom'];
|
|
188
|
+
if (anchor === 'base')
|
|
189
|
+
return { anchor: base };
|
|
190
|
+
return anchor === 'tip' ? { anchor: tip } : { anchor: tip, outside: true };
|
|
191
|
+
}
|
|
192
|
+
/** Whether a label at `anchor` goes to one side or the other of a bar with the sign of its value. */
|
|
193
|
+
static followsSign(anchor) {
|
|
194
|
+
return anchor === 'outside' || anchor === 'tip' || anchor === 'base';
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* The `label` the shapes of a plot kind write their value in: this plot's `styles.values` over the `defaults` the kind
|
|
198
|
+
* sets, with what every label shares ({@link hooks}) - its dimming and isolating of a series. A label inside its shape
|
|
199
|
+
* never reaches out of the plot, so only one `outside` has the margins grow to hold it; and it takes the default
|
|
200
|
+
* `fill` only `outside`, for inside it is written in the color that contrasts with its shape.
|
|
201
|
+
*/
|
|
202
|
+
shapeLabel(env, text, defaults = {}) {
|
|
203
|
+
const { fitMargins, styles: shared, ...events } = this.hooks(env);
|
|
204
|
+
const { font } = this;
|
|
205
|
+
return {
|
|
206
|
+
...events,
|
|
207
|
+
text,
|
|
208
|
+
anchor: defaults.anchor,
|
|
209
|
+
outside: defaults.outside,
|
|
210
|
+
gap: defaults.gap,
|
|
211
|
+
fitMargins: defaults.outside ? fitMargins : undefined,
|
|
212
|
+
styles: {
|
|
213
|
+
...shared,
|
|
214
|
+
...font,
|
|
215
|
+
// Inside its shape, a label unset is written in the color that reads best on it.
|
|
216
|
+
fill: font?.fill ?? (defaults.outside ? defaults.fill : undefined),
|
|
217
|
+
fontSize: font?.fontSize ?? defaults.fontSize ?? 12,
|
|
218
|
+
fontWeight: font?.fontWeight ?? defaults.fontWeight
|
|
219
|
+
}
|
|
151
220
|
};
|
|
152
221
|
}
|
|
153
222
|
/**
|
|
@@ -229,17 +298,16 @@ export class ValueLabels {
|
|
|
229
298
|
x: (processed.channels.x ?? position.x),
|
|
230
299
|
y: (processed.channels.y2 ?? processed.channels.y ?? topOf),
|
|
231
300
|
grouping: SERIES_ID_KEY,
|
|
232
|
-
text: (d) => format(Number(valueOf(d)),
|
|
301
|
+
text: (d) => format(Number(valueOf(d)), d, nameOf(d)),
|
|
233
302
|
styles: {
|
|
234
303
|
...font,
|
|
235
|
-
|
|
304
|
+
fill: this.fill ?? ((d) => colorOf(d) ?? 'currentColor'),
|
|
236
305
|
fontSize: font?.fontSize ?? 12,
|
|
237
306
|
dx: font?.dx ?? (anchor === 'start' ? 6 : anchor === 'end' ? -6 : 0),
|
|
238
307
|
dy: font?.dy ?? (anchor === 'outside' ? -8 : 0),
|
|
239
308
|
textAnchor: this.textAnchor ?? (anchor === 'start' || anchor === 'end' ? anchor : 'middle'),
|
|
240
309
|
lineAnchor: font?.lineAnchor ?? (anchor === 'outside' ? 'bottom' : 'middle')
|
|
241
310
|
},
|
|
242
|
-
fill: this.fill ? undefined : colorOf,
|
|
243
311
|
declutter: {
|
|
244
312
|
connector: this.strokeStyle,
|
|
245
313
|
aligned: !!end.lane && (anchor === 'start' || anchor === 'end'),
|
|
@@ -297,7 +365,7 @@ export class ValueLabels {
|
|
|
297
365
|
const lo = Number(domain[0]);
|
|
298
366
|
const hi = Number(domain[domain.length - 1]);
|
|
299
367
|
for (const s of series)
|
|
300
|
-
texts.push(format(lo, s.name), format(hi, s.name));
|
|
368
|
+
texts.push(format(lo, undefined, s.name), format(hi, undefined, s.name));
|
|
301
369
|
}
|
|
302
370
|
else {
|
|
303
371
|
for (const s of series) {
|
|
@@ -307,7 +375,7 @@ export class ValueLabels {
|
|
|
307
375
|
for (const d of s.data) {
|
|
308
376
|
const v = Number(y(d));
|
|
309
377
|
if (!Number.isNaN(v))
|
|
310
|
-
texts.push(format(v, s.name));
|
|
378
|
+
texts.push(format(v, undefined, s.name));
|
|
311
379
|
}
|
|
312
380
|
}
|
|
313
381
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Plot, RuleX, RuleY, Text } from 'svelteplot';
|
|
3
3
|
import { TimelineSteps } from './TimelineSteps';
|
|
4
4
|
import { getConfiguration } from '../../configuration/config.svelte';
|
|
5
|
+
import ConfigVars from '../../configuration/ConfigVars.svelte';
|
|
5
6
|
import type { Orientation, TimeValue } from '../../types/layout/timeline';
|
|
6
7
|
|
|
7
8
|
/**
|
|
@@ -54,6 +55,9 @@
|
|
|
54
55
|
);
|
|
55
56
|
</script>
|
|
56
57
|
|
|
58
|
+
<!-- Its colors are the configuration's, with or without a figure around it. -->
|
|
59
|
+
<ConfigVars />
|
|
60
|
+
|
|
57
61
|
<!-- Drawn with the configuration's font even outside a figure's chrome, which would hand it down. -->
|
|
58
62
|
<div style="display: contents" style:font-family={config.font}>
|
|
59
63
|
<Plot
|
|
@@ -89,7 +93,7 @@
|
|
|
89
93
|
{...textOffset}
|
|
90
94
|
fontSize={rule.activeFontSize}
|
|
91
95
|
fontWeight={rule.activeFontWeight}
|
|
92
|
-
fill=
|
|
96
|
+
fill="var(--dct-timeline-active, currentColor)"
|
|
93
97
|
/>
|
|
94
98
|
</Plot>
|
|
95
99
|
</div>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Box } from '../margins/Box';
|
|
2
|
-
import
|
|
2
|
+
import { PlotAxes } from '../../phases/data/PlotAxes';
|
|
3
3
|
import type { ProcessedData, ProcessedRow } from '../../types/phases';
|
|
4
|
-
import type { TooltipAnchorX, TooltipAnchorY } from '../../types/layout/tooltip';
|
|
5
4
|
import type { Series } from '../../types/plots/data/common';
|
|
5
|
+
import type { TooltipAnchorX, TooltipAnchorY } from '../../types/layout/tooltip';
|
|
6
6
|
/** What a tooltip is shown from, each read reactively. */
|
|
7
7
|
export type TooltipInputs = {
|
|
8
8
|
/** The point it sits beside. */
|
|
@@ -46,16 +46,15 @@ export declare class TooltipState {
|
|
|
46
46
|
/** A value as plain text: a date as a locale date, a number as `number` writes it (when given), anything else as itself. */
|
|
47
47
|
static value(value: unknown, number?: (value: number) => string): string;
|
|
48
48
|
/**
|
|
49
|
-
* How a hovered row reads by default, on every plot: its series,
|
|
50
|
-
* plot groups its rows; then where it sits - `category: value` when one
|
|
51
|
-
* axis
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* (the plot's `y` when neither axis holds categories) and the color's - read as it writes them.
|
|
49
|
+
* How a hovered row reads by default, on every plot, from its context (see {@link RowContext}): its series,
|
|
50
|
+
* when the plot groups its rows; then where it sits - `category: value` when one axis is a band of categories,
|
|
51
|
+
* else `x: y` (an axis the transforms spread into a span, a bin's, as `from-to`); then the value its color
|
|
52
|
+
* shows, when that is a number (a heatmap's cells). With `number`, the values - the one on the value axis and
|
|
53
|
+
* the color's - read as it writes them.
|
|
55
54
|
*/
|
|
56
55
|
static default(state: {
|
|
57
56
|
processedData?: ProcessedData;
|
|
58
|
-
resolvedSeries?: Series<
|
|
57
|
+
resolvedSeries?: Series<any>[];
|
|
59
58
|
channels?: {
|
|
60
59
|
grouping?: unknown;
|
|
61
60
|
color?: {
|
|
@@ -2,7 +2,8 @@ import { Box } from '../margins/Box';
|
|
|
2
2
|
import { PlotMargins } from '../margins/PlotMargins.svelte';
|
|
3
3
|
import { resolveAccessor } from '../../utils/accessors';
|
|
4
4
|
import { SERIES_KEY } from '../../phases/transforms/TransformsPhase';
|
|
5
|
-
import {
|
|
5
|
+
import { RowContext } from '../../phases/context/RowContext';
|
|
6
|
+
import { PlotAxes } from '../../phases/data/PlotAxes';
|
|
6
7
|
/** A tooltip anchor as the side of the point the tooltip sits on. */
|
|
7
8
|
const SIDES = {
|
|
8
9
|
left: 'before',
|
|
@@ -69,29 +70,33 @@ export class TooltipState {
|
|
|
69
70
|
return number && typeof value === 'number' ? number(value) : String(value);
|
|
70
71
|
}
|
|
71
72
|
/**
|
|
72
|
-
* How a hovered row reads by default, on every plot: its series,
|
|
73
|
-
* plot groups its rows; then where it sits - `category: value` when one
|
|
74
|
-
* axis
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
* (the plot's `y` when neither axis holds categories) and the color's - read as it writes them.
|
|
73
|
+
* How a hovered row reads by default, on every plot, from its context (see {@link RowContext}): its series,
|
|
74
|
+
* when the plot groups its rows; then where it sits - `category: value` when one axis is a band of categories,
|
|
75
|
+
* else `x: y` (an axis the transforms spread into a span, a bin's, as `from-to`); then the value its color
|
|
76
|
+
* shows, when that is a number (a heatmap's cells). With `number`, the values - the one on the value axis and
|
|
77
|
+
* the color's - read as it writes them.
|
|
78
78
|
*/
|
|
79
79
|
static default(state, number) {
|
|
80
80
|
const processed = state.processedData;
|
|
81
81
|
if (!processed)
|
|
82
82
|
return () => '';
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
// With no band axis, the value is the y.
|
|
86
|
-
const valueY = TooltipState.#axisText(processed, 'y', number);
|
|
83
|
+
const valueAxis = PlotAxes.valueOf(state);
|
|
84
|
+
const contextOf = RowContext.reader(state);
|
|
87
85
|
const bandX = state.axes?.bands.includes('x') ?? false;
|
|
88
86
|
const bandY = state.axes?.bands.includes('y') ?? false;
|
|
89
|
-
const
|
|
87
|
+
const along = (axis) => {
|
|
88
|
+
const span = TooltipState.#spanText(processed, axis, number);
|
|
89
|
+
const measured = axis === valueAxis && !state.axes?.bands.includes(axis);
|
|
90
|
+
return (row) => span ? span(row) : TooltipState.value(contextOf(row)[axis], measured ? number : undefined);
|
|
91
|
+
};
|
|
92
|
+
const x = along('x');
|
|
93
|
+
const y = along('y');
|
|
94
|
+
const valueOf = (row) => TooltipState.value(contextOf(row).value, number);
|
|
90
95
|
const position = bandX && !bandY
|
|
91
|
-
? (row) => `${x(row)}: ${
|
|
96
|
+
? (row) => `${x(row)}: ${valueOf(row)}`
|
|
92
97
|
: bandY && !bandX
|
|
93
|
-
? (row) => `${y(row)}: ${
|
|
94
|
-
: (row) => `${x(row)}: ${
|
|
98
|
+
? (row) => `${y(row)}: ${valueOf(row)}`
|
|
99
|
+
: (row) => `${x(row)}: ${y(row)}`;
|
|
95
100
|
const grouped = state.channels?.grouping !== undefined;
|
|
96
101
|
const color = state.channels?.color;
|
|
97
102
|
const colorName = typeof color?.source === 'string' ? color.source : 'color';
|
|
@@ -106,26 +111,20 @@ export class TooltipState {
|
|
|
106
111
|
};
|
|
107
112
|
}
|
|
108
113
|
/**
|
|
109
|
-
* How
|
|
110
|
-
* the
|
|
114
|
+
* How an axis the transforms spread into a span reads on a processed row - a bin's edges as `from-to` - or
|
|
115
|
+
* `undefined` when the axis has a value of its own or is a stack's (whose own value the context gives).
|
|
111
116
|
*/
|
|
112
|
-
static #
|
|
117
|
+
static #spanText(processed, axis, number) {
|
|
113
118
|
const { channels, transforms } = processed;
|
|
114
|
-
const read = (channel) => resolveAccessor(channel);
|
|
115
|
-
const point = channels[axis];
|
|
116
|
-
if (point !== undefined) {
|
|
117
|
-
const value = read(point);
|
|
118
|
-
return (row) => TooltipState.value(value(row), number);
|
|
119
|
-
}
|
|
120
119
|
const low = channels[`${axis}1`];
|
|
121
120
|
const high = channels[`${axis}2`];
|
|
122
|
-
if (low === undefined || high === undefined)
|
|
123
|
-
return
|
|
121
|
+
if (channels[axis] !== undefined || low === undefined || high === undefined)
|
|
122
|
+
return undefined;
|
|
123
|
+
if (transforms.some((t) => t.type === STACKS[axis]))
|
|
124
|
+
return undefined;
|
|
125
|
+
const read = (channel) => resolveAccessor(channel);
|
|
124
126
|
const from = read(low);
|
|
125
127
|
const to = read(high);
|
|
126
|
-
if (transforms.some((t) => t.type === STACKS[axis])) {
|
|
127
|
-
return (row) => TooltipState.value(Number(to(row)) - Number(from(row)), number);
|
|
128
|
-
}
|
|
129
128
|
return (row) => `${TooltipState.value(from(row), number)}-${TooltipState.value(to(row), number)}`;
|
|
130
129
|
}
|
|
131
130
|
}
|
|
@@ -6,6 +6,7 @@ export class MarkerKinds {
|
|
|
6
6
|
static traits = {
|
|
7
7
|
area: { clip: true, drawsRows: true, legendSymbol: 'area' },
|
|
8
8
|
arrow: { clip: false, drawsRows: true },
|
|
9
|
+
band: { clip: true, drawsRows: false, legendSymbol: 'rect' },
|
|
9
10
|
bar: { clip: true, drawsRows: true, legendSymbol: 'bar' },
|
|
10
11
|
bollinger: { clip: true, drawsRows: true, legendSymbol: 'line' },
|
|
11
12
|
brush: { clip: false, drawsRows: false },
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { MarkerEvents } from '../utils/MarkerEvents';
|
|
2
3
|
import { AreaX, AreaY } from 'svelteplot';
|
|
3
4
|
import { usePlot } from '../../layout/plot/usePlot';
|
|
4
5
|
import { MarkerChannels } from '../utils/MarkerChannels';
|
|
@@ -12,6 +13,7 @@
|
|
|
12
13
|
* a band, the area runs from zero up to its own value.
|
|
13
14
|
*/
|
|
14
15
|
let { marker }: { marker: AreaMarkerConfig } = $props();
|
|
16
|
+
const events = MarkerEvents.use(() => marker);
|
|
15
17
|
|
|
16
18
|
const plot = usePlot();
|
|
17
19
|
const isHorizontal = $derived(plot.axes?.isHorizontal ?? false);
|
|
@@ -36,6 +38,7 @@
|
|
|
36
38
|
|
|
37
39
|
{#snippet area(rows: typeof data, fillOpacity: number | undefined)}
|
|
38
40
|
<AreaMark
|
|
41
|
+
{...events.props}
|
|
39
42
|
data={rows}
|
|
40
43
|
x={marker.x}
|
|
41
44
|
y={marker.y}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { RowStyle } from '../utils/RowStyle';
|
|
3
|
+
import { MarkerEvents } from '../utils/MarkerEvents';
|
|
2
4
|
import { Arrow } from 'svelteplot';
|
|
3
5
|
import { usePlot } from '../../layout/plot/usePlot';
|
|
4
6
|
import { RowStroke } from '../utils/RowStroke';
|
|
@@ -12,11 +14,12 @@
|
|
|
12
14
|
* last, so such an arrow is placed in pixels instead.
|
|
13
15
|
*/
|
|
14
16
|
let { marker }: { marker: ArrowMarkerConfig } = $props();
|
|
17
|
+
const events = MarkerEvents.use(() => marker);
|
|
15
18
|
|
|
16
19
|
const plot = usePlot().svelteplot;
|
|
17
20
|
const data = $derived(marker.data ?? []);
|
|
18
|
-
/** Each row's
|
|
19
|
-
const row = $derived(RowStroke.of(marker
|
|
21
|
+
/** Each row's stroke: the marker's `styles`, which can be functions of the row. */
|
|
22
|
+
const row = $derived(RowStroke.of(marker.styles, data, { stroke: 'currentColor' }));
|
|
20
23
|
|
|
21
24
|
type Row = Record<string, unknown>;
|
|
22
25
|
type Channel = string | number | ((d: never) => unknown) | undefined;
|
|
@@ -51,6 +54,7 @@
|
|
|
51
54
|
</script>
|
|
52
55
|
|
|
53
56
|
<Arrow
|
|
57
|
+
{...events.props}
|
|
54
58
|
data={placed}
|
|
55
59
|
x1={onBand ? own('__x1') : marker.x1}
|
|
56
60
|
y1={onBand ? own('__y1') : marker.y1}
|
|
@@ -59,9 +63,9 @@
|
|
|
59
63
|
bend={marker.bend}
|
|
60
64
|
headAngle={marker.headAngle ?? 60}
|
|
61
65
|
headLength={marker.headLength ?? 8}
|
|
62
|
-
inset={marker.inset ?? 0}
|
|
63
|
-
insetStart={marker.insetStart}
|
|
64
|
-
insetEnd={marker.insetEnd}
|
|
66
|
+
inset={RowStyle.field(marker.styles?.inset) ?? 0}
|
|
67
|
+
insetStart={RowStyle.field(marker.styles?.insetStart)}
|
|
68
|
+
insetEnd={RowStyle.field(marker.styles?.insetEnd)}
|
|
65
69
|
sweep={marker.sweep}
|
|
66
70
|
stroke={row.stroke}
|
|
67
71
|
strokeWidth={row.strokeWidth}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { usePlot } from '../../layout/plot/usePlot';
|
|
3
|
+
import { getConfiguration } from '../../configuration/config.svelte';
|
|
4
|
+
import { MarkerEvents } from '../utils/MarkerEvents';
|
|
5
|
+
import { RowStyle } from '../utils/RowStyle';
|
|
6
|
+
import { Bands, type Band } from './Bands';
|
|
7
|
+
import type { BandMarkerConfig } from '../../types/markers/common';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Renders one `'band'` marker: a rectangle over the band of each category it names, across the whole of the
|
|
11
|
+
* other axis. Nothing on an axis that is not a band scale. It takes the pointer only with a handler of its own,
|
|
12
|
+
* so a band behind the plot's shapes does not take their hover.
|
|
13
|
+
*/
|
|
14
|
+
const { marker }: { marker: BandMarkerConfig } = $props();
|
|
15
|
+
const cfg = $derived(getConfiguration());
|
|
16
|
+
const events = MarkerEvents.use(() => marker);
|
|
17
|
+
const plot = usePlot().svelteplot;
|
|
18
|
+
|
|
19
|
+
const bands = $derived(Bands.of(marker));
|
|
20
|
+
const rows = $derived(marker.data ?? []);
|
|
21
|
+
const styles = $derived({ ...cfg.band, ...marker.styles });
|
|
22
|
+
const scale = $derived(plot.scales[marker.axis]);
|
|
23
|
+
const across = $derived(plot.scales[marker.axis === 'x' ? 'y' : 'x']);
|
|
24
|
+
|
|
25
|
+
/** The pixels the other axis spans, lowest first. */
|
|
26
|
+
const extent = $derived.by((): [number, number] => {
|
|
27
|
+
const range = across?.fn?.range?.() as number[] | undefined;
|
|
28
|
+
if (!range || range.length < 2) return [0, 0];
|
|
29
|
+
const [a, b] = [Number(range[0]), Number(range[range.length - 1])];
|
|
30
|
+
return [Math.min(a, b), Math.max(a, b)];
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/** Where a band is drawn: its slice of the band along the axis, the other axis' whole span across it. */
|
|
34
|
+
function boxOf(band: Band) {
|
|
35
|
+
const bandwidth = scale.fn.bandwidth?.() ?? 0;
|
|
36
|
+
const start = Number(scale.fn(band.category as never));
|
|
37
|
+
const from = start + band.slice.start * bandwidth;
|
|
38
|
+
const size = Math.max(0, bandwidth * (1 - band.slice.start - band.slice.end));
|
|
39
|
+
const [low, high] = extent;
|
|
40
|
+
return marker.axis === 'x'
|
|
41
|
+
? { x: from, y: low, width: size, height: high - low }
|
|
42
|
+
: { x: low, y: from, width: high - low, height: size };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** A color of `styles` for the row: a value, the field of the rows it names, or a function of the row. */
|
|
46
|
+
const colorOf = (style: unknown, row: unknown) => RowStyle.colorOf(style, rows)?.(row);
|
|
47
|
+
/** A number of `styles` for the row: a value, the field of the rows it names, or a function of the row. */
|
|
48
|
+
const numberOf = (style: unknown, row: unknown): number | undefined => {
|
|
49
|
+
const read = RowStyle.field(style as never) as unknown;
|
|
50
|
+
const value = typeof read === 'function' ? (read as (row: unknown) => unknown)(row) : read;
|
|
51
|
+
return value == null ? undefined : Number(value);
|
|
52
|
+
};
|
|
53
|
+
</script>
|
|
54
|
+
|
|
55
|
+
{#if scale?.type === 'band'}
|
|
56
|
+
<g class="band" pointer-events={events.any ? undefined : 'none'}>
|
|
57
|
+
{#each bands as band (band.category instanceof Date ? +band.category : band.category)}
|
|
58
|
+
{@const box = boxOf(band)}
|
|
59
|
+
{@const radius = numberOf(styles.borderRadius, band.row)}
|
|
60
|
+
<rect
|
|
61
|
+
{...box}
|
|
62
|
+
rx={radius}
|
|
63
|
+
ry={radius}
|
|
64
|
+
fill={colorOf(styles.fill, band.row)}
|
|
65
|
+
fill-opacity={numberOf(styles.fillOpacity, band.row)}
|
|
66
|
+
stroke={colorOf(styles.stroke, band.row)}
|
|
67
|
+
stroke-width={numberOf(styles.strokeWidth, band.row)}
|
|
68
|
+
stroke-opacity={numberOf(styles.strokeOpacity, band.row)}
|
|
69
|
+
stroke-dasharray={colorOf(styles.strokeDasharray, band.row)}
|
|
70
|
+
{...events.forRow(band.row, band.index)}
|
|
71
|
+
/>
|
|
72
|
+
{/each}
|
|
73
|
+
</g>
|
|
74
|
+
{/if}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BandMarkerConfig } from '../../types/markers/common';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
marker: BandMarkerConfig;
|
|
4
|
+
};
|
|
5
|
+
declare const BandMarker: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
6
|
+
type BandMarker = ReturnType<typeof BandMarker>;
|
|
7
|
+
export default BandMarker;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AxisValue } from '../../types/layout/mapping';
|
|
2
|
+
import type { BandSlice } from '../../types/layout/hover';
|
|
3
|
+
import type { BandMarkerConfig } from '../../types/markers/common';
|
|
4
|
+
/** One band to draw: its category, the part of it filled, and the first row that names it. */
|
|
5
|
+
export type Band = {
|
|
6
|
+
category: AxisValue;
|
|
7
|
+
slice: BandSlice;
|
|
8
|
+
row: unknown;
|
|
9
|
+
index: number;
|
|
10
|
+
};
|
|
11
|
+
/** The bands a `band` marker draws, one per category its rows (or its `value`) name, in the order they first come. */
|
|
12
|
+
export declare class Bands {
|
|
13
|
+
#private;
|
|
14
|
+
/** The marker's bands. Rows that share a category share one band, which fills what all of their slices do. */
|
|
15
|
+
static of(marker: Pick<BandMarkerConfig, 'value' | 'slice' | 'data'>): Band[];
|
|
16
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { resolveAccessor } from '../../utils/accessors';
|
|
2
|
+
/** The bands a `band` marker draws, one per category its rows (or its `value`) name, in the order they first come. */
|
|
3
|
+
export class Bands {
|
|
4
|
+
static #WHOLE = { start: 0, end: 0 };
|
|
5
|
+
/** The marker's bands. Rows that share a category share one band, which fills what all of their slices do. */
|
|
6
|
+
static of(marker) {
|
|
7
|
+
const { rows, categoryOf } = Bands.#rowsOf(marker);
|
|
8
|
+
const sliceOf = Bands.#sliceOf(marker.slice);
|
|
9
|
+
const bands = new Map();
|
|
10
|
+
rows.forEach((row, index) => {
|
|
11
|
+
const category = categoryOf(row);
|
|
12
|
+
if (category == null)
|
|
13
|
+
return;
|
|
14
|
+
const key = category instanceof Date ? +category : category;
|
|
15
|
+
const slice = sliceOf(row);
|
|
16
|
+
const band = bands.get(key);
|
|
17
|
+
if (!band) {
|
|
18
|
+
bands.set(key, { category, slice, row, index });
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
// What either one fills: the least left out at each end.
|
|
22
|
+
band.slice = {
|
|
23
|
+
start: Math.min(band.slice.start, slice.start),
|
|
24
|
+
end: Math.min(band.slice.end, slice.end)
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
return [...bands.values()];
|
|
28
|
+
}
|
|
29
|
+
/** The rows a marker draws from, and the category of each: its `data` and `value`, or its `value`'s own. */
|
|
30
|
+
static #rowsOf(marker) {
|
|
31
|
+
const { value, data } = marker;
|
|
32
|
+
if (data) {
|
|
33
|
+
const read = resolveAccessor(value);
|
|
34
|
+
return { rows: data, categoryOf: read };
|
|
35
|
+
}
|
|
36
|
+
const values = (Array.isArray(value) ? value : [value]);
|
|
37
|
+
return { rows: values, categoryOf: (row) => row };
|
|
38
|
+
}
|
|
39
|
+
/** Each row's slice: the marker's own, or a function of the row's; the whole band when it gives none. */
|
|
40
|
+
static #sliceOf(slice) {
|
|
41
|
+
const whole = Bands.#WHOLE;
|
|
42
|
+
const read = typeof slice === 'function' ? slice : () => slice;
|
|
43
|
+
return (row) => {
|
|
44
|
+
const own = read(row);
|
|
45
|
+
return own ? { start: own.start ?? 0, end: own.end ?? 0 } : whole;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|