@fundar/data-chart-telling 1.0.0 → 1.2.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 +53 -0
- package/README.md +58 -19
- package/dist/configuration/config.svelte.d.ts +1 -1
- package/dist/configuration/config.svelte.js +172 -95
- package/dist/configuration/themes/index.d.ts +5 -1304
- package/dist/index.d.ts +24 -14
- package/dist/index.js +20 -10
- package/dist/layout/base/BasePlotLayout.svelte +129 -51
- 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/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/hover/HoverSettings.d.ts +20 -6
- package/dist/layout/hover/HoverSettings.js +29 -4
- 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 +1 -1
- package/dist/layout/legend/LegendChannels.js +36 -12
- package/dist/layout/legend/LegendLayout.svelte +9 -1
- package/dist/layout/legend/LegendState.svelte.d.ts +9 -0
- package/dist/layout/legend/LegendState.svelte.js +24 -3
- 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 +4 -8
- package/dist/layout/plot/Plot.svelte +6 -3
- package/dist/layout/plot/PublicPlotContext.d.ts +5 -4
- package/dist/layout/plot/PublicPlotContext.js +7 -3
- package/dist/layout/plot/Slice.d.ts +5 -1
- package/dist/layout/plot/Slice.js +18 -6
- package/dist/layout/scales/EdgeTicks.d.ts +39 -0
- package/dist/layout/scales/EdgeTicks.js +82 -0
- package/dist/layout/scales/NiceTicks.d.ts +43 -0
- package/dist/layout/scales/NiceTicks.js +76 -0
- package/dist/layout/scales/ScalesLayout.svelte +133 -34
- package/dist/layout/scales/ScalesLayout.svelte.d.ts +10 -0
- package/dist/layout/scales/SveltePlotScale.d.ts +15 -0
- package/dist/layout/scales/SveltePlotScale.js +86 -0
- 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 +83 -23
- package/dist/layout/timeline/Timeline.svelte +5 -2
- package/dist/layout/timeline/Timeline.svelte.d.ts +2 -0
- package/dist/layout/timeline/TimelineLayout.svelte +39 -13
- package/dist/layout/timeline/TimelineLayout.svelte.d.ts +7 -5
- package/dist/layout/timeline/TimelineRule.svelte +1 -0
- package/dist/layout/timeline/TimelineState.svelte.d.ts +13 -5
- package/dist/layout/timeline/TimelineState.svelte.js +42 -8
- package/dist/layout/timeline/TimelineTime.d.ts +18 -0
- package/dist/layout/timeline/TimelineTime.js +117 -0
- package/dist/layout/tooltip/Tooltip.svelte +10 -7
- package/dist/layout/tooltip/Tooltip.svelte.d.ts +6 -4
- package/dist/layout/tooltip/TooltipState.svelte.d.ts +8 -2
- package/dist/layout/tooltip/TooltipState.svelte.js +23 -4
- 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.js +1 -1
- package/dist/markers/delta/DeltaMarker.svelte +9 -7
- 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 +9 -3
- 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 +8 -2
- package/dist/phases/data/DataPhase.d.ts +5 -11
- package/dist/phases/data/DataPhase.js +14 -11
- package/dist/phases/data/PlotAxes.d.ts +10 -0
- package/dist/phases/data/PlotAxes.js +14 -1
- package/dist/phases/facet/FacetPanels.d.ts +55 -0
- package/dist/phases/facet/FacetPanels.js +96 -0
- package/dist/phases/facet/FacetPhase.d.ts +1 -42
- package/dist/phases/facet/FacetPhase.js +1 -87
- package/dist/phases/hover/HoverPhase.d.ts +6 -43
- package/dist/phases/hover/HoverPhase.js +19 -54
- package/dist/phases/mapping/MappingPhase.d.ts +1 -1
- package/dist/phases/mapping/MappingPhase.js +3 -5
- 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.d.ts +1 -3
- package/dist/phases/scales/ScalesPhase.js +37 -27
- package/dist/phases/sharedScales/SharedScalesPhase.d.ts +6 -2
- package/dist/phases/sharedScales/SharedScalesPhase.js +14 -8
- package/dist/phases/statistics/Statistics.d.ts +10 -6
- package/dist/phases/statistics/Statistics.js +20 -10
- package/dist/phases/statistics/StatisticsPhase.js +10 -6
- 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/tooltip/TooltipPhase.d.ts +4 -2
- package/dist/phases/tooltip/TooltipPhase.js +10 -3
- package/dist/phases/transforms/ProcessedPositions.d.ts +30 -0
- package/dist/phases/transforms/ProcessedPositions.js +74 -0
- package/dist/phases/transforms/TransformsPhase.d.ts +5 -42
- package/dist/phases/transforms/TransformsPhase.js +67 -58
- 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 +4 -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 +6 -5
- package/dist/plots/{scatter → correlation/scatter}/markers.d.ts +4 -4
- package/dist/plots/{scatter → correlation/scatter}/markers.js +5 -4
- package/dist/plots/distribution/box/BoxSummaries.d.ts +19 -0
- package/dist/plots/distribution/box/BoxSummaries.js +101 -0
- package/dist/plots/distribution/box/Plot.svelte +42 -0
- package/dist/plots/distribution/box/Plot.svelte.d.ts +26 -0
- package/dist/plots/distribution/box/defaults.d.ts +12 -0
- package/dist/plots/distribution/box/defaults.js +34 -0
- package/dist/plots/distribution/box/markers.d.ts +12 -0
- package/dist/plots/distribution/box/markers.js +34 -0
- 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 +4 -4
- package/dist/plots/{histogram → distribution/histogram}/markers.d.ts +3 -3
- package/dist/plots/{histogram → distribution/histogram}/markers.js +7 -7
- 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 +7 -6
- package/dist/plots/{pyramid → distribution/pyramid}/markers.d.ts +4 -4
- package/dist/plots/{pyramid → distribution/pyramid}/markers.js +8 -11
- 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 +2 -3
- 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 +7 -6
- 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 +5 -5
- package/dist/plots/{geo → map/geo}/phases/markers.d.ts +1 -1
- package/dist/plots/{geo → map/geo}/phases/markers.js +8 -13
- 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 +7 -4
- 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 +17 -15
- package/dist/plots/{bar → ranking/bar}/markers.d.ts +8 -8
- package/dist/plots/{bar → ranking/bar}/markers.js +11 -19
- 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.js +1 -1
- package/dist/types/configuration/styling.d.ts +287 -132
- package/dist/types/layout/composer.d.ts +5 -2
- package/dist/types/layout/coordinates.d.ts +5 -4
- package/dist/types/layout/legend.d.ts +21 -5
- package/dist/types/layout/plot.d.ts +44 -1
- package/dist/types/layout/scales.d.ts +51 -3
- 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 +19 -7
- 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/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 +9 -0
- 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/hover/phase.d.ts +6 -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 +20 -4
- package/dist/types/phases/statistics/phase.d.ts +3 -1
- package/dist/types/phases/statistics/source.d.ts +3 -1
- package/dist/types/phases/transforms/phase.d.ts +32 -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/distribution/box/props.d.ts +10 -0
- package/dist/types/plots/distribution/box/state.d.ts +23 -0
- 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/distribution/density/state.js +1 -0
- package/dist/types/plots/{histogram → distribution/histogram}/props.d.ts +7 -7
- package/dist/types/plots/distribution/histogram/props.js +1 -0
- 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 +3 -1
- 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/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 +39 -8
- package/docs/composer.md +19 -3
- package/docs/concepts.md +1 -1
- package/docs/development.md +14 -5
- package/docs/facets.md +62 -8
- package/docs/getting-started.md +8 -9
- package/docs/legend.md +73 -24
- package/docs/markers.md +45 -32
- 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 -154
- package/docs/scales.md +50 -27
- package/docs/state.md +1 -1
- package/docs/styles-and-segments.md +96 -39
- package/docs/theming.md +33 -19
- package/docs/timeline.md +62 -28
- package/docs/tooltip-and-hover.md +72 -24
- package/docs/transforms-and-statistics.md +56 -25
- package/examples/BarValues.svelte +2 -2
- package/examples/Box.svelte +7 -0
- package/examples/Bullet.svelte +17 -0
- package/examples/Chrome.svelte +17 -0
- package/examples/ChromeOrder.svelte +18 -0
- package/examples/Cleveland.svelte +15 -0
- package/examples/Composer.svelte +23 -0
- package/examples/CustomTooltip.svelte +21 -14
- package/examples/Density.svelte +7 -0
- package/examples/Dumbbell.svelte +16 -0
- package/examples/Facets.svelte +3 -3
- package/examples/FacetsCarousel.svelte +14 -0
- package/examples/FacetsRowsCols.svelte +23 -0
- package/examples/FirstPlot.svelte +7 -0
- package/examples/Forest.svelte +17 -0
- package/examples/Gaps.svelte +21 -0
- package/examples/GroupedBars.svelte +15 -0
- package/examples/Heatmap.svelte +7 -0
- package/examples/HeatmapSegments.svelte +26 -0
- package/examples/Histogram.svelte +14 -0
- package/examples/HorizontalBars.svelte +15 -0
- package/examples/LegendSections.svelte +27 -0
- package/examples/LegendToggle.svelte +3 -3
- package/examples/LineByRegion.svelte +18 -0
- package/examples/LineDates.svelte +15 -0
- package/examples/LineStep.svelte +16 -0
- package/examples/LineStepSegment.svelte +18 -0
- package/examples/Lollipop.svelte +17 -0
- package/examples/Markers.svelte +27 -0
- package/examples/MovingAverage.svelte +15 -0
- package/examples/Pyramid.svelte +14 -0
- package/examples/Regression.svelte +14 -0
- package/examples/ResponsiveLine.svelte +7 -7
- package/examples/Scales.svelte +26 -0
- package/examples/Scatter.svelte +16 -0
- package/examples/SegmentHighlight.svelte +22 -0
- package/examples/Segments.svelte +11 -3
- package/examples/SegmentsBySeries.svelte +25 -0
- package/examples/Slope.svelte +17 -0
- package/examples/Sparkline.svelte +14 -0
- package/examples/StackedArea.svelte +16 -0
- package/examples/StackedBars.svelte +15 -0
- package/examples/TimelinePlayer.svelte +8 -7
- package/examples/TimelineRule.svelte +19 -0
- package/examples/Tooltip.svelte +3 -3
- package/examples/ValueLabels.svelte +21 -0
- 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 +51 -12
- package/llms.txt +60 -4
- package/package.json +12 -2
- package/dist/layout/scales/buildScale.d.ts +0 -8
- package/dist/layout/scales/buildScale.js +0 -67
- package/dist/layout/scales/niceDomain.d.ts +0 -23
- package/dist/layout/scales/niceDomain.js +0 -59
- 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 -12
- /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/geo/props.js → layout/styles/gaps.js} +0 -0
- /package/dist/types/{plots/geo/state.js → layout/styles/geo.js} +0 -0
- /package/dist/types/{plots/heatmap/props.js → layout/styles/values.js} +0 -0
- /package/dist/types/{plots/heatmap/state.js → markers/axis/violin.js} +0 -0
- /package/dist/types/{plots/histogram/props.js → markers/channels/commonMarkerConfigWithRowOffset.js} +0 -0
- /package/dist/types/plots/{line → correlation/heatmap}/props.js +0 -0
- /package/dist/types/plots/{histogram → correlation/heatmap}/state.js +0 -0
- /package/dist/types/plots/{pyramid → correlation/scatter}/props.js +0 -0
- /package/dist/types/plots/{line → correlation/scatter}/state.js +0 -0
- /package/dist/types/plots/{scatter → distribution/box}/props.js +0 -0
- /package/dist/types/plots/{pyramid → distribution/box}/state.js +0 -0
- /package/dist/types/plots/{scatter/state.js → distribution/density/props.js} +0 -0
- /package/dist/{plots/utils → utils}/accessors.d.ts +0 -0
- /package/dist/{plots/utils → utils}/accessors.js +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { resolveAccessor } from '../../
|
|
1
|
+
import { resolveAccessor } from '../../utils/accessors';
|
|
2
2
|
import { getConfiguration } from '../../configuration/config.svelte';
|
|
3
3
|
import { ChannelName } from '../../plots/utils/ChannelName';
|
|
4
4
|
import { MarkerKinds } from '../../markers/MarkerKinds';
|
|
5
5
|
import { ContinuousDomain } from '../../utils/ContinuousDomain';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
6
|
+
import { ColorRamp } from '../../utils/color';
|
|
7
|
+
import { OpacityScale } from '../../utils/OpacityScale';
|
|
8
|
+
import { SymbolScale } from '../../utils/SymbolScale';
|
|
9
9
|
/**
|
|
10
10
|
* What a plot's value channels - `color`, `opacity`, `r` and `symbol` - draw
|
|
11
11
|
* with, as legend entries: the plot's own (a heatmap's cells, a map's
|
|
@@ -17,6 +17,7 @@ export class LegendChannels {
|
|
|
17
17
|
const taken = new Set((plot.resolvedSeries ?? []).map((s) => s.name));
|
|
18
18
|
return [
|
|
19
19
|
...LegendChannels.#plotColor(plot),
|
|
20
|
+
...LegendChannels.#segmentColors(plot),
|
|
20
21
|
...markers.flatMap((marker) => LegendChannels.#markerColor(marker, taken)),
|
|
21
22
|
...LegendChannels.#plotOpacity(plot),
|
|
22
23
|
...markers.flatMap((marker) => LegendChannels.#markerOpacity(marker, plot)),
|
|
@@ -45,6 +46,15 @@ export class LegendChannels {
|
|
|
45
46
|
static #title(channel, property) {
|
|
46
47
|
return typeof channel === 'string' ? channel : ChannelName.of(channel, property);
|
|
47
48
|
}
|
|
49
|
+
/** The domain svelteplot sizes with: the configured one or the values' own, taken down to 0 unless `zero` is off. */
|
|
50
|
+
static #sizeDomain(scale, values) {
|
|
51
|
+
const [low, high] = scale?.domain ?? [Math.min(...values), Math.max(...values)];
|
|
52
|
+
return scale?.zero === false ? [low, high] : [Math.min(0, low), Math.max(0, high)];
|
|
53
|
+
}
|
|
54
|
+
/** A plot channel's name: its field key, or the name of the function that computes it. */
|
|
55
|
+
static #sourceTitle(source, property) {
|
|
56
|
+
return typeof source === 'string' ? source : ChannelName.of(source, property);
|
|
57
|
+
}
|
|
48
58
|
/** `marker`'s rows read through `channel` (a field or a function), without the missing and non-finite ones. */
|
|
49
59
|
static #values(marker, channel) {
|
|
50
60
|
if (channel === undefined || channel === null || typeof channel === 'number')
|
|
@@ -102,6 +112,11 @@ export class LegendChannels {
|
|
|
102
112
|
LegendChannels.#scaleEntry(typeof source === 'string' ? source : undefined, domain, scale)
|
|
103
113
|
];
|
|
104
114
|
}
|
|
115
|
+
/** One continuous ramp per segment that sets its own, over the values of just its own features. */
|
|
116
|
+
static #segmentColors(plot) {
|
|
117
|
+
const source = plot.channels?.color?.source;
|
|
118
|
+
return (plot.colorRamps ?? []).map(({ name, domain, scale }) => LegendChannels.#scaleEntry(typeof source === 'string' ? `${source} (${name})` : name, domain, scale));
|
|
119
|
+
}
|
|
105
120
|
/**
|
|
106
121
|
* A marker's `color` channel: a continuous scale for numbers; for
|
|
107
122
|
* categories, one item each in the color the marker draws it, unless a
|
|
@@ -118,7 +133,7 @@ export class LegendChannels {
|
|
|
118
133
|
return domain ? [LegendChannels.#scaleEntry(title, domain, scale)] : [];
|
|
119
134
|
}
|
|
120
135
|
const categories = [...new Set(values.map(String))];
|
|
121
|
-
const colorOf =
|
|
136
|
+
const colorOf = ColorRamp.resolve(scale, categories, getConfiguration().palette);
|
|
122
137
|
const mark = MarkerKinds.of(marker.type)?.legendSymbol;
|
|
123
138
|
return categories
|
|
124
139
|
.filter((name) => !taken.has(name))
|
|
@@ -127,7 +142,7 @@ export class LegendChannels {
|
|
|
127
142
|
static #opacityEntry(title, domain, scale, color) {
|
|
128
143
|
if (scale?.range !== undefined && !Array.isArray(scale.range))
|
|
129
144
|
return [];
|
|
130
|
-
const read =
|
|
145
|
+
const read = OpacityScale.resolve(scale, domain, getConfiguration().continuous.opacityRange);
|
|
131
146
|
return [
|
|
132
147
|
{
|
|
133
148
|
type: 'opacity',
|
|
@@ -141,13 +156,20 @@ export class LegendChannels {
|
|
|
141
156
|
}
|
|
142
157
|
];
|
|
143
158
|
}
|
|
144
|
-
/**
|
|
159
|
+
/**
|
|
160
|
+
* The plot's own numeric `opacity` channel, over the `opacityDomain` it hands
|
|
161
|
+
* over, in its series' color - unless a `color` channel colors the marks, and
|
|
162
|
+
* no one color stands for them.
|
|
163
|
+
*/
|
|
145
164
|
static #plotOpacity(plot) {
|
|
146
165
|
if (!plot.opacityDomain)
|
|
147
166
|
return [];
|
|
148
167
|
const source = plot.channels?.opacity?.source;
|
|
149
168
|
const name = plot.resolvedSeries?.[0]?.name;
|
|
150
|
-
const
|
|
169
|
+
const colored = plot.channels?.color?.source !== undefined || !!plot.colorDomain;
|
|
170
|
+
const color = !colored && name !== undefined && name !== 'default'
|
|
171
|
+
? plot.colorForSeries?.(name)
|
|
172
|
+
: undefined;
|
|
151
173
|
return LegendChannels.#opacityEntry(typeof source === 'string' ? source : undefined, plot.opacityDomain, plot.scales?.opacity, color);
|
|
152
174
|
}
|
|
153
175
|
/** A marker's numeric `opacity` channel, in the color the marker draws. */
|
|
@@ -176,13 +198,14 @@ export class LegendChannels {
|
|
|
176
198
|
if (values.length === 0)
|
|
177
199
|
return [];
|
|
178
200
|
const { filled, color, symbol } = LegendChannels.look(sized);
|
|
179
|
-
const source = plot.channels?.r?.source
|
|
201
|
+
const source = LegendChannels.#sourceTitle(plot.channels?.r?.source, 'r') ??
|
|
202
|
+
LegendChannels.#title(sized[0].r, 'r');
|
|
180
203
|
return [
|
|
181
204
|
{
|
|
182
205
|
type: 'size',
|
|
183
206
|
channel: 'r',
|
|
184
207
|
...(typeof source === 'string' ? { title: source } : {}),
|
|
185
|
-
domain: plot.scales?.r
|
|
208
|
+
domain: LegendChannels.#sizeDomain(plot.scales?.r, values),
|
|
186
209
|
range: plot.scales?.r?.range ?? [0, 10],
|
|
187
210
|
...(color ? { color } : {}),
|
|
188
211
|
filled,
|
|
@@ -204,9 +227,10 @@ export class LegendChannels {
|
|
|
204
227
|
shaped.flatMap((marker) => LegendChannels.#values(marker, marker.symbol).map(String))).filter((value, i, all) => all.indexOf(value) === i);
|
|
205
228
|
if (domain.length === 0)
|
|
206
229
|
return [];
|
|
207
|
-
const shapeOf =
|
|
230
|
+
const shapeOf = SymbolScale.resolve(config, domain, getConfiguration().symbols);
|
|
208
231
|
const { filled, color } = LegendChannels.look(shaped);
|
|
209
|
-
const source = plot.channels?.symbol?.source
|
|
232
|
+
const source = LegendChannels.#sourceTitle(plot.channels?.symbol?.source, 'symbol') ??
|
|
233
|
+
LegendChannels.#title(shaped[0].symbol, 'symbol');
|
|
210
234
|
return [
|
|
211
235
|
{
|
|
212
236
|
type: 'symbol',
|
|
@@ -15,10 +15,18 @@
|
|
|
15
15
|
const defaultItemsLayout = $derived<LegendItemsLayout>(
|
|
16
16
|
sections.length === 1 ? { type: 'horizontal' } : { type: 'vertical' }
|
|
17
17
|
);
|
|
18
|
+
|
|
19
|
+
// Sections of different channels can share a title, so a key leads with its channel; a repeat takes its position.
|
|
20
|
+
const keys = $derived.by(() => {
|
|
21
|
+
const bases = sections.map(
|
|
22
|
+
(section) => `${'channel' in section ? section.channel : section.type}:${section.title ?? ''}`
|
|
23
|
+
);
|
|
24
|
+
return bases.map((base, i) => (bases.indexOf(base) === i ? base : `${base}:${i}`));
|
|
25
|
+
});
|
|
18
26
|
</script>
|
|
19
27
|
|
|
20
28
|
<div class="dct-legend">
|
|
21
|
-
{#each sections as section, i (
|
|
29
|
+
{#each sections as section, i (keys[i])}
|
|
22
30
|
<div class="dct-legend__section">
|
|
23
31
|
{#if section.title}
|
|
24
32
|
<div class="dct-legend__title">{section.title}</div>
|
|
@@ -18,8 +18,17 @@ export declare class LegendState {
|
|
|
18
18
|
static current(): LegendState | null;
|
|
19
19
|
/** A new legend, shared with everything below. Call during component init. */
|
|
20
20
|
static provide(): LegendState;
|
|
21
|
+
/** Keeps the plots below out of the enclosing legend: they still follow its toggles, but add nothing to it. Call during component init. */
|
|
22
|
+
static silence(): void;
|
|
23
|
+
/** Whether the plots here are kept out of the enclosing legend (see {@link silence}). Call during component init. */
|
|
24
|
+
static isSilenced(): boolean;
|
|
21
25
|
/** The enclosing figure's legend, or a private one for a legend drawn outside any. Call during component init. */
|
|
22
26
|
static ensure(): LegendState;
|
|
27
|
+
/** Whether `value` lies within `range`; a missing value always does. */
|
|
28
|
+
static inRange(value: number | null | undefined, range: {
|
|
29
|
+
min: number;
|
|
30
|
+
max: number;
|
|
31
|
+
}): boolean;
|
|
23
32
|
/** Whether `series` is turned off. */
|
|
24
33
|
isOff(series: string): boolean;
|
|
25
34
|
/** What turning `series` off does, while it is off. */
|
|
@@ -5,6 +5,7 @@ import { MarkerKinds } from '../../markers/MarkerKinds';
|
|
|
5
5
|
import { LegendChannels } from './LegendChannels';
|
|
6
6
|
import { LegendText } from './LegendText';
|
|
7
7
|
const LEGEND_KEY = Symbol('dct-legend');
|
|
8
|
+
const QUIET_KEY = Symbol('dct-legend-quiet');
|
|
8
9
|
/**
|
|
9
10
|
* A figure's legend, shared by every plot and legend under it: what the
|
|
10
11
|
* reader turned off - each series' {@link LegendDisabledAction}, and the
|
|
@@ -29,10 +30,22 @@ export class LegendState {
|
|
|
29
30
|
setContext(LEGEND_KEY, legend);
|
|
30
31
|
return legend;
|
|
31
32
|
}
|
|
33
|
+
/** Keeps the plots below out of the enclosing legend: they still follow its toggles, but add nothing to it. Call during component init. */
|
|
34
|
+
static silence() {
|
|
35
|
+
setContext(QUIET_KEY, true);
|
|
36
|
+
}
|
|
37
|
+
/** Whether the plots here are kept out of the enclosing legend (see {@link silence}). Call during component init. */
|
|
38
|
+
static isSilenced() {
|
|
39
|
+
return getContext(QUIET_KEY) ?? false;
|
|
40
|
+
}
|
|
32
41
|
/** The enclosing figure's legend, or a private one for a legend drawn outside any. Call during component init. */
|
|
33
42
|
static ensure() {
|
|
34
43
|
return LegendState.current() ?? new LegendState();
|
|
35
44
|
}
|
|
45
|
+
/** Whether `value` lies within `range`; a missing value always does. */
|
|
46
|
+
static inRange(value, range) {
|
|
47
|
+
return value == null || (value >= range.min && value <= range.max);
|
|
48
|
+
}
|
|
36
49
|
/** Whether `series` is turned off. */
|
|
37
50
|
isOff(series) {
|
|
38
51
|
return this.disabled.has(series);
|
|
@@ -145,19 +158,21 @@ export class LegendState {
|
|
|
145
158
|
const { title, domain, range, color, filled, symbol } = entry;
|
|
146
159
|
ramps.push({
|
|
147
160
|
type: 'size',
|
|
161
|
+
channel: 'r',
|
|
148
162
|
title: title && format(title),
|
|
149
163
|
domain,
|
|
150
164
|
range,
|
|
151
165
|
color,
|
|
152
166
|
filled,
|
|
153
167
|
...(symbol ? { symbol } : {}),
|
|
154
|
-
...adjust('
|
|
168
|
+
...adjust('r', title)
|
|
155
169
|
});
|
|
156
170
|
}
|
|
157
171
|
else if (entry.type === 'symbol') {
|
|
158
172
|
const { title, items: shapes, color, filled } = entry;
|
|
159
173
|
ramps.push({
|
|
160
174
|
type: 'symbol',
|
|
175
|
+
channel: 'symbol',
|
|
161
176
|
title: title && format(title),
|
|
162
177
|
items: shapes,
|
|
163
178
|
color,
|
|
@@ -169,6 +184,7 @@ export class LegendState {
|
|
|
169
184
|
const { title, min, max, opacityMin, opacityMax, color } = entry;
|
|
170
185
|
ramps.push({
|
|
171
186
|
type: 'continuous',
|
|
187
|
+
channel: 'opacity',
|
|
172
188
|
title: title && format(title),
|
|
173
189
|
min,
|
|
174
190
|
max,
|
|
@@ -181,6 +197,7 @@ export class LegendState {
|
|
|
181
197
|
const { title, min, max, colorMin, colorMax, scheme, pivot } = entry;
|
|
182
198
|
const section = {
|
|
183
199
|
type: 'continuous',
|
|
200
|
+
channel: 'color',
|
|
184
201
|
title: title && format(title),
|
|
185
202
|
min,
|
|
186
203
|
max,
|
|
@@ -264,11 +281,15 @@ export class LegendState {
|
|
|
264
281
|
*/
|
|
265
282
|
static entriesOf(plot) {
|
|
266
283
|
const color = (name) => name !== undefined && name !== 'default' ? plot.colorForSeries?.(name) : undefined;
|
|
284
|
+
// A marker that is `legend: false` is decoration - a connector - and does not give the series its symbol.
|
|
267
285
|
const mark = plot.markers
|
|
268
|
-
?.
|
|
286
|
+
?.filter((marker) => marker.legend !== false)
|
|
287
|
+
.map((marker) => MarkerKinds.of(marker.type)?.legendSymbol)
|
|
269
288
|
.find((kind) => kind !== undefined);
|
|
270
289
|
const dots = LegendChannels.look((plot.markers ?? []).filter((marker) => marker.type === 'dot' && !marker.legend));
|
|
271
|
-
|
|
290
|
+
// A series with no rows draws nothing, so it has nothing to show.
|
|
291
|
+
const drawn = (plot.resolvedSeries ?? []).filter((s) => !Array.isArray(s.data) || s.data.length > 0);
|
|
292
|
+
const series = drawn.map((s) => ({
|
|
272
293
|
type: 'series',
|
|
273
294
|
name: s.name,
|
|
274
295
|
color: color(s.name),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { ticks } from 'd3-array';
|
|
3
3
|
import type { SizeLegendSection } from '../../types/layout/legend';
|
|
4
|
-
import { SymbolPath } from '../../utils/
|
|
4
|
+
import { SymbolPath } from '../../utils/SymbolPath';
|
|
5
5
|
import { AxisNumberFormat } from './AxisNumberFormat';
|
|
6
6
|
import { getConfiguration } from '../../configuration/config.svelte';
|
|
7
7
|
|
|
@@ -29,6 +29,8 @@ export type PlotMarginsInputs = {
|
|
|
29
29
|
scales: () => Partial<Record<AxisChannelName, Pick<AxisScale, 'tickRotate'>>> | undefined;
|
|
30
30
|
/** The tick labels' font size. */
|
|
31
31
|
tickFontSize: () => number;
|
|
32
|
+
/** How wide the widest tick label of an axis is, where the plot measured it: a rotated axis takes room for that, not for a guessed width. */
|
|
33
|
+
tickWidth?: () => Partial<Record<AxisChannelName, number | undefined>>;
|
|
32
34
|
/** Receives the margins the labels settled on - the plot's bindable `margins`. */
|
|
33
35
|
settle?: (margins: MarginConfig) => void;
|
|
34
36
|
};
|
|
@@ -93,9 +95,4 @@ export declare class PlotMargins {
|
|
|
93
95
|
x: number;
|
|
94
96
|
y: number;
|
|
95
97
|
}, anchor: BoxAnchors): Box;
|
|
96
|
-
/**
|
|
97
|
-
* Changes whenever the labels' margins move after mount, which svelteplot
|
|
98
|
-
* only takes on a remount. The same margins read back from `settle` keep it.
|
|
99
|
-
*/
|
|
100
|
-
readonly remountKey: string;
|
|
101
98
|
}
|
|
@@ -161,18 +161,19 @@ export class PlotMargins {
|
|
|
161
161
|
/**
|
|
162
162
|
* How much more room (or less) each axis' rotated tick labels take across
|
|
163
163
|
* it, on its side. An x label stands as tall as its text, a y label as wide;
|
|
164
|
-
* rotated, it reaches across by its turned box.
|
|
165
|
-
* as wide as its font size.
|
|
164
|
+
* rotated, it reaches across by its turned box.
|
|
166
165
|
*/
|
|
167
166
|
#tickRoom = $derived.by(() => {
|
|
168
167
|
const scales = this.#inputs.scales();
|
|
169
168
|
const height = this.#inputs.tickFontSize();
|
|
170
|
-
const
|
|
169
|
+
const measured = this.#inputs.tickWidth?.();
|
|
171
170
|
const room = {};
|
|
172
171
|
for (const axis of ['x', 'y']) {
|
|
173
172
|
const degrees = scales?.[axis]?.tickRotate;
|
|
174
173
|
if (!degrees)
|
|
175
174
|
continue;
|
|
175
|
+
// A label is taken as twice as wide as its font size, unless the plot measured it.
|
|
176
|
+
const width = measured?.[axis] || 2 * height;
|
|
176
177
|
const rad = (degrees * Math.PI) / 180;
|
|
177
178
|
const [across, along] = axis === 'x' ? [height, width] : [width, height];
|
|
178
179
|
const turned = Math.abs(Math.cos(rad)) * across + Math.abs(Math.sin(rad)) * along;
|
|
@@ -211,9 +212,4 @@ export class PlotMargins {
|
|
|
211
212
|
place(size, point, anchor) {
|
|
212
213
|
return size.placeNear(point, anchor, this.box);
|
|
213
214
|
}
|
|
214
|
-
/**
|
|
215
|
-
* Changes whenever the labels' margins move after mount, which svelteplot
|
|
216
|
-
* only takes on a remount. The same margins read back from `settle` keep it.
|
|
217
|
-
*/
|
|
218
|
-
remountKey = $derived.by(() => JSON.stringify(this.#labels ?? null));
|
|
219
215
|
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import { HoverState } from '../hover/HoverState.svelte';
|
|
15
15
|
import { HoverSettings } from '../hover/HoverSettings';
|
|
16
16
|
import { Interpolation } from '../../utils/Interpolation';
|
|
17
|
-
import {
|
|
17
|
+
import { FacetPanels } from '../../phases/facet/FacetPanels';
|
|
18
18
|
import { merge } from '../../utils/merge';
|
|
19
19
|
import { Pipeline } from '../../phases/Pipeline';
|
|
20
20
|
import { Slice } from './Slice';
|
|
@@ -191,7 +191,9 @@
|
|
|
191
191
|
margins: place.margins,
|
|
192
192
|
tooltip: tooltipConfig,
|
|
193
193
|
scales: slicing.facetScales<TScales>(sharedScales, place),
|
|
194
|
-
panel: panels
|
|
194
|
+
panel: panels
|
|
195
|
+
? FacetPanels.buildPanelState(panels, slicing.panelKey(place) ?? '')
|
|
196
|
+
: undefined,
|
|
195
197
|
keep: slicing.keep({ time, facet: place })
|
|
196
198
|
})}
|
|
197
199
|
</HoverScope>
|
|
@@ -246,9 +248,10 @@
|
|
|
246
248
|
<TimelineLayout
|
|
247
249
|
data={rows}
|
|
248
250
|
accessor={timeline.accessor}
|
|
251
|
+
dateFormat={timeline.dateFormat}
|
|
249
252
|
progress={timelineState?.progress ?? timeline.progress ?? 0}
|
|
250
253
|
values={sharedTimeline ? sharedTimeline.steps : timeline.values}
|
|
251
|
-
onsteps={ownTimeline ? (found) => ownTimeline.setSteps(found) : undefined}
|
|
254
|
+
onsteps={ownTimeline ? (found, temporal) => ownTimeline.setSteps(found, temporal) : undefined}
|
|
252
255
|
orientation={timeline.orientation}
|
|
253
256
|
show={false}
|
|
254
257
|
filterMode={slicing.filterMode}
|
|
@@ -8,7 +8,7 @@ import type { Margins } from '../margins/Margins';
|
|
|
8
8
|
import type { PlotAxes } from '../../phases/data/PlotAxes';
|
|
9
9
|
import type { AxisValue } from '../../types/layout/mapping';
|
|
10
10
|
import type { HoverPoint, HoverStrategy } from '../../types/layout/hover';
|
|
11
|
-
import type { PlayerControl,
|
|
11
|
+
import type { PlayerControl, TimeInput, TimelineStep } from '../../types/layout/timeline';
|
|
12
12
|
import type { LegendDisabledAction, LegendEntry, LegendRange } from '../../types/layout/legend';
|
|
13
13
|
/** What the pointer is over, shared by every plot in a figure. Read-only. */
|
|
14
14
|
export declare class PublicHover {
|
|
@@ -69,11 +69,11 @@ export declare class PublicTimeline {
|
|
|
69
69
|
/** Whether the figure has a timeline at all. */
|
|
70
70
|
get enabled(): boolean;
|
|
71
71
|
/** Every step it moves across, ascending. */
|
|
72
|
-
get steps():
|
|
72
|
+
get steps(): TimelineStep[];
|
|
73
73
|
/** The position across the steps, `0`-`1`. */
|
|
74
74
|
get progress(): number;
|
|
75
75
|
/** The step the position lands on, or `undefined` without steps. */
|
|
76
|
-
get value():
|
|
76
|
+
get value(): TimelineStep | undefined;
|
|
77
77
|
get index(): number;
|
|
78
78
|
get playing(): boolean;
|
|
79
79
|
get loop(): boolean;
|
|
@@ -83,7 +83,8 @@ export declare class PublicTimeline {
|
|
|
83
83
|
get controls(): PlayerControl[];
|
|
84
84
|
seek(progress: number): void;
|
|
85
85
|
seekIndex(index: number): void;
|
|
86
|
-
|
|
86
|
+
/** Moves to the step closest to `value`. */
|
|
87
|
+
seekValue(value: TimeInput): void;
|
|
87
88
|
next(): void;
|
|
88
89
|
previous(): void;
|
|
89
90
|
play(): void;
|
|
@@ -104,7 +104,7 @@ export class PublicTimeline {
|
|
|
104
104
|
}
|
|
105
105
|
/** Every step it moves across, ascending. */
|
|
106
106
|
get steps() {
|
|
107
|
-
return this.#state.steps;
|
|
107
|
+
return this.#state.steps.map((step) => this.#state.step(step));
|
|
108
108
|
}
|
|
109
109
|
/** The position across the steps, `0`-`1`. */
|
|
110
110
|
get progress() {
|
|
@@ -112,7 +112,8 @@ export class PublicTimeline {
|
|
|
112
112
|
}
|
|
113
113
|
/** The step the position lands on, or `undefined` without steps. */
|
|
114
114
|
get value() {
|
|
115
|
-
|
|
115
|
+
const { value } = this.#state;
|
|
116
|
+
return value === undefined ? undefined : this.#state.step(value);
|
|
116
117
|
}
|
|
117
118
|
get index() {
|
|
118
119
|
return this.#state.index;
|
|
@@ -139,8 +140,11 @@ export class PublicTimeline {
|
|
|
139
140
|
seekIndex(index) {
|
|
140
141
|
this.#state.seekIndex(index);
|
|
141
142
|
}
|
|
143
|
+
/** Moves to the step closest to `value`. */
|
|
142
144
|
seekValue(value) {
|
|
143
|
-
this.#state.
|
|
145
|
+
const time = this.#state.timeOf(value);
|
|
146
|
+
if (time !== undefined)
|
|
147
|
+
this.#state.seekValue(time);
|
|
144
148
|
}
|
|
145
149
|
next() {
|
|
146
150
|
this.#state.next();
|
|
@@ -39,6 +39,10 @@ export declare class Slice<TRow extends Record<string, unknown>> {
|
|
|
39
39
|
* displays its axes.
|
|
40
40
|
*/
|
|
41
41
|
facetScales<TScales extends object>(shared: Record<string, object> | undefined, place: FacetCellContext<TRow>): TScales | undefined;
|
|
42
|
-
/**
|
|
42
|
+
/**
|
|
43
|
+
* The scales a timeline alone keeps every step on - the domains all its rows
|
|
44
|
+
* span - unless it fits each step's own: both under `'free'`, or the one axis
|
|
45
|
+
* `'free-x'`/`'free-y'` names, which leaves the other on its shared domain.
|
|
46
|
+
*/
|
|
43
47
|
timelineScales<TScales extends object>(shared: Record<string, object> | undefined): TScales | undefined;
|
|
44
48
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { resolveAccessor } from '../../
|
|
1
|
+
import { resolveAccessor } from '../../utils/accessors';
|
|
2
2
|
import { merge } from '../../utils/merge';
|
|
3
3
|
import { TimelineSteps } from '../timeline/TimelineSteps';
|
|
4
|
+
import { TimelineTime } from '../timeline/TimelineTime';
|
|
4
5
|
import { buildFacetAxesDisplay } from '../facet/axes';
|
|
5
6
|
import { buildFacetPlaceKey, isFacetWrap } from '../facet/config';
|
|
6
7
|
/**
|
|
@@ -55,10 +56,11 @@ export class Slice {
|
|
|
55
56
|
};
|
|
56
57
|
if (timeline && place.time !== undefined) {
|
|
57
58
|
const get = resolveAccessor(timeline.accessor);
|
|
59
|
+
const reader = new TimelineTime(timeline.dateFormat);
|
|
58
60
|
const time = place.time;
|
|
59
61
|
tests.push((row) => {
|
|
60
|
-
const value = get(row);
|
|
61
|
-
if (value
|
|
62
|
+
const value = reader.toTime(get(row));
|
|
63
|
+
if (value === undefined)
|
|
62
64
|
return true;
|
|
63
65
|
return TimelineSteps.matches(value, time, this.filterMode);
|
|
64
66
|
});
|
|
@@ -88,11 +90,21 @@ export class Slice {
|
|
|
88
90
|
return undefined;
|
|
89
91
|
return merge(shared?.[key], this.#axes?.(place));
|
|
90
92
|
}
|
|
91
|
-
/**
|
|
93
|
+
/**
|
|
94
|
+
* The scales a timeline alone keeps every step on - the domains all its rows
|
|
95
|
+
* span - unless it fits each step's own: both under `'free'`, or the one axis
|
|
96
|
+
* `'free-x'`/`'free-y'` names, which leaves the other on its shared domain.
|
|
97
|
+
*/
|
|
92
98
|
timelineScales(shared) {
|
|
93
99
|
const { timeline, facet } = this;
|
|
94
|
-
|
|
100
|
+
const mode = timeline?.scales;
|
|
101
|
+
if (!timeline || facet || mode === 'free')
|
|
95
102
|
return undefined;
|
|
96
|
-
|
|
103
|
+
const all = shared?.[''];
|
|
104
|
+
if (!all || (mode !== 'free-x' && mode !== 'free-y'))
|
|
105
|
+
return all;
|
|
106
|
+
const kept = { ...all };
|
|
107
|
+
delete kept[mode === 'free-x' ? 'x' : 'y'];
|
|
108
|
+
return kept;
|
|
97
109
|
}
|
|
98
110
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { AxisChannelName } from '../../types/layout/mapping';
|
|
2
|
+
import type { AxisScale, EdgeTicksOptions } from '../../types/layout/scales';
|
|
3
|
+
/** What {@link EdgeTicks.build} measures an axis with. */
|
|
4
|
+
export type EdgeTicksInput = {
|
|
5
|
+
/** The axis measured: labels sit side by side along x, stacked along y. */
|
|
6
|
+
axis: AxisChannelName;
|
|
7
|
+
/** The axis' numeric values; their extent is the axis' domain. */
|
|
8
|
+
values: number[];
|
|
9
|
+
/** The axis' length in pixels. */
|
|
10
|
+
span: number;
|
|
11
|
+
/** The pixels between ticks the axis aims for, and the fewest ticks it takes. */
|
|
12
|
+
spacing: number;
|
|
13
|
+
min: number;
|
|
14
|
+
/** The tick labels' font size, in pixels. */
|
|
15
|
+
fontSize: number;
|
|
16
|
+
options: EdgeTicksOptions;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* The ticks of a continuous axis: its nice ticks plus the data's first and
|
|
20
|
+
* last values, so a reader sees where the data starts and ends. When an edge
|
|
21
|
+
* tick lands too close to the nice tick next to it for both labels to fit,
|
|
22
|
+
* `options.collision` decides which gives way, or widens the axis instead.
|
|
23
|
+
*/
|
|
24
|
+
export declare class EdgeTicks {
|
|
25
|
+
/** The share of the font size one label character takes, on average. */
|
|
26
|
+
static readonly CHARACTER_WIDTH = 0.6;
|
|
27
|
+
/** The pixels left between two neighbouring labels. */
|
|
28
|
+
static readonly LABEL_GAP = 6;
|
|
29
|
+
/** A plot's `scales.<axis>.edgeTicks` over the configuration's `axis.edgeTicks.<axis>`. */
|
|
30
|
+
static resolve(option: AxisScale['edgeTicks'], configured: EdgeTicksOptions): EdgeTicksOptions;
|
|
31
|
+
/**
|
|
32
|
+
* The axis' ticks, and the domain it widens to when `'extend'` resolved a
|
|
33
|
+
* collision. `undefined` when edge ticks are off or the values span nothing.
|
|
34
|
+
*/
|
|
35
|
+
static build({ axis, values, span, spacing, min, fontSize, options }: EdgeTicksInput): {
|
|
36
|
+
ticks: number[];
|
|
37
|
+
domain?: [number, number];
|
|
38
|
+
} | undefined;
|
|
39
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { NiceTicks } from './NiceTicks';
|
|
2
|
+
/**
|
|
3
|
+
* The ticks of a continuous axis: its nice ticks plus the data's first and
|
|
4
|
+
* last values, so a reader sees where the data starts and ends. When an edge
|
|
5
|
+
* tick lands too close to the nice tick next to it for both labels to fit,
|
|
6
|
+
* `options.collision` decides which gives way, or widens the axis instead.
|
|
7
|
+
*/
|
|
8
|
+
export class EdgeTicks {
|
|
9
|
+
/** The share of the font size one label character takes, on average. */
|
|
10
|
+
static CHARACTER_WIDTH = 0.6;
|
|
11
|
+
/** The pixels left between two neighbouring labels. */
|
|
12
|
+
static LABEL_GAP = 6;
|
|
13
|
+
/** A plot's `scales.<axis>.edgeTicks` over the configuration's `axis.edgeTicks.<axis>`. */
|
|
14
|
+
static resolve(option, configured) {
|
|
15
|
+
if (option === undefined)
|
|
16
|
+
return configured;
|
|
17
|
+
if (typeof option === 'boolean')
|
|
18
|
+
return { ...configured, enabled: option };
|
|
19
|
+
return { enabled: true, collision: option.collision ?? configured.collision };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* The axis' ticks, and the domain it widens to when `'extend'` resolved a
|
|
23
|
+
* collision. `undefined` when edge ticks are off or the values span nothing.
|
|
24
|
+
*/
|
|
25
|
+
static build({ axis, values, span, spacing, min, fontSize, options }) {
|
|
26
|
+
if (!options.enabled || values.length < 2)
|
|
27
|
+
return undefined;
|
|
28
|
+
const lo = Math.min(...values);
|
|
29
|
+
const hi = Math.max(...values);
|
|
30
|
+
if (!(hi > lo))
|
|
31
|
+
return undefined;
|
|
32
|
+
const count = NiceTicks.count(span, spacing, min);
|
|
33
|
+
// Whole-number values (years, counts) never get ticks between them.
|
|
34
|
+
const step = values.every(Number.isInteger)
|
|
35
|
+
? Math.max(1, NiceTicks.step(lo, hi, count))
|
|
36
|
+
: NiceTicks.step(lo, hi, count);
|
|
37
|
+
const nice = NiceTicks.inRange(lo, hi, step);
|
|
38
|
+
if (!nice.length)
|
|
39
|
+
return { ticks: [lo, hi] };
|
|
40
|
+
const eps = step * 1e-6;
|
|
41
|
+
const pixels = (value) => ((value - lo) / (hi - lo)) * span;
|
|
42
|
+
// Side by side, two labels need half of each one's width; stacked, one line's height.
|
|
43
|
+
const labelWidth = (value) => String(value).length * fontSize * EdgeTicks.CHARACTER_WIDTH;
|
|
44
|
+
const room = (edge, neighbour) => axis === 'x' ? (labelWidth(edge) + labelWidth(neighbour)) / 2 : fontSize;
|
|
45
|
+
const crowds = (edge, neighbour) => Math.abs(pixels(edge) - pixels(neighbour)) < room(edge, neighbour) + EdgeTicks.LABEL_GAP;
|
|
46
|
+
const inner = [...nice];
|
|
47
|
+
const before = [];
|
|
48
|
+
const after = [];
|
|
49
|
+
let domainLo = lo;
|
|
50
|
+
let domainHi = hi;
|
|
51
|
+
const first = nice[0];
|
|
52
|
+
if (first - lo > eps) {
|
|
53
|
+
if (!crowds(lo, first))
|
|
54
|
+
before.push(lo);
|
|
55
|
+
else if (options.collision === 'drop-nice') {
|
|
56
|
+
before.push(lo);
|
|
57
|
+
inner.shift();
|
|
58
|
+
}
|
|
59
|
+
else if (options.collision === 'extend') {
|
|
60
|
+
domainLo = first - step;
|
|
61
|
+
before.push(domainLo);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const last = nice[nice.length - 1];
|
|
65
|
+
if (hi - last > eps) {
|
|
66
|
+
if (!crowds(hi, last))
|
|
67
|
+
after.push(hi);
|
|
68
|
+
else if (options.collision === 'drop-nice') {
|
|
69
|
+
after.push(hi);
|
|
70
|
+
if (inner[inner.length - 1] === last)
|
|
71
|
+
inner.pop();
|
|
72
|
+
}
|
|
73
|
+
else if (options.collision === 'extend') {
|
|
74
|
+
domainHi = last + step;
|
|
75
|
+
after.push(domainHi);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const ticks = [...before, ...inner, ...after];
|
|
79
|
+
const widened = domainLo !== lo || domainHi !== hi;
|
|
80
|
+
return widened ? { ticks, domain: [domainLo, domainHi] } : { ticks };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { AxisChannelName } from '../../types/layout/mapping';
|
|
2
|
+
import type { NiceOption } from '../../types/layout/scales';
|
|
3
|
+
/**
|
|
4
|
+
* "Nice" (1/2/5×10ⁿ) tick steps and the domains they round to, compatible with
|
|
5
|
+
* d3-array's and reimplemented here to avoid depending on internals svelteplot
|
|
6
|
+
* itself pulls in (not one of our declared dependencies) - see
|
|
7
|
+
* https://d3js.org/d3-array/ticks.
|
|
8
|
+
*/
|
|
9
|
+
export declare class NiceTicks {
|
|
10
|
+
/**
|
|
11
|
+
* How far past a tick, as a share of the tick step, a domain still ends on
|
|
12
|
+
* it. Plain `Math.ceil`/`Math.floor` (what d3's `nice()` uses) has no
|
|
13
|
+
* tolerance: parts that add up to `100`, but come out `100.00000000000001`
|
|
14
|
+
* after summing or `100.2` after each was rounded at the source, round a
|
|
15
|
+
* full step further (`100` → `120`). 5% of the step catches that noise and
|
|
16
|
+
* lets a mark pass the last tick by a few pixels at most.
|
|
17
|
+
*/
|
|
18
|
+
static readonly TOLERANCE = 0.05;
|
|
19
|
+
/** The pixels between ticks an axis aims for, along x and along y. */
|
|
20
|
+
static readonly SPACING: {
|
|
21
|
+
readonly x: 80;
|
|
22
|
+
readonly y: 50;
|
|
23
|
+
};
|
|
24
|
+
/** The step between nice ticks for an approximate `count` over `[start, stop]`. */
|
|
25
|
+
static step(start: number, stop: number, count: number): number;
|
|
26
|
+
/** Multiples of `step` covering `[start, stop]`, inclusive of either endpoint when it lands exactly on one. */
|
|
27
|
+
static inRange(start: number, stop: number, step: number): number[];
|
|
28
|
+
/** The tolerance a scale's `nice` asks for, or `undefined` for the default. */
|
|
29
|
+
static toleranceOf(nice: NiceOption | undefined): number | undefined;
|
|
30
|
+
/** How many ticks fit `span` pixels at one per `spacing`, and at least `min`. */
|
|
31
|
+
static count(span: number, spacing: number, min: number): number;
|
|
32
|
+
/**
|
|
33
|
+
* `[lo, hi]` widened outward to the nearest nice step for about `count`
|
|
34
|
+
* ticks, like d3's `scale.nice(count)` - except a value within
|
|
35
|
+
* `tolerance × step` past a tick stays on it (see {@link NiceTicks.TOLERANCE}).
|
|
36
|
+
*/
|
|
37
|
+
static domain(lo: number, hi: number, count?: number, tolerance?: number): [number, number];
|
|
38
|
+
/** {@link NiceTicks.domain} with as many ticks as fit `axis` in a plot of this size. */
|
|
39
|
+
static fit(size: {
|
|
40
|
+
width: number;
|
|
41
|
+
height: number;
|
|
42
|
+
}, axis: AxisChannelName, lo: number, hi: number, tolerance?: number): [number, number];
|
|
43
|
+
}
|