@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,8 +1,9 @@
|
|
|
1
1
|
import { Transforms } from './Transforms';
|
|
2
|
+
import { ValueSelection } from './ValueSelection';
|
|
3
|
+
import { ProcessedPositions } from './ProcessedPositions';
|
|
2
4
|
import { seriesIdOf } from '../../utils/grouping';
|
|
3
|
-
import { PANEL_KEY } from '../facet/
|
|
4
|
-
import { resolveAccessor } from '../../
|
|
5
|
-
import { isGapValue } from '../../plots/utils/gaps';
|
|
5
|
+
import { PANEL_KEY } from '../facet/FacetPanels';
|
|
6
|
+
import { resolveAccessor } from '../../utils/accessors';
|
|
6
7
|
import { buildGroupedSeries } from '../../plots/utils/segments';
|
|
7
8
|
import { PlotAxes } from '../data/PlotAxes';
|
|
8
9
|
/** The field each processed row carries its series name under, for its color, legend and labels. */
|
|
@@ -20,7 +21,8 @@ const NOT_OPTIONS = new Set(['data', 'z', 'grouping', 'transforms', 'sort', 'fil
|
|
|
20
21
|
* The "transforms" phase every axis-based plot shares: runs the plot-level
|
|
21
22
|
* transforms once over every visible series' rows together, so a stack sees
|
|
22
23
|
* every series and a bin keeps each series apart (both group by series), and
|
|
23
|
-
* leaves the result in `state.processedData` for the plot's own marks
|
|
24
|
+
* leaves the result in `state.processedData` for the plot's own marks - and
|
|
25
|
+
* in `state.processedGroups`, split back into the visual groups they draw. With
|
|
24
26
|
* facet panels, the transforms run once per panel's rows, so a stack never
|
|
25
27
|
* combines two panels, and every row they return keeps its panel. A gap that
|
|
26
28
|
* `styles.gaps` fills is read at its interpolated value, so it takes its place
|
|
@@ -29,8 +31,11 @@ const NOT_OPTIONS = new Set(['data', 'z', 'grouping', 'transforms', 'sort', 'fil
|
|
|
29
31
|
export class TransformsPhase {
|
|
30
32
|
phase = 'transforms';
|
|
31
33
|
#options;
|
|
32
|
-
|
|
34
|
+
#connect;
|
|
35
|
+
/** `connect`: whether a series' visual segments bridge into each other, as the kind's "data" phase splits them. */
|
|
36
|
+
constructor(options = {}, connect = true) {
|
|
33
37
|
this.#options = options;
|
|
38
|
+
this.#connect = connect;
|
|
34
39
|
}
|
|
35
40
|
run = (state, ctx) => {
|
|
36
41
|
const options = this.#options;
|
|
@@ -62,7 +67,7 @@ export class TransformsPhase {
|
|
|
62
67
|
if (!transforms.length) {
|
|
63
68
|
const channels = Object.fromEntries(Object.entries({ x, y }).filter(([, channel]) => channel !== undefined));
|
|
64
69
|
const processedData = { data, channels, options: {}, transforms };
|
|
65
|
-
return { ...state, processedData };
|
|
70
|
+
return this.#withGroups({ ...state, processedData });
|
|
66
71
|
}
|
|
67
72
|
const out = TransformsPhase.#runByPanel(data, (rows) => Transforms.resolve({ data: rows, x, y, grouping: SERIES_ID_KEY, transforms }, rows));
|
|
68
73
|
const channels = {};
|
|
@@ -89,8 +94,59 @@ export class TransformsPhase {
|
|
|
89
94
|
options: markOptions,
|
|
90
95
|
transforms
|
|
91
96
|
};
|
|
92
|
-
return { ...state, processedData };
|
|
97
|
+
return this.#withGroups({ ...state, processedData });
|
|
93
98
|
};
|
|
99
|
+
/**
|
|
100
|
+
* `state` with its processed rows split into the visual groups the kind's marks
|
|
101
|
+
* draw (`processedGroups`), and the rows its value labels are written for
|
|
102
|
+
* (`labelled`).
|
|
103
|
+
*/
|
|
104
|
+
#withGroups(state) {
|
|
105
|
+
const processedGroups = this.#options.groups === 'runs'
|
|
106
|
+
? TransformsPhase.#buildRuns(state)
|
|
107
|
+
: TransformsPhase.#buildGroups(state, this.#connect);
|
|
108
|
+
return { ...state, processedGroups, ...this.#labelled(state) };
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The rows `styles.values` writes labels for, picked per facet panel - a
|
|
112
|
+
* panel's own last row, not the last of every panel - by the author's
|
|
113
|
+
* `select` and `series`, over the plot's own default. Left out while the
|
|
114
|
+
* labels are off, or when the plot picks no rows.
|
|
115
|
+
*/
|
|
116
|
+
#labelled(state) {
|
|
117
|
+
const options = this.#options.labels;
|
|
118
|
+
const values = state.values;
|
|
119
|
+
if (!options || !(values?.show ?? options.show))
|
|
120
|
+
return {};
|
|
121
|
+
const processed = state.processedData;
|
|
122
|
+
const valueAxis = PlotAxes.valueOf(state);
|
|
123
|
+
const select = values?.select ?? options.select;
|
|
124
|
+
const selections = ValueSelection.transforms(select, values?.series, valueAxis);
|
|
125
|
+
const position = ProcessedPositions.of(processed, valueAxis);
|
|
126
|
+
const skip = options.skip?.(state);
|
|
127
|
+
const channels = {
|
|
128
|
+
x: position.x,
|
|
129
|
+
y: position.y,
|
|
130
|
+
group: options.group === 'category'
|
|
131
|
+
? position[PlotAxes.categoryOf(state)]
|
|
132
|
+
: SERIES_ID_KEY
|
|
133
|
+
};
|
|
134
|
+
const panels = new Map();
|
|
135
|
+
for (const row of processed.data) {
|
|
136
|
+
if (skip?.(row))
|
|
137
|
+
continue;
|
|
138
|
+
const bucket = panels.get(row[PANEL_KEY]);
|
|
139
|
+
if (bucket)
|
|
140
|
+
bucket.push(row);
|
|
141
|
+
else
|
|
142
|
+
panels.set(row[PANEL_KEY], [row]);
|
|
143
|
+
}
|
|
144
|
+
const labelled = new Set([...panels.values()].flatMap((rows) => ValueSelection.pick(rows, selections, channels)));
|
|
145
|
+
return {
|
|
146
|
+
labelled: processed.data.filter((row) => labelled.has(row)),
|
|
147
|
+
labelSelects: ValueSelection.selectors(select)
|
|
148
|
+
};
|
|
149
|
+
}
|
|
94
150
|
/** What a gap-filled row carries: its interpolated value and the kind of zone that filled it. */
|
|
95
151
|
static #fillTags(fill) {
|
|
96
152
|
return fill ? { [GAP_VALUE]: fill.value, [GAP_KIND]: fill.kind } : {};
|
|
@@ -100,7 +156,7 @@ export class TransformsPhase {
|
|
|
100
156
|
* into its styled visual segments by `segments`, matched on the processed `x`.
|
|
101
157
|
* Each series reads its rows through its value axis: a stack's top, a bin's start.
|
|
102
158
|
*/
|
|
103
|
-
static
|
|
159
|
+
static #buildGroups(state, connect) {
|
|
104
160
|
const { data } = state.processedData;
|
|
105
161
|
const series = (state.resolvedSeries ?? []).map((s) => TransformsPhase.#processedSeries(state, s, data.filter((row) => row[SERIES_ID_KEY] === seriesIdOf(s))));
|
|
106
162
|
return buildGroupedSeries(series, state.segments, connect);
|
|
@@ -108,11 +164,11 @@ export class TransformsPhase {
|
|
|
108
164
|
/**
|
|
109
165
|
* The processed rows in their own order, split into runs of consecutive rows
|
|
110
166
|
* from the same visible series, each cut into its styled visual segments like
|
|
111
|
-
* {@link TransformsPhase
|
|
167
|
+
* {@link TransformsPhase.#buildGroups}. Drawn in turn, the runs keep the rows' order
|
|
112
168
|
* across series, so a transform that reorders rows (`sort`, `reverse`,
|
|
113
169
|
* `shuffle`) decides which rows paint on top. Unreordered, each series is one run.
|
|
114
170
|
*/
|
|
115
|
-
static
|
|
171
|
+
static #buildRuns(state) {
|
|
116
172
|
const byId = new Map((state.resolvedSeries ?? []).map((s) => [seriesIdOf(s), s]));
|
|
117
173
|
const runs = [];
|
|
118
174
|
for (const row of state.processedData.data) {
|
|
@@ -127,54 +183,6 @@ export class TransformsPhase {
|
|
|
127
183
|
}
|
|
128
184
|
return buildGroupedSeries(runs, state.segments, false);
|
|
129
185
|
}
|
|
130
|
-
/**
|
|
131
|
-
* Where a processed row sits: the top of its value (`y2`, or `y` - `x2`/`x`
|
|
132
|
-
* when `valueAxis` is `x`) and, on the other axis, its own position (or the
|
|
133
|
-
* middle of its `1`-`2` span, a bin's centre).
|
|
134
|
-
*/
|
|
135
|
-
static processedPosition(processed, valueAxis = 'y') {
|
|
136
|
-
const { channels } = processed;
|
|
137
|
-
const read = (channel) => resolveAccessor(channel);
|
|
138
|
-
const along = (axis) => {
|
|
139
|
-
const own = channels[axis];
|
|
140
|
-
const from = channels[`${axis}1`];
|
|
141
|
-
const to = channels[`${axis}2`];
|
|
142
|
-
if (axis === valueAxis) {
|
|
143
|
-
const top = to ?? own;
|
|
144
|
-
return top !== undefined ? read(top) : () => undefined;
|
|
145
|
-
}
|
|
146
|
-
if (own !== undefined)
|
|
147
|
-
return read(own);
|
|
148
|
-
if (from === undefined || to === undefined)
|
|
149
|
-
return () => undefined;
|
|
150
|
-
return (row) => (Number(read(from)(row)) + Number(read(to)(row))) / 2;
|
|
151
|
-
};
|
|
152
|
-
return { x: along('x'), y: along('y') };
|
|
153
|
-
}
|
|
154
|
-
/**
|
|
155
|
-
* A processed row's span along `valueAxis`: from its `1` channel (a stack's
|
|
156
|
-
* bottom) or, with none, from `baseline`, to its top. `undefined` when the
|
|
157
|
-
* row has no value there. `stacked` tells a stack from plain values.
|
|
158
|
-
*/
|
|
159
|
-
static processedSpan(processed, valueAxis, baseline = 0) {
|
|
160
|
-
const from = processed.channels[`${valueAxis}1`];
|
|
161
|
-
const stacked = from !== undefined && processed.channels[`${valueAxis}2`] !== undefined;
|
|
162
|
-
const top = TransformsPhase.processedPosition(processed, valueAxis)[valueAxis];
|
|
163
|
-
const bottom = stacked
|
|
164
|
-
? resolveAccessor(from)
|
|
165
|
-
: () => baseline;
|
|
166
|
-
return {
|
|
167
|
-
stacked,
|
|
168
|
-
of: (row) => {
|
|
169
|
-
const end = top(row);
|
|
170
|
-
const start = bottom(row);
|
|
171
|
-
if (isGapValue(end) || isGapValue(start))
|
|
172
|
-
return undefined;
|
|
173
|
-
const span = [Number(start), Number(end)];
|
|
174
|
-
return Number.isFinite(span[0]) && Number.isFinite(span[1]) ? span : undefined;
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
186
|
/**
|
|
179
187
|
* One series accessor shared by every series as-is, so a field key keeps
|
|
180
188
|
* feeding svelteplot's axis-title inference; a per-series function otherwise.
|
|
@@ -234,6 +242,7 @@ export class TransformsPhase {
|
|
|
234
242
|
return {
|
|
235
243
|
name: source.name,
|
|
236
244
|
...(source.id !== undefined ? { id: source.id } : {}),
|
|
245
|
+
...(source.panel !== undefined ? { panel: source.panel } : {}),
|
|
237
246
|
x: read('x'),
|
|
238
247
|
y: read('y'),
|
|
239
248
|
data
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ValueSelect } from '../../types/layout/styles';
|
|
2
|
+
import type { MarkerTransform } from '../../types/transforms';
|
|
3
|
+
import type { ProcessedRow } from '../../types/phases';
|
|
4
|
+
/**
|
|
5
|
+
* Which rows of a plot a value label is written for: `styles.values.select`
|
|
6
|
+
* (or the plot's own default) and `series`, run as `filter` and `select`
|
|
7
|
+
* transforms over the processed rows. The labelled rows are the union of what
|
|
8
|
+
* each selector picks, returned as the rows themselves, in their own order.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ValueSelection {
|
|
11
|
+
/** `select` as a list: none is every row. */
|
|
12
|
+
static selectors(select: ValueSelect | ValueSelect[] | undefined): ValueSelect[];
|
|
13
|
+
/**
|
|
14
|
+
* The transforms that pick the rows, one list per selector: the series filter,
|
|
15
|
+
* then the `select` of that selector, with `'min'` and `'max'` read on
|
|
16
|
+
* `valueAxis`. Without selectors, one list that only filters the series.
|
|
17
|
+
*/
|
|
18
|
+
static transforms(select: ValueSelect | ValueSelect[] | undefined, series: string | string[] | undefined, valueAxis: 'x' | 'y'): MarkerTransform[][];
|
|
19
|
+
/**
|
|
20
|
+
* The rows of `rows` that any of `selections` picks, grouped by `group`
|
|
21
|
+
* (a field key or accessor) and compared on `x` and `y` - the value axis'
|
|
22
|
+
* channel is what `'min'` and `'max'` read. A transform returns copies of its
|
|
23
|
+
* rows, so each is traced back to the row it came from.
|
|
24
|
+
*/
|
|
25
|
+
static pick(rows: ProcessedRow[], selections: MarkerTransform[][], channels: {
|
|
26
|
+
x: unknown;
|
|
27
|
+
y: unknown;
|
|
28
|
+
group: unknown;
|
|
29
|
+
}): ProcessedRow[];
|
|
30
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Transforms } from './Transforms';
|
|
2
|
+
import { SERIES_KEY } from './TransformsPhase';
|
|
3
|
+
/** The field a row carries its place in the rows picked from, under which a transform's copy of it is traced back. */
|
|
4
|
+
const PLACE = '__place';
|
|
5
|
+
/**
|
|
6
|
+
* Which rows of a plot a value label is written for: `styles.values.select`
|
|
7
|
+
* (or the plot's own default) and `series`, run as `filter` and `select`
|
|
8
|
+
* transforms over the processed rows. The labelled rows are the union of what
|
|
9
|
+
* each selector picks, returned as the rows themselves, in their own order.
|
|
10
|
+
*/
|
|
11
|
+
export class ValueSelection {
|
|
12
|
+
/** `select` as a list: none is every row. */
|
|
13
|
+
static selectors(select) {
|
|
14
|
+
return select === undefined ? [] : Array.isArray(select) ? select : [select];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The transforms that pick the rows, one list per selector: the series filter,
|
|
18
|
+
* then the `select` of that selector, with `'min'` and `'max'` read on
|
|
19
|
+
* `valueAxis`. Without selectors, one list that only filters the series.
|
|
20
|
+
*/
|
|
21
|
+
static transforms(select, series, valueAxis) {
|
|
22
|
+
const names = series === undefined ? undefined : new Set([series].flat());
|
|
23
|
+
const filter = names
|
|
24
|
+
? [{ type: 'filter', filter: (d) => names.has(String(d[SERIES_KEY])) }]
|
|
25
|
+
: [];
|
|
26
|
+
const selectors = ValueSelection.selectors(select);
|
|
27
|
+
if (selectors.length === 0)
|
|
28
|
+
return [filter];
|
|
29
|
+
return selectors.map((selector) => [
|
|
30
|
+
...filter,
|
|
31
|
+
{
|
|
32
|
+
type: 'select',
|
|
33
|
+
select: selector === 'min' || selector === 'max' ? { [valueAxis]: selector } : selector
|
|
34
|
+
}
|
|
35
|
+
]);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The rows of `rows` that any of `selections` picks, grouped by `group`
|
|
39
|
+
* (a field key or accessor) and compared on `x` and `y` - the value axis'
|
|
40
|
+
* channel is what `'min'` and `'max'` read. A transform returns copies of its
|
|
41
|
+
* rows, so each is traced back to the row it came from.
|
|
42
|
+
*/
|
|
43
|
+
static pick(rows, selections, channels) {
|
|
44
|
+
const placed = rows.map((row, index) => ({ ...row, [PLACE]: index }));
|
|
45
|
+
const chosen = new Set();
|
|
46
|
+
for (const transforms of selections) {
|
|
47
|
+
const picked = Transforms.resolve({ data: placed, ...channels, grouping: channels.group, transforms }, placed);
|
|
48
|
+
for (const row of picked.data ?? placed)
|
|
49
|
+
chosen.add(row[PLACE]);
|
|
50
|
+
}
|
|
51
|
+
return rows.filter((_, index) => chosen.has(index));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<script lang="ts" generics="TData extends Record<string, unknown>">
|
|
2
|
-
import Plot from '
|
|
2
|
+
import Plot from '../../../layout/plot/Plot.svelte';
|
|
3
3
|
import { buildHeatmapDefaults } from './defaults';
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
HeatmapPlotProps,
|
|
6
|
+
HeatmapPlotCoreProps
|
|
7
|
+
} from '../../../types/plots/correlation/heatmap/props';
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* A categorical grid of value-colored cells. Draws from pre-built `series` or flat `data` rows.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import Plot from '
|
|
2
|
-
import type { HeatmapPlotProps } from '
|
|
1
|
+
import Plot from '../../../layout/plot/Plot.svelte';
|
|
2
|
+
import type { HeatmapPlotProps } from '../../../types/plots/correlation/heatmap/props';
|
|
3
3
|
declare function $$render<TData extends Record<string, unknown>>(): {
|
|
4
4
|
props: HeatmapPlotProps<TData>;
|
|
5
5
|
exports: {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { AxisPlotDefaults } from '
|
|
2
|
-
import type { HeatmapPlotState, HeatmapPlotCtx } from '
|
|
1
|
+
import type { AxisPlotDefaults } from '../../../types/phases';
|
|
2
|
+
import type { HeatmapPlotState, HeatmapPlotCtx } from '../../../types/plots/correlation/heatmap/state';
|
|
3
3
|
/**
|
|
4
4
|
* HeatmapPlot on the shared pipeline: both axes are categories. A heatmap's
|
|
5
5
|
* `color` is each cell's numeric value, which the "data" phase reads as a
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { ContinuousDomain } from '
|
|
1
|
+
import { ColorRamp } from '../../../utils/color';
|
|
2
|
+
import { OpacityScale } from '../../../utils/OpacityScale';
|
|
3
|
+
import { ContinuousDomain } from '../../../utils/ContinuousDomain';
|
|
4
4
|
import { buildMarks, buildValueLabels } from './markers';
|
|
5
5
|
/**
|
|
6
6
|
* HeatmapPlot's own "scales" output, over the band axes the shared phase laid
|
|
@@ -17,7 +17,7 @@ function extendWithColorScales(state, ctx) {
|
|
|
17
17
|
// active range) keeps the original domain - only which cells are hidden
|
|
18
18
|
// changes (resolved in the "markers" phase).
|
|
19
19
|
const effectiveDomain = ContinuousDomain.ramp(valueDomain, range);
|
|
20
|
-
const colorScale =
|
|
20
|
+
const colorScale = ColorRamp.continuous(cfg, scales.color, effectiveDomain);
|
|
21
21
|
const resolveColor = (row) => colorScale(Number(colorAcc.accessor(row)));
|
|
22
22
|
const opacityAcc = channels.opacity;
|
|
23
23
|
let opacityDomainOut;
|
|
@@ -32,7 +32,7 @@ function extendWithColorScales(state, ctx) {
|
|
|
32
32
|
: [...new Set(rawVals.map(String))];
|
|
33
33
|
if (allNumeric && rawVals.length)
|
|
34
34
|
opacityDomainOut = opacityDomain;
|
|
35
|
-
const opacityScale =
|
|
35
|
+
const opacityScale = OpacityScale.resolve(scales.opacity, opacityDomain, cfg.continuous.opacityRange);
|
|
36
36
|
return (row) => opacityScale(opacityAcc.accessor(row));
|
|
37
37
|
})()
|
|
38
38
|
: undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { TextMarkerConfig } from '
|
|
2
|
-
import type { HeatmapPlotState, HeatmapPlotCtx } from '
|
|
3
|
-
import type { ValueLabels } from '
|
|
4
|
-
import type { AxisBasedMarkersConfig } from '
|
|
1
|
+
import type { TextMarkerConfig } from '../../../types/markers/common';
|
|
2
|
+
import type { HeatmapPlotState, HeatmapPlotCtx } from '../../../types/plots/correlation/heatmap/state';
|
|
3
|
+
import type { ValueLabels } from '../../../layout/styles/ValueLabels';
|
|
4
|
+
import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
|
|
5
5
|
/**
|
|
6
6
|
* HeatmapPlot's `styles.values` as one `'text'` marker over the same cells
|
|
7
7
|
* the plot draws, each labelled with its own value and centred on it. Shown
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { LegendState } from '../../../layout/legend/LegendState.svelte';
|
|
2
|
+
import { DisabledStyle } from '../../../layout/legend/DisabledStyle';
|
|
3
|
+
import { resolveAccessor } from '../../../utils/accessors';
|
|
3
4
|
/** A processed channel as a per-row function. */
|
|
4
5
|
function readChannel(channel) {
|
|
5
6
|
return resolveAccessor(channel);
|
|
@@ -98,7 +99,7 @@ export function buildMarks(state, ctx) {
|
|
|
98
99
|
return map;
|
|
99
100
|
})();
|
|
100
101
|
function rangeFilteredStyle(base, value) {
|
|
101
|
-
if (range == null || (value
|
|
102
|
+
if (range == null || LegendState.inRange(value, range))
|
|
102
103
|
return base;
|
|
103
104
|
return { ...base, ...DisabledStyle.fill(range.disabledStyle) };
|
|
104
105
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
<script lang="ts" generics="TData extends Record<string, unknown>">
|
|
2
|
-
import Plot from '
|
|
2
|
+
import Plot from '../../../layout/plot/Plot.svelte';
|
|
3
3
|
import { buildScatterDefaults } from './defaults';
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
ScatterPlotProps,
|
|
6
|
+
ScatterPlotCoreProps
|
|
7
|
+
} from '../../../types/plots/correlation/scatter/props';
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
10
|
* A point cloud on continuous x/y axes; `r` sizes each dot. Draws from pre-built `series` or flat `data` rows.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import Plot from '
|
|
2
|
-
import type { ScatterPlotProps } from '
|
|
1
|
+
import Plot from '../../../layout/plot/Plot.svelte';
|
|
2
|
+
import type { ScatterPlotProps } from '../../../types/plots/correlation/scatter/props';
|
|
3
3
|
declare function $$render<TData extends Record<string, unknown>>(): {
|
|
4
4
|
props: ScatterPlotProps<TData>;
|
|
5
5
|
exports: {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AxisPlotDefaults } from '
|
|
2
|
-
import type { ScatterPlotState, ScatterPlotCtx } from '
|
|
1
|
+
import type { AxisPlotDefaults } from '../../../types/phases';
|
|
2
|
+
import type { ScatterPlotState, ScatterPlotCtx } from '../../../types/plots/correlation/scatter/state';
|
|
3
3
|
/** ScatterPlot on the shared pipeline: discrete dots, its own radius-padded scales, and its own markers. Its plot defaults to: hover the exact point. */
|
|
4
4
|
export declare function buildScatterDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<ScatterPlotState<TData>, ScatterPlotCtx>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { ProcessedPositions } from '../../../phases/transforms/ProcessedPositions';
|
|
1
2
|
import { buildMarks, buildValueLabels } from './markers';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { MarkerAxisValues } from '../../phases/scales/MarkerAxisValues';
|
|
3
|
+
import { Margins } from '../../../layout/margins/Margins';
|
|
4
|
+
import { MarkerAxisValues } from '../../../phases/scales/MarkerAxisValues';
|
|
5
5
|
/** Stand-in max render radius for a channel-bound `r` (svelteplot's own auto sqrt scale). */
|
|
6
6
|
const AUTO_SCALED_RADIUS_ESTIMATE = 20;
|
|
7
7
|
/**
|
|
@@ -28,7 +28,7 @@ function paddedDomain(values, radiusPx, sizePx) {
|
|
|
28
28
|
function fitDomains(state, ctx) {
|
|
29
29
|
const { scales, channels, groupedSeries } = state;
|
|
30
30
|
const processed = state.processedData;
|
|
31
|
-
const position =
|
|
31
|
+
const position = ProcessedPositions.of(processed);
|
|
32
32
|
const extra = {
|
|
33
33
|
x: MarkerAxisValues.of(state.markers ?? [], 'x'),
|
|
34
34
|
y: MarkerAxisValues.of(state.markers ?? [], 'y')
|
|
@@ -53,7 +53,7 @@ function fitDomains(state, ctx) {
|
|
|
53
53
|
const values = [...processed.data.map((d) => Number(position[axis](d))), ...extra[axis]];
|
|
54
54
|
const domain = paddedDomain(values, radius, size);
|
|
55
55
|
if (domain)
|
|
56
|
-
fit[axis] = { domain };
|
|
56
|
+
fit[axis] = { domain, fitted: true };
|
|
57
57
|
}
|
|
58
58
|
return fit;
|
|
59
59
|
}
|
|
@@ -66,6 +66,7 @@ export function buildScatterDefaults() {
|
|
|
66
66
|
connect: false
|
|
67
67
|
}
|
|
68
68
|
},
|
|
69
|
+
transforms: { groups: 'runs' },
|
|
69
70
|
scales: { fit: fitDomains },
|
|
70
71
|
markers: { marks: buildMarks, valueLabels: buildValueLabels },
|
|
71
72
|
hover: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { ScatterPlotState, ScatterPlotCtx } from '
|
|
2
|
-
import type { TextMarkerConfig } from '
|
|
3
|
-
import { ValueLabels } from '
|
|
4
|
-
import type { AxisBasedMarkersConfig } from '
|
|
1
|
+
import type { ScatterPlotState, ScatterPlotCtx } from '../../../types/plots/correlation/scatter/state';
|
|
2
|
+
import type { TextMarkerConfig } from '../../../types/markers/common';
|
|
3
|
+
import { ValueLabels } from '../../../layout/styles/ValueLabels';
|
|
4
|
+
import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
|
|
5
5
|
/**
|
|
6
6
|
* ScatterPlot's `styles.values` as one `'text'` marker over the same
|
|
7
7
|
* processed rows its dots draw, each labelled with its own `y` value. A label
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ProcessedPositions } from '../../../phases/transforms/ProcessedPositions';
|
|
2
|
+
import { SERIES_KEY } from '../../../phases/transforms/TransformsPhase';
|
|
3
|
+
import { ValueLabels } from '../../../layout/styles/ValueLabels';
|
|
3
4
|
/**
|
|
4
5
|
* ScatterPlot's `styles.values` as one `'text'` marker over the same
|
|
5
6
|
* processed rows its dots draw, each labelled with its own `y` value. A label
|
|
@@ -11,7 +12,7 @@ export function buildValueLabels(labels, state, ctx) {
|
|
|
11
12
|
if (!processedData?.data.length)
|
|
12
13
|
return [];
|
|
13
14
|
const { font, format } = labels;
|
|
14
|
-
const position =
|
|
15
|
+
const position = ProcessedPositions.of(processedData);
|
|
15
16
|
const nameOf = (d) => String(d[SERIES_KEY]);
|
|
16
17
|
const valueOf = ValueLabels.valueOf(state);
|
|
17
18
|
return [
|
|
@@ -89,7 +90,7 @@ export function buildMarks(state, ctx) {
|
|
|
89
90
|
}
|
|
90
91
|
: undefined;
|
|
91
92
|
const markers = [];
|
|
92
|
-
|
|
93
|
+
(state.processedGroups ?? []).forEach((group) => {
|
|
93
94
|
const defaultColor = colorForSeries(group.series.name);
|
|
94
95
|
const disabledDots = interaction?.dotsFor(group.series.name);
|
|
95
96
|
for (const seg of group.visualSegments) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { HoverPosition } from '../../../types/phases';
|
|
2
|
+
import type { BoxPlotState, BoxSummaryRow } from '../../../types/plots/distribution/box/state';
|
|
3
|
+
/**
|
|
4
|
+
* The boxes a box plot draws, one summary row per series, category and facet
|
|
5
|
+
* panel - the same quartiles and whiskers svelteplot's `BoxX`/`BoxY` compute,
|
|
6
|
+
* so its hover and tooltip read a box rather than every value inside it.
|
|
7
|
+
*/
|
|
8
|
+
export declare class BoxSummaries {
|
|
9
|
+
/** One summary per box, in the order the processed rows first reach it. */
|
|
10
|
+
static of<TData extends Record<string, unknown>>(state: BoxPlotState<TData>): BoxSummaryRow[];
|
|
11
|
+
/** Where a box's summary sits for hover: at its category, level with its median. */
|
|
12
|
+
static position<TData extends Record<string, unknown>>(state: BoxPlotState<TData>): HoverPosition;
|
|
13
|
+
/**
|
|
14
|
+
* How a hovered box reads by default: its series, when the plot groups its
|
|
15
|
+
* rows; its category; then its five numbers, highest first, and how many
|
|
16
|
+
* values fall past the whiskers.
|
|
17
|
+
*/
|
|
18
|
+
static format<TData extends Record<string, unknown>>(state: BoxPlotState<TData>): (row: BoxSummaryRow) => string;
|
|
19
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { ProcessedPositions } from '../../../phases/transforms/ProcessedPositions';
|
|
2
|
+
import { quantile } from 'd3-array';
|
|
3
|
+
import { SERIES_ID_KEY, SERIES_KEY } from '../../../phases/transforms/TransformsPhase';
|
|
4
|
+
import { PANEL_KEY } from '../../../phases/facet/FacetPanels';
|
|
5
|
+
import { PlotAxes } from '../../../phases/data/PlotAxes';
|
|
6
|
+
import { TooltipState } from '../../../layout/tooltip/TooltipState.svelte';
|
|
7
|
+
import { isGapValue } from '../../utils/gaps';
|
|
8
|
+
/** The whiskers reach this many interquartile ranges past the box, as svelteplot draws them. */
|
|
9
|
+
const WHISKER_IQR = 1.5;
|
|
10
|
+
/** A summary value as a tooltip shows it: at most two decimals. */
|
|
11
|
+
const round = (value) => String(Math.round(value * 100) / 100);
|
|
12
|
+
/**
|
|
13
|
+
* The boxes a box plot draws, one summary row per series, category and facet
|
|
14
|
+
* panel - the same quartiles and whiskers svelteplot's `BoxX`/`BoxY` compute,
|
|
15
|
+
* so its hover and tooltip read a box rather than every value inside it.
|
|
16
|
+
*/
|
|
17
|
+
export class BoxSummaries {
|
|
18
|
+
/** One summary per box, in the order the processed rows first reach it. */
|
|
19
|
+
static of(state) {
|
|
20
|
+
const processed = state.processedData;
|
|
21
|
+
if (!processed?.data.length)
|
|
22
|
+
return [];
|
|
23
|
+
const valueAxis = PlotAxes.valueOf(state);
|
|
24
|
+
const categoryAxis = PlotAxes.categoryOf(state);
|
|
25
|
+
const position = ProcessedPositions.of(processed, valueAxis);
|
|
26
|
+
const valueOf = position[valueAxis];
|
|
27
|
+
const categoryOf = position[categoryAxis];
|
|
28
|
+
const categoryField = processed.channels[categoryAxis];
|
|
29
|
+
const boxes = new Map();
|
|
30
|
+
for (const row of processed.data) {
|
|
31
|
+
const value = valueOf(row);
|
|
32
|
+
if (isGapValue(value))
|
|
33
|
+
continue;
|
|
34
|
+
const n = Number(value);
|
|
35
|
+
if (!Number.isFinite(n))
|
|
36
|
+
continue;
|
|
37
|
+
const key = JSON.stringify([
|
|
38
|
+
row[SERIES_ID_KEY],
|
|
39
|
+
row[PANEL_KEY] ?? null,
|
|
40
|
+
String(categoryOf(row))
|
|
41
|
+
]);
|
|
42
|
+
const box = boxes.get(key);
|
|
43
|
+
if (box)
|
|
44
|
+
box.values.push(n);
|
|
45
|
+
else
|
|
46
|
+
boxes.set(key, { first: row, values: [n] });
|
|
47
|
+
}
|
|
48
|
+
return [...boxes.values()].map(({ first, values }) => {
|
|
49
|
+
const sorted = values.sort((a, b) => a - b);
|
|
50
|
+
const p25 = quantile(sorted, 0.25);
|
|
51
|
+
const median = quantile(sorted, 0.5);
|
|
52
|
+
const p75 = quantile(sorted, 0.75);
|
|
53
|
+
const reach = (p75 - p25) * WHISKER_IQR;
|
|
54
|
+
const inside = sorted.filter((v) => v >= p25 - reach && v <= p75 + reach);
|
|
55
|
+
const category = categoryOf(first);
|
|
56
|
+
return {
|
|
57
|
+
...(typeof categoryField === 'string' ? { [categoryField]: category } : {}),
|
|
58
|
+
[SERIES_KEY]: first[SERIES_KEY],
|
|
59
|
+
[SERIES_ID_KEY]: first[SERIES_ID_KEY],
|
|
60
|
+
...(first[PANEL_KEY] !== undefined ? { [PANEL_KEY]: first[PANEL_KEY] } : {}),
|
|
61
|
+
category,
|
|
62
|
+
min: inside[0] ?? p25,
|
|
63
|
+
p25,
|
|
64
|
+
median,
|
|
65
|
+
p75,
|
|
66
|
+
max: inside.at(-1) ?? p75,
|
|
67
|
+
count: sorted.length,
|
|
68
|
+
outliers: sorted.filter((v) => v < p25 - reach || v > p75 + reach)
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/** Where a box's summary sits for hover: at its category, level with its median. */
|
|
73
|
+
static position(state) {
|
|
74
|
+
const valueAxis = PlotAxes.valueOf(state);
|
|
75
|
+
const at = {
|
|
76
|
+
[valueAxis]: (row) => row.median,
|
|
77
|
+
[PlotAxes.other(valueAxis)]: (row) => row.category
|
|
78
|
+
};
|
|
79
|
+
return at;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* How a hovered box reads by default: its series, when the plot groups its
|
|
83
|
+
* rows; its category; then its five numbers, highest first, and how many
|
|
84
|
+
* values fall past the whiskers.
|
|
85
|
+
*/
|
|
86
|
+
static format(state) {
|
|
87
|
+
const grouped = state.channels?.grouping !== undefined;
|
|
88
|
+
return (row) => {
|
|
89
|
+
const lines = grouped ? [String(row[SERIES_KEY])] : [];
|
|
90
|
+
lines.push(TooltipState.value(row.category));
|
|
91
|
+
lines.push(`max: ${round(row.max)}`);
|
|
92
|
+
lines.push(`p75: ${round(row.p75)}`);
|
|
93
|
+
lines.push(`median: ${round(row.median)}`);
|
|
94
|
+
lines.push(`p25: ${round(row.p25)}`);
|
|
95
|
+
lines.push(`min: ${round(row.min)}`);
|
|
96
|
+
if (row.outliers.length)
|
|
97
|
+
lines.push(`outliers: ${row.outliers.length}`);
|
|
98
|
+
return lines.join('\n');
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script lang="ts" generics="TData extends Record<string, unknown>">
|
|
2
|
+
import Plot from '../../../layout/plot/Plot.svelte';
|
|
3
|
+
import { buildBoxDefaults } from './defaults';
|
|
4
|
+
import type { BoxPlotProps, BoxPlotCoreProps } from '../../../types/plots/distribution/box/props';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A box plot: the distribution of each series' values per category - quartiles, whiskers and outliers - one box per category, upright, or sideways when the categories run along `y`. Draws from pre-built `series` or flat `data` rows.
|
|
8
|
+
* Optional chrome (`title`, `subtitle`, `caption`, `header`, `footer`,
|
|
9
|
+
* `legend`) frames it; `timeline` and `facet` slice its `data` rows.
|
|
10
|
+
* `margins` is bindable: it reports the margin the plot settled on.
|
|
11
|
+
*/
|
|
12
|
+
let {
|
|
13
|
+
title,
|
|
14
|
+
subtitle,
|
|
15
|
+
caption,
|
|
16
|
+
header,
|
|
17
|
+
footer,
|
|
18
|
+
legend,
|
|
19
|
+
order,
|
|
20
|
+
timeline,
|
|
21
|
+
facet,
|
|
22
|
+
tooltip,
|
|
23
|
+
margins = $bindable(),
|
|
24
|
+
...core
|
|
25
|
+
}: BoxPlotProps<TData> = $props();
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<Plot
|
|
29
|
+
core={core as BoxPlotCoreProps<TData>}
|
|
30
|
+
defaults={buildBoxDefaults}
|
|
31
|
+
bind:margins
|
|
32
|
+
{title}
|
|
33
|
+
{subtitle}
|
|
34
|
+
{caption}
|
|
35
|
+
{header}
|
|
36
|
+
{footer}
|
|
37
|
+
{legend}
|
|
38
|
+
{order}
|
|
39
|
+
{timeline}
|
|
40
|
+
{facet}
|
|
41
|
+
{tooltip}
|
|
42
|
+
/>
|