@fundar/data-chart-telling 1.1.0 → 1.3.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 +45 -0
- package/README.md +8 -7
- package/dist/configuration/config.svelte.d.ts +1 -1
- package/dist/configuration/config.svelte.js +177 -100
- package/dist/configuration/themes/index.d.ts +5 -1428
- package/dist/index.d.ts +23 -14
- package/dist/index.js +20 -11
- package/dist/layout/base/BasePlotLayout.svelte +115 -50
- package/dist/layout/base/BasePlotLayout.svelte.d.ts +1 -38
- package/dist/layout/coordinates/CoordinatesLayout.svelte +42 -40
- package/dist/layout/coordinates/CoordinatesLayout.svelte.d.ts +0 -2
- package/dist/layout/coordinates/ProjectionZoom.svelte +48 -0
- package/dist/layout/coordinates/ProjectionZoom.svelte.d.ts +10 -0
- package/dist/layout/coordinates/ZoomedProjection.d.ts +11 -0
- package/dist/layout/coordinates/ZoomedProjection.js +24 -0
- package/dist/layout/coordinates/camera.svelte.js +11 -8
- package/dist/layout/coordinates/projections/argentina.js +1 -1
- package/dist/layout/coordinates/projections/fit.d.ts +1 -1
- package/dist/layout/coordinates/projections/fit.js +1 -1
- package/dist/layout/coordinates/zoom.svelte.d.ts +4 -5
- package/dist/layout/coordinates/zoom.svelte.js +4 -5
- package/dist/layout/facet/FacetLayout.svelte +1 -1
- package/dist/layout/facet/config.js +1 -1
- package/dist/layout/facet/scope.d.ts +40 -0
- package/dist/layout/facet/scope.js +104 -0
- package/dist/layout/figure/Figure.svelte +2 -0
- package/dist/layout/geometry/GeometryLayout.svelte +14 -9
- package/dist/layout/geometry/GeometryLayout.svelte.d.ts +0 -3
- package/dist/layout/geometry/MarkerOffset.svelte +28 -0
- package/dist/layout/geometry/MarkerOffset.svelte.d.ts +13 -0
- package/dist/layout/grid/GridCell.svelte +6 -8
- package/dist/layout/legend/ContinuousSection.svelte +44 -9
- package/dist/layout/legend/DiscreteBadgeItem.svelte +2 -2
- package/dist/layout/legend/DiscreteSection.svelte +2 -2
- package/dist/layout/legend/DiscreteSymbolIcon.svelte +39 -15
- package/dist/layout/legend/LegendChannels.js +36 -12
- package/dist/layout/legend/LegendLayout.svelte +9 -1
- package/dist/layout/legend/LegendState.svelte.d.ts +4 -0
- package/dist/layout/legend/LegendState.svelte.js +23 -8
- package/dist/layout/legend/SizeSection.svelte +1 -1
- package/dist/layout/margins/PlotMargins.svelte.d.ts +2 -5
- package/dist/layout/margins/PlotMargins.svelte.js +35 -8
- package/dist/layout/plot/Plot.svelte +22 -2
- package/dist/layout/plot/Slice.d.ts +5 -1
- package/dist/layout/plot/Slice.js +14 -4
- package/dist/layout/scales/NiceTicks.d.ts +3 -0
- package/dist/layout/scales/NiceTicks.js +4 -0
- package/dist/layout/scales/ScalesLayout.svelte +93 -7
- package/dist/layout/scales/ScalesLayout.svelte.d.ts +5 -0
- package/dist/layout/scales/SveltePlotScale.d.ts +2 -2
- package/dist/layout/scales/SveltePlotScale.js +13 -6
- package/dist/layout/scales/TickLabels.d.ts +32 -0
- package/dist/layout/scales/TickLabels.js +55 -0
- package/dist/layout/styles/StylesLayout.svelte +2 -2
- package/dist/layout/styles/ValueLabels.d.ts +33 -5
- package/dist/layout/styles/ValueLabels.js +80 -21
- package/dist/layout/timeline/TimelineLayout.svelte +1 -1
- package/dist/layout/tooltip/Tooltip.svelte +4 -4
- package/dist/layout/tooltip/Tooltip.svelte.d.ts +4 -4
- package/dist/layout/tooltip/TooltipState.svelte.js +1 -1
- package/dist/markers/MarkerKinds.d.ts +5 -0
- package/dist/markers/MarkerKinds.js +1 -0
- package/dist/markers/area/AreaMarker.svelte +15 -63
- package/dist/markers/arrow/ArrowMarker.svelte +51 -9
- package/dist/markers/bar/BarMarker.svelte +8 -4
- package/dist/markers/bollinger/BollingerMarker.svelte +33 -18
- package/dist/markers/box/BoxMarker.svelte +40 -9
- package/dist/markers/delta/Delta.d.ts +6 -1
- package/dist/markers/delta/Delta.js +16 -1
- package/dist/markers/delta/DeltaMarker.svelte +9 -87
- package/dist/markers/delta/DeltaPoint.svelte +97 -0
- package/dist/markers/delta/DeltaPoint.svelte.d.ts +29 -0
- package/dist/markers/dot/DotMarker.svelte +24 -27
- package/dist/markers/image/ImageMarker.svelte +17 -12
- package/dist/markers/inset/InsetMarker.svelte +2 -2
- package/dist/markers/line/LineMarker.svelte +1 -0
- package/dist/markers/link/LinkMarker.svelte +174 -29
- package/dist/markers/regression/RegressionMarker.svelte +16 -33
- package/dist/markers/rule/RuleMarker.svelte +14 -5
- package/dist/markers/text/Declutter.d.ts +4 -0
- package/dist/markers/text/Declutter.js +26 -11
- package/dist/markers/text/TextMarker.svelte +91 -48
- package/dist/markers/tick/TickMarker.svelte +27 -25
- package/dist/markers/utils/MarkerChannels.d.ts +24 -0
- package/dist/markers/utils/MarkerChannels.js +42 -7
- package/dist/markers/utils/RowOffset.d.ts +23 -0
- package/dist/markers/utils/RowOffset.js +23 -0
- package/dist/markers/utils/RowOffsetMarks.svelte +30 -0
- package/dist/markers/utils/RowOffsetMarks.svelte.d.ts +33 -0
- package/dist/markers/utils/RowStroke.d.ts +31 -0
- package/dist/markers/utils/RowStroke.js +28 -0
- package/dist/markers/violin/ViolinMarker.svelte +75 -0
- package/dist/markers/violin/ViolinMarker.svelte.d.ts +7 -0
- package/dist/markers/violin/ViolinProfiles.d.ts +29 -0
- package/dist/markers/violin/ViolinProfiles.js +55 -0
- package/dist/markers/waffle/WaffleMarker.svelte +17 -37
- package/dist/phases/Pipeline.d.ts +5 -0
- package/dist/phases/Pipeline.js +5 -0
- package/dist/phases/data/DataPhase.js +3 -3
- package/dist/phases/data/PlotAxes.d.ts +10 -0
- package/dist/phases/data/PlotAxes.js +14 -1
- package/dist/phases/facet/FacetPanels.d.ts +1 -0
- package/dist/phases/facet/FacetPanels.js +1 -0
- package/dist/phases/facet/FacetPhase.d.ts +2 -1
- package/dist/phases/facet/FacetPhase.js +19 -4
- package/dist/phases/mapping/MappingPhase.js +1 -1
- package/dist/phases/markers/MarkersPhase.js +2 -1
- package/dist/phases/scales/CategoryOrder.d.ts +23 -0
- package/dist/phases/scales/CategoryOrder.js +73 -0
- package/dist/phases/scales/ScalesPhase.js +21 -7
- package/dist/phases/sharedScales/SharedScalesPhase.d.ts +3 -2
- package/dist/phases/sharedScales/SharedScalesPhase.js +5 -2
- package/dist/phases/statistics/Statistics.d.ts +10 -6
- package/dist/phases/statistics/Statistics.js +20 -10
- package/dist/phases/statistics/StatisticsPhase.js +16 -3
- package/dist/phases/statistics/methods/BollingerStatistic.d.ts +1 -1
- package/dist/phases/statistics/methods/BollingerStatistic.js +13 -11
- package/dist/phases/statistics/methods/BoxStatistic.d.ts +1 -1
- package/dist/phases/statistics/methods/BoxStatistic.js +14 -12
- package/dist/phases/statistics/methods/Density2dStatistic.d.ts +1 -1
- package/dist/phases/statistics/methods/Density2dStatistic.js +13 -11
- package/dist/phases/statistics/methods/DensityStatistic.d.ts +1 -1
- package/dist/phases/statistics/methods/DensityStatistic.js +11 -9
- package/dist/phases/statistics/methods/DeviationStatistic.d.ts +8 -0
- package/dist/phases/statistics/methods/DeviationStatistic.js +111 -0
- package/dist/phases/statistics/methods/MovingAverageStatistic.d.ts +1 -1
- package/dist/phases/statistics/methods/MovingAverageStatistic.js +11 -9
- package/dist/phases/statistics/methods/RegressionStatistic.d.ts +1 -1
- package/dist/phases/statistics/methods/RegressionStatistic.js +16 -14
- package/dist/phases/transforms/ProcessedPositions.js +1 -1
- package/dist/phases/transforms/TransformsPhase.js +49 -3
- package/dist/phases/transforms/ValueSelection.d.ts +30 -0
- package/dist/phases/transforms/ValueSelection.js +53 -0
- package/dist/plots/{heatmap → correlation/heatmap}/Plot.svelte +5 -2
- package/dist/plots/{heatmap → correlation/heatmap}/Plot.svelte.d.ts +2 -2
- package/dist/plots/{heatmap → correlation/heatmap}/defaults.d.ts +2 -2
- package/dist/plots/{heatmap → correlation/heatmap}/defaults.js +5 -5
- package/dist/plots/{heatmap → correlation/heatmap}/markers.d.ts +4 -4
- package/dist/plots/{heatmap → correlation/heatmap}/markers.js +3 -3
- package/dist/plots/{scatter → correlation/scatter}/Plot.svelte +5 -2
- package/dist/plots/{scatter → correlation/scatter}/Plot.svelte.d.ts +2 -2
- package/dist/plots/{scatter → correlation/scatter}/defaults.d.ts +2 -2
- package/dist/plots/{scatter → correlation/scatter}/defaults.js +4 -4
- package/dist/plots/{scatter → correlation/scatter}/markers.d.ts +4 -4
- package/dist/plots/{scatter → correlation/scatter}/markers.js +3 -3
- package/dist/plots/{box → distribution/box}/BoxSummaries.d.ts +2 -2
- package/dist/plots/{box → distribution/box}/BoxSummaries.js +6 -6
- package/dist/plots/{box → distribution/box}/Plot.svelte +2 -2
- package/dist/plots/{box → distribution/box}/Plot.svelte.d.ts +2 -2
- package/dist/plots/{box → distribution/box}/defaults.d.ts +2 -2
- package/dist/plots/{box → distribution/box}/defaults.js +1 -1
- package/dist/plots/{box → distribution/box}/markers.d.ts +2 -2
- package/dist/plots/distribution/density/Plot.svelte +45 -0
- package/dist/plots/distribution/density/Plot.svelte.d.ts +26 -0
- package/dist/plots/distribution/density/defaults.d.ts +9 -0
- package/dist/plots/distribution/density/defaults.js +29 -0
- package/dist/plots/distribution/density/markers.d.ts +9 -0
- package/dist/plots/distribution/density/markers.js +42 -0
- package/dist/plots/{histogram → distribution/histogram}/Plot.svelte +2 -2
- package/dist/plots/{histogram → distribution/histogram}/Plot.svelte.d.ts +2 -2
- package/dist/plots/{histogram → distribution/histogram}/defaults.d.ts +2 -2
- package/dist/plots/{histogram → distribution/histogram}/defaults.js +3 -3
- package/dist/plots/{histogram → distribution/histogram}/markers.d.ts +3 -3
- package/dist/plots/{histogram → distribution/histogram}/markers.js +5 -5
- package/dist/plots/{pyramid → distribution/pyramid}/Plot.svelte +5 -2
- package/dist/plots/{pyramid → distribution/pyramid}/Plot.svelte.d.ts +2 -2
- package/dist/plots/{pyramid → distribution/pyramid}/defaults.d.ts +2 -2
- package/dist/plots/{pyramid → distribution/pyramid}/defaults.js +6 -6
- package/dist/plots/{pyramid → distribution/pyramid}/markers.d.ts +4 -4
- package/dist/plots/{pyramid → distribution/pyramid}/markers.js +6 -6
- package/dist/plots/distribution/violin/Plot.svelte +45 -0
- package/dist/plots/distribution/violin/Plot.svelte.d.ts +26 -0
- package/dist/plots/distribution/violin/defaults.d.ts +10 -0
- package/dist/plots/distribution/violin/defaults.js +58 -0
- package/dist/plots/distribution/violin/markers.d.ts +10 -0
- package/dist/plots/distribution/violin/markers.js +71 -0
- package/dist/plots/{area → evolution/area}/Plot.svelte +2 -2
- package/dist/plots/{area → evolution/area}/Plot.svelte.d.ts +2 -2
- package/dist/plots/{area → evolution/area}/defaults.d.ts +2 -2
- package/dist/plots/{area → evolution/area}/defaults.js +2 -0
- package/dist/plots/{area → evolution/area}/markers.d.ts +2 -2
- package/dist/plots/{area → evolution/area}/markers.js +1 -1
- package/dist/plots/{line → evolution/line}/Plot.svelte +2 -2
- package/dist/plots/{line → evolution/line}/Plot.svelte.d.ts +2 -2
- package/dist/plots/{line → evolution/line}/defaults.d.ts +2 -2
- package/dist/plots/{line → evolution/line}/defaults.js +2 -0
- package/dist/plots/{line → evolution/line}/markers.d.ts +11 -8
- package/dist/plots/{line → evolution/line}/markers.js +6 -4
- package/dist/plots/evolution/slope/Plot.svelte +42 -0
- package/dist/plots/evolution/slope/Plot.svelte.d.ts +26 -0
- package/dist/plots/evolution/slope/defaults.d.ts +8 -0
- package/dist/plots/evolution/slope/defaults.js +31 -0
- package/dist/plots/evolution/slope/markers.d.ts +16 -0
- package/dist/plots/evolution/slope/markers.js +79 -0
- package/dist/plots/evolution/sparkline/Plot.svelte +45 -0
- package/dist/plots/evolution/sparkline/Plot.svelte.d.ts +26 -0
- package/dist/plots/evolution/sparkline/defaults.d.ts +7 -0
- package/dist/plots/evolution/sparkline/defaults.js +23 -0
- package/dist/plots/evolution/sparkline/markers.d.ts +7 -0
- package/dist/plots/evolution/sparkline/markers.js +56 -0
- package/dist/plots/{geo → map/geo}/Core.svelte +11 -10
- package/dist/plots/{geo → map/geo}/Core.svelte.d.ts +1 -1
- package/dist/plots/map/geo/GeoFeatures.svelte.d.ts +9 -0
- package/dist/plots/map/geo/GeoFeatures.svelte.js +55 -0
- package/dist/plots/map/geo/GeoGeometry.d.ts +27 -0
- package/dist/plots/map/geo/GeoGeometry.js +142 -0
- package/dist/plots/map/geo/GeoSegments.d.ts +16 -0
- package/dist/plots/map/geo/GeoSegments.js +23 -0
- package/dist/plots/{geo → map/geo}/Plot.svelte +10 -10
- package/dist/plots/{geo → map/geo}/Plot.svelte.d.ts +2 -2
- package/dist/plots/{geo → map/geo}/defaults.d.ts +2 -2
- package/dist/plots/{geo → map/geo}/defaults.js +1 -1
- package/dist/plots/{geo → map/geo}/phases/data.d.ts +1 -1
- package/dist/plots/{geo → map/geo}/phases/data.js +7 -6
- package/dist/plots/{geo → map/geo}/phases/hover.d.ts +1 -1
- package/dist/plots/{geo → map/geo}/phases/hover.js +2 -2
- package/dist/plots/{geo → map/geo}/phases/markers.d.ts +1 -1
- package/dist/plots/{geo → map/geo}/phases/markers.js +6 -10
- package/dist/plots/{geo → map/geo}/phases/scales.d.ts +2 -2
- package/dist/plots/{geo → map/geo}/phases/scales.js +28 -12
- package/dist/plots/{geo → map/geo}/phases/tooltip.d.ts +1 -1
- package/dist/plots/map/geo/phases/tooltip.js +5 -0
- package/dist/plots/{geo → map/geo}/slices.d.ts +2 -2
- package/dist/plots/{geo → map/geo}/slices.js +2 -2
- package/dist/plots/{bar → ranking/bar}/Plot.svelte +2 -2
- package/dist/plots/{bar → ranking/bar}/Plot.svelte.d.ts +2 -2
- package/dist/plots/ranking/bar/defaults.d.ts +16 -0
- package/dist/plots/{bar → ranking/bar}/defaults.js +15 -9
- package/dist/plots/{bar → ranking/bar}/markers.d.ts +8 -8
- package/dist/plots/{bar → ranking/bar}/markers.js +8 -17
- package/dist/plots/ranking/bullet/Plot.svelte +42 -0
- package/dist/plots/ranking/bullet/Plot.svelte.d.ts +26 -0
- package/dist/plots/ranking/bullet/defaults.d.ts +8 -0
- package/dist/plots/ranking/bullet/defaults.js +24 -0
- package/dist/plots/ranking/bullet/markers.d.ts +10 -0
- package/dist/plots/ranking/bullet/markers.js +90 -0
- package/dist/plots/ranking/cleveland/ClevelandConnector.d.ts +48 -0
- package/dist/plots/ranking/cleveland/ClevelandConnector.js +140 -0
- package/dist/plots/ranking/cleveland/ClevelandMarkers.d.ts +33 -0
- package/dist/plots/ranking/cleveland/ClevelandMarkers.js +375 -0
- package/dist/plots/ranking/cleveland/ClevelandRanges.d.ts +31 -0
- package/dist/plots/ranking/cleveland/ClevelandRanges.js +116 -0
- package/dist/plots/ranking/cleveland/Plot.svelte +45 -0
- package/dist/plots/ranking/cleveland/Plot.svelte.d.ts +26 -0
- package/dist/plots/ranking/cleveland/defaults.d.ts +13 -0
- package/dist/plots/ranking/cleveland/defaults.js +66 -0
- package/dist/plots/ranking/dumbbell/Plot.svelte +45 -0
- package/dist/plots/ranking/dumbbell/Plot.svelte.d.ts +26 -0
- package/dist/plots/ranking/dumbbell/defaults.d.ts +9 -0
- package/dist/plots/ranking/dumbbell/defaults.js +19 -0
- package/dist/plots/ranking/forest/Plot.svelte +42 -0
- package/dist/plots/ranking/forest/Plot.svelte.d.ts +26 -0
- package/dist/plots/ranking/forest/defaults.d.ts +11 -0
- package/dist/plots/ranking/forest/defaults.js +20 -0
- package/dist/plots/ranking/lollipop/Plot.svelte +45 -0
- package/dist/plots/ranking/lollipop/Plot.svelte.d.ts +26 -0
- package/dist/plots/ranking/lollipop/defaults.d.ts +9 -0
- package/dist/plots/ranking/lollipop/defaults.js +18 -0
- package/dist/plots/utils/RowNumbers.d.ts +16 -0
- package/dist/plots/utils/RowNumbers.js +24 -0
- package/dist/plots/utils/gaps.js +1 -1
- package/dist/plots/utils/segments.d.ts +4 -1
- package/dist/plots/utils/segments.js +20 -7
- package/dist/types/configuration/styling.d.ts +284 -143
- package/dist/types/layout/coordinates.d.ts +5 -4
- package/dist/types/layout/facet.d.ts +18 -0
- package/dist/types/layout/legend.d.ts +23 -5
- package/dist/types/layout/plot.d.ts +46 -1
- package/dist/types/layout/scales.d.ts +39 -7
- package/dist/types/layout/statistics/deviation.d.ts +40 -0
- package/dist/types/layout/statistics/index.d.ts +7 -2
- package/dist/types/layout/styles/base.d.ts +18 -0
- package/dist/types/layout/styles/bullet.d.ts +25 -0
- package/dist/types/layout/styles/connector.d.ts +98 -0
- package/dist/types/layout/styles/curve.d.ts +11 -0
- package/dist/types/layout/styles/frame.d.ts +17 -0
- package/dist/types/layout/styles/gaps.d.ts +12 -0
- package/dist/types/layout/styles/geo.d.ts +55 -0
- package/dist/types/layout/styles/index.d.ts +8 -0
- package/dist/types/layout/styles/index.js +8 -0
- package/dist/types/layout/styles/values.d.ts +47 -0
- package/dist/types/layout/timeline.d.ts +5 -2
- package/dist/types/layout/tooltip.d.ts +6 -2
- package/dist/types/markers/axis/area.d.ts +2 -2
- package/dist/types/markers/axis/arrow.d.ts +3 -0
- package/dist/types/markers/axis/axisBasedMarkersConfig.d.ts +2 -1
- package/dist/types/markers/axis/bar.d.ts +1 -1
- package/dist/types/markers/axis/box.d.ts +5 -0
- package/dist/types/markers/axis/delta.d.ts +15 -2
- package/dist/types/markers/axis/difference.d.ts +2 -2
- package/dist/types/markers/axis/image.d.ts +3 -2
- package/dist/types/markers/axis/line.d.ts +2 -0
- package/dist/types/markers/axis/rule.d.ts +18 -2
- package/dist/types/markers/axis/trail.d.ts +2 -3
- package/dist/types/markers/axis/violin.d.ts +25 -0
- package/dist/types/markers/basic/dot.d.ts +3 -2
- package/dist/types/markers/basic/text.d.ts +13 -3
- package/dist/types/markers/channels/commonMarkerConfig.d.ts +7 -3
- package/dist/types/markers/channels/commonMarkerConfigWithRowOffset.d.ts +13 -0
- package/dist/types/markers/common.d.ts +1 -1
- package/dist/types/markers/common.js +1 -0
- package/dist/types/markers/geo/link.d.ts +5 -1
- package/dist/types/phases/facet/phase.d.ts +4 -0
- package/dist/types/phases/index.d.ts +1 -1
- package/dist/types/phases/scales/phase.d.ts +5 -1
- package/dist/types/phases/state.d.ts +15 -2
- package/dist/types/phases/statistics/source.d.ts +3 -1
- package/dist/types/phases/transforms/phase.d.ts +22 -0
- package/dist/types/plots/{heatmap → correlation/heatmap}/props.d.ts +6 -6
- package/dist/types/plots/{heatmap → correlation/heatmap}/state.d.ts +4 -4
- package/dist/types/plots/{scatter → correlation/scatter}/props.d.ts +6 -6
- package/dist/types/plots/{scatter → correlation/scatter}/state.d.ts +2 -2
- package/dist/types/plots/{box → distribution/box}/props.d.ts +6 -6
- package/dist/types/plots/{box → distribution/box}/state.d.ts +3 -3
- package/dist/types/plots/distribution/density/props.d.ts +23 -0
- package/dist/types/plots/distribution/density/state.d.ts +6 -0
- package/dist/types/plots/{histogram → distribution/histogram}/props.d.ts +7 -7
- package/dist/types/plots/{histogram → distribution/histogram}/state.d.ts +2 -2
- package/dist/types/plots/distribution/histogram/state.js +1 -0
- package/dist/types/plots/{pyramid → distribution/pyramid}/props.d.ts +6 -6
- package/dist/types/plots/distribution/pyramid/props.js +1 -0
- package/dist/types/plots/{pyramid → distribution/pyramid}/state.d.ts +3 -3
- package/dist/types/plots/distribution/pyramid/state.js +1 -0
- package/dist/types/plots/distribution/violin/props.d.ts +23 -0
- package/dist/types/plots/distribution/violin/props.js +1 -0
- package/dist/types/plots/distribution/violin/state.d.ts +6 -0
- package/dist/types/plots/distribution/violin/state.js +1 -0
- package/dist/types/plots/{area → evolution/area}/props.d.ts +6 -6
- package/dist/types/plots/evolution/area/props.js +1 -0
- package/dist/types/plots/{area → evolution/area}/state.d.ts +2 -2
- package/dist/types/plots/evolution/area/state.js +1 -0
- package/dist/types/plots/evolution/line/props.d.ts +10 -0
- package/dist/types/plots/evolution/line/props.js +1 -0
- package/dist/types/plots/{line → evolution/line}/state.d.ts +3 -3
- package/dist/types/plots/evolution/line/state.js +1 -0
- package/dist/types/plots/evolution/slope/props.d.ts +5 -0
- package/dist/types/plots/evolution/slope/props.js +1 -0
- package/dist/types/plots/evolution/slope/state.d.ts +5 -0
- package/dist/types/plots/evolution/slope/state.js +1 -0
- package/dist/types/plots/evolution/sparkline/props.d.ts +5 -0
- package/dist/types/plots/evolution/sparkline/props.js +1 -0
- package/dist/types/plots/evolution/sparkline/state.d.ts +5 -0
- package/dist/types/plots/evolution/sparkline/state.js +1 -0
- package/dist/types/plots/{geo → map/geo}/props.d.ts +8 -8
- package/dist/types/plots/map/geo/props.js +1 -0
- package/dist/types/plots/{geo → map/geo}/state.d.ts +18 -11
- package/dist/types/plots/map/geo/state.js +1 -0
- package/dist/types/plots/props.d.ts +7 -4
- package/dist/types/plots/{bar → ranking/bar}/props.d.ts +6 -6
- package/dist/types/plots/ranking/bar/props.js +1 -0
- package/dist/types/plots/{bar → ranking/bar}/state.d.ts +2 -2
- package/dist/types/plots/ranking/bar/state.js +1 -0
- package/dist/types/plots/ranking/bullet/props.d.ts +22 -0
- package/dist/types/plots/ranking/bullet/props.js +1 -0
- package/dist/types/plots/ranking/bullet/state.d.ts +5 -0
- package/dist/types/plots/ranking/bullet/state.js +1 -0
- package/dist/types/plots/ranking/cleveland/props.d.ts +10 -0
- package/dist/types/plots/ranking/cleveland/props.js +1 -0
- package/dist/types/plots/ranking/cleveland/state.d.ts +49 -0
- package/dist/types/plots/ranking/cleveland/state.js +1 -0
- package/dist/types/plots/ranking/dumbbell/props.d.ts +10 -0
- package/dist/types/plots/ranking/dumbbell/props.js +1 -0
- package/dist/types/plots/ranking/dumbbell/state.d.ts +5 -0
- package/dist/types/plots/ranking/dumbbell/state.js +1 -0
- package/dist/types/plots/ranking/forest/props.d.ts +23 -0
- package/dist/types/plots/ranking/forest/props.js +1 -0
- package/dist/types/plots/ranking/forest/state.d.ts +5 -0
- package/dist/types/plots/ranking/forest/state.js +1 -0
- package/dist/types/plots/ranking/lollipop/props.d.ts +10 -0
- package/dist/types/plots/ranking/lollipop/props.js +1 -0
- package/dist/types/plots/ranking/lollipop/state.d.ts +5 -0
- package/dist/types/plots/ranking/lollipop/state.js +1 -0
- package/dist/types/plots/segments/common.d.ts +4 -1
- package/dist/types/plots/segments/config.d.ts +4 -2
- package/dist/utils/OpacityScale.d.ts +14 -0
- package/dist/utils/OpacityScale.js +43 -0
- package/dist/utils/{symbol.d.ts → SymbolPath.d.ts} +0 -12
- package/dist/utils/{symbol.js → SymbolPath.js} +0 -24
- package/dist/utils/SymbolScale.d.ts +18 -0
- package/dist/utils/SymbolScale.js +29 -0
- package/dist/utils/color/ColorRamp.d.ts +27 -0
- package/dist/utils/color/ColorRamp.js +120 -0
- package/dist/utils/color/CssColor.d.ts +19 -0
- package/dist/utils/color/CssColor.js +114 -0
- package/dist/utils/color/Palette.d.ts +21 -0
- package/dist/utils/color/Palette.js +52 -0
- package/dist/utils/color/index.d.ts +11 -3
- package/dist/utils/color/index.js +14 -3
- package/dist/utils/grouping.js +1 -1
- package/docs/architecture.md +1 -1
- package/docs/chrome.md +2 -2
- package/docs/composer.md +2 -2
- package/docs/concepts.md +1 -1
- package/docs/development.md +1 -1
- package/docs/facets.md +50 -3
- package/docs/getting-started.md +2 -2
- package/docs/legend.md +13 -11
- package/docs/markers.md +57 -27
- package/docs/plots/correlation/heatmap.md +26 -0
- package/docs/plots/correlation/scatter.md +35 -0
- package/docs/plots/distribution/box.md +28 -0
- package/docs/plots/distribution/density.md +26 -0
- package/docs/plots/distribution/histogram.md +33 -0
- package/docs/plots/distribution/pyramid.md +31 -0
- package/docs/plots/distribution/violin.md +35 -0
- package/docs/plots/evolution/area.md +32 -0
- package/docs/plots/evolution/line.md +93 -0
- package/docs/plots/evolution/slope.md +39 -0
- package/docs/plots/evolution/sparkline.md +34 -0
- package/docs/plots/ranking/bar.md +59 -0
- package/docs/plots/ranking/bullet.md +37 -0
- package/docs/plots/ranking/cleveland.md +54 -0
- package/docs/plots/ranking/dumbbell.md +39 -0
- package/docs/plots/ranking/forest.md +40 -0
- package/docs/plots/ranking/lollipop.md +39 -0
- package/docs/plots.md +22 -280
- package/docs/scales.md +30 -24
- package/docs/styles-and-segments.md +25 -21
- package/docs/theming.md +23 -20
- package/docs/timeline.md +3 -3
- package/docs/tooltip-and-hover.md +10 -10
- package/docs/transforms-and-statistics.md +13 -12
- package/examples/BarValues.svelte +1 -1
- package/examples/Box.svelte +1 -1
- package/examples/Bullet.svelte +17 -0
- package/examples/Chrome.svelte +1 -1
- package/examples/ChromeOrder.svelte +1 -1
- package/examples/Cleveland.svelte +15 -0
- package/examples/Composer.svelte +2 -2
- package/examples/CustomTooltip.svelte +1 -1
- package/examples/Density.svelte +7 -0
- package/examples/Dumbbell.svelte +16 -0
- package/examples/Facets.svelte +1 -1
- package/examples/FacetsCarousel.svelte +1 -1
- package/examples/FacetsRowsCols.svelte +1 -1
- package/examples/FacetsScoped.svelte +26 -0
- package/examples/FirstPlot.svelte +1 -1
- package/examples/Forest.svelte +17 -0
- package/examples/Gaps.svelte +2 -2
- package/examples/GroupedBars.svelte +1 -1
- package/examples/Heatmap.svelte +3 -3
- package/examples/HeatmapSegments.svelte +8 -8
- package/examples/Histogram.svelte +1 -1
- package/examples/HorizontalBars.svelte +1 -1
- package/examples/LegendSections.svelte +1 -1
- package/examples/LegendToggle.svelte +1 -1
- package/examples/LineByRegion.svelte +1 -1
- package/examples/LineDates.svelte +1 -1
- package/examples/LineStep.svelte +16 -0
- package/examples/LineStepSegment.svelte +18 -0
- package/examples/Lollipop.svelte +17 -0
- package/examples/Markers.svelte +1 -1
- package/examples/MovingAverage.svelte +1 -1
- package/examples/Pyramid.svelte +9 -2
- package/examples/Regression.svelte +2 -2
- package/examples/ResponsiveLine.svelte +1 -1
- package/examples/Scales.svelte +1 -1
- package/examples/Scatter.svelte +2 -2
- package/examples/SegmentHighlight.svelte +1 -1
- package/examples/Segments.svelte +1 -1
- package/examples/SegmentsBySeries.svelte +1 -1
- package/examples/Slope.svelte +17 -0
- package/examples/Sparkline.svelte +14 -0
- package/examples/StackedArea.svelte +1 -1
- package/examples/StackedBars.svelte +1 -1
- package/examples/TimelinePlayer.svelte +1 -1
- package/examples/TimelineRule.svelte +1 -1
- package/examples/Tooltip.svelte +1 -1
- package/examples/ValueLabels.svelte +1 -1
- package/examples/Violin.svelte +14 -0
- package/examples/datasets/argentina-chile-trends.ts +34 -0
- package/examples/datasets/commodity-prices.ts +48 -0
- package/examples/datasets/countries-over-time.ts +368 -0
- package/examples/datasets/daily-temperature.ts +121 -0
- package/examples/datasets/earthquakes.ts +977 -0
- package/examples/datasets/flight-routes.ts +29 -0
- package/examples/datasets/height-density.ts +37 -0
- package/examples/datasets/heights.ts +370 -0
- package/examples/datasets/index.ts +24 -0
- package/examples/datasets/inflation-by-region.ts +44 -0
- package/examples/datasets/inflation-ranges.ts +34 -0
- package/examples/datasets/iris-flower.ts +207 -0
- package/examples/datasets/life-expectancy.ts +95 -0
- package/examples/datasets/napoleons-march.ts +182 -0
- package/examples/datasets/penguins.ts +54 -0
- package/examples/datasets/population-by-age-with-gaps.ts +23 -0
- package/examples/datasets/population-by-age.ts +890 -0
- package/examples/datasets/province-population.ts +521 -0
- package/examples/datasets/stock-prices.ts +63 -0
- package/examples/datasets/weather-stations-over-time.ts +31 -0
- package/examples/datasets/weather-stations.ts +22 -0
- package/examples/datasets/wind-vectors.ts +30 -0
- package/examples/datasets/world-temperature.ts +400 -0
- package/llms-full.txt +27 -14
- package/llms.txt +33 -4
- package/package.json +10 -1
- package/dist/plots/bar/defaults.d.ts +0 -9
- package/dist/plots/geo/features.svelte.d.ts +0 -5
- package/dist/plots/geo/features.svelte.js +0 -44
- package/dist/plots/geo/phases/tooltip.js +0 -5
- package/dist/plots/utils/geoAccessors.d.ts +0 -72
- package/dist/plots/utils/geoAccessors.js +0 -220
- package/dist/plots/utils/geoSegments.d.ts +0 -29
- package/dist/plots/utils/geoSegments.js +0 -37
- package/dist/types/layout/styles.d.ts +0 -122
- package/dist/types/markers/axis/curveName.d.ts +0 -2
- package/dist/types/plots/line/props.d.ts +0 -10
- package/dist/utils/color/contrast.d.ts +0 -9
- package/dist/utils/color/contrast.js +0 -40
- package/dist/utils/color/cssColor.d.ts +0 -4
- package/dist/utils/color/cssColor.js +0 -77
- package/dist/utils/color/ramp.d.ts +0 -17
- package/dist/utils/color/ramp.js +0 -110
- package/dist/utils/opacity.d.ts +0 -9
- package/dist/utils/opacity.js +0 -38
- package/examples/data.ts +0 -324
- /package/dist/plots/{box → distribution/box}/markers.js +0 -0
- /package/dist/types/layout/{styles.js → statistics/deviation.js} +0 -0
- /package/dist/types/{markers/axis/curveName.js → layout/styles/base.js} +0 -0
- /package/dist/types/{plots/area/props.js → layout/styles/bullet.js} +0 -0
- /package/dist/types/{plots/area/state.js → layout/styles/connector.js} +0 -0
- /package/dist/types/{plots/bar/props.js → layout/styles/curve.js} +0 -0
- /package/dist/types/{plots/bar/state.js → layout/styles/frame.js} +0 -0
- /package/dist/types/{plots/box/props.js → layout/styles/gaps.js} +0 -0
- /package/dist/types/{plots/box/state.js → layout/styles/geo.js} +0 -0
- /package/dist/types/{plots/geo/props.js → layout/styles/values.js} +0 -0
- /package/dist/types/{plots/geo/state.js → markers/axis/violin.js} +0 -0
- /package/dist/types/{plots/heatmap/props.js → markers/channels/commonMarkerConfigWithRowOffset.js} +0 -0
- /package/dist/types/plots/{histogram → correlation/heatmap}/props.js +0 -0
- /package/dist/types/plots/{heatmap → correlation/heatmap}/state.js +0 -0
- /package/dist/types/plots/{line → correlation/scatter}/props.js +0 -0
- /package/dist/types/plots/{histogram → correlation/scatter}/state.js +0 -0
- /package/dist/types/plots/{pyramid → distribution/box}/props.js +0 -0
- /package/dist/types/plots/{line → distribution/box}/state.js +0 -0
- /package/dist/types/plots/{scatter → distribution/density}/props.js +0 -0
- /package/dist/types/plots/{pyramid → distribution/density}/state.js +0 -0
- /package/dist/types/plots/{scatter/state.js → distribution/histogram/props.js} +0 -0
- /package/dist/{plots/utils → utils}/accessors.d.ts +0 -0
- /package/dist/{plots/utils → utils}/accessors.js +0 -0
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import { DISCRETE_SCALE_TYPES } from '../../types/layout/scales';
|
|
10
10
|
import type { AxisBasedScalesConfig } from '../../types/layout/scales';
|
|
11
11
|
import type { AxisValue } from '../../types/layout/mapping';
|
|
12
|
+
import type { PlotLayoutState } from '../../types/layout/plot';
|
|
12
13
|
|
|
13
14
|
/** Axis ticks, titles and grid lines for the plot kinds with an x/y axis pair. */
|
|
14
15
|
let {
|
|
@@ -19,7 +20,9 @@
|
|
|
19
20
|
height,
|
|
20
21
|
numericMargins,
|
|
21
22
|
scales,
|
|
22
|
-
edgeDomains = undefined
|
|
23
|
+
edgeDomains = undefined,
|
|
24
|
+
tickValues = undefined,
|
|
25
|
+
state: plotState
|
|
23
26
|
}: {
|
|
24
27
|
data: TData[];
|
|
25
28
|
getX: (d: TData) => AxisValue;
|
|
@@ -33,8 +36,18 @@
|
|
|
33
36
|
* `'extend'` resolved a collision (see `EdgeTicks`), for the plot to give its scale.
|
|
34
37
|
*/
|
|
35
38
|
edgeDomains?: Map<'x' | 'y', [number, number]>;
|
|
39
|
+
/** The labels a category axis writes, when it leaves some out for want of room. */
|
|
40
|
+
tickValues?: Partial<Record<'x' | 'y', string[]>>;
|
|
41
|
+
/** The plot's state: its fitted axes and the y channel's field, which titles a vertical y axis with no rows. */
|
|
42
|
+
state: Pick<PlotLayoutState, 'fittedAxes' | 'channels'>;
|
|
36
43
|
} = $props();
|
|
37
44
|
|
|
45
|
+
const fittedAxes = $derived(plotState.fittedAxes);
|
|
46
|
+
const yField = $derived.by(() => {
|
|
47
|
+
const source = plotState.channels?.y?.source;
|
|
48
|
+
return typeof source === 'string' ? source : undefined;
|
|
49
|
+
});
|
|
50
|
+
|
|
38
51
|
const cfg = $derived(getConfiguration());
|
|
39
52
|
const plot = usePlot().svelteplot;
|
|
40
53
|
|
|
@@ -101,6 +114,8 @@
|
|
|
101
114
|
if (!extent) return undefined;
|
|
102
115
|
const [lo, hi] = extent;
|
|
103
116
|
if (!Number.isInteger(lo) || !Number.isInteger(hi)) return undefined;
|
|
117
|
+
const numbers = values.filter((v): v is number => typeof v === 'number');
|
|
118
|
+
if (numbers.length === 0 || !numbers.every(Number.isInteger)) return undefined;
|
|
104
119
|
return hi - lo < NiceTicks.count(span, spacing, min) ? 1 : undefined;
|
|
105
120
|
}
|
|
106
121
|
|
|
@@ -139,7 +154,7 @@
|
|
|
139
154
|
scale?.ticks != null ||
|
|
140
155
|
scale?.tickSpacing != null ||
|
|
141
156
|
scale?.interval != null ||
|
|
142
|
-
scale?.domain != null
|
|
157
|
+
(scale?.domain != null && !fittedAxes?.includes(axis))
|
|
143
158
|
)
|
|
144
159
|
return undefined;
|
|
145
160
|
if (type != null && isDiscreteType(type)) return undefined;
|
|
@@ -179,6 +194,12 @@
|
|
|
179
194
|
});
|
|
180
195
|
});
|
|
181
196
|
|
|
197
|
+
/** A turned label is written on one line: the axis does not wrap it. */
|
|
198
|
+
const turned = $derived(scales?.x?.tickRotate ? { wordwrap: false } : {}) as Record<
|
|
199
|
+
string,
|
|
200
|
+
unknown
|
|
201
|
+
>;
|
|
202
|
+
|
|
182
203
|
const yTitleFontSize = $derived(scales?.y?.titleFontSize ?? cfg.axis.titleFontSize);
|
|
183
204
|
|
|
184
205
|
/**
|
|
@@ -187,7 +208,8 @@
|
|
|
187
208
|
*/
|
|
188
209
|
const verticalYLabel = $derived.by(() => {
|
|
189
210
|
if (scales?.y?.labelOrientation !== 'vertical' || scales.y.label === false) return null;
|
|
190
|
-
const text =
|
|
211
|
+
const text =
|
|
212
|
+
scales.y.label || plot.scales.y.autoTitle || (data.length === 0 ? yField : undefined);
|
|
191
213
|
if (!text) return null;
|
|
192
214
|
const position = scales.y.labelPosition ?? 'middle';
|
|
193
215
|
const x = yTitleFontSize;
|
|
@@ -220,11 +242,75 @@
|
|
|
220
242
|
$effect(() => () => {
|
|
221
243
|
$autoMarginLeft.delete(marginId);
|
|
222
244
|
});
|
|
245
|
+
|
|
246
|
+
// The top y tick's label is centered on the plot's top edge, so it reaches
|
|
247
|
+
// half its height above it - more than svelteplot's own 5px `'auto'` top margin.
|
|
248
|
+
const { autoMarginTop } = getContext<{ autoMarginTop: Writable<Map<string, number>> }>(
|
|
249
|
+
'svelteplot/autoMargins'
|
|
250
|
+
);
|
|
251
|
+
const tickMarginId = `dct-y-tick-${Math.random().toString(36).slice(2)}`;
|
|
252
|
+
$effect(() => {
|
|
253
|
+
const wanted =
|
|
254
|
+
(scales?.y?.axisDisplay ?? 'visible') === 'visible'
|
|
255
|
+
? Math.ceil(cfg.axis.fontSize / 2) + 2
|
|
256
|
+
: undefined;
|
|
257
|
+
untrack(() => {
|
|
258
|
+
if (wanted === undefined) $autoMarginTop.delete(tickMarginId);
|
|
259
|
+
else if ($autoMarginTop.get(tickMarginId) !== wanted)
|
|
260
|
+
$autoMarginTop.set(tickMarginId, wanted);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
$effect(() => () => {
|
|
264
|
+
$autoMarginTop.delete(tickMarginId);
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// An x label centred on the domain's end reaches past the plot's right side; an `'auto'` right margin takes that much room.
|
|
268
|
+
let xAxisEl: SVGGElement | undefined = $state();
|
|
269
|
+
const { autoMarginRight } = getContext<{ autoMarginRight: Writable<Map<string, number>> }>(
|
|
270
|
+
'svelteplot/autoMargins'
|
|
271
|
+
);
|
|
272
|
+
const overhangId = `dct-x-tick-overhang-${Math.random().toString(36).slice(2)}`;
|
|
273
|
+
$effect(() => {
|
|
274
|
+
const el = xAxisEl;
|
|
275
|
+
// Read so a new axis, a new box or a new margin measures again.
|
|
276
|
+
void [scales?.x, xEdgeTicks, tickValues?.x, plot.options.marginLeft, plot.facetWidth];
|
|
277
|
+
if (!el) return;
|
|
278
|
+
let frame: number | undefined;
|
|
279
|
+
let cancelled = false;
|
|
280
|
+
const measure = () => {
|
|
281
|
+
if (cancelled) return;
|
|
282
|
+
const labels = el.querySelectorAll('g.tick text');
|
|
283
|
+
const last = labels.item(labels.length - 1);
|
|
284
|
+
const svg = el.ownerSVGElement;
|
|
285
|
+
const { marginLeft } = plot.options;
|
|
286
|
+
if (last && svg && Number.isFinite(marginLeft) && Number.isFinite(plot.facetWidth)) {
|
|
287
|
+
const edge = svg.getBoundingClientRect().left + Number(marginLeft) + plot.facetWidth;
|
|
288
|
+
const overhang = Math.max(0, Math.ceil(last.getBoundingClientRect().right - edge));
|
|
289
|
+
untrack(() => {
|
|
290
|
+
if (overhang === 0) $autoMarginRight.delete(overhangId);
|
|
291
|
+
else if ($autoMarginRight.get(overhangId) !== overhang)
|
|
292
|
+
$autoMarginRight.set(overhangId, overhang);
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
// Text measures right only once its fonts load.
|
|
297
|
+
(document.fonts?.ready ?? Promise.resolve()).then(() => {
|
|
298
|
+
if (!cancelled) frame = requestAnimationFrame(measure);
|
|
299
|
+
});
|
|
300
|
+
return () => {
|
|
301
|
+
cancelled = true;
|
|
302
|
+
if (frame !== undefined) cancelAnimationFrame(frame);
|
|
303
|
+
};
|
|
304
|
+
});
|
|
305
|
+
$effect(() => () => {
|
|
306
|
+
$autoMarginRight.delete(overhangId);
|
|
307
|
+
});
|
|
223
308
|
</script>
|
|
224
309
|
|
|
225
310
|
{#snippet axisX()}
|
|
226
311
|
<AxisX
|
|
227
|
-
ticks={xEdgeTicks?.ticks}
|
|
312
|
+
ticks={(xEdgeTicks?.ticks ?? tickValues?.x) as string[] | undefined}
|
|
313
|
+
{...turned}
|
|
228
314
|
tickCount={xTickCount}
|
|
229
315
|
interval={xTickInterval}
|
|
230
316
|
tickSize={scales?.x?.tickSize ?? cfg.axis.xTickSize}
|
|
@@ -234,13 +320,13 @@
|
|
|
234
320
|
/>
|
|
235
321
|
{/snippet}
|
|
236
322
|
{#if scales?.x?.axisDisplay === 'hidden'}
|
|
237
|
-
<g style:visibility="hidden">{@render axisX()}</g>
|
|
323
|
+
<g style:visibility="hidden" bind:this={xAxisEl}>{@render axisX()}</g>
|
|
238
324
|
{:else if scales?.x?.axisDisplay !== 'none'}
|
|
239
|
-
{@render axisX()}
|
|
325
|
+
<g bind:this={xAxisEl}>{@render axisX()}</g>
|
|
240
326
|
{/if}
|
|
241
327
|
{#snippet axisY()}
|
|
242
328
|
<AxisY
|
|
243
|
-
ticks={yEdgeTicks?.ticks}
|
|
329
|
+
ticks={(yEdgeTicks?.ticks ?? tickValues?.y) as string[] | undefined}
|
|
244
330
|
tickCount={yTickCount}
|
|
245
331
|
interval={yTickInterval}
|
|
246
332
|
tickSize={scales?.y?.tickSize ?? cfg.axis.yTickSize}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { AxisBasedScalesConfig } from '../../types/layout/scales';
|
|
2
2
|
import type { AxisValue } from '../../types/layout/mapping';
|
|
3
|
+
import type { PlotLayoutState } from '../../types/layout/plot';
|
|
3
4
|
declare function $$render<TData extends Record<string, unknown>>(): {
|
|
4
5
|
props: {
|
|
5
6
|
data: TData[];
|
|
@@ -19,6 +20,10 @@ declare function $$render<TData extends Record<string, unknown>>(): {
|
|
|
19
20
|
* `'extend'` resolved a collision (see `EdgeTicks`), for the plot to give its scale.
|
|
20
21
|
*/
|
|
21
22
|
edgeDomains?: Map<"x" | "y", [number, number]>;
|
|
23
|
+
/** The labels a category axis writes, when it leaves some out for want of room. */
|
|
24
|
+
tickValues?: Partial<Record<"x" | "y", string[]>>;
|
|
25
|
+
/** The plot's state: its fitted axes and the y channel's field, which titles a vertical y axis with no rows. */
|
|
26
|
+
state: Pick<PlotLayoutState, "fittedAxes" | "channels">;
|
|
22
27
|
};
|
|
23
28
|
exports: {};
|
|
24
29
|
bindings: "";
|
|
@@ -7,8 +7,8 @@ export declare class SveltePlotScale {
|
|
|
7
7
|
static readonly CONTINUOUS_NUMERIC_TYPES: ReadonlySet<string>;
|
|
8
8
|
/**
|
|
9
9
|
* The scale without what the package handles itself - `grid`, `axisDisplay`
|
|
10
|
-
* and a vertical `label`, which `ScalesLayout` draws, and `
|
|
11
|
-
* which the "scales" phase applies - with a custom `sort` resolved into a
|
|
10
|
+
* and a vertical `label`, which `ScalesLayout` draws, and a `nice` object's `tolerance`,
|
|
11
|
+
* which the "scales" phase applies (svelteplot is told plain `nice: true`) - with a custom `sort` resolved into a
|
|
12
12
|
* `domain`, and `nice: true` on an unpinned numeric axis.
|
|
13
13
|
*/
|
|
14
14
|
static build<TData>(scale: AxisScale<TData> | undefined, rows: TData[], getAxisValue: (d: TData) => AxisValue): AxisScale<TData> | undefined;
|
|
@@ -12,8 +12,8 @@ export class SveltePlotScale {
|
|
|
12
12
|
]);
|
|
13
13
|
/**
|
|
14
14
|
* The scale without what the package handles itself - `grid`, `axisDisplay`
|
|
15
|
-
* and a vertical `label`, which `ScalesLayout` draws, and `
|
|
16
|
-
* which the "scales" phase applies - with a custom `sort` resolved into a
|
|
15
|
+
* and a vertical `label`, which `ScalesLayout` draws, and a `nice` object's `tolerance`,
|
|
16
|
+
* which the "scales" phase applies (svelteplot is told plain `nice: true`) - with a custom `sort` resolved into a
|
|
17
17
|
* `domain`, and `nice: true` on an unpinned numeric axis.
|
|
18
18
|
*/
|
|
19
19
|
static build(scale, rows, getAxisValue) {
|
|
@@ -24,24 +24,27 @@ export class SveltePlotScale {
|
|
|
24
24
|
(scale?.type == null || SveltePlotScale.CONTINUOUS_NUMERIC_TYPES.has(scale.type)) &&
|
|
25
25
|
SveltePlotScale.#isNumeric(rows, getAxisValue);
|
|
26
26
|
const removesAxis = scale?.axisDisplay === 'none';
|
|
27
|
-
|
|
27
|
+
// svelteplot treats a categorical axis told to be `nice` as linear, and draws nothing.
|
|
28
|
+
const dropsNice = scale?.nice != null && SveltePlotScale.#isCategorical(rows, getAxisValue);
|
|
29
|
+
if (!sorted && !wantsNice && !removesAxis && !dropsNice)
|
|
28
30
|
return sorted;
|
|
29
31
|
const out = { ...sorted };
|
|
30
32
|
delete out.grid;
|
|
31
33
|
delete out.axisDisplay;
|
|
32
|
-
delete out.niceTolerance;
|
|
33
34
|
if (removesAxis)
|
|
34
35
|
out.axis = false;
|
|
35
36
|
if (scale?.labelOrientation === 'vertical')
|
|
36
37
|
out.label = false;
|
|
37
|
-
if (
|
|
38
|
+
if (dropsNice)
|
|
39
|
+
delete out.nice;
|
|
40
|
+
else if (wantsNice || typeof scale?.nice === 'object')
|
|
38
41
|
out.nice = true;
|
|
39
42
|
return out;
|
|
40
43
|
}
|
|
41
44
|
/** svelteplot's `sort` option only does a fixed ascending sort; a custom `scale.sort` comparator is resolved into an explicit `domain` instead, which svelteplot honors as-is. */
|
|
42
45
|
static #sorted(scale, rows, getAxisValue) {
|
|
43
46
|
const sort = scale?.sort;
|
|
44
|
-
if (
|
|
47
|
+
if (typeof sort !== 'function' || scale?.domain)
|
|
45
48
|
return scale;
|
|
46
49
|
const reps = SveltePlotScale.#uniqueRows(rows, getAxisValue);
|
|
47
50
|
if (reps.length === 0 || !reps.every((r) => typeof getAxisValue(r) === 'string'))
|
|
@@ -62,6 +65,10 @@ export class SveltePlotScale {
|
|
|
62
65
|
}
|
|
63
66
|
return out;
|
|
64
67
|
}
|
|
68
|
+
/** Whether the axis lays out text categories: any of its values is a string. */
|
|
69
|
+
static #isCategorical(rows, getAxisValue) {
|
|
70
|
+
return rows.some((row) => typeof getAxisValue(row) === 'string');
|
|
71
|
+
}
|
|
65
72
|
/** Whether the axis' values are numeric; `nice` on a categorical axis would make svelteplot treat it as linear. */
|
|
66
73
|
static #isNumeric(rows, getAxisValue) {
|
|
67
74
|
let numericSeen = 0;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { PlotStylesConfig } from '../../types/configuration/styling';
|
|
2
|
+
/** How a category axis lays its tick labels out: the angle they stand at, and which of them are written. */
|
|
3
|
+
export type TickLayout = {
|
|
4
|
+
/** `0`, `-45` or `-90` degrees. */
|
|
5
|
+
rotate: 0 | -45 | -90;
|
|
6
|
+
/** Every how-manieth label is written: `1` writes them all. */
|
|
7
|
+
every: number;
|
|
8
|
+
/** The widest label, in px, as it is written - not wrapped, when it is rotated. */
|
|
9
|
+
width: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Where the tick labels of a category axis fit. Written flat they wrap at their
|
|
13
|
+
* spaces to the width of their band - a word is never split - and stand side by
|
|
14
|
+
* side as long as the widest line is narrower than the step between categories.
|
|
15
|
+
* Otherwise they turn: at 45 degrees a label needs a step of about one and a
|
|
16
|
+
* half lines of text, at 90 degrees of one; past that, only every few labels
|
|
17
|
+
* are written.
|
|
18
|
+
*/
|
|
19
|
+
export declare class TickLabels {
|
|
20
|
+
/** The gap, in px, kept between neighbouring labels. */
|
|
21
|
+
static readonly GAP = 6;
|
|
22
|
+
/**
|
|
23
|
+
* The layout of `labels` along an axis `span` px long - the categories
|
|
24
|
+
* `bandPadding` (0-1) apart - written at `fontSize`.
|
|
25
|
+
*/
|
|
26
|
+
static layout(labels: readonly string[], span: number, bandPadding: number, fontSize: number, cfg: Pick<PlotStylesConfig, 'font'>): TickLayout;
|
|
27
|
+
/**
|
|
28
|
+
* The layout of a category axis running down the plot, whose labels stand
|
|
29
|
+
* flat in a row each: only how many can be written.
|
|
30
|
+
*/
|
|
31
|
+
static rows(count: number, span: number, fontSize: number): number;
|
|
32
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Box } from '../margins/Box';
|
|
2
|
+
/**
|
|
3
|
+
* Where the tick labels of a category axis fit. Written flat they wrap at their
|
|
4
|
+
* spaces to the width of their band - a word is never split - and stand side by
|
|
5
|
+
* side as long as the widest line is narrower than the step between categories.
|
|
6
|
+
* Otherwise they turn: at 45 degrees a label needs a step of about one and a
|
|
7
|
+
* half lines of text, at 90 degrees of one; past that, only every few labels
|
|
8
|
+
* are written.
|
|
9
|
+
*/
|
|
10
|
+
export class TickLabels {
|
|
11
|
+
/** The gap, in px, kept between neighbouring labels. */
|
|
12
|
+
static GAP = 6;
|
|
13
|
+
/**
|
|
14
|
+
* The layout of `labels` along an axis `span` px long - the categories
|
|
15
|
+
* `bandPadding` (0-1) apart - written at `fontSize`.
|
|
16
|
+
*/
|
|
17
|
+
static layout(labels, span, bandPadding, fontSize, cfg) {
|
|
18
|
+
const count = labels.length;
|
|
19
|
+
const measure = (text) => Box.ofText(text, fontSize, cfg).width;
|
|
20
|
+
const lineHeight = fontSize * 1.2;
|
|
21
|
+
const whole = Math.max(0, ...labels.map(measure));
|
|
22
|
+
const flat = { rotate: 0, every: 1, width: whole };
|
|
23
|
+
if (count < 2 || span <= 0 || whole === 0)
|
|
24
|
+
return flat;
|
|
25
|
+
const step = span / count;
|
|
26
|
+
const room = step - TickLabels.GAP;
|
|
27
|
+
// What a flat label measures once wrapped to its band, as the axis does.
|
|
28
|
+
const maxLine = step * (1 - bandPadding) * 0.9;
|
|
29
|
+
const wrapped = Math.max(0, ...labels.map((label) => {
|
|
30
|
+
const text = measure(label);
|
|
31
|
+
if (text <= maxLine)
|
|
32
|
+
return text;
|
|
33
|
+
const words = Math.max(0, ...label.split(/\s+/).map(measure));
|
|
34
|
+
return Math.max(words, maxLine);
|
|
35
|
+
}));
|
|
36
|
+
if (wrapped <= room)
|
|
37
|
+
return { ...flat, width: wrapped };
|
|
38
|
+
// Turned, a label stands as wide as a line of text across its step.
|
|
39
|
+
if (room >= lineHeight / Math.sin(Math.PI / 4))
|
|
40
|
+
return { rotate: -45, every: 1, width: whole };
|
|
41
|
+
if (room >= lineHeight)
|
|
42
|
+
return { rotate: -90, every: 1, width: whole };
|
|
43
|
+
return { rotate: -90, every: Math.ceil(lineHeight / Math.max(1, room)), width: whole };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The layout of a category axis running down the plot, whose labels stand
|
|
47
|
+
* flat in a row each: only how many can be written.
|
|
48
|
+
*/
|
|
49
|
+
static rows(count, span, fontSize) {
|
|
50
|
+
if (count < 2 || span <= 0)
|
|
51
|
+
return 1;
|
|
52
|
+
const row = span / count;
|
|
53
|
+
return Math.max(1, Math.ceil((fontSize * 1.2 + 2) / row));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Frame } from 'svelteplot';
|
|
3
3
|
import TileLayer from './TileLayer.svelte';
|
|
4
|
-
import {
|
|
4
|
+
import { GeoGeometry } from '../../plots/map/geo/GeoGeometry';
|
|
5
5
|
import type { StylesLayoutConfig } from '../../types/layout/styles';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
let minLat = Infinity;
|
|
37
37
|
let maxLat = -Infinity;
|
|
38
38
|
for (const f of features) {
|
|
39
|
-
const b =
|
|
39
|
+
const b = GeoGeometry.lonLatBounds(f.geometry);
|
|
40
40
|
if (!b) continue;
|
|
41
41
|
if (b[0] < minLon) minLon = b[0];
|
|
42
42
|
if (b[2] > maxLon) maxLon = b[2];
|
|
@@ -8,7 +8,7 @@ import type { FontStyle, StrokeStyle } from '../../types/plots/styling';
|
|
|
8
8
|
import type { TextAnchor, ValueAnchor } from '../../types/plots/constants';
|
|
9
9
|
import type { BoxAnchors, EdgeBox } from '../../types/layout/box';
|
|
10
10
|
import type { MarginSide } from '../../types/plots/props';
|
|
11
|
-
import type { AxisPlotCtx, AxisPlotState, ProcessedRow } from '../../types/phases';
|
|
11
|
+
import type { AxisPlotCtx, AxisPlotState, ProcessedData, ProcessedRow } from '../../types/phases';
|
|
12
12
|
import type { TextMarkerConfig } from '../../types/markers/common';
|
|
13
13
|
/**
|
|
14
14
|
* A plot's value labels: the author's `styles.values` over the plot kind's
|
|
@@ -20,12 +20,14 @@ export declare class ValueLabels {
|
|
|
20
20
|
#private;
|
|
21
21
|
readonly show: boolean;
|
|
22
22
|
readonly anchor: ValueAnchor;
|
|
23
|
-
readonly format: (value: number, seriesName: string) => string;
|
|
23
|
+
readonly format: (value: number, seriesName: string, row?: Record<string, unknown>) => string;
|
|
24
24
|
readonly hoverIsolate: boolean;
|
|
25
25
|
readonly font: FontStyle | undefined;
|
|
26
26
|
readonly fontSize: number;
|
|
27
27
|
/** The connectors of labels that had to move apart. */
|
|
28
28
|
readonly strokeStyle: StrokeStyle | undefined;
|
|
29
|
+
/** `'series'` writes each label in its series' color; any other CSS color writes them all in it. */
|
|
30
|
+
readonly color: 'series' | string | undefined;
|
|
29
31
|
/** How labels that would overlap move apart - the configuration's `text.declutter`. */
|
|
30
32
|
readonly declutter: PlotStylesConfig['text']['declutter'];
|
|
31
33
|
/** Where the labels are expected to sit: boxes around their points, on the edges those can reach. */
|
|
@@ -33,6 +35,14 @@ export declare class ValueLabels {
|
|
|
33
35
|
constructor(values: ValuesStyle | undefined, cfg: PlotStylesConfig, options?: Omit<ValueLabelsOptions<never>, 'reach'>, reach?: (labels: ValueLabels) => EdgeBox[]);
|
|
34
36
|
/** A plot's value labels: `values` over `options`, the kind's own defaults, their reach read off `state`. */
|
|
35
37
|
static build<TState>(values: ValuesStyle | undefined, cfg: PlotStylesConfig, options: ValueLabelsOptions<TState>, state: TState): ValueLabels;
|
|
38
|
+
/** The configuration the labels were built under, for a plot kind's own label defaults. */
|
|
39
|
+
get config(): PlotStylesConfig;
|
|
40
|
+
/**
|
|
41
|
+
* The fill every label takes whatever its series: the author's own
|
|
42
|
+
* `fontStyle.fill`, else a literal `color`. `undefined` leaves each label to
|
|
43
|
+
* its plot's default (its series' color, or the axis').
|
|
44
|
+
*/
|
|
45
|
+
get fill(): string | undefined;
|
|
36
46
|
/** One line of label text's height. */
|
|
37
47
|
get lineHeight(): number;
|
|
38
48
|
/** The box one label's `text` takes. */
|
|
@@ -82,9 +92,27 @@ export declare class ValueLabels {
|
|
|
82
92
|
* (`filter` + `selectLast`, per series), at its top (a stacked row's
|
|
83
93
|
* `y2`), labelled with its own value and placed by `anchor`. Labels that
|
|
84
94
|
* would overlap fan out into a shared column (`declutter`), colored by the
|
|
85
|
-
* segment the row falls in.
|
|
95
|
+
* segment the row falls in. A plot that labels each end of its series apart
|
|
96
|
+
* passes the `rows` and `anchor` of one end, and `lane` to route its labels
|
|
97
|
+
* out to a lane whether or not they overlap (`flip: false` keeps one on the
|
|
98
|
+
* left in the margin instead of flipping it over its points).
|
|
86
99
|
*/
|
|
87
|
-
atSeriesEnds<TData extends Record<string, unknown>>(state: AxisPlotState<TData, object
|
|
100
|
+
atSeriesEnds<TData extends Record<string, unknown>>(state: AxisPlotState<TData, object>, end?: {
|
|
101
|
+
rows?: ProcessedRow[];
|
|
102
|
+
anchor?: ValueAnchor;
|
|
103
|
+
lane?: boolean | {
|
|
104
|
+
elbowGap: number;
|
|
105
|
+
};
|
|
106
|
+
flip?: boolean;
|
|
107
|
+
}): TextMarkerConfig[];
|
|
108
|
+
/** How far (px) a lane takes the label of a series' first point from it - clear of the line that leaves it. */
|
|
109
|
+
static readonly FIRST_LANE_GAP = 28;
|
|
110
|
+
/** The rows of a series-over-`x` plot that cannot be labelled: a gap, or a stack with no top. For the "transforms" phase's `labels.skip`. */
|
|
111
|
+
static skipGaps<TData extends Record<string, unknown>>(state: {
|
|
112
|
+
processedData?: ProcessedData;
|
|
113
|
+
resolvedSeries?: Series<TData>[];
|
|
114
|
+
axes?: PlotAxes;
|
|
115
|
+
}): (row: ProcessedRow) => boolean;
|
|
88
116
|
/**
|
|
89
117
|
* Where {@link atSeriesEnds}' labels are expected to sit: past each
|
|
90
118
|
* series' last point, at the right edge (or the left, for labels set
|
|
@@ -93,5 +121,5 @@ export declare class ValueLabels {
|
|
|
93
121
|
* domain when the scales set one, so it holds across a timeline; else off
|
|
94
122
|
* every value.
|
|
95
123
|
*/
|
|
96
|
-
reachAtSeriesEnds<TData extends Record<string, unknown>>(state: AxisPlotState<TData, object
|
|
124
|
+
reachAtSeriesEnds<TData extends Record<string, unknown>>(state: AxisPlotState<TData, object>, anchor?: ValueAnchor): EdgeBox[];
|
|
97
125
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { ProcessedPositions } from '../../phases/transforms/ProcessedPositions';
|
|
2
2
|
import { Box } from '../margins/Box';
|
|
3
|
-
import { resolveAccessor } from '../../
|
|
3
|
+
import { resolveAccessor } from '../../utils/accessors';
|
|
4
4
|
import { SERIES_ID_KEY, SERIES_KEY } from '../../phases/transforms/TransformsPhase';
|
|
5
5
|
import { seriesIdOf } from '../../utils/grouping';
|
|
6
|
-
import { Transforms } from '../../phases/transforms/Transforms';
|
|
7
6
|
import { isGapValue } from '../../plots/utils/gaps';
|
|
8
7
|
import { PlotAxes } from '../../phases/data/PlotAxes';
|
|
9
8
|
/**
|
|
@@ -21,6 +20,8 @@ export class ValueLabels {
|
|
|
21
20
|
fontSize;
|
|
22
21
|
/** The connectors of labels that had to move apart. */
|
|
23
22
|
strokeStyle;
|
|
23
|
+
/** `'series'` writes each label in its series' color; any other CSS color writes them all in it. */
|
|
24
|
+
color;
|
|
24
25
|
/** How labels that would overlap move apart - the configuration's `text.declutter`. */
|
|
25
26
|
declutter;
|
|
26
27
|
/** Where the labels are expected to sit: boxes around their points, on the edges those can reach. */
|
|
@@ -34,6 +35,7 @@ export class ValueLabels {
|
|
|
34
35
|
this.font = values?.fontStyle;
|
|
35
36
|
this.fontSize = typeof this.font?.fontSize === 'number' ? this.font.fontSize : 12;
|
|
36
37
|
this.strokeStyle = values?.strokeStyle;
|
|
38
|
+
this.color = values?.color;
|
|
37
39
|
this.declutter = cfg.text.declutter;
|
|
38
40
|
this.#cfg = cfg;
|
|
39
41
|
this.reach = (this.show && reach?.(this)) || [];
|
|
@@ -43,6 +45,18 @@ export class ValueLabels {
|
|
|
43
45
|
const { reach } = options;
|
|
44
46
|
return new ValueLabels(values, cfg, options, reach && ((labels) => reach(labels, state)));
|
|
45
47
|
}
|
|
48
|
+
/** The configuration the labels were built under, for a plot kind's own label defaults. */
|
|
49
|
+
get config() {
|
|
50
|
+
return this.#cfg;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The fill every label takes whatever its series: the author's own
|
|
54
|
+
* `fontStyle.fill`, else a literal `color`. `undefined` leaves each label to
|
|
55
|
+
* its plot's default (its series' color, or the axis').
|
|
56
|
+
*/
|
|
57
|
+
get fill() {
|
|
58
|
+
return this.font?.fill ?? (this.color === 'series' ? undefined : this.color);
|
|
59
|
+
}
|
|
46
60
|
/** One line of label text's height. */
|
|
47
61
|
get lineHeight() {
|
|
48
62
|
return this.fontSize * 1.2;
|
|
@@ -133,13 +147,45 @@ export class ValueLabels {
|
|
|
133
147
|
* (`filter` + `selectLast`, per series), at its top (a stacked row's
|
|
134
148
|
* `y2`), labelled with its own value and placed by `anchor`. Labels that
|
|
135
149
|
* would overlap fan out into a shared column (`declutter`), colored by the
|
|
136
|
-
* segment the row falls in.
|
|
150
|
+
* segment the row falls in. A plot that labels each end of its series apart
|
|
151
|
+
* passes the `rows` and `anchor` of one end, and `lane` to route its labels
|
|
152
|
+
* out to a lane whether or not they overlap (`flip: false` keeps one on the
|
|
153
|
+
* left in the margin instead of flipping it over its points).
|
|
137
154
|
*/
|
|
138
|
-
atSeriesEnds(state) {
|
|
155
|
+
atSeriesEnds(state, end = {}) {
|
|
156
|
+
if (end.rows)
|
|
157
|
+
return this.#seriesEnds(state, end);
|
|
158
|
+
// A label on a series' first point would sit on its own line: it goes out to a lane instead.
|
|
159
|
+
const firsts = ValueLabels.#firstRows(state);
|
|
160
|
+
const labelled = state.labelled ?? [];
|
|
161
|
+
return [
|
|
162
|
+
...this.#seriesEnds(state, { rows: labelled.filter((row) => !firsts.has(row)) }),
|
|
163
|
+
...this.#seriesEnds(state, {
|
|
164
|
+
rows: labelled.filter((row) => firsts.has(row)),
|
|
165
|
+
lane: { elbowGap: ValueLabels.FIRST_LANE_GAP }
|
|
166
|
+
})
|
|
167
|
+
];
|
|
168
|
+
}
|
|
169
|
+
/** How far (px) a lane takes the label of a series' first point from it - clear of the line that leaves it. */
|
|
170
|
+
static FIRST_LANE_GAP = 28;
|
|
171
|
+
/** The first row of every series that has more than one. */
|
|
172
|
+
static #firstRows(state) {
|
|
173
|
+
const first = new Map();
|
|
174
|
+
const counts = new Map();
|
|
175
|
+
for (const row of state.processedData?.data ?? []) {
|
|
176
|
+
const id = String(row[SERIES_ID_KEY]);
|
|
177
|
+
if (!first.has(id))
|
|
178
|
+
first.set(id, row);
|
|
179
|
+
counts.set(id, (counts.get(id) ?? 0) + 1);
|
|
180
|
+
}
|
|
181
|
+
return new Set([...first].filter(([id]) => (counts.get(id) ?? 0) > 1).map(([, row]) => row));
|
|
182
|
+
}
|
|
183
|
+
#seriesEnds(state, end) {
|
|
139
184
|
const processed = state.processedData;
|
|
140
185
|
if (!processed)
|
|
141
186
|
return [];
|
|
142
|
-
const { font,
|
|
187
|
+
const { font, format } = this;
|
|
188
|
+
const anchor = end.anchor ?? this.anchor;
|
|
143
189
|
const position = ProcessedPositions.of(processed);
|
|
144
190
|
const topOf = (d) => position.y(d);
|
|
145
191
|
const nameOf = (d) => String(d[SERIES_KEY]);
|
|
@@ -153,33 +199,39 @@ export class ValueLabels {
|
|
|
153
199
|
group?.color ??
|
|
154
200
|
state.colorForSeries?.(nameOf(d)));
|
|
155
201
|
};
|
|
156
|
-
const marker =
|
|
202
|
+
const marker = {
|
|
157
203
|
type: 'text',
|
|
158
|
-
|
|
204
|
+
// The rows the "transforms" phase picked for the labels: by default each series' last.
|
|
205
|
+
data: end.rows ?? state.labelled ?? [],
|
|
159
206
|
x: (processed.channels.x ?? position.x),
|
|
160
207
|
y: (processed.channels.y2 ?? processed.channels.y ?? topOf),
|
|
161
208
|
grouping: SERIES_ID_KEY,
|
|
162
|
-
transforms: [
|
|
163
|
-
{
|
|
164
|
-
type: 'filter',
|
|
165
|
-
filter: (d) => !isGapValue(valueOf(d)) && !isGapValue(topOf(d))
|
|
166
|
-
},
|
|
167
|
-
{ type: 'selectLast' }
|
|
168
|
-
],
|
|
169
209
|
text: (d) => format(Number(valueOf(d)), nameOf(d)),
|
|
170
210
|
styles: {
|
|
171
211
|
...font,
|
|
212
|
+
...(this.fill ? { fill: this.fill } : {}),
|
|
172
213
|
fontSize: font?.fontSize ?? 12,
|
|
173
214
|
dx: font?.dx ?? (anchor === 'start' ? 6 : anchor === 'end' ? -6 : 0),
|
|
174
215
|
dy: font?.dy ?? (anchor === 'outside' ? -8 : 0),
|
|
175
216
|
textAnchor: this.textAnchor ?? (anchor === 'start' || anchor === 'end' ? anchor : 'middle'),
|
|
176
217
|
lineAnchor: font?.lineAnchor ?? (anchor === 'outside' ? 'bottom' : 'middle')
|
|
177
218
|
},
|
|
178
|
-
fill:
|
|
179
|
-
declutter: {
|
|
180
|
-
|
|
219
|
+
fill: this.fill ? undefined : colorOf,
|
|
220
|
+
declutter: {
|
|
221
|
+
connector: this.strokeStyle,
|
|
222
|
+
aligned: !!end.lane && (anchor === 'start' || anchor === 'end'),
|
|
223
|
+
elbowGap: typeof end.lane === 'object' ? end.lane.elbowGap : undefined,
|
|
224
|
+
flip: end.flip
|
|
225
|
+
}
|
|
226
|
+
};
|
|
181
227
|
return marker.data?.length ? [marker] : [];
|
|
182
228
|
}
|
|
229
|
+
/** The rows of a series-over-`x` plot that cannot be labelled: a gap, or a stack with no top. For the "transforms" phase's `labels.skip`. */
|
|
230
|
+
static skipGaps(state) {
|
|
231
|
+
const valueOf = ValueLabels.valueOf(state);
|
|
232
|
+
const top = ProcessedPositions.of(state.processedData).y;
|
|
233
|
+
return (row) => isGapValue(valueOf(row)) || isGapValue(top(row));
|
|
234
|
+
}
|
|
183
235
|
/**
|
|
184
236
|
* Where {@link atSeriesEnds}' labels are expected to sit: past each
|
|
185
237
|
* series' last point, at the right edge (or the left, for labels set
|
|
@@ -188,9 +240,9 @@ export class ValueLabels {
|
|
|
188
240
|
* domain when the scales set one, so it holds across a timeline; else off
|
|
189
241
|
* every value.
|
|
190
242
|
*/
|
|
191
|
-
reachAtSeriesEnds(state) {
|
|
243
|
+
reachAtSeriesEnds(state, anchor = this.anchor) {
|
|
192
244
|
const series = state.resolvedSeries ?? [];
|
|
193
|
-
const {
|
|
245
|
+
const { font, format } = this;
|
|
194
246
|
const dx = typeof font?.dx === 'number' ? font.dx : anchor === 'start' ? 6 : anchor === 'end' ? -6 : 0;
|
|
195
247
|
const dy = typeof font?.dy === 'number' ? font.dy : anchor === 'outside' ? -8 : 0;
|
|
196
248
|
const textAnchor = this.textAnchor ?? (anchor === 'start' ? 'start' : anchor === 'end' ? 'end' : 'middle');
|
|
@@ -203,11 +255,18 @@ export class ValueLabels {
|
|
|
203
255
|
const { elbowGap, laneStep, labelGap } = this.declutter;
|
|
204
256
|
const lanes = elbowGap + (series.length - 1) * laneStep + labelGap;
|
|
205
257
|
const at = { x: series.length > 1 ? (Math.sign(dx) || 1) * lanes : dx, y: dy };
|
|
258
|
+
// Only a label that can sit at the plot's right end - any but a first point's - reaches that edge.
|
|
259
|
+
const selects = state.labelSelects ?? [];
|
|
260
|
+
const atRight = selects.length === 0 || selects.some((select) => select !== 'first');
|
|
261
|
+
// Likewise a label set before its point reaches the left edge only from a point that can sit there: any but a last one - or a last one that is also the first, of a series with a single point.
|
|
262
|
+
const atLeft = selects.length === 0 ||
|
|
263
|
+
selects.some((select) => select !== 'last') ||
|
|
264
|
+
series.some((s) => s.data.length < 2);
|
|
206
265
|
const edges = [
|
|
207
266
|
'top',
|
|
208
267
|
'bottom',
|
|
209
|
-
...(dx < 0 ? ['left'] : []),
|
|
210
|
-
...(dx >= 0 || series.length > 1 ? ['right'] : [])
|
|
268
|
+
...(dx < 0 && atLeft ? ['left'] : []),
|
|
269
|
+
...((dx >= 0 || series.length > 1) && atRight ? ['right'] : [])
|
|
211
270
|
];
|
|
212
271
|
const texts = [];
|
|
213
272
|
const domain = state.scales.y?.domain;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" generics="TRow extends Record<string, unknown>">
|
|
2
2
|
import { untrack } from 'svelte';
|
|
3
|
-
import { resolveAccessor } from '../../
|
|
3
|
+
import { resolveAccessor } from '../../utils/accessors';
|
|
4
4
|
import TimelineFrame from './TimelineFrame.svelte';
|
|
5
5
|
import { TimelineSteps } from './TimelineSteps';
|
|
6
6
|
import { TimelineTime } from './TimelineTime';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts" generics="TRow extends Record<string, unknown>">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import { TooltipState } from './TooltipState.svelte';
|
|
4
|
-
import type { TooltipAnchorX, TooltipAnchorY } from '../../types/layout/tooltip';
|
|
4
|
+
import type { TooltipAnchorX, TooltipAnchorY, TooltipRow } from '../../types/layout/tooltip';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* A plot's floating tooltip at `(x, y)`, inside a `position: relative`
|
|
@@ -28,13 +28,13 @@
|
|
|
28
28
|
visible: boolean;
|
|
29
29
|
x: number;
|
|
30
30
|
y: number;
|
|
31
|
-
/** Every row the hover matched. */
|
|
32
|
-
rows: TRow[];
|
|
31
|
+
/** Every row the hover matched, with the color the plot draws it in. */
|
|
32
|
+
rows: TooltipRow<TRow>[];
|
|
33
33
|
format: (row: TRow) => string;
|
|
34
34
|
/** The order the `format` text reads the rows in. Unset, as matched. */
|
|
35
35
|
sort?: (a: TRow, b: TRow) => number;
|
|
36
36
|
/** Custom tooltip body, given every row; replaces the `format` text and the default box. */
|
|
37
|
-
content?: Snippet<[{ rows: TRow[] }]>;
|
|
37
|
+
content?: Snippet<[{ rows: TooltipRow<TRow>[] }]>;
|
|
38
38
|
/** Box the tooltip must stay within. Defaults to its plot's box. */
|
|
39
39
|
bounds?: { width: number; height: number };
|
|
40
40
|
/** Preferred horizontal side of the point. Defaults to `'right'`. */
|