@pibbl/core 0.0.1 → 0.0.3-alpha.85.1
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/README.md +1 -1
- package/THIRD_PARTY_NOTICES.txt +81 -0
- package/dist/features/machines/animation.d.ts +64 -0
- package/dist/features/machines/animation.js +55 -0
- package/dist/features/machines/animation.js.map +7 -0
- package/dist/features/machines/animation.mjs +1 -0
- package/dist/features/machines/assign.d.ts +16 -0
- package/dist/features/machines/assign.js +15 -0
- package/dist/features/machines/assign.js.map +7 -0
- package/dist/features/machines/callback.d.ts +9 -0
- package/dist/features/machines/callback.js +7 -0
- package/dist/features/machines/callback.js.map +7 -0
- package/dist/features/machines/hook.d.ts +30 -0
- package/dist/features/machines/hook.js +37 -0
- package/dist/features/machines/hook.js.map +7 -0
- package/dist/features/machines/index.d.ts +6 -0
- package/dist/features/machines/index.js +12 -0
- package/dist/features/machines/index.js.map +7 -0
- package/dist/features/machines/index.mjs +1 -0
- package/dist/features/machines/runtime.d.ts +18 -0
- package/dist/features/machines/runtime.js +363 -0
- package/dist/features/machines/runtime.js.map +7 -0
- package/dist/features/machines/types.d.ts +164 -0
- package/dist/features/physics/2d-geometry.d.ts +3 -3
- package/dist/features/physics/2d-geometry.js.map +1 -1
- package/dist/features/physics/2d.d.ts +115 -62
- package/dist/features/physics/2d.js +59 -28
- package/dist/features/physics/2d.js.map +2 -2
- package/dist/features/physics/lib/2d/query-types.d.ts +6 -0
- package/dist/features/physics/lib/2d/runtime/controller.d.ts +7 -6
- package/dist/features/physics/lib/2d/runtime/controller.js.map +2 -2
- package/dist/features/physics/lib/2d/types.d.ts +8 -30
- package/dist/features/physics/lib/2d/world/queries.d.ts +7 -6
- package/dist/features/physics/lib/2d/world/queries.js.map +2 -2
- package/dist/features/sprites/formats/aseprite.d.ts +5 -0
- package/dist/features/sprites/formats/texture-packer.d.ts +5 -0
- package/dist/features/sprites/index.d.ts +6 -0
- package/dist/features/sprites/loader.d.ts +25 -0
- package/dist/features/sprites/model.d.ts +75 -0
- package/dist/features/sprites/sprite.d.ts +22 -0
- package/dist/features/textures/index.d.ts +12 -2
- package/dist/features/textures/index.js +33 -1
- package/dist/features/textures/index.js.map +2 -2
- package/dist/features/textures/lib/chemical-field.d.ts +56 -0
- package/dist/features/textures/lib/chemical-field.js +154 -0
- package/dist/features/textures/lib/chemical-field.js.map +7 -0
- package/dist/features/textures/lib/chemical-recipes.d.ts +119 -0
- package/dist/features/textures/lib/chemical-recipes.js +275 -0
- package/dist/features/textures/lib/chemical-recipes.js.map +7 -0
- package/dist/features/textures/lib/definitions.d.ts +3 -18
- package/dist/features/textures/lib/definitions.js +15 -20
- package/dist/features/textures/lib/definitions.js.map +2 -2
- package/dist/features/textures/lib/geometric-patterns.d.ts +149 -0
- package/dist/features/textures/lib/geometric-patterns.js +305 -0
- package/dist/features/textures/lib/geometric-patterns.js.map +7 -0
- package/dist/features/textures/lib/gray-scott.d.ts +55 -0
- package/dist/features/textures/lib/gray-scott.js +39 -0
- package/dist/features/textures/lib/gray-scott.js.map +7 -0
- package/dist/features/textures/lib/patterns.d.ts +123 -0
- package/dist/features/textures/lib/patterns.js +344 -0
- package/dist/features/textures/lib/patterns.js.map +7 -0
- package/dist/features/textures/lib/reaction-diffusion.d.ts +3 -2
- package/dist/features/textures/lib/reaction-diffusion.js +9 -20
- package/dist/features/textures/lib/reaction-diffusion.js.map +2 -2
- package/dist/features/textures/lib/simulation.d.ts +10 -4
- package/dist/features/textures/lib/simulation.js +23 -13
- package/dist/features/textures/lib/simulation.js.map +2 -2
- package/dist/features/viz/index.d.ts +79 -5
- package/dist/features/viz/index.js +145 -4
- package/dist/features/viz/index.js.map +2 -2
- package/dist/features/viz/inspection/bar.d.ts +79 -0
- package/dist/features/viz/inspection/bar.js +49 -0
- package/dist/features/viz/inspection/bar.js.map +7 -0
- package/dist/features/viz/inspection/candle.d.ts +156 -0
- package/dist/features/viz/inspection/candle.js +120 -0
- package/dist/features/viz/inspection/candle.js.map +7 -0
- package/dist/features/viz/inspection/capture-types.d.ts +65 -0
- package/dist/features/viz/inspection/capture.d.ts +16 -0
- package/dist/features/viz/inspection/capture.js +49 -0
- package/dist/features/viz/inspection/capture.js.map +7 -0
- package/dist/features/viz/inspection/handler.d.ts +36 -0
- package/dist/features/viz/inspection/handler.js +91 -0
- package/dist/features/viz/inspection/handler.js.map +7 -0
- package/dist/features/viz/inspection/ohlc-bar.d.ts +132 -0
- package/dist/features/viz/inspection/ohlc-bar.js +118 -0
- package/dist/features/viz/inspection/ohlc-bar.js.map +7 -0
- package/dist/features/viz/inspection/owned-ref.d.ts +16 -0
- package/dist/features/viz/inspection/owned-ref.js +99 -0
- package/dist/features/viz/inspection/owned-ref.js.map +7 -0
- package/dist/features/viz/inspection/painted-point.d.ts +22 -0
- package/dist/features/viz/inspection/painted-point.js +29 -0
- package/dist/features/viz/inspection/painted-point.js.map +7 -0
- package/dist/features/viz/inspection/queries.d.ts +100 -0
- package/dist/features/viz/inspection/queries.js +192 -0
- package/dist/features/viz/inspection/queries.js.map +7 -0
- package/dist/features/viz/inspection/query-types.d.ts +177 -0
- package/dist/features/viz/inspection/volume.d.ts +104 -0
- package/dist/features/viz/inspection/volume.js +95 -0
- package/dist/features/viz/inspection/volume.js.map +7 -0
- package/dist/features/viz/inspection.d.ts +19 -0
- package/dist/features/viz/inspection.js +54 -0
- package/dist/features/viz/inspection.js.map +7 -0
- package/dist/features/viz/inspection.mjs +1 -0
- package/dist/features/viz/lib/area-series.d.ts +62 -0
- package/dist/features/viz/lib/area-series.js +120 -0
- package/dist/features/viz/lib/area-series.js.map +7 -0
- package/dist/features/viz/lib/axis-labels.d.ts +2 -0
- package/dist/features/viz/lib/axis-labels.js +41 -0
- package/dist/features/viz/lib/axis-labels.js.map +7 -0
- package/dist/features/viz/lib/axis-title.d.ts +23 -0
- package/dist/features/viz/lib/axis-title.js +23 -0
- package/dist/features/viz/lib/axis-title.js.map +7 -0
- package/dist/features/viz/lib/axis.d.ts +1 -1
- package/dist/features/viz/lib/axis.js +50 -50
- package/dist/features/viz/lib/axis.js.map +2 -2
- package/dist/features/viz/lib/bar-scale.d.ts +7 -0
- package/dist/features/viz/lib/bar-scale.js +34 -0
- package/dist/features/viz/lib/bar-scale.js.map +7 -0
- package/dist/features/viz/lib/bar-series.d.ts +3 -1
- package/dist/features/viz/lib/bar-series.js +21 -5
- package/dist/features/viz/lib/bar-series.js.map +2 -2
- package/dist/features/viz/lib/baseline-series.d.ts +55 -0
- package/dist/features/viz/lib/baseline-series.js +136 -0
- package/dist/features/viz/lib/baseline-series.js.map +7 -0
- package/dist/features/viz/lib/candlestick-series.d.ts +62 -0
- package/dist/features/viz/lib/candlestick-series.js +150 -0
- package/dist/features/viz/lib/candlestick-series.js.map +7 -0
- package/dist/features/viz/lib/censored-point-series.d.ts +71 -0
- package/dist/features/viz/lib/censored-point-series.js +129 -0
- package/dist/features/viz/lib/censored-point-series.js.map +7 -0
- package/dist/features/viz/lib/chart-lines.d.ts +41 -0
- package/dist/features/viz/lib/chart-lines.js +32 -0
- package/dist/features/viz/lib/chart-lines.js.map +7 -0
- package/dist/features/viz/lib/color-context.d.ts +4 -0
- package/dist/features/viz/lib/color-context.js +41 -0
- package/dist/features/viz/lib/color-context.js.map +7 -0
- package/dist/features/viz/lib/color-math.d.ts +4 -0
- package/dist/features/viz/lib/color-math.js +31 -0
- package/dist/features/viz/lib/color-math.js.map +7 -0
- package/dist/features/viz/lib/color-types.d.ts +53 -0
- package/dist/features/viz/lib/curve-definition.d.ts +49 -0
- package/dist/features/viz/lib/curve-definition.js +148 -0
- package/dist/features/viz/lib/curve-definition.js.map +7 -0
- package/dist/features/viz/lib/diverging-color-scale.d.ts +11 -0
- package/dist/features/viz/lib/diverging-color-scale.js +51 -0
- package/dist/features/viz/lib/diverging-color-scale.js.map +7 -0
- package/dist/features/viz/lib/domain-navigation.d.ts +40 -0
- package/dist/features/viz/lib/domain-navigation.js +77 -0
- package/dist/features/viz/lib/domain-navigation.js.map +7 -0
- package/dist/features/viz/lib/editable-chart-elements.d.ts +178 -0
- package/dist/features/viz/lib/editable-chart-elements.js +733 -0
- package/dist/features/viz/lib/editable-chart-elements.js.map +7 -0
- package/dist/features/viz/lib/financial-aggregation.d.ts +127 -0
- package/dist/features/viz/lib/financial-aggregation.js +116 -0
- package/dist/features/viz/lib/financial-aggregation.js.map +7 -0
- package/dist/features/viz/lib/financial-autoscale.d.ts +64 -0
- package/dist/features/viz/lib/financial-autoscale.js +61 -0
- package/dist/features/viz/lib/financial-autoscale.js.map +7 -0
- package/dist/features/viz/lib/financial-comparison.d.ts +62 -0
- package/dist/features/viz/lib/financial-comparison.js +98 -0
- package/dist/features/viz/lib/financial-comparison.js.map +7 -0
- package/dist/features/viz/lib/financial-geometry.d.ts +77 -0
- package/dist/features/viz/lib/financial-geometry.js +67 -0
- package/dist/features/viz/lib/financial-geometry.js.map +7 -0
- package/dist/features/viz/lib/financial-indicators.d.ts +114 -0
- package/dist/features/viz/lib/financial-indicators.js +135 -0
- package/dist/features/viz/lib/financial-indicators.js.map +7 -0
- package/dist/features/viz/lib/financial-oscillators.d.ts +171 -0
- package/dist/features/viz/lib/financial-oscillators.js +265 -0
- package/dist/features/viz/lib/financial-oscillators.js.map +7 -0
- package/dist/features/viz/lib/hover-data.d.ts +1 -1
- package/dist/features/viz/lib/hover-data.js +6 -3
- package/dist/features/viz/lib/hover-data.js.map +2 -2
- package/dist/features/viz/lib/hover-types.d.ts +5 -5
- package/dist/features/viz/lib/interval-band-series.d.ts +49 -0
- package/dist/features/viz/lib/interval-band-series.js +136 -0
- package/dist/features/viz/lib/interval-band-series.js.map +7 -0
- package/dist/features/viz/lib/interval-diamond-series.d.ts +43 -0
- package/dist/features/viz/lib/interval-diamond-series.js +124 -0
- package/dist/features/viz/lib/interval-diamond-series.js.map +7 -0
- package/dist/features/viz/lib/interval-series.d.ts +79 -0
- package/dist/features/viz/lib/interval-series.js +158 -0
- package/dist/features/viz/lib/interval-series.js.map +7 -0
- package/dist/features/viz/lib/line-series.d.ts +1 -1
- package/dist/features/viz/lib/line-series.js +47 -28
- package/dist/features/viz/lib/line-series.js.map +2 -2
- package/dist/features/viz/lib/linear-scale-component.d.ts +7 -0
- package/dist/features/viz/lib/linear-scale-component.js +18 -0
- package/dist/features/viz/lib/linear-scale-component.js.map +7 -0
- package/dist/features/viz/lib/linear-scale.js +1 -1
- package/dist/features/viz/lib/linear-scale.js.map +2 -2
- package/dist/features/viz/lib/log-scale-component.d.ts +7 -0
- package/dist/features/viz/lib/log-scale-component.js +19 -0
- package/dist/features/viz/lib/log-scale-component.js.map +7 -0
- package/dist/features/viz/lib/log-scale.d.ts +2 -0
- package/dist/features/viz/lib/log-scale.js +53 -0
- package/dist/features/viz/lib/log-scale.js.map +7 -0
- package/dist/features/viz/lib/monotone-curve.d.ts +11 -0
- package/dist/features/viz/lib/monotone-curve.js +63 -0
- package/dist/features/viz/lib/monotone-curve.js.map +7 -0
- package/dist/features/viz/lib/nearest.d.ts +9 -9
- package/dist/features/viz/lib/nearest.js.map +1 -1
- package/dist/features/viz/lib/numeric-range-interpolation.d.ts +15 -0
- package/dist/features/viz/lib/numeric-range-interpolation.js +36 -0
- package/dist/features/viz/lib/numeric-range-interpolation.js.map +7 -0
- package/dist/features/viz/lib/numeric-ticks.d.ts +38 -0
- package/dist/features/viz/lib/numeric-ticks.js +54 -0
- package/dist/features/viz/lib/numeric-ticks.js.map +7 -0
- package/dist/features/viz/lib/ohlc-bar-series.d.ts +55 -0
- package/dist/features/viz/lib/ohlc-bar-series.js +168 -0
- package/dist/features/viz/lib/ohlc-bar-series.js.map +7 -0
- package/dist/features/viz/lib/paired-series.d.ts +44 -0
- package/dist/features/viz/lib/paired-series.js +93 -0
- package/dist/features/viz/lib/paired-series.js.map +7 -0
- package/dist/features/viz/lib/plot-series.js +11 -6
- package/dist/features/viz/lib/plot-series.js.map +2 -2
- package/dist/features/viz/lib/plot-types.d.ts +4 -3
- package/dist/features/viz/lib/point-scale-component.d.ts +7 -0
- package/dist/features/viz/lib/point-scale-component.js +19 -0
- package/dist/features/viz/lib/point-scale-component.js.map +7 -0
- package/dist/features/viz/lib/point-scale.d.ts +2 -0
- package/dist/features/viz/lib/point-scale.js +45 -0
- package/dist/features/viz/lib/point-scale.js.map +7 -0
- package/dist/features/viz/lib/point-series.d.ts +1 -1
- package/dist/features/viz/lib/point-series.js +36 -9
- package/dist/features/viz/lib/point-series.js.map +2 -2
- package/dist/features/viz/lib/point-types.d.ts +5 -2
- package/dist/features/viz/lib/reference-band.d.ts +16 -0
- package/dist/features/viz/lib/reference-band.js +27 -0
- package/dist/features/viz/lib/reference-band.js.map +7 -0
- package/dist/features/viz/lib/scale-adjust.js +9 -4
- package/dist/features/viz/lib/scale-adjust.js.map +2 -2
- package/dist/features/viz/lib/scale-context.d.ts +5 -4
- package/dist/features/viz/lib/scale-context.js +15 -11
- package/dist/features/viz/lib/scale-context.js.map +2 -2
- package/dist/features/viz/lib/scale-provider.d.ts +2 -0
- package/dist/features/viz/lib/scale-provider.js +13 -0
- package/dist/features/viz/lib/scale-provider.js.map +7 -0
- package/dist/features/viz/lib/scale-ticks.d.ts +5 -0
- package/dist/features/viz/lib/scale-ticks.js +64 -0
- package/dist/features/viz/lib/scale-ticks.js.map +7 -0
- package/dist/features/viz/lib/scale-view.d.ts +4 -0
- package/dist/features/viz/lib/scale-view.js +21 -0
- package/dist/features/viz/lib/scale-view.js.map +7 -0
- package/dist/features/viz/lib/sequential-color-scale.d.ts +11 -0
- package/dist/features/viz/lib/sequential-color-scale.js +49 -0
- package/dist/features/viz/lib/sequential-color-scale.js.map +7 -0
- package/dist/features/viz/lib/series-position.d.ts +12 -0
- package/dist/features/viz/lib/series-position.js +44 -0
- package/dist/features/viz/lib/series-position.js.map +7 -0
- package/dist/features/viz/lib/step-curves.d.ts +19 -0
- package/dist/features/viz/lib/step-curves.js +53 -0
- package/dist/features/viz/lib/step-curves.js.map +7 -0
- package/dist/features/viz/lib/symlog-scale-component.d.ts +7 -0
- package/dist/features/viz/lib/symlog-scale-component.js +19 -0
- package/dist/features/viz/lib/symlog-scale-component.js.map +7 -0
- package/dist/features/viz/lib/symlog-scale.d.ts +2 -0
- package/dist/features/viz/lib/symlog-scale.js +38 -0
- package/dist/features/viz/lib/symlog-scale.js.map +7 -0
- package/dist/features/viz/lib/threshold-color-scale.d.ts +43 -0
- package/dist/features/viz/lib/threshold-color-scale.js +59 -0
- package/dist/features/viz/lib/threshold-color-scale.js.map +7 -0
- package/dist/features/viz/lib/trading-time-mapping.d.ts +32 -0
- package/dist/features/viz/lib/trading-time-mapping.js +89 -0
- package/dist/features/viz/lib/trading-time-mapping.js.map +7 -0
- package/dist/features/viz/lib/trading-time-scale.d.ts +83 -0
- package/dist/features/viz/lib/trading-time-scale.js +96 -0
- package/dist/features/viz/lib/trading-time-scale.js.map +7 -0
- package/dist/features/viz/lib/trajectory-series.d.ts +71 -0
- package/dist/features/viz/lib/trajectory-series.js +111 -0
- package/dist/features/viz/lib/trajectory-series.js.map +7 -0
- package/dist/features/viz/lib/types.d.ts +114 -21
- package/dist/features/viz/lib/use-bar-scale.d.ts +8 -0
- package/dist/features/viz/lib/use-bar-scale.js +9 -0
- package/dist/features/viz/lib/use-bar-scale.js.map +7 -0
- package/dist/features/viz/lib/use-continuous-scale.d.ts +8 -0
- package/dist/features/viz/lib/use-continuous-scale.js +14 -0
- package/dist/features/viz/lib/use-continuous-scale.js.map +7 -0
- package/dist/features/viz/lib/use-linear-scale.d.ts +8 -0
- package/dist/features/viz/lib/use-linear-scale.js +9 -0
- package/dist/features/viz/lib/use-linear-scale.js.map +7 -0
- package/dist/features/viz/lib/use-log-scale.d.ts +8 -0
- package/dist/features/viz/lib/use-log-scale.js +9 -0
- package/dist/features/viz/lib/use-log-scale.js.map +7 -0
- package/dist/features/viz/lib/use-point-scale.d.ts +8 -0
- package/dist/features/viz/lib/use-point-scale.js +9 -0
- package/dist/features/viz/lib/use-point-scale.js.map +7 -0
- package/dist/features/viz/lib/use-symlog-scale.d.ts +8 -0
- package/dist/features/viz/lib/use-symlog-scale.js +9 -0
- package/dist/features/viz/lib/use-symlog-scale.js.map +7 -0
- package/dist/features/viz/lib/use-utc-scale.d.ts +8 -0
- package/dist/features/viz/lib/use-utc-scale.js +9 -0
- package/dist/features/viz/lib/use-utc-scale.js.map +7 -0
- package/dist/features/viz/lib/utc-labels.d.ts +12 -0
- package/dist/features/viz/lib/utc-labels.js +27 -0
- package/dist/features/viz/lib/utc-labels.js.map +7 -0
- package/dist/features/viz/lib/utc-scale-component.d.ts +7 -0
- package/dist/features/viz/lib/utc-scale-component.js +18 -0
- package/dist/features/viz/lib/utc-scale-component.js.map +7 -0
- package/dist/features/viz/lib/utc-scale.d.ts +21 -0
- package/dist/features/viz/lib/utc-scale.js +123 -0
- package/dist/features/viz/lib/utc-scale.js.map +7 -0
- package/dist/features/viz/lib/volume-series.d.ts +59 -0
- package/dist/features/viz/lib/volume-series.js +117 -0
- package/dist/features/viz/lib/volume-series.js.map +7 -0
- package/dist/features/viz/lib/weighted-point-series.d.ts +71 -0
- package/dist/features/viz/lib/weighted-point-series.js +169 -0
- package/dist/features/viz/lib/weighted-point-series.js.map +7 -0
- package/dist/filters/emboss-gpu.d.ts +4 -0
- package/dist/filters/emboss-gpu.js +39 -0
- package/dist/filters/emboss-gpu.js.map +7 -0
- package/dist/filters/emboss.d.ts +32 -0
- package/dist/filters/emboss.js +106 -0
- package/dist/filters/emboss.js.map +7 -0
- package/dist/filters/reflection-gpu.d.ts +3 -1
- package/dist/filters/reflection-gpu.js +5 -2
- package/dist/filters/reflection-gpu.js.map +2 -2
- package/dist/filters/render-emboss-boundary.d.ts +13 -0
- package/dist/filters/render-emboss-boundary.js +131 -0
- package/dist/filters/render-emboss-boundary.js.map +7 -0
- package/dist/filters.d.ts +2 -0
- package/dist/filters.js +2 -0
- package/dist/filters.js.map +2 -2
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +2 -2
- package/dist/internal.d.ts +2 -0
- package/dist/internal.js +4 -0
- package/dist/internal.js.map +2 -2
- package/dist/lib/animation/definition.d.ts +5 -3
- package/dist/lib/animation/definition.js +29 -4
- package/dist/lib/animation/definition.js.map +2 -2
- package/dist/lib/animation/playback.d.ts +8 -0
- package/dist/lib/animation/playback.js +33 -11
- package/dist/lib/animation/playback.js.map +2 -2
- package/dist/lib/animation/spring.d.ts +3 -1
- package/dist/lib/animation/spring.js.map +2 -2
- package/dist/lib/animation/types.d.ts +29 -73
- package/dist/lib/events/event-facade.d.ts +13 -0
- package/dist/lib/events/event-facade.js +23 -0
- package/dist/lib/events/event-facade.js.map +2 -2
- package/dist/lib/events/propagation.js +19 -14
- package/dist/lib/events/propagation.js.map +2 -2
- package/dist/lib/execute-render.js +13 -0
- package/dist/lib/execute-render.js.map +2 -2
- package/dist/lib/hooks/use-animated-value.d.ts +11 -21
- package/dist/lib/hooks/use-animated-value.js +23 -70
- package/dist/lib/hooks/use-animated-value.js.map +3 -3
- package/dist/lib/hooks/use-playback.js +1 -0
- package/dist/lib/hooks/use-playback.js.map +2 -2
- package/dist/lib/recording/recording.d.ts +43 -0
- package/dist/lib/recording/recording.js +555 -0
- package/dist/lib/recording/recording.js.map +7 -0
- package/dist/lib/recording/types.d.ts +118 -0
- package/dist/lib/recording/wasm-bytes.d.ts +1 -0
- package/dist/lib/recording/wasm-bytes.js +5 -0
- package/dist/lib/recording/wasm-bytes.js.map +7 -0
- package/dist/lib/recording/worker-source.d.ts +1 -0
- package/dist/lib/recording/worker-source.js +5 -0
- package/dist/lib/recording/worker-source.js.map +7 -0
- package/dist/lib/render-transaction.d.ts +5 -2
- package/dist/lib/render-transaction.js +23 -1
- package/dist/lib/render-transaction.js.map +2 -2
- package/dist/lib/series-inspection-frame.d.ts +18 -0
- package/dist/lib/series-inspection-frame.js +70 -0
- package/dist/lib/series-inspection-frame.js.map +7 -0
- package/dist/lib/types.d.ts +6 -0
- package/package.json +27 -5
- package/dist/features/viz/lib/scale.d.ts +0 -11
- package/dist/features/viz/lib/scale.js +0 -80
- package/dist/features/viz/lib/scale.js.map +0 -7
- package/dist/features/viz/lib/use-scale.d.ts +0 -20
- package/dist/features/viz/lib/use-scale.js +0 -10
- package/dist/features/viz/lib/use-scale.js.map +0 -7
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/censored-point-series.tsx"],
|
|
4
|
+
"sourcesContent": ["import { Path, resolveSignalValue } from \"@pibbl/core\";\nimport type {\n FillStyle,\n PibblEventHandlers,\n PibblEventParticipationOptions,\n SignalValue,\n StrokeStyle,\n} from \"@pibbl/core\";\nimport type { SignalStyle } from \"@pibbl/core/internal\";\nimport { validateTexturePaint, withHooksForbidden } from \"@pibbl/core/internal\";\nimport type { LineAccessor, ScaleId } from \"./types.js\";\nimport { finiteCoordinate, pointAccessor, pointData } from \"./point-data.js\";\nimport { opacity, width } from \"./paint.js\";\nimport { useContinuousScale } from \"./use-continuous-scale.js\";\n\n/** A supplied assay reporting status. `below` and `above` retain the supplied reporting limit.\n * @see {@link CensoredPointSeriesProps}\n */\nexport type CensoringStatus = \"observed\" | \"below\" | \"above\";\n\n/** Extracts an observation's supplied reporting status.\n * @param datum - Original record being read.\n * @param index - Zero-based source index.\n * @param data - Complete supplied record array.\n * @returns The supplied status, or a nullish sentinel that omits the record.\n * @see {@link CensoringStatus}\n */\nexport type CensoringAccessor<D> =\n | {\n [K in keyof D]-?: D[K] extends CensoringStatus | null | undefined\n ? K\n : never;\n }[keyof D]\n | ((\n datum: D,\n index: number,\n data: readonly D[],\n ) => CensoringStatus | null | undefined);\n\n/** Shared mark paint and local-pixel geometry for {@link CensoredPointSeries}. */\nexport interface CensoredPointSeriesStyle {\n /** Circle and open censor marker radius in local pixels; defaults to 4. */\n readonly radius?: number;\n /** Fill for observed circles; defaults to #087f8c. Censor markers remain open. */\n readonly fill?: FillStyle;\n /** Outline for circles and open directional censor markers; defaults to #087f8c. */\n readonly stroke?: StrokeStyle;\n /** Outline width in local pixels; defaults to 1.5. */\n readonly strokeWidth?: number;\n /** Shared paint opacity from zero to one; defaults to 1. */\n readonly opacity?: number;\n /** Cursor for painted mark targets. */\n readonly cursor?: string;\n}\n\n/** Authored inputs for supplied observed and censored numeric observations.\n * @see {@link CensoredPointSeries}\n */\nexport interface CensoredPointSeriesProps<D>\n extends PibblEventHandlers, PibblEventParticipationOptions {\n /** Original records, or a signal of records. The series performs no imputation or inference. */\n readonly data: SignalValue<readonly D[]>;\n /** Property or callback supplying the numeric horizontal coordinate. */\n readonly x: LineAccessor<D>;\n /** Property or callback supplying the numeric vertical value or reporting limit. */\n readonly y: LineAccessor<D>;\n /** Property or callback yielding `observed`, `below`, or `above`. */\n readonly censoring: CensoringAccessor<D>;\n /** Ancestor continuous numeric scale mapping x. */\n readonly xScale: ScaleId;\n /** Ancestor continuous numeric scale mapping y and its reporting limit. */\n readonly yScale: ScaleId;\n /** Optional synchronous predicate; excluded rows contribute no mark.\n * @param datum - Original record being tested.\n * @param index - Zero-based source index.\n * @param data - Complete supplied record array.\n * @returns Whether this record contributes a mark.\n */\n readonly defined?: (datum: D, index: number, data: readonly D[]) => boolean;\n /** Shared style; whole-object and shallow field signals are observed by the series. */\n readonly style?: SignalValue<SignalStyle<CensoredPointSeriesStyle>>;\n}\n\nconst fields = [\"radius\", \"fill\", \"stroke\", \"strokeWidth\", \"opacity\", \"cursor\"];\n\nfunction paint(\n value: unknown,\n name: string,\n): FillStyle | StrokeStyle | undefined {\n if (\n value === undefined ||\n typeof value === \"string\" ||\n value instanceof CanvasGradient ||\n value instanceof CanvasPattern\n )\n return value;\n try {\n validateTexturePaint(value as never);\n return value as FillStyle | StrokeStyle;\n } catch {\n // Fall through to the local series error rather than leaking protocol detail.\n }\n throw new TypeError(`CensoredPointSeries: invalid ${name}.`);\n}\n\nfunction triangle(\n path: Path2D,\n x: number,\n y: number,\n radius: number,\n direction: number,\n) {\n path.moveTo(x, y + direction * radius);\n path.lineTo(x - radius * 0.78, y - direction * radius * 0.55);\n path.lineTo(x + radius * 0.78, y - direction * radius * 0.55);\n path.closePath();\n}\n\n/**\n * Draws supplied numeric observations as circles and below/above reporting limits as open arrows.\n *\n * `below` points toward decreasing y-domain values and `above` toward increasing y-domain values,\n * including when the y scale uses a reversed domain or range. The supplied `y` value remains the\n * reporting limit; this component never substitutes a measurement, imputes a value, or fits a model.\n *\n * @param props - Supplied observations, coordinates, reporting statuses, scales, and paint.\n * See {@link CensoredPointSeriesProps}.\n * @returns Two ordinary batched paths for observed and open censored marks.\n * @see {@link CensoredPointSeriesProps}\n */\nexport function CensoredPointSeries<D>({\n data: input,\n x: xInput,\n y: yInput,\n censoring: censoringInput,\n xScale: xId,\n yScale: yId,\n defined,\n style: styleInput,\n pointerEvents,\n ...events\n}: CensoredPointSeriesProps<D>) {\n const xScale = useContinuousScale(xId).get();\n const yScale = useContinuousScale(yId).get();\n const data = pointData(resolveSignalValue(input), \"CensoredPointSeries\");\n const x = pointAccessor(xInput),\n y = pointAccessor(yInput);\n const censoring =\n typeof censoringInput === \"function\"\n ? censoringInput\n : (datum: D) =>\n datum[censoringInput] as CensoringStatus | null | undefined;\n const specified = resolveSignalValue(styleInput) ?? {};\n if (\n specified === null ||\n typeof specified !== \"object\" ||\n Array.isArray(specified)\n )\n throw new TypeError(\"CensoredPointSeries: style must be an object.\");\n const style: Record<string, unknown> = {};\n for (const key of Object.keys(specified)) {\n if (!fields.includes(key))\n throw new TypeError(\n `CensoredPointSeries: unsupported style field ${key}.`,\n );\n style[key] = resolveSignalValue(\n (specified as Record<string, unknown>)[key],\n );\n }\n const resolved = style as CensoredPointSeriesStyle;\n const radius = width(resolved.radius ?? 4, \"CensoredPointSeries radius\");\n const strokeWidth = width(resolved.strokeWidth ?? 1.5, \"CensoredPointSeries\");\n const alpha = opacity(resolved.opacity ?? 1, \"CensoredPointSeries\");\n if (resolved.cursor !== undefined && typeof resolved.cursor !== \"string\")\n throw new TypeError(\"CensoredPointSeries: cursor must be a string.\");\n const fill = paint(resolved.fill ?? \"#087f8c\", \"fill\");\n const stroke = paint(resolved.stroke ?? \"#087f8c\", \"stroke\");\n const observed = new Path2D();\n const censored = new Path2D();\n // The sign is a property of the domain-to-range mapping, rather than canvas orientation.\n const increasingY = Math.sign(\n (yScale.domain[1] - yScale.domain[0]) * (yScale.range[1] - yScale.range[0]),\n );\n for (let i = 0; i < data.length; i++) {\n const datum = data[i];\n const coordinates = withHooksForbidden(\n \"CensoredPointSeries: accessors cannot call hooks.\",\n () => {\n if (defined && !defined(datum, i, data)) return undefined;\n return {\n x: x(datum, i, data),\n y: y(datum, i, data),\n censoring: censoring(datum, i, data),\n };\n },\n );\n if (\n !coordinates ||\n !finiteCoordinate(coordinates.x) ||\n !finiteCoordinate(coordinates.y) ||\n coordinates.censoring == null\n )\n continue;\n if (\n !([\"observed\", \"below\", \"above\"] as const).includes(coordinates.censoring)\n )\n throw new TypeError(\n `CensoredPointSeries: unknown censoring status ${String(coordinates.censoring)} (row ${i}).`,\n );\n const px = xScale.map(coordinates.x),\n py = yScale.map(coordinates.y);\n if (!Number.isFinite(px) || !Number.isFinite(py))\n throw new RangeError(\n `CensoredPointSeries: mapped coordinates must be finite (row ${i}).`,\n );\n if (radius === 0) continue;\n if (coordinates.censoring === \"observed\") {\n observed.moveTo(px + radius, py);\n observed.arc(px, py, radius, 0, Math.PI * 2);\n observed.closePath();\n } else {\n const direction =\n coordinates.censoring === \"above\" ? increasingY : -increasingY;\n triangle(censored, px, py, radius, direction || 1);\n }\n }\n const common = {\n stroke,\n strokeWidth,\n opacity: alpha,\n cursor: resolved.cursor,\n };\n return (\n <>\n <Path\n {...events}\n pointerEvents={pointerEvents}\n style={{ d: observed, fill, ...common }}\n />\n <Path\n {...events}\n pointerEvents={pointerEvents}\n style={{ d: censored, fill: \"transparent\", ...common }}\n />\n </>\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type SignalValue } from "@pibbl/core";
|
|
2
|
+
import type { AxisProps, AxisStyle, BandCategory, ScaleId } from "./types.js";
|
|
3
|
+
import type { SignalStyle } from "@pibbl/core/internal";
|
|
4
|
+
/** Shared geometry and paint for decorative chart lines; no layout is allocated. See {@link GridLines}. */
|
|
5
|
+
export interface ChartLineProps {
|
|
6
|
+
/** Ancestor scale providing the line's mapped coordinate. */
|
|
7
|
+
readonly scale: ScaleId;
|
|
8
|
+
/** Direction the painted line extends. */
|
|
9
|
+
readonly direction: "horizontal" | "vertical";
|
|
10
|
+
/** Explicit perpendicular pixel endpoints, in the caller's local coordinate space. */
|
|
11
|
+
readonly span: SignalValue<readonly [number, number]>;
|
|
12
|
+
/** Stroke defaults to #dce5e8, width to 1, opacity to 1. */
|
|
13
|
+
readonly style?: SignalValue<SignalStyle<Pick<AxisStyle, "stroke" | "strokeWidth" | "opacity">>>;
|
|
14
|
+
}
|
|
15
|
+
/** Grid positions use Axis tick rules, independent of Axis label visibility. See {@link GridLines}. */
|
|
16
|
+
export type GridLinesProps = ChartLineProps & ({
|
|
17
|
+
/** Explicit domain ticks; same validation as Axis. */
|
|
18
|
+
readonly tickValues: AxisProps["tickValues"];
|
|
19
|
+
/** Mutually exclusive with explicit values. */
|
|
20
|
+
readonly tickCount?: never;
|
|
21
|
+
} | {
|
|
22
|
+
/** Mutually exclusive with generated ticks. */
|
|
23
|
+
readonly tickValues?: never;
|
|
24
|
+
/** Requested tick count; defaults to five. */
|
|
25
|
+
readonly tickCount?: AxisProps["tickCount"];
|
|
26
|
+
});
|
|
27
|
+
/** A reference value must belong to the selected scale's domain. See {@link ReferenceLine}. */
|
|
28
|
+
export interface ReferenceLineProps extends ChartLineProps {
|
|
29
|
+
/** Numeric domain value or categorical identity; signals update the line. */
|
|
30
|
+
readonly value: SignalValue<BandCategory>;
|
|
31
|
+
}
|
|
32
|
+
/** Paint grid lines at scale ticks, without labels or allocation.
|
|
33
|
+
* @param props - Scale geometry and presentation. See {@link GridLinesProps}.
|
|
34
|
+
* @returns Decorative chart content in the caller's coordinate space.
|
|
35
|
+
*/
|
|
36
|
+
export declare function GridLines(props: GridLinesProps): import("../../../jsx-runtime.js").JSX.Element[];
|
|
37
|
+
/** Paint one decorative line at a domain value, without labels or allocation.
|
|
38
|
+
* @param props - Scale geometry and presentation. See {@link ReferenceLineProps}.
|
|
39
|
+
* @returns Decorative chart content in the caller's coordinate space.
|
|
40
|
+
*/
|
|
41
|
+
export declare function ReferenceLine(props: ReferenceLineProps): import("../../../jsx-runtime.js").JSX.Element[];
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx } from "@pibbl/core/jsx-runtime";
|
|
2
|
+
import { Line, resolveSignalValue } from "@pibbl/core";
|
|
3
|
+
import { lookupScale } from "./scale-context.js";
|
|
4
|
+
import { ticks, position } from "./scale-ticks.js";
|
|
5
|
+
import { width, opacity } from "./paint.js";
|
|
6
|
+
function lines(props, selection) {
|
|
7
|
+
if (props.direction !== "horizontal" && props.direction !== "vertical") throw new TypeError("Chart line direction must be horizontal or vertical.");
|
|
8
|
+
const source = lookupScale(props.scale, "Chart line");
|
|
9
|
+
if (!source) throw new TypeError("Chart lines require a scale ID.");
|
|
10
|
+
const scale = source.get(), span = resolveSignalValue(props.span);
|
|
11
|
+
if (!Array.isArray(span) || span.length !== 2 || !span.every((v) => typeof v === "number" && Number.isFinite(v))) throw new RangeError("Chart line span must have two finite pixel endpoints.");
|
|
12
|
+
const style = resolveSignalValue(props.style) ?? {};
|
|
13
|
+
const stroke = resolveSignalValue(style.stroke) ?? "#dce5e8";
|
|
14
|
+
const strokeWidth = width(resolveSignalValue(style.strokeWidth) ?? 1, "Chart line");
|
|
15
|
+
const alpha = opacity(resolveSignalValue(style.opacity) ?? 1, "Chart line");
|
|
16
|
+
return ticks(scale, selection).map((value, index) => {
|
|
17
|
+
const p = position(scale, value);
|
|
18
|
+
const coords = props.direction === "horizontal" ? [[span[0], p], [span[1], p]] : [[p, span[0]], [p, span[1]]];
|
|
19
|
+
return /* @__PURE__ */ jsx(Line, { pointerEvents: "none", style: { coords, stroke, strokeWidth, opacity: alpha } }, index);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function GridLines(props) {
|
|
23
|
+
return lines(props, props);
|
|
24
|
+
}
|
|
25
|
+
function ReferenceLine(props) {
|
|
26
|
+
return lines(props, { tickValues: [resolveSignalValue(props.value)] });
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
GridLines,
|
|
30
|
+
ReferenceLine
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=chart-lines.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/chart-lines.tsx"],
|
|
4
|
+
"sourcesContent": ["import { Line, resolveSignalValue, type SignalValue } from \"@pibbl/core\";\nimport type { AxisProps, AxisStyle, BandCategory, ScaleId } from \"./types.js\";\nimport type { SignalStyle } from \"@pibbl/core/internal\";\nimport { lookupScale } from \"./scale-context.js\";\nimport { ticks, position } from \"./scale-ticks.js\";\nimport { width, opacity } from \"./paint.js\";\n/** Shared geometry and paint for decorative chart lines; no layout is allocated. See {@link GridLines}. */\nexport interface ChartLineProps {\n /** Ancestor scale providing the line's mapped coordinate. */\n readonly scale: ScaleId;\n /** Direction the painted line extends. */\n readonly direction: \"horizontal\" | \"vertical\";\n /** Explicit perpendicular pixel endpoints, in the caller's local coordinate space. */\n readonly span: SignalValue<readonly [number, number]>;\n /** Stroke defaults to #dce5e8, width to 1, opacity to 1. */\n readonly style?: SignalValue<SignalStyle<Pick<AxisStyle, \"stroke\" | \"strokeWidth\" | \"opacity\">>>;\n}\n/** Grid positions use Axis tick rules, independent of Axis label visibility. See {@link GridLines}. */\nexport type GridLinesProps = ChartLineProps & (\n {\n /** Explicit domain ticks; same validation as Axis. */\n readonly tickValues: AxisProps[\"tickValues\"];\n /** Mutually exclusive with explicit values. */\n readonly tickCount?: never;\n } |\n {\n /** Mutually exclusive with generated ticks. */\n readonly tickValues?: never;\n /** Requested tick count; defaults to five. */\n readonly tickCount?: AxisProps[\"tickCount\"];\n }\n);\n/** A reference value must belong to the selected scale's domain. See {@link ReferenceLine}. */\nexport interface ReferenceLineProps extends ChartLineProps {\n /** Numeric domain value or categorical identity; signals update the line. */\n readonly value: SignalValue<BandCategory>;\n}\nfunction lines(props: ChartLineProps, selection: Pick<AxisProps, \"tickCount\" | \"tickValues\">) {\n if (props.direction !== \"horizontal\" && props.direction !== \"vertical\") throw new TypeError(\"Chart line direction must be horizontal or vertical.\");\n const source = lookupScale(props.scale, \"Chart line\");\n if (!source) throw new TypeError(\"Chart lines require a scale ID.\");\n const scale = source.get(), span = resolveSignalValue(props.span);\n if (!Array.isArray(span) || span.length !== 2 || !span.every(v => typeof v === \"number\" && Number.isFinite(v))) throw new RangeError(\"Chart line span must have two finite pixel endpoints.\");\n const style = resolveSignalValue(props.style) ?? {};\n const stroke = resolveSignalValue(style.stroke) ?? \"#dce5e8\";\n const strokeWidth = width(resolveSignalValue(style.strokeWidth) ?? 1, \"Chart line\");\n const alpha = opacity(resolveSignalValue(style.opacity) ?? 1, \"Chart line\");\n return ticks(scale, selection).map((value, index) => {\n const p = position(scale, value);\n const coords: [number, number][] = props.direction === \"horizontal\" ? [[span[0], p], [span[1], p]] : [[p, span[0]], [p, span[1]]];\n return <Line key={index} pointerEvents=\"none\" style={{ coords, stroke, strokeWidth, opacity: alpha }} />;\n });\n}\n/** Paint grid lines at scale ticks, without labels or allocation.\n * @param props - Scale geometry and presentation. See {@link GridLinesProps}.\n * @returns Decorative chart content in the caller's coordinate space.\n */\nexport function GridLines(props: GridLinesProps) { return lines(props, props); }\n/** Paint one decorative line at a domain value, without labels or allocation.\n * @param props - Scale geometry and presentation. See {@link ReferenceLineProps}.\n * @returns Decorative chart content in the caller's coordinate space.\n */\nexport function ReferenceLine(props: ReferenceLineProps) { return lines(props, { tickValues: [resolveSignalValue(props.value)] }); }\n"],
|
|
5
|
+
"mappings": "AAkDW;AAlDX,SAAS,MAAM,0BAA4C;AAG3D,SAAS,mBAAmB;AAC5B,SAAS,OAAO,gBAAgB;AAChC,SAAS,OAAO,eAAe;AAgC/B,SAAS,MAAM,OAAuB,WAAwD;AAC5F,MAAI,MAAM,cAAc,gBAAgB,MAAM,cAAc,WAAY,OAAM,IAAI,UAAU,sDAAsD;AAClJ,QAAM,SAAS,YAAY,MAAM,OAAO,YAAY;AACpD,MAAI,CAAC,OAAQ,OAAM,IAAI,UAAU,iCAAiC;AAClE,QAAM,QAAQ,OAAO,IAAI,GAAG,OAAO,mBAAmB,MAAM,IAAI;AAChE,MAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,KAAK,WAAW,KAAK,CAAC,KAAK,MAAM,OAAK,OAAO,MAAM,YAAY,OAAO,SAAS,CAAC,CAAC,EAAG,OAAM,IAAI,WAAW,uDAAuD;AAC5L,QAAM,QAAQ,mBAAmB,MAAM,KAAK,KAAK,CAAC;AAClD,QAAM,SAAS,mBAAmB,MAAM,MAAM,KAAK;AACnD,QAAM,cAAc,MAAM,mBAAmB,MAAM,WAAW,KAAK,GAAG,YAAY;AAClF,QAAM,QAAQ,QAAQ,mBAAmB,MAAM,OAAO,KAAK,GAAG,YAAY;AAC1E,SAAO,MAAM,OAAO,SAAS,EAAE,IAAI,CAAC,OAAO,UAAU;AACnD,UAAM,IAAI,SAAS,OAAO,KAAK;AAC/B,UAAM,SAA6B,MAAM,cAAc,eAAe,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;AAChI,WAAO,oBAAC,QAAiB,eAAc,QAAO,OAAO,EAAE,QAAQ,QAAQ,aAAa,SAAS,MAAM,KAAjF,KAAoF;AAAA,EACxG,CAAC;AACH;AAKO,SAAS,UAAU,OAAuB;AAAE,SAAO,MAAM,OAAO,KAAK;AAAG;AAKxE,SAAS,cAAc,OAA2B;AAAE,SAAO,MAAM,OAAO,EAAE,YAAY,CAAC,mBAAmB,MAAM,KAAK,CAAC,EAAE,CAAC;AAAG;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type Signal } from "@pibbl/core";
|
|
2
|
+
import type { ScaleId } from "./types.js";
|
|
3
|
+
export declare function provideColor<T>(id: ScaleId, kind: string, resolve: () => T, deps: readonly unknown[]): void;
|
|
4
|
+
export declare function useColor<T>(id: ScaleId, kind: string): Signal<T>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useComputed } from "@pibbl/core";
|
|
2
|
+
import {
|
|
3
|
+
getCurrentBackendHostCanvas,
|
|
4
|
+
setCurrentComponentAfterRender,
|
|
5
|
+
useInternalHookSlot
|
|
6
|
+
} from "@pibbl/core/internal";
|
|
7
|
+
let current;
|
|
8
|
+
function provideColor(id, kind, resolve, deps) {
|
|
9
|
+
if ((typeof id !== "string" || id.length === 0) && typeof id !== "symbol")
|
|
10
|
+
throw new TypeError("Color scale id requires a nonempty string or symbol.");
|
|
11
|
+
const value = useComputed(resolve, deps), parent = current;
|
|
12
|
+
current = { id, kind, value, canvas: getCurrentBackendHostCanvas(), parent };
|
|
13
|
+
const restore = () => {
|
|
14
|
+
current = parent;
|
|
15
|
+
};
|
|
16
|
+
try {
|
|
17
|
+
setCurrentComponentAfterRender(restore);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
restore();
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function useColor(id, kind) {
|
|
24
|
+
useInternalHookSlot("vizColorScaleLookup", () => void 0);
|
|
25
|
+
for (let scope = current; scope; scope = scope.parent) {
|
|
26
|
+
if (scope.id !== id) continue;
|
|
27
|
+
if (scope.canvas !== getCurrentBackendHostCanvas())
|
|
28
|
+
throw new Error("Color scale cannot cross a Layer boundary.");
|
|
29
|
+
if (scope.kind !== kind)
|
|
30
|
+
throw new TypeError(`Expected ${kind} color scale; found ${scope.kind}.`);
|
|
31
|
+
return scope.value;
|
|
32
|
+
}
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Unknown color scale ${String(id)}; add the matching ancestor provider.`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
export {
|
|
38
|
+
provideColor,
|
|
39
|
+
useColor
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=color-context.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/color-context.ts"],
|
|
4
|
+
"sourcesContent": ["import { useComputed, type Signal } from \"@pibbl/core\";\nimport {\n getCurrentBackendHostCanvas,\n setCurrentComponentAfterRender,\n useInternalHookSlot,\n} from \"@pibbl/core/internal\";\nimport type { ScaleId } from \"./types.js\";\ninterface Scope {\n id: ScaleId;\n kind: string;\n value: Signal<unknown>;\n canvas: ReturnType<typeof getCurrentBackendHostCanvas>;\n parent: Scope | undefined;\n}\nlet current: Scope | undefined;\nexport function provideColor<T>(\n id: ScaleId,\n kind: string,\n resolve: () => T,\n deps: readonly unknown[],\n): void {\n if ((typeof id !== \"string\" || id.length === 0) && typeof id !== \"symbol\")\n throw new TypeError(\"Color scale id requires a nonempty string or symbol.\");\n const value = useComputed(resolve, deps),\n parent = current;\n current = { id, kind, value, canvas: getCurrentBackendHostCanvas(), parent };\n const restore = () => {\n current = parent;\n };\n try {\n setCurrentComponentAfterRender(restore);\n } catch (error) {\n restore();\n throw error;\n }\n}\nexport function useColor<T>(id: ScaleId, kind: string): Signal<T> {\n useInternalHookSlot(\"vizColorScaleLookup\", () => undefined);\n for (let scope = current; scope; scope = scope.parent) {\n if (scope.id !== id) continue;\n if (scope.canvas !== getCurrentBackendHostCanvas())\n throw new Error(\"Color scale cannot cross a Layer boundary.\");\n if (scope.kind !== kind)\n throw new TypeError(`Expected ${kind} color scale; found ${scope.kind}.`);\n return scope.value as Signal<T>;\n }\n throw new Error(\n `Unknown color scale ${String(id)}; add the matching ancestor provider.`,\n );\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,mBAAgC;AACzC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AASP,IAAI;AACG,SAAS,aACd,IACA,MACA,SACA,MACM;AACN,OAAK,OAAO,OAAO,YAAY,GAAG,WAAW,MAAM,OAAO,OAAO;AAC/D,UAAM,IAAI,UAAU,sDAAsD;AAC5E,QAAM,QAAQ,YAAY,SAAS,IAAI,GACrC,SAAS;AACX,YAAU,EAAE,IAAI,MAAM,OAAO,QAAQ,4BAA4B,GAAG,OAAO;AAC3E,QAAM,UAAU,MAAM;AACpB,cAAU;AAAA,EACZ;AACA,MAAI;AACF,mCAA+B,OAAO;AAAA,EACxC,SAAS,OAAO;AACd,YAAQ;AACR,UAAM;AAAA,EACR;AACF;AACO,SAAS,SAAY,IAAa,MAAyB;AAChE,sBAAoB,uBAAuB,MAAM,MAAS;AAC1D,WAAS,QAAQ,SAAS,OAAO,QAAQ,MAAM,QAAQ;AACrD,QAAI,MAAM,OAAO,GAAI;AACrB,QAAI,MAAM,WAAW,4BAA4B;AAC/C,YAAM,IAAI,MAAM,4CAA4C;AAC9D,QAAI,MAAM,SAAS;AACjB,YAAM,IAAI,UAAU,YAAY,IAAI,uBAAuB,MAAM,IAAI,GAAG;AAC1E,WAAO,MAAM;AAAA,EACf;AACA,QAAM,IAAI;AAAA,IACR,uBAAuB,OAAO,EAAE,CAAC;AAAA,EACnC;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function finiteColorValue(value: number): number;
|
|
2
|
+
export declare function hexColor(color: string): string;
|
|
3
|
+
export declare function colorMix(a: string, b: string, t: number): string;
|
|
4
|
+
export declare function colorPosition(value: number, a: number, b: number): number;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
function finiteColorValue(value) {
|
|
2
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
3
|
+
throw new RangeError("Color scale values must be finite numbers.");
|
|
4
|
+
return value;
|
|
5
|
+
}
|
|
6
|
+
function hexColor(color) {
|
|
7
|
+
if (typeof color !== "string" || !/^#[0-9a-f]{6}$/i.test(color))
|
|
8
|
+
throw new TypeError("Color scales require #RRGGBB colors.");
|
|
9
|
+
return color.toLowerCase();
|
|
10
|
+
}
|
|
11
|
+
function colorMix(a, b, t) {
|
|
12
|
+
return "#" + [1, 3, 5].map(
|
|
13
|
+
(i) => Math.round(
|
|
14
|
+
parseInt(a.slice(i, i + 2), 16) * (1 - t) + parseInt(b.slice(i, i + 2), 16) * t
|
|
15
|
+
).toString(16).padStart(2, "0")
|
|
16
|
+
).join("");
|
|
17
|
+
}
|
|
18
|
+
function colorPosition(value, a, b) {
|
|
19
|
+
if (a === b) return 0.5;
|
|
20
|
+
if (a < b && value <= a || a > b && value >= a) return 0;
|
|
21
|
+
if (a < b && value >= b || a > b && value <= b) return 1;
|
|
22
|
+
const span = b - a;
|
|
23
|
+
return Number.isFinite(span) ? (value - a) / span : (value / 2 - a / 2) / (b / 2 - a / 2);
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
colorMix,
|
|
27
|
+
colorPosition,
|
|
28
|
+
finiteColorValue,
|
|
29
|
+
hexColor
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=color-math.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/color-math.ts"],
|
|
4
|
+
"sourcesContent": ["export function finiteColorValue(value: number): number {\n if (typeof value !== \"number\" || !Number.isFinite(value))\n throw new RangeError(\"Color scale values must be finite numbers.\");\n return value;\n}\nexport function hexColor(color: string): string {\n if (typeof color !== \"string\" || !/^#[0-9a-f]{6}$/i.test(color))\n throw new TypeError(\"Color scales require #RRGGBB colors.\");\n return color.toLowerCase();\n}\nexport function colorMix(a: string, b: string, t: number): string {\n return (\n \"#\" +\n [1, 3, 5]\n .map((i) =>\n Math.round(\n parseInt(a.slice(i, i + 2), 16) * (1 - t) +\n parseInt(b.slice(i, i + 2), 16) * t,\n )\n .toString(16)\n .padStart(2, \"0\"),\n )\n .join(\"\")\n );\n}\nexport function colorPosition(value: number, a: number, b: number): number {\n if (a === b) return 0.5;\n if ((a < b && value <= a) || (a > b && value >= a)) return 0;\n if ((a < b && value >= b) || (a > b && value <= b)) return 1;\n const span = b - a;\n return Number.isFinite(span)\n ? (value - a) / span\n : (value / 2 - a / 2) / (b / 2 - a / 2);\n}\n"],
|
|
5
|
+
"mappings": "AAAO,SAAS,iBAAiB,OAAuB;AACtD,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK;AACrD,UAAM,IAAI,WAAW,4CAA4C;AACnE,SAAO;AACT;AACO,SAAS,SAAS,OAAuB;AAC9C,MAAI,OAAO,UAAU,YAAY,CAAC,kBAAkB,KAAK,KAAK;AAC5D,UAAM,IAAI,UAAU,sCAAsC;AAC5D,SAAO,MAAM,YAAY;AAC3B;AACO,SAAS,SAAS,GAAW,GAAW,GAAmB;AAChE,SACE,MACA,CAAC,GAAG,GAAG,CAAC,EACL;AAAA,IAAI,CAAC,MACJ,KAAK;AAAA,MACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,KACrC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI;AAAA,IACtC,EACG,SAAS,EAAE,EACX,SAAS,GAAG,GAAG;AAAA,EACpB,EACC,KAAK,EAAE;AAEd;AACO,SAAS,cAAc,OAAe,GAAW,GAAmB;AACzE,MAAI,MAAM,EAAG,QAAO;AACpB,MAAK,IAAI,KAAK,SAAS,KAAO,IAAI,KAAK,SAAS,EAAI,QAAO;AAC3D,MAAK,IAAI,KAAK,SAAS,KAAO,IAAI,KAAK,SAAS,EAAI,QAAO;AAC3D,QAAM,OAAO,IAAI;AACjB,SAAO,OAAO,SAAS,IAAI,KACtB,QAAQ,KAAK,QACb,QAAQ,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI;AACzC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { PibblNode, SignalValue } from "@pibbl/core";
|
|
2
|
+
import type { ScaleId } from "./types.js";
|
|
3
|
+
/** One authored domain/color association. @see {@link ResolvedSequentialColorScale} */
|
|
4
|
+
export interface ColorScaleStop {
|
|
5
|
+
/** Numeric data value at the color stop. */ readonly value: number;
|
|
6
|
+
/** Canonical lowercase six-digit hexadecimal sRGB color. */ readonly color: string;
|
|
7
|
+
}
|
|
8
|
+
/** Readonly continuous two-stop color mapping. @see {@link SequentialColorScaleProps} */
|
|
9
|
+
export interface ResolvedSequentialColorScale {
|
|
10
|
+
/** Authored finite endpoints, preserving ascending or descending order. */ readonly domain: readonly [
|
|
11
|
+
number,
|
|
12
|
+
number
|
|
13
|
+
];
|
|
14
|
+
/** Canonical endpoint colors, in authored order. */ readonly colors: readonly [
|
|
15
|
+
string,
|
|
16
|
+
string
|
|
17
|
+
];
|
|
18
|
+
/** Frozen endpoint/value pairs for scale-derived annotations. */ readonly stops: readonly ColorScaleStop[];
|
|
19
|
+
/** Maps finite data to a clamped color.
|
|
20
|
+
* @param value - Numeric input.
|
|
21
|
+
* @returns Canonical #rrggbb color. */ map(value: number): string;
|
|
22
|
+
}
|
|
23
|
+
/** Readonly continuous mapping with an explicit center. @see {@link DivergingColorScaleProps} */
|
|
24
|
+
export interface ResolvedDivergingColorScale {
|
|
25
|
+
/** Strictly monotonic finite endpoints and center, in authored order. */ readonly domain: readonly [
|
|
26
|
+
number,
|
|
27
|
+
number,
|
|
28
|
+
number
|
|
29
|
+
];
|
|
30
|
+
/** Canonical endpoint and center colors. */ readonly colors: readonly [
|
|
31
|
+
string,
|
|
32
|
+
string,
|
|
33
|
+
string
|
|
34
|
+
];
|
|
35
|
+
/** Frozen endpoint/center pairs for scale-derived annotations. */ readonly stops: readonly ColorScaleStop[];
|
|
36
|
+
/** Maps finite data through the authored center.
|
|
37
|
+
* @param value - Numeric input.
|
|
38
|
+
* @returns Canonical #rrggbb color. */ map(value: number): string;
|
|
39
|
+
}
|
|
40
|
+
/** Inputs for a dedicated sequential color provider. @see {@link ResolvedSequentialColorScale} */
|
|
41
|
+
export interface SequentialColorScaleProps {
|
|
42
|
+
/** Identity in the color-scale namespace. See {@link ScaleId}. */ readonly id: ScaleId;
|
|
43
|
+
/** Finite endpoints; equal endpoints map all finite inputs to the color midpoint. */ readonly domain: SignalValue<readonly [number, number]>;
|
|
44
|
+
/** Required #RRGGBB endpoint colors. No default palette is chosen. */ readonly colors: SignalValue<readonly [string, string]>;
|
|
45
|
+
/** Descendants consuming the mapping. See {@link PibblNode}. */ readonly children?: PibblNode;
|
|
46
|
+
}
|
|
47
|
+
/** Inputs for a dedicated diverging color provider. @see {@link ResolvedDivergingColorScale} */
|
|
48
|
+
export interface DivergingColorScaleProps {
|
|
49
|
+
/** Identity in the color-scale namespace. See {@link ScaleId}. */ readonly id: ScaleId;
|
|
50
|
+
/** Strictly increasing or decreasing finite endpoints and center. */ readonly domain: SignalValue<readonly [number, number, number]>;
|
|
51
|
+
/** Required #RRGGBB endpoint and center colors. */ readonly colors: SignalValue<readonly [string, string, string]>;
|
|
52
|
+
/** Descendants consuming the mapping. See {@link PibblNode}. */ readonly children?: PibblNode;
|
|
53
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { LineSeriesProps } from "./types.js";
|
|
2
|
+
/** A mapped Cartesian coordinate used by private series curve rendering. */
|
|
3
|
+
export type SeriesCurvePoint = readonly [number, number];
|
|
4
|
+
/**
|
|
5
|
+
* A private generated segment. Cubic controls reserve the representation needed by a later
|
|
6
|
+
* smooth-curve implementation; current step definitions generate straight segments only.
|
|
7
|
+
*/
|
|
8
|
+
export interface SeriesCurveSegment {
|
|
9
|
+
/** Endpoint of this segment. */
|
|
10
|
+
readonly end: SeriesCurvePoint;
|
|
11
|
+
/** First cubic Bézier control point when the segment is cubic. */
|
|
12
|
+
readonly control1?: SeriesCurvePoint;
|
|
13
|
+
/** Second cubic Bézier control point when the segment is cubic. */
|
|
14
|
+
readonly control2?: SeriesCurvePoint;
|
|
15
|
+
}
|
|
16
|
+
/** A private immutable path beginning at one point and continuing through generated segments. */
|
|
17
|
+
export interface SeriesCurveGeometry {
|
|
18
|
+
/** Initial coordinate for the geometry. */
|
|
19
|
+
readonly start: SeriesCurvePoint;
|
|
20
|
+
/** Ordered segments after {@link SeriesCurveGeometry.start}. */
|
|
21
|
+
readonly segments: readonly SeriesCurveSegment[];
|
|
22
|
+
}
|
|
23
|
+
declare const seriesCurveBrand: unique symbol;
|
|
24
|
+
/**
|
|
25
|
+
* An opaque immutable definition controlling how a series connects adjacent observations.
|
|
26
|
+
*
|
|
27
|
+
* Obtain a definition from one of the named curve factories. Definitions intentionally expose
|
|
28
|
+
* no algorithm selector or custom callback surface.
|
|
29
|
+
*
|
|
30
|
+
* @see {@link LineSeriesProps}
|
|
31
|
+
*/
|
|
32
|
+
export interface SeriesCurve {
|
|
33
|
+
/** Nominal marker that prevents callers from forging a recognized definition. */
|
|
34
|
+
readonly [seriesCurveBrand]: true;
|
|
35
|
+
}
|
|
36
|
+
type SeriesCurveBuilder = (points: readonly SeriesCurvePoint[]) => readonly SeriesCurveSegment[];
|
|
37
|
+
/** @internal Creates one module-recognized immutable curve definition. */
|
|
38
|
+
export declare function createSeriesCurve(builder: SeriesCurveBuilder): SeriesCurve;
|
|
39
|
+
/** @internal Rejects values that were not created by a named curve factory. */
|
|
40
|
+
export declare function resolveSeriesCurve(value: unknown): SeriesCurve | undefined;
|
|
41
|
+
/** @internal Builds the curve geometry for one already-valid contiguous run. */
|
|
42
|
+
export declare function curveGeometry(curve: SeriesCurve | undefined, points: readonly SeriesCurvePoint[]): SeriesCurveGeometry;
|
|
43
|
+
/** @internal Appends one generated geometry in its authored forward direction. */
|
|
44
|
+
export declare function appendCurveForward(path: Path2D, geometry: SeriesCurveGeometry): void;
|
|
45
|
+
/** @internal Appends one generated geometry in reverse without rebuilding its curve strategy. */
|
|
46
|
+
export declare function appendCurveReverse(path: Path2D, geometry: SeriesCurveGeometry): void;
|
|
47
|
+
/** @internal Rejects interval-band cubics whose paired boundaries cross between observations. */
|
|
48
|
+
export declare function validatePairedCurveGeometry(upper: SeriesCurveGeometry, lower: SeriesCurveGeometry): void;
|
|
49
|
+
export {};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
const builders = /* @__PURE__ */ new WeakMap();
|
|
2
|
+
function createSeriesCurve(builder) {
|
|
3
|
+
const definition = Object.freeze({});
|
|
4
|
+
builders.set(definition, builder);
|
|
5
|
+
return definition;
|
|
6
|
+
}
|
|
7
|
+
function resolveSeriesCurve(value) {
|
|
8
|
+
if (value === void 0 || value === "linear") return void 0;
|
|
9
|
+
if (typeof value !== "object" || value === null || !builders.has(value))
|
|
10
|
+
throw new TypeError(
|
|
11
|
+
'Series curve must be "linear" or a definition from a named factory.'
|
|
12
|
+
);
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function curveGeometry(curve, points) {
|
|
16
|
+
const start = points[0];
|
|
17
|
+
return Object.freeze({
|
|
18
|
+
start,
|
|
19
|
+
segments: Object.freeze(
|
|
20
|
+
curve ? [...builders.get(curve)(points)] : points.slice(1).map((end) => Object.freeze({ end }))
|
|
21
|
+
)
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function appendCurveForward(path, geometry) {
|
|
25
|
+
for (const segment of geometry.segments) {
|
|
26
|
+
if (segment.control1 && segment.control2)
|
|
27
|
+
path.bezierCurveTo(
|
|
28
|
+
segment.control1[0],
|
|
29
|
+
segment.control1[1],
|
|
30
|
+
segment.control2[0],
|
|
31
|
+
segment.control2[1],
|
|
32
|
+
segment.end[0],
|
|
33
|
+
segment.end[1]
|
|
34
|
+
);
|
|
35
|
+
else path.lineTo(segment.end[0], segment.end[1]);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function appendCurveReverse(path, geometry) {
|
|
39
|
+
const ends = geometry.segments.map((segment) => segment.end);
|
|
40
|
+
path.lineTo(
|
|
41
|
+
(ends.at(-1) ?? geometry.start)[0],
|
|
42
|
+
(ends.at(-1) ?? geometry.start)[1]
|
|
43
|
+
);
|
|
44
|
+
for (let i = geometry.segments.length - 1; i >= 0; i--) {
|
|
45
|
+
const segment = geometry.segments[i];
|
|
46
|
+
const start = i === 0 ? geometry.start : geometry.segments[i - 1].end;
|
|
47
|
+
if (segment.control1 && segment.control2)
|
|
48
|
+
path.bezierCurveTo(
|
|
49
|
+
segment.control2[0],
|
|
50
|
+
segment.control2[1],
|
|
51
|
+
segment.control1[0],
|
|
52
|
+
segment.control1[1],
|
|
53
|
+
start[0],
|
|
54
|
+
start[1]
|
|
55
|
+
);
|
|
56
|
+
else path.lineTo(start[0], start[1]);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function cubicValue(values, t) {
|
|
60
|
+
const [p0, p1, p2, p3] = values;
|
|
61
|
+
const inverse = 1 - t;
|
|
62
|
+
return inverse ** 3 * p0 + 3 * inverse ** 2 * t * p1 + 3 * inverse * t ** 2 * p2 + t ** 3 * p3;
|
|
63
|
+
}
|
|
64
|
+
function derivativeRoots(values) {
|
|
65
|
+
const [p0, p1, p2, p3] = values;
|
|
66
|
+
const a = -p0 + 3 * p1 - 3 * p2 + p3;
|
|
67
|
+
const b = 3 * p0 - 6 * p1 + 3 * p2;
|
|
68
|
+
const c = -3 * p0 + 3 * p1;
|
|
69
|
+
if (a === 0) {
|
|
70
|
+
if (b === 0) return [];
|
|
71
|
+
return [-c / (2 * b)];
|
|
72
|
+
}
|
|
73
|
+
const discriminant = 4 * b * b - 12 * a * c;
|
|
74
|
+
if (discriminant < 0) return [];
|
|
75
|
+
const root = Math.sqrt(discriminant);
|
|
76
|
+
const q = -b - (b >= 0 ? root / 2 : -root / 2);
|
|
77
|
+
return q === 0 ? [-b / (3 * a)] : [q / (3 * a), c / q];
|
|
78
|
+
}
|
|
79
|
+
function cubicY(start, segment) {
|
|
80
|
+
const end = segment.end;
|
|
81
|
+
const control1 = segment.control1 ?? [
|
|
82
|
+
start[0] + (end[0] - start[0]) / 3,
|
|
83
|
+
start[1] + (end[1] - start[1]) / 3
|
|
84
|
+
];
|
|
85
|
+
const control2 = segment.control2 ?? [
|
|
86
|
+
start[0] + (end[0] - start[0]) * 2 / 3,
|
|
87
|
+
start[1] + (end[1] - start[1]) * 2 / 3
|
|
88
|
+
];
|
|
89
|
+
return [start[1], control1[1], control2[1], end[1]];
|
|
90
|
+
}
|
|
91
|
+
function validatePairedCurveGeometry(upper, lower) {
|
|
92
|
+
if (upper.segments.length !== lower.segments.length)
|
|
93
|
+
throw new RangeError(
|
|
94
|
+
"IntervalBandSeries curve boundaries have incompatible geometry."
|
|
95
|
+
);
|
|
96
|
+
let upperStart = upper.start;
|
|
97
|
+
let lowerStart = lower.start;
|
|
98
|
+
let orientation = 0;
|
|
99
|
+
for (let i = 0; i < upper.segments.length && orientation === 0; i++) {
|
|
100
|
+
for (const value of [
|
|
101
|
+
upperStart[1] - lowerStart[1],
|
|
102
|
+
upper.segments[i].end[1] - lower.segments[i].end[1]
|
|
103
|
+
]) {
|
|
104
|
+
if (value !== 0) {
|
|
105
|
+
orientation = Math.sign(value);
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
upperStart = upper.segments[i].end;
|
|
110
|
+
lowerStart = lower.segments[i].end;
|
|
111
|
+
}
|
|
112
|
+
upperStart = upper.start;
|
|
113
|
+
lowerStart = lower.start;
|
|
114
|
+
for (let i = 0; i < upper.segments.length; i++) {
|
|
115
|
+
const upperSegment = upper.segments[i], lowerSegment = lower.segments[i];
|
|
116
|
+
const upperY = cubicY(upperStart, upperSegment);
|
|
117
|
+
const lowerY = cubicY(lowerStart, lowerSegment);
|
|
118
|
+
const difference = upperY.map((value, index) => value - lowerY[index]);
|
|
119
|
+
if (!difference.every(Number.isFinite))
|
|
120
|
+
throw new RangeError(
|
|
121
|
+
"IntervalBandSeries curve boundaries must be finite."
|
|
122
|
+
);
|
|
123
|
+
const magnitude = Math.max(...difference.map(Math.abs));
|
|
124
|
+
const normalized = difference.map(
|
|
125
|
+
(value) => magnitude === 0 ? 0 : value / magnitude
|
|
126
|
+
);
|
|
127
|
+
const candidates = [0, 1, ...derivativeRoots(normalized)].filter(
|
|
128
|
+
(value) => value >= 0 && value <= 1
|
|
129
|
+
);
|
|
130
|
+
for (const t of candidates) {
|
|
131
|
+
const value = cubicValue(normalized, t);
|
|
132
|
+
if (!Number.isFinite(value) || // Relative tolerance accounts only for floating-point evaluation at tangencies.
|
|
133
|
+
orientation !== 0 && value * orientation < -64 * Number.EPSILON)
|
|
134
|
+
throw new RangeError("IntervalBandSeries curve boundaries cross.");
|
|
135
|
+
}
|
|
136
|
+
upperStart = upperSegment.end;
|
|
137
|
+
lowerStart = lowerSegment.end;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
export {
|
|
141
|
+
appendCurveForward,
|
|
142
|
+
appendCurveReverse,
|
|
143
|
+
createSeriesCurve,
|
|
144
|
+
curveGeometry,
|
|
145
|
+
resolveSeriesCurve,
|
|
146
|
+
validatePairedCurveGeometry
|
|
147
|
+
};
|
|
148
|
+
//# sourceMappingURL=curve-definition.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/curve-definition.ts"],
|
|
4
|
+
"sourcesContent": ["import type { LineSeriesProps } from \"./types.js\";\n/** A mapped Cartesian coordinate used by private series curve rendering. */\nexport type SeriesCurvePoint = readonly [number, number];\n\n/**\n * A private generated segment. Cubic controls reserve the representation needed by a later\n * smooth-curve implementation; current step definitions generate straight segments only.\n */\nexport interface SeriesCurveSegment {\n /** Endpoint of this segment. */\n readonly end: SeriesCurvePoint;\n /** First cubic B\u00E9zier control point when the segment is cubic. */\n readonly control1?: SeriesCurvePoint;\n /** Second cubic B\u00E9zier control point when the segment is cubic. */\n readonly control2?: SeriesCurvePoint;\n}\n\n/** A private immutable path beginning at one point and continuing through generated segments. */\nexport interface SeriesCurveGeometry {\n /** Initial coordinate for the geometry. */\n readonly start: SeriesCurvePoint;\n /** Ordered segments after {@link SeriesCurveGeometry.start}. */\n readonly segments: readonly SeriesCurveSegment[];\n}\n\ndeclare const seriesCurveBrand: unique symbol;\n\n/**\n * An opaque immutable definition controlling how a series connects adjacent observations.\n *\n * Obtain a definition from one of the named curve factories. Definitions intentionally expose\n * no algorithm selector or custom callback surface.\n *\n * @see {@link LineSeriesProps}\n */\nexport interface SeriesCurve {\n /** Nominal marker that prevents callers from forging a recognized definition. */\n readonly [seriesCurveBrand]: true;\n}\n\ntype SeriesCurveBuilder = (\n points: readonly SeriesCurvePoint[],\n) => readonly SeriesCurveSegment[];\n\nconst builders = new WeakMap<SeriesCurve, SeriesCurveBuilder>();\n\n/** @internal Creates one module-recognized immutable curve definition. */\nexport function createSeriesCurve(builder: SeriesCurveBuilder): SeriesCurve {\n const definition = Object.freeze({}) as unknown as SeriesCurve;\n builders.set(definition, builder);\n return definition;\n}\n\n/** @internal Rejects values that were not created by a named curve factory. */\nexport function resolveSeriesCurve(value: unknown): SeriesCurve | undefined {\n if (value === undefined || value === \"linear\") return undefined;\n if (\n typeof value !== \"object\" ||\n value === null ||\n !builders.has(value as SeriesCurve)\n )\n throw new TypeError(\n 'Series curve must be \"linear\" or a definition from a named factory.',\n );\n return value as SeriesCurve;\n}\n\n/** @internal Builds the curve geometry for one already-valid contiguous run. */\nexport function curveGeometry(\n curve: SeriesCurve | undefined,\n points: readonly SeriesCurvePoint[],\n): SeriesCurveGeometry {\n const start = points[0];\n return Object.freeze({\n start,\n segments: Object.freeze(\n curve\n ? [...builders.get(curve)!(points)]\n : points.slice(1).map((end) => Object.freeze({ end })),\n ),\n });\n}\n\n/** @internal Appends one generated geometry in its authored forward direction. */\nexport function appendCurveForward(\n path: Path2D,\n geometry: SeriesCurveGeometry,\n): void {\n for (const segment of geometry.segments) {\n if (segment.control1 && segment.control2)\n path.bezierCurveTo(\n segment.control1[0],\n segment.control1[1],\n segment.control2[0],\n segment.control2[1],\n segment.end[0],\n segment.end[1],\n );\n else path.lineTo(segment.end[0], segment.end[1]);\n }\n}\n\n/** @internal Appends one generated geometry in reverse without rebuilding its curve strategy. */\nexport function appendCurveReverse(\n path: Path2D,\n geometry: SeriesCurveGeometry,\n): void {\n const ends = geometry.segments.map((segment) => segment.end);\n path.lineTo(\n (ends.at(-1) ?? geometry.start)[0],\n (ends.at(-1) ?? geometry.start)[1],\n );\n for (let i = geometry.segments.length - 1; i >= 0; i--) {\n const segment = geometry.segments[i];\n const start = i === 0 ? geometry.start : geometry.segments[i - 1].end;\n if (segment.control1 && segment.control2)\n path.bezierCurveTo(\n segment.control2[0],\n segment.control2[1],\n segment.control1[0],\n segment.control1[1],\n start[0],\n start[1],\n );\n else path.lineTo(start[0], start[1]);\n }\n}\n\nfunction cubicValue(\n values: readonly [number, number, number, number],\n t: number,\n): number {\n const [p0, p1, p2, p3] = values;\n const inverse = 1 - t;\n return (\n inverse ** 3 * p0 +\n 3 * inverse ** 2 * t * p1 +\n 3 * inverse * t ** 2 * p2 +\n t ** 3 * p3\n );\n}\n\nfunction derivativeRoots(\n values: readonly [number, number, number, number],\n): readonly number[] {\n const [p0, p1, p2, p3] = values;\n const a = -p0 + 3 * p1 - 3 * p2 + p3;\n const b = 3 * p0 - 6 * p1 + 3 * p2;\n const c = -3 * p0 + 3 * p1;\n if (a === 0) {\n if (b === 0) return [];\n return [-c / (2 * b)];\n }\n const discriminant = 4 * b * b - 12 * a * c;\n if (discriminant < 0) return [];\n const root = Math.sqrt(discriminant);\n const q = -b - (b >= 0 ? root / 2 : -root / 2);\n return q === 0 ? [-b / (3 * a)] : [q / (3 * a), c / q];\n}\n\nfunction cubicY(\n start: SeriesCurvePoint,\n segment: SeriesCurveSegment,\n): readonly [number, number, number, number] {\n const end = segment.end;\n const control1 = segment.control1 ?? [\n start[0] + (end[0] - start[0]) / 3,\n start[1] + (end[1] - start[1]) / 3,\n ];\n const control2 = segment.control2 ?? [\n start[0] + ((end[0] - start[0]) * 2) / 3,\n start[1] + ((end[1] - start[1]) * 2) / 3,\n ];\n return [start[1], control1[1], control2[1], end[1]];\n}\n\n/** @internal Rejects interval-band cubics whose paired boundaries cross between observations. */\nexport function validatePairedCurveGeometry(\n upper: SeriesCurveGeometry,\n lower: SeriesCurveGeometry,\n): void {\n if (upper.segments.length !== lower.segments.length)\n throw new RangeError(\n \"IntervalBandSeries curve boundaries have incompatible geometry.\",\n );\n let upperStart = upper.start;\n let lowerStart = lower.start;\n let orientation = 0;\n for (let i = 0; i < upper.segments.length && orientation === 0; i++) {\n for (const value of [\n upperStart[1] - lowerStart[1],\n upper.segments[i].end[1] - lower.segments[i].end[1],\n ]) {\n if (value !== 0) {\n orientation = Math.sign(value);\n break;\n }\n }\n upperStart = upper.segments[i].end;\n lowerStart = lower.segments[i].end;\n }\n upperStart = upper.start;\n lowerStart = lower.start;\n for (let i = 0; i < upper.segments.length; i++) {\n const upperSegment = upper.segments[i],\n lowerSegment = lower.segments[i];\n const upperY = cubicY(upperStart, upperSegment);\n const lowerY = cubicY(lowerStart, lowerSegment);\n const difference = upperY.map((value, index) => value - lowerY[index]) as [\n number,\n number,\n number,\n number,\n ];\n if (!difference.every(Number.isFinite))\n throw new RangeError(\n \"IntervalBandSeries curve boundaries must be finite.\",\n );\n const magnitude = Math.max(...difference.map(Math.abs));\n const normalized = difference.map((value) =>\n magnitude === 0 ? 0 : value / magnitude,\n ) as [number, number, number, number];\n const candidates = [0, 1, ...derivativeRoots(normalized)].filter(\n (value) => value >= 0 && value <= 1,\n );\n for (const t of candidates) {\n const value = cubicValue(normalized, t);\n if (\n !Number.isFinite(value) ||\n // Relative tolerance accounts only for floating-point evaluation at tangencies.\n (orientation !== 0 && value * orientation < -64 * Number.EPSILON)\n )\n throw new RangeError(\"IntervalBandSeries curve boundaries cross.\");\n }\n upperStart = upperSegment.end;\n lowerStart = lowerSegment.end;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type Signal } from "@pibbl/core";
|
|
2
|
+
import type { DivergingColorScaleProps, ResolvedDivergingColorScale } from "./color-types.js";
|
|
3
|
+
import type { ScaleId } from "./types.js";
|
|
4
|
+
/** Provides an allocation-independent color mapping with an authored center.
|
|
5
|
+
* @param props - Explicit domain, colors, identity, and children. See {@link DivergingColorScaleProps}.
|
|
6
|
+
* @returns Descendant content. */
|
|
7
|
+
export declare function DivergingColorScale(props: DivergingColorScaleProps): import("@pibbl/core").PibblNode;
|
|
8
|
+
/** Reads the dedicated ancestor diverging mapping.
|
|
9
|
+
* @param id - Color-scale identity. See {@link ScaleId}.
|
|
10
|
+
* @returns Shared readonly mapping signal. See {@link ResolvedDivergingColorScale}. */
|
|
11
|
+
export declare function useDivergingColorScale(id: ScaleId): Signal<ResolvedDivergingColorScale>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { resolveSignalValue } from "@pibbl/core";
|
|
2
|
+
import { provideColor, useColor } from "./color-context.js";
|
|
3
|
+
import {
|
|
4
|
+
colorMix,
|
|
5
|
+
colorPosition,
|
|
6
|
+
finiteColorValue,
|
|
7
|
+
hexColor
|
|
8
|
+
} from "./color-math.js";
|
|
9
|
+
function resolve(props) {
|
|
10
|
+
const input = resolveSignalValue(props.domain), paint = resolveSignalValue(props.colors);
|
|
11
|
+
if (!Array.isArray(input) || input.length !== 3 || !Array.isArray(paint) || paint.length !== 3)
|
|
12
|
+
throw new RangeError(
|
|
13
|
+
"Diverging color scales require three domain values and three colors."
|
|
14
|
+
);
|
|
15
|
+
const domain = Object.freeze(
|
|
16
|
+
Array.from(input, finiteColorValue)
|
|
17
|
+
), colors = Object.freeze(Array.from(paint, hexColor));
|
|
18
|
+
const [a, m, b] = domain;
|
|
19
|
+
if (!(a < m && m < b || a > m && m > b))
|
|
20
|
+
throw new RangeError(
|
|
21
|
+
"Diverging color domain must be strictly monotonic around its center."
|
|
22
|
+
);
|
|
23
|
+
const stops = Object.freeze(
|
|
24
|
+
domain.map((value, i) => Object.freeze({ value, color: colors[i] }))
|
|
25
|
+
);
|
|
26
|
+
return Object.freeze({
|
|
27
|
+
domain,
|
|
28
|
+
colors,
|
|
29
|
+
stops,
|
|
30
|
+
map(value) {
|
|
31
|
+
finiteColorValue(value);
|
|
32
|
+
if (value === m) return colors[1];
|
|
33
|
+
return (a < m ? value < m : value > m) ? colorMix(colors[0], colors[1], colorPosition(value, a, m)) : colorMix(colors[1], colors[2], colorPosition(value, m, b));
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function DivergingColorScale(props) {
|
|
38
|
+
provideColor(props.id, "diverging", () => resolve(props), [
|
|
39
|
+
props.domain,
|
|
40
|
+
props.colors
|
|
41
|
+
]);
|
|
42
|
+
return props.children;
|
|
43
|
+
}
|
|
44
|
+
function useDivergingColorScale(id) {
|
|
45
|
+
return useColor(id, "diverging");
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
DivergingColorScale,
|
|
49
|
+
useDivergingColorScale
|
|
50
|
+
};
|
|
51
|
+
//# sourceMappingURL=diverging-color-scale.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/features/viz/lib/diverging-color-scale.ts"],
|
|
4
|
+
"sourcesContent": ["import { resolveSignalValue, type Signal } from \"@pibbl/core\";\nimport type {\n DivergingColorScaleProps,\n ResolvedDivergingColorScale,\n} from \"./color-types.js\";\nimport type { ScaleId } from \"./types.js\";\nimport { provideColor, useColor } from \"./color-context.js\";\nimport {\n colorMix,\n colorPosition,\n finiteColorValue,\n hexColor,\n} from \"./color-math.js\";\nfunction resolve(props: DivergingColorScaleProps): ResolvedDivergingColorScale {\n const input = resolveSignalValue(props.domain),\n paint = resolveSignalValue(props.colors);\n if (\n !Array.isArray(input) ||\n input.length !== 3 ||\n !Array.isArray(paint) ||\n paint.length !== 3\n )\n throw new RangeError(\n \"Diverging color scales require three domain values and three colors.\",\n );\n const domain = Object.freeze(\n Array.from(input, finiteColorValue),\n ) as readonly [number, number, number],\n colors = Object.freeze(Array.from(paint, hexColor)) as readonly [\n string,\n string,\n string,\n ];\n const [a, m, b] = domain;\n if (!((a < m && m < b) || (a > m && m > b)))\n throw new RangeError(\n \"Diverging color domain must be strictly monotonic around its center.\",\n );\n const stops = Object.freeze(\n domain.map((value, i) => Object.freeze({ value, color: colors[i] })),\n );\n return Object.freeze({\n domain,\n colors,\n stops,\n map(value: number) {\n finiteColorValue(value);\n if (value === m) return colors[1];\n return (a < m ? value < m : value > m)\n ? colorMix(colors[0], colors[1], colorPosition(value, a, m))\n : colorMix(colors[1], colors[2], colorPosition(value, m, b));\n },\n });\n}\n/** Provides an allocation-independent color mapping with an authored center.\n * @param props - Explicit domain, colors, identity, and children. See {@link DivergingColorScaleProps}.\n * @returns Descendant content. */\nexport function DivergingColorScale(props: DivergingColorScaleProps) {\n provideColor(props.id, \"diverging\", () => resolve(props), [\n props.domain,\n props.colors,\n ]);\n return props.children;\n}\n/** Reads the dedicated ancestor diverging mapping.\n * @param id - Color-scale identity. See {@link ScaleId}.\n * @returns Shared readonly mapping signal. See {@link ResolvedDivergingColorScale}. */\nexport function useDivergingColorScale(\n id: ScaleId,\n): Signal<ResolvedDivergingColorScale> {\n return useColor(id, \"diverging\");\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,0BAAuC;AAMhD,SAAS,cAAc,gBAAgB;AACvC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,QAAQ,OAA8D;AAC7E,QAAM,QAAQ,mBAAmB,MAAM,MAAM,GAC3C,QAAQ,mBAAmB,MAAM,MAAM;AACzC,MACE,CAAC,MAAM,QAAQ,KAAK,KACpB,MAAM,WAAW,KACjB,CAAC,MAAM,QAAQ,KAAK,KACpB,MAAM,WAAW;AAEjB,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,QAAM,SAAS,OAAO;AAAA,IAClB,MAAM,KAAK,OAAO,gBAAgB;AAAA,EACpC,GACA,SAAS,OAAO,OAAO,MAAM,KAAK,OAAO,QAAQ,CAAC;AAKpD,QAAM,CAAC,GAAG,GAAG,CAAC,IAAI;AAClB,MAAI,EAAG,IAAI,KAAK,IAAI,KAAO,IAAI,KAAK,IAAI;AACtC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AACF,QAAM,QAAQ,OAAO;AAAA,IACnB,OAAO,IAAI,CAAC,OAAO,MAAM,OAAO,OAAO,EAAE,OAAO,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC;AAAA,EACrE;AACA,SAAO,OAAO,OAAO;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA,IAAI,OAAe;AACjB,uBAAiB,KAAK;AACtB,UAAI,UAAU,EAAG,QAAO,OAAO,CAAC;AAChC,cAAQ,IAAI,IAAI,QAAQ,IAAI,QAAQ,KAChC,SAAS,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,cAAc,OAAO,GAAG,CAAC,CAAC,IACzD,SAAS,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,cAAc,OAAO,GAAG,CAAC,CAAC;AAAA,IAC/D;AAAA,EACF,CAAC;AACH;AAIO,SAAS,oBAAoB,OAAiC;AACnE,eAAa,MAAM,IAAI,aAAa,MAAM,QAAQ,KAAK,GAAG;AAAA,IACxD,MAAM;AAAA,IACN,MAAM;AAAA,EACR,CAAC;AACD,SAAO,MAAM;AACf;AAIO,SAAS,uBACd,IACqC;AACrC,SAAO,SAAS,IAAI,WAAW;AACjC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|