minerva-design 1.4.0 → 1.5.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 +9 -0
- package/README.md +21 -21
- package/custom-elements.json +4047 -1703
- package/dist/angular/fesm2022/minerva-angular.mjs +1436 -5
- package/dist/angular/fesm2022/minerva-angular.mjs.map +1 -1
- package/dist/angular/types/minerva-angular.d.ts +573 -4
- package/dist/charts/canvas.d.cts +2 -2
- package/dist/charts/canvas.d.ts +2 -2
- package/dist/charts/core.cjs +1 -1
- package/dist/charts/core.d.cts +6 -4
- package/dist/charts/core.d.ts +6 -4
- package/dist/charts/core.js +24 -16
- package/dist/charts/engine/axis.cjs +1 -1
- package/dist/charts/engine/axis.cjs.map +1 -1
- package/dist/charts/engine/axis.js +42 -19
- package/dist/charts/engine/axis.js.map +1 -1
- package/dist/charts/engine/canvas.cjs +1 -1
- package/dist/charts/engine/canvas.cjs.map +1 -1
- package/dist/charts/engine/canvas.js +154 -127
- package/dist/charts/engine/canvas.js.map +1 -1
- package/dist/charts/engine/chart.cjs +1 -1
- package/dist/charts/engine/chart.cjs.map +1 -1
- package/dist/charts/engine/chart.js +365 -251
- package/dist/charts/engine/chart.js.map +1 -1
- package/dist/charts/engine/color.cjs +1 -1
- package/dist/charts/engine/color.cjs.map +1 -1
- package/dist/charts/engine/color.d.cts +18 -0
- package/dist/charts/engine/color.d.ts +18 -0
- package/dist/charts/engine/color.js +48 -2
- package/dist/charts/engine/color.js.map +1 -1
- package/dist/charts/engine/controller.cjs +2 -2
- package/dist/charts/engine/controller.cjs.map +1 -1
- package/dist/charts/engine/controller.d.cts +32 -1
- package/dist/charts/engine/controller.d.ts +32 -1
- package/dist/charts/engine/controller.js +310 -263
- package/dist/charts/engine/controller.js.map +1 -1
- package/dist/charts/engine/data.cjs +1 -1
- package/dist/charts/engine/data.cjs.map +1 -1
- package/dist/charts/engine/data.d.cts +3 -1
- package/dist/charts/engine/data.d.ts +3 -1
- package/dist/charts/engine/data.js +6 -4
- package/dist/charts/engine/data.js.map +1 -1
- package/dist/charts/engine/defaults.cjs +2 -0
- package/dist/charts/engine/defaults.cjs.map +1 -0
- package/dist/charts/engine/defaults.d.cts +20 -0
- package/dist/charts/engine/defaults.d.ts +20 -0
- package/dist/charts/engine/defaults.js +35 -0
- package/dist/charts/engine/defaults.js.map +1 -0
- package/dist/charts/engine/format.cjs +1 -1
- package/dist/charts/engine/format.cjs.map +1 -1
- package/dist/charts/engine/format.d.cts +6 -0
- package/dist/charts/engine/format.d.ts +6 -0
- package/dist/charts/engine/format.js +15 -2
- package/dist/charts/engine/format.js.map +1 -1
- package/dist/charts/engine/graph/chart.cjs +2 -0
- package/dist/charts/engine/graph/chart.cjs.map +1 -0
- package/dist/charts/engine/graph/chart.d.cts +3 -0
- package/dist/charts/engine/graph/chart.d.ts +3 -0
- package/dist/charts/engine/graph/chart.js +1565 -0
- package/dist/charts/engine/graph/chart.js.map +1 -0
- package/dist/charts/engine/graph/circular.cjs +2 -0
- package/dist/charts/engine/graph/circular.cjs.map +1 -0
- package/dist/charts/engine/graph/circular.d.cts +16 -0
- package/dist/charts/engine/graph/circular.d.ts +16 -0
- package/dist/charts/engine/graph/circular.js +62 -0
- package/dist/charts/engine/graph/circular.js.map +1 -0
- package/dist/charts/engine/graph/dag.cjs +2 -0
- package/dist/charts/engine/graph/dag.cjs.map +1 -0
- package/dist/charts/engine/graph/dag.d.cts +34 -0
- package/dist/charts/engine/graph/dag.d.ts +34 -0
- package/dist/charts/engine/graph/dag.js +314 -0
- package/dist/charts/engine/graph/dag.js.map +1 -0
- package/dist/charts/engine/graph/dom.cjs +2 -0
- package/dist/charts/engine/graph/dom.cjs.map +1 -0
- package/dist/charts/engine/graph/dom.d.cts +23 -0
- package/dist/charts/engine/graph/dom.d.ts +23 -0
- package/dist/charts/engine/graph/dom.js +158 -0
- package/dist/charts/engine/graph/dom.js.map +1 -0
- package/dist/charts/engine/graph/force.cjs +2 -0
- package/dist/charts/engine/graph/force.cjs.map +1 -0
- package/dist/charts/engine/graph/force.d.cts +67 -0
- package/dist/charts/engine/graph/force.d.ts +67 -0
- package/dist/charts/engine/graph/force.js +325 -0
- package/dist/charts/engine/graph/force.js.map +1 -0
- package/dist/charts/engine/graph/geometry.cjs +2 -0
- package/dist/charts/engine/graph/geometry.cjs.map +1 -0
- package/dist/charts/engine/graph/geometry.d.cts +37 -0
- package/dist/charts/engine/graph/geometry.d.ts +37 -0
- package/dist/charts/engine/graph/geometry.js +144 -0
- package/dist/charts/engine/graph/geometry.js.map +1 -0
- package/dist/charts/engine/graph/index.cjs +1 -0
- package/dist/charts/engine/graph/index.d.cts +6 -0
- package/dist/charts/engine/graph/index.d.ts +6 -0
- package/dist/charts/engine/graph/index.js +6 -0
- package/dist/charts/engine/graph/labels.cjs +2 -0
- package/dist/charts/engine/graph/labels.cjs.map +1 -0
- package/dist/charts/engine/graph/labels.d.cts +12 -0
- package/dist/charts/engine/graph/labels.d.ts +12 -0
- package/dist/charts/engine/graph/labels.js +128 -0
- package/dist/charts/engine/graph/labels.js.map +1 -0
- package/dist/charts/engine/graph/model.cjs +2 -0
- package/dist/charts/engine/graph/model.cjs.map +1 -0
- package/dist/charts/engine/graph/model.d.cts +43 -0
- package/dist/charts/engine/graph/model.d.ts +43 -0
- package/dist/charts/engine/graph/model.js +88 -0
- package/dist/charts/engine/graph/model.js.map +1 -0
- package/dist/charts/engine/graph/sizing.cjs +2 -0
- package/dist/charts/engine/graph/sizing.cjs.map +1 -0
- package/dist/charts/engine/graph/sizing.d.cts +33 -0
- package/dist/charts/engine/graph/sizing.d.ts +33 -0
- package/dist/charts/engine/graph/sizing.js +60 -0
- package/dist/charts/engine/graph/sizing.js.map +1 -0
- package/dist/charts/engine/graph/tree.cjs +2 -0
- package/dist/charts/engine/graph/tree.cjs.map +1 -0
- package/dist/charts/engine/graph/tree.d.cts +30 -0
- package/dist/charts/engine/graph/tree.d.ts +30 -0
- package/dist/charts/engine/graph/tree.js +218 -0
- package/dist/charts/engine/graph/tree.js.map +1 -0
- package/dist/charts/engine/graph/types.d.cts +626 -0
- package/dist/charts/engine/graph/types.d.ts +626 -0
- package/dist/charts/engine/graph/worker.cjs +46 -0
- package/dist/charts/engine/graph/worker.cjs.map +1 -0
- package/dist/charts/engine/graph/worker.d.cts +36 -0
- package/dist/charts/engine/graph/worker.d.ts +36 -0
- package/dist/charts/engine/graph/worker.js +129 -0
- package/dist/charts/engine/graph/worker.js.map +1 -0
- package/dist/charts/engine/items.cjs +1 -1
- package/dist/charts/engine/items.cjs.map +1 -1
- package/dist/charts/engine/items.d.cts +15 -2
- package/dist/charts/engine/items.d.ts +15 -2
- package/dist/charts/engine/items.js +131 -112
- package/dist/charts/engine/items.js.map +1 -1
- package/dist/charts/engine/labels.cjs +1 -1
- package/dist/charts/engine/labels.cjs.map +1 -1
- package/dist/charts/engine/labels.js +28 -4
- package/dist/charts/engine/labels.js.map +1 -1
- package/dist/charts/engine/layout.cjs +1 -1
- package/dist/charts/engine/layout.cjs.map +1 -1
- package/dist/charts/engine/layout.d.cts +9 -0
- package/dist/charts/engine/layout.d.ts +9 -0
- package/dist/charts/engine/layout.js +11 -2
- package/dist/charts/engine/layout.js.map +1 -1
- package/dist/charts/engine/model.cjs +1 -1
- package/dist/charts/engine/model.cjs.map +1 -1
- package/dist/charts/engine/model.d.cts +40 -3
- package/dist/charts/engine/model.d.ts +40 -3
- package/dist/charts/engine/model.js +246 -165
- package/dist/charts/engine/model.js.map +1 -1
- package/dist/charts/engine/orderbook/format.cjs +1 -1
- package/dist/charts/engine/orderbook/format.cjs.map +1 -1
- package/dist/charts/engine/orderbook/format.d.cts +3 -2
- package/dist/charts/engine/orderbook/format.d.ts +3 -2
- package/dist/charts/engine/orderbook/format.js +5 -5
- package/dist/charts/engine/orderbook/format.js.map +1 -1
- package/dist/charts/engine/orderbook/heatmap.cjs +1 -1
- package/dist/charts/engine/orderbook/heatmap.cjs.map +1 -1
- package/dist/charts/engine/orderbook/heatmap.js +527 -408
- package/dist/charts/engine/orderbook/heatmap.js.map +1 -1
- package/dist/charts/engine/orderbook/layout.cjs +2 -0
- package/dist/charts/engine/orderbook/layout.cjs.map +1 -0
- package/dist/charts/engine/orderbook/layout.d.cts +37 -0
- package/dist/charts/engine/orderbook/layout.d.ts +37 -0
- package/dist/charts/engine/orderbook/layout.js +70 -0
- package/dist/charts/engine/orderbook/layout.js.map +1 -0
- package/dist/charts/engine/orderbook/tape.cjs +1 -1
- package/dist/charts/engine/orderbook/tape.cjs.map +1 -1
- package/dist/charts/engine/orderbook/tape.js +1 -1
- package/dist/charts/engine/orderbook/tape.js.map +1 -1
- package/dist/charts/engine/orderbook/types.d.cts +18 -2
- package/dist/charts/engine/orderbook/types.d.ts +18 -2
- package/dist/charts/engine/overlay.cjs +1 -1
- package/dist/charts/engine/overlay.cjs.map +1 -1
- package/dist/charts/engine/overlay.d.cts +10 -0
- package/dist/charts/engine/overlay.d.ts +10 -0
- package/dist/charts/engine/overlay.js +6 -0
- package/dist/charts/engine/overlay.js.map +1 -1
- package/dist/charts/engine/presets.cjs +2 -2
- package/dist/charts/engine/presets.cjs.map +1 -1
- package/dist/charts/engine/presets.d.cts +25 -3
- package/dist/charts/engine/presets.d.ts +25 -3
- package/dist/charts/engine/presets.js +115 -101
- package/dist/charts/engine/presets.js.map +1 -1
- package/dist/charts/engine/renderers/detect.cjs +1 -1
- package/dist/charts/engine/renderers/detect.cjs.map +1 -1
- package/dist/charts/engine/renderers/detect.d.cts +2 -1
- package/dist/charts/engine/renderers/detect.d.ts +2 -1
- package/dist/charts/engine/renderers/detect.js +23 -21
- package/dist/charts/engine/renderers/detect.js.map +1 -1
- package/dist/charts/engine/scene.cjs +1 -1
- package/dist/charts/engine/scene.cjs.map +1 -1
- package/dist/charts/engine/scene.d.cts +57 -4
- package/dist/charts/engine/scene.d.ts +57 -4
- package/dist/charts/engine/scene.js +335 -182
- package/dist/charts/engine/scene.js.map +1 -1
- package/dist/charts/engine/shapes/bullet.cjs +1 -1
- package/dist/charts/engine/shapes/bullet.cjs.map +1 -1
- package/dist/charts/engine/shapes/bullet.js +110 -110
- package/dist/charts/engine/shapes/bullet.js.map +1 -1
- package/dist/charts/engine/shapes/chart.cjs +1 -1
- package/dist/charts/engine/shapes/chart.cjs.map +1 -1
- package/dist/charts/engine/shapes/chart.js +4 -1
- package/dist/charts/engine/shapes/chart.js.map +1 -1
- package/dist/charts/engine/shapes/chord.cjs +2 -0
- package/dist/charts/engine/shapes/chord.cjs.map +1 -0
- package/dist/charts/engine/shapes/chord.d.cts +18 -0
- package/dist/charts/engine/shapes/chord.d.ts +18 -0
- package/dist/charts/engine/shapes/chord.js +414 -0
- package/dist/charts/engine/shapes/chord.js.map +1 -0
- package/dist/charts/engine/shapes/draw.cjs +1 -1
- package/dist/charts/engine/shapes/draw.cjs.map +1 -1
- package/dist/charts/engine/shapes/draw.d.cts +5 -1
- package/dist/charts/engine/shapes/draw.d.ts +5 -1
- package/dist/charts/engine/shapes/draw.js +47 -17
- package/dist/charts/engine/shapes/draw.js.map +1 -1
- package/dist/charts/engine/shapes/hit.cjs +1 -1
- package/dist/charts/engine/shapes/hit.cjs.map +1 -1
- package/dist/charts/engine/shapes/hit.d.cts +3 -1
- package/dist/charts/engine/shapes/hit.d.ts +3 -1
- package/dist/charts/engine/shapes/hit.js +75 -46
- package/dist/charts/engine/shapes/hit.js.map +1 -1
- package/dist/charts/engine/shapes/index.d.cts +3 -2
- package/dist/charts/engine/shapes/index.d.ts +3 -2
- package/dist/charts/engine/shapes/labels.cjs +1 -1
- package/dist/charts/engine/shapes/labels.cjs.map +1 -1
- package/dist/charts/engine/shapes/labels.js +12 -4
- package/dist/charts/engine/shapes/labels.js.map +1 -1
- package/dist/charts/engine/shapes/layout.cjs +2 -2
- package/dist/charts/engine/shapes/layout.cjs.map +1 -1
- package/dist/charts/engine/shapes/layout.d.cts +3 -1
- package/dist/charts/engine/shapes/layout.d.ts +3 -1
- package/dist/charts/engine/shapes/layout.js +106 -78
- package/dist/charts/engine/shapes/layout.js.map +1 -1
- package/dist/charts/engine/shapes/scene.cjs +1 -1
- package/dist/charts/engine/shapes/scene.cjs.map +1 -1
- package/dist/charts/engine/shapes/scene.d.cts +33 -3
- package/dist/charts/engine/shapes/scene.d.ts +33 -3
- package/dist/charts/engine/shapes/scene.js +62 -19
- package/dist/charts/engine/shapes/scene.js.map +1 -1
- package/dist/charts/engine/shapes/types.d.cts +119 -8
- package/dist/charts/engine/shapes/types.d.ts +119 -8
- package/dist/charts/engine/signature.cjs +1 -1
- package/dist/charts/engine/signature.cjs.map +1 -1
- package/dist/charts/engine/signature.js +1 -1
- package/dist/charts/engine/signature.js.map +1 -1
- package/dist/charts/engine/three-d/canvas2d.cjs +1 -1
- package/dist/charts/engine/three-d/canvas2d.cjs.map +1 -1
- package/dist/charts/engine/three-d/canvas2d.d.cts +5 -2
- package/dist/charts/engine/three-d/canvas2d.d.ts +5 -2
- package/dist/charts/engine/three-d/canvas2d.js +89 -65
- package/dist/charts/engine/three-d/canvas2d.js.map +1 -1
- package/dist/charts/engine/three-d/detect.cjs +1 -1
- package/dist/charts/engine/three-d/detect.cjs.map +1 -1
- package/dist/charts/engine/three-d/detect.d.cts +3 -2
- package/dist/charts/engine/three-d/detect.d.ts +3 -2
- package/dist/charts/engine/three-d/detect.js +22 -20
- package/dist/charts/engine/three-d/detect.js.map +1 -1
- package/dist/charts/engine/three-d/geometry.cjs +1 -1
- package/dist/charts/engine/three-d/geometry.cjs.map +1 -1
- package/dist/charts/engine/three-d/geometry.d.cts +6 -0
- package/dist/charts/engine/three-d/geometry.d.ts +6 -0
- package/dist/charts/engine/three-d/geometry.js +106 -90
- package/dist/charts/engine/three-d/geometry.js.map +1 -1
- package/dist/charts/engine/three-d/model.cjs +1 -1
- package/dist/charts/engine/three-d/model.cjs.map +1 -1
- package/dist/charts/engine/three-d/model.d.cts +2 -0
- package/dist/charts/engine/three-d/model.d.ts +2 -0
- package/dist/charts/engine/three-d/model.js +2 -0
- package/dist/charts/engine/three-d/model.js.map +1 -1
- package/dist/charts/engine/three-d/overlay.cjs +1 -1
- package/dist/charts/engine/three-d/overlay.cjs.map +1 -1
- package/dist/charts/engine/three-d/overlay.js +43 -36
- package/dist/charts/engine/three-d/overlay.js.map +1 -1
- package/dist/charts/engine/three-d/render-types.cjs +1 -1
- package/dist/charts/engine/three-d/render-types.cjs.map +1 -1
- package/dist/charts/engine/three-d/render-types.d.cts +24 -3
- package/dist/charts/engine/three-d/render-types.d.ts +24 -3
- package/dist/charts/engine/three-d/render-types.js +6 -7
- package/dist/charts/engine/three-d/render-types.js.map +1 -1
- package/dist/charts/engine/three-d/shaders.cjs +63 -28
- package/dist/charts/engine/three-d/shaders.cjs.map +1 -1
- package/dist/charts/engine/three-d/shaders.d.cts +2 -3
- package/dist/charts/engine/three-d/shaders.d.ts +2 -3
- package/dist/charts/engine/three-d/shaders.js +41 -22
- package/dist/charts/engine/three-d/shaders.js.map +1 -1
- package/dist/charts/engine/three-d/sort.cjs +1 -1
- package/dist/charts/engine/three-d/sort.cjs.map +1 -1
- package/dist/charts/engine/three-d/sort.d.cts +15 -4
- package/dist/charts/engine/three-d/sort.d.ts +15 -4
- package/dist/charts/engine/three-d/sort.js +117 -43
- package/dist/charts/engine/three-d/sort.js.map +1 -1
- package/dist/charts/engine/three-d/types.d.cts +27 -0
- package/dist/charts/engine/three-d/types.d.ts +27 -0
- package/dist/charts/engine/three-d/webgl.cjs +1 -1
- package/dist/charts/engine/three-d/webgl.cjs.map +1 -1
- package/dist/charts/engine/three-d/webgl.js +15 -13
- package/dist/charts/engine/three-d/webgl.js.map +1 -1
- package/dist/charts/engine/three-d/webgpu.cjs +1 -1
- package/dist/charts/engine/three-d/webgpu.cjs.map +1 -1
- package/dist/charts/engine/three-d/webgpu.js +50 -39
- package/dist/charts/engine/three-d/webgpu.js.map +1 -1
- package/dist/charts/engine/trading/chart.cjs +1 -1
- package/dist/charts/engine/trading/chart.cjs.map +1 -1
- package/dist/charts/engine/trading/chart.d.cts +10 -0
- package/dist/charts/engine/trading/chart.d.ts +10 -0
- package/dist/charts/engine/trading/chart.js +1475 -776
- package/dist/charts/engine/trading/chart.js.map +1 -1
- package/dist/charts/engine/trading/drawings.cjs +2 -1
- package/dist/charts/engine/trading/drawings.cjs.map +1 -1
- package/dist/charts/engine/trading/drawings.d.cts +47 -9
- package/dist/charts/engine/trading/drawings.d.ts +47 -9
- package/dist/charts/engine/trading/drawings.js +338 -75
- package/dist/charts/engine/trading/drawings.js.map +1 -1
- package/dist/charts/engine/trading/format.cjs +1 -1
- package/dist/charts/engine/trading/format.cjs.map +1 -1
- package/dist/charts/engine/trading/format.d.cts +13 -0
- package/dist/charts/engine/trading/format.d.ts +13 -0
- package/dist/charts/engine/trading/format.js +51 -19
- package/dist/charts/engine/trading/format.js.map +1 -1
- package/dist/charts/engine/trading/index.cjs +1 -1
- package/dist/charts/engine/trading/index.d.cts +2 -1
- package/dist/charts/engine/trading/index.d.ts +2 -1
- package/dist/charts/engine/trading/index.js +4 -3
- package/dist/charts/engine/trading/indicators.cjs +1 -1
- package/dist/charts/engine/trading/indicators.cjs.map +1 -1
- package/dist/charts/engine/trading/indicators.d.cts +180 -10
- package/dist/charts/engine/trading/indicators.d.ts +180 -10
- package/dist/charts/engine/trading/indicators.js +449 -173
- package/dist/charts/engine/trading/indicators.js.map +1 -1
- package/dist/charts/engine/trading/labels.cjs +1 -1
- package/dist/charts/engine/trading/labels.cjs.map +1 -1
- package/dist/charts/engine/trading/labels.js +84 -4
- package/dist/charts/engine/trading/labels.js.map +1 -1
- package/dist/charts/engine/trading/store.cjs +1 -1
- package/dist/charts/engine/trading/store.cjs.map +1 -1
- package/dist/charts/engine/trading/store.d.cts +21 -0
- package/dist/charts/engine/trading/store.d.ts +21 -0
- package/dist/charts/engine/trading/store.js +22 -1
- package/dist/charts/engine/trading/store.js.map +1 -1
- package/dist/charts/engine/trading/studies.cjs +1 -1
- package/dist/charts/engine/trading/studies.cjs.map +1 -1
- package/dist/charts/engine/trading/studies.d.cts +41 -8
- package/dist/charts/engine/trading/studies.d.ts +41 -8
- package/dist/charts/engine/trading/studies.js +349 -93
- package/dist/charts/engine/trading/studies.js.map +1 -1
- package/dist/charts/engine/trading/sync.cjs +2 -0
- package/dist/charts/engine/trading/sync.cjs.map +1 -0
- package/dist/charts/engine/trading/sync.d.cts +8 -0
- package/dist/charts/engine/trading/sync.d.ts +8 -0
- package/dist/charts/engine/trading/sync.js +25 -0
- package/dist/charts/engine/trading/sync.js.map +1 -0
- package/dist/charts/engine/trading/types.d.cts +484 -9
- package/dist/charts/engine/trading/types.d.ts +484 -9
- package/dist/charts/engine/types.d.cts +82 -8
- package/dist/charts/engine/types.d.ts +82 -8
- package/dist/charts/index.cjs +1 -1
- package/dist/charts/index.d.cts +3 -2
- package/dist/charts/index.d.ts +3 -2
- package/dist/charts/index.js +30 -22
- package/dist/charts/react/charts.cjs +1 -1
- package/dist/charts/react/charts.cjs.map +1 -1
- package/dist/charts/react/charts.js +46 -34
- package/dist/charts/react/charts.js.map +1 -1
- package/dist/charts/react/graph.cjs +2 -0
- package/dist/charts/react/graph.cjs.map +1 -0
- package/dist/charts/react/graph.d.cts +213 -0
- package/dist/charts/react/graph.d.ts +213 -0
- package/dist/charts/react/graph.js +159 -0
- package/dist/charts/react/graph.js.map +1 -0
- package/dist/charts/react/shapes.cjs +1 -1
- package/dist/charts/react/shapes.cjs.map +1 -1
- package/dist/charts/react/shapes.d.cts +87 -4
- package/dist/charts/react/shapes.d.ts +87 -4
- package/dist/charts/react/shapes.js +55 -12
- package/dist/charts/react/shapes.js.map +1 -1
- package/dist/charts/react/trading.cjs +1 -1
- package/dist/charts/react/trading.cjs.map +1 -1
- package/dist/charts/react/trading.d.cts +53 -1
- package/dist/charts/react/trading.d.ts +53 -1
- package/dist/charts/react/trading.js +68 -37
- package/dist/charts/react/trading.js.map +1 -1
- package/dist/charts/react/types.d.cts +11 -0
- package/dist/charts/react/types.d.ts +11 -0
- package/dist/core/contracts.cjs +1 -1
- package/dist/core/contracts.cjs.map +1 -1
- package/dist/core/contracts.js +1 -1
- package/dist/core/contracts.js.map +1 -1
- package/dist/native/charts/src/canvas.cjs +1 -1
- package/dist/native/charts/src/canvas.js +3 -3
- package/dist/native/charts/src/engine/axis.cjs +1 -1
- package/dist/native/charts/src/engine/axis.cjs.map +1 -1
- package/dist/native/charts/src/engine/axis.js +42 -19
- package/dist/native/charts/src/engine/axis.js.map +1 -1
- package/dist/native/charts/src/engine/color.cjs +1 -1
- package/dist/native/charts/src/engine/color.cjs.map +1 -1
- package/dist/native/charts/src/engine/color.js +47 -5
- package/dist/native/charts/src/engine/color.js.map +1 -1
- package/dist/native/charts/src/engine/controller.cjs +2 -2
- package/dist/native/charts/src/engine/controller.cjs.map +1 -1
- package/dist/native/charts/src/engine/controller.js +300 -253
- package/dist/native/charts/src/engine/controller.js.map +1 -1
- package/dist/native/charts/src/engine/data.cjs +1 -1
- package/dist/native/charts/src/engine/data.cjs.map +1 -1
- package/dist/native/charts/src/engine/data.js +6 -4
- package/dist/native/charts/src/engine/data.js.map +1 -1
- package/dist/native/charts/src/engine/format.cjs +1 -1
- package/dist/native/charts/src/engine/format.cjs.map +1 -1
- package/dist/native/charts/src/engine/format.js +15 -2
- package/dist/native/charts/src/engine/format.js.map +1 -1
- package/dist/native/charts/src/engine/labels.cjs +1 -1
- package/dist/native/charts/src/engine/labels.cjs.map +1 -1
- package/dist/native/charts/src/engine/labels.js +28 -4
- package/dist/native/charts/src/engine/labels.js.map +1 -1
- package/dist/native/charts/src/engine/layout.cjs +1 -1
- package/dist/native/charts/src/engine/layout.cjs.map +1 -1
- package/dist/native/charts/src/engine/layout.js +11 -2
- package/dist/native/charts/src/engine/layout.js.map +1 -1
- package/dist/native/charts/src/engine/model.cjs +1 -1
- package/dist/native/charts/src/engine/model.cjs.map +1 -1
- package/dist/native/charts/src/engine/model.js +252 -171
- package/dist/native/charts/src/engine/model.js.map +1 -1
- package/dist/native/charts/src/engine/overlay.cjs.map +1 -1
- package/dist/native/charts/src/engine/overlay.js.map +1 -1
- package/dist/native/charts/src/engine/presets.cjs +2 -2
- package/dist/native/charts/src/engine/presets.cjs.map +1 -1
- package/dist/native/charts/src/engine/presets.js +104 -90
- package/dist/native/charts/src/engine/presets.js.map +1 -1
- package/dist/native/charts/src/engine/scene.cjs +1 -1
- package/dist/native/charts/src/engine/scene.cjs.map +1 -1
- package/dist/native/charts/src/engine/scene.js +341 -188
- package/dist/native/charts/src/engine/scene.js.map +1 -1
- package/dist/native/charts/src/engine/shapes/bullet.cjs +1 -1
- package/dist/native/charts/src/engine/shapes/bullet.cjs.map +1 -1
- package/dist/native/charts/src/engine/shapes/bullet.js +110 -110
- package/dist/native/charts/src/engine/shapes/bullet.js.map +1 -1
- package/dist/native/charts/src/engine/shapes/calendar.cjs +1 -1
- package/dist/native/charts/src/engine/shapes/calendar.cjs.map +1 -1
- package/dist/native/charts/src/engine/shapes/calendar.js +21 -16
- package/dist/native/charts/src/engine/shapes/calendar.js.map +1 -1
- package/dist/native/charts/src/engine/shapes/chord.cjs +2 -0
- package/dist/native/charts/src/engine/shapes/chord.cjs.map +1 -0
- package/dist/native/charts/src/engine/shapes/chord.js +414 -0
- package/dist/native/charts/src/engine/shapes/chord.js.map +1 -0
- package/dist/native/charts/src/engine/shapes/draw.cjs +1 -1
- package/dist/native/charts/src/engine/shapes/draw.cjs.map +1 -1
- package/dist/native/charts/src/engine/shapes/draw.js +47 -17
- package/dist/native/charts/src/engine/shapes/draw.js.map +1 -1
- package/dist/native/charts/src/engine/shapes/hit.cjs +1 -1
- package/dist/native/charts/src/engine/shapes/hit.cjs.map +1 -1
- package/dist/native/charts/src/engine/shapes/hit.js +73 -44
- package/dist/native/charts/src/engine/shapes/hit.js.map +1 -1
- package/dist/native/charts/src/engine/shapes/labels.cjs +1 -1
- package/dist/native/charts/src/engine/shapes/labels.cjs.map +1 -1
- package/dist/native/charts/src/engine/shapes/labels.js +12 -4
- package/dist/native/charts/src/engine/shapes/labels.js.map +1 -1
- package/dist/native/charts/src/engine/shapes/layout.cjs +2 -2
- package/dist/native/charts/src/engine/shapes/layout.cjs.map +1 -1
- package/dist/native/charts/src/engine/shapes/layout.js +117 -90
- package/dist/native/charts/src/engine/shapes/layout.js.map +1 -1
- package/dist/native/charts/src/engine/shapes/scene.cjs +1 -1
- package/dist/native/charts/src/engine/shapes/scene.cjs.map +1 -1
- package/dist/native/charts/src/engine/shapes/scene.js +62 -19
- package/dist/native/charts/src/engine/shapes/scene.js.map +1 -1
- package/dist/native/components/Chart/scene.cjs +1 -1
- package/dist/native/components/Chart/scene.cjs.map +1 -1
- package/dist/native/components/Chart/scene.js +140 -71
- package/dist/native/components/Chart/scene.js.map +1 -1
- package/dist/native/components/Charts/charts.cjs +1 -1
- package/dist/native/components/Charts/charts.cjs.map +1 -1
- package/dist/native/components/Charts/charts.js +54 -42
- package/dist/native/components/Charts/charts.js.map +1 -1
- package/dist/native/components/Charts/types.d.cts +11 -0
- package/dist/native/components/Charts/types.d.ts +11 -0
- package/dist/native/components/ShapeChart/ShapeChartBase.cjs +1 -1
- package/dist/native/components/ShapeChart/ShapeChartBase.cjs.map +1 -1
- package/dist/native/components/ShapeChart/ShapeChartBase.js +1 -0
- package/dist/native/components/ShapeChart/ShapeChartBase.js.map +1 -1
- package/dist/native/components/ShapeChart/charts.cjs +1 -1
- package/dist/native/components/ShapeChart/charts.cjs.map +1 -1
- package/dist/native/components/ShapeChart/charts.d.cts +6 -1
- package/dist/native/components/ShapeChart/charts.d.ts +6 -1
- package/dist/native/components/ShapeChart/charts.js +138 -96
- package/dist/native/components/ShapeChart/charts.js.map +1 -1
- package/dist/native/components/ShapeChart/draw.cjs +1 -1
- package/dist/native/components/ShapeChart/draw.cjs.map +1 -1
- package/dist/native/components/ShapeChart/draw.d.cts +1 -1
- package/dist/native/components/ShapeChart/draw.d.ts +1 -1
- package/dist/native/components/ShapeChart/draw.js +26 -17
- package/dist/native/components/ShapeChart/draw.js.map +1 -1
- package/dist/native/components/ShapeChart/geometry.cjs +1 -1
- package/dist/native/components/ShapeChart/geometry.cjs.map +1 -1
- package/dist/native/components/ShapeChart/geometry.js +138 -59
- package/dist/native/components/ShapeChart/geometry.js.map +1 -1
- package/dist/native/components/ShapeChart/index.cjs +1 -1
- package/dist/native/components/ShapeChart/index.d.cts +1 -1
- package/dist/native/components/ShapeChart/index.d.ts +1 -1
- package/dist/native/components/ShapeChart/index.js +2 -2
- package/dist/native/components/ShapeChart/recorder.cjs +1 -1
- package/dist/native/components/ShapeChart/recorder.cjs.map +1 -1
- package/dist/native/components/ShapeChart/recorder.d.cts +10 -1
- package/dist/native/components/ShapeChart/recorder.d.ts +10 -1
- package/dist/native/components/ShapeChart/recorder.js +19 -10
- package/dist/native/components/ShapeChart/recorder.js.map +1 -1
- package/dist/native/components/ShapeChart/types.d.cts +92 -7
- package/dist/native/components/ShapeChart/types.d.ts +92 -7
- package/dist/native/index.cjs +1 -1
- package/dist/native/index.js +2 -2
- package/dist/native/source/components/Chart/scene.tsx +158 -14
- package/dist/native/source/components/Charts/charts.tsx +30 -2
- package/dist/native/source/components/Charts/types.ts +11 -0
- package/dist/native/source/components/ShapeChart/ShapeChartBase.tsx +2 -0
- package/dist/native/source/components/ShapeChart/charts.tsx +91 -35
- package/dist/native/source/components/ShapeChart/draw.tsx +39 -8
- package/dist/native/source/components/ShapeChart/geometry.ts +189 -8
- package/dist/native/source/components/ShapeChart/index.ts +1 -0
- package/dist/native/source/components/ShapeChart/recorder.ts +20 -5
- package/dist/native/source/components/ShapeChart/types.ts +96 -5
- package/dist/native/source/manifest.ts +1 -0
- package/dist/taro/charts.d.ts +25 -5
- package/dist/taro/index.js +3900 -2836
- package/dist/taro/shape-charts.d.ts +96 -4
- package/dist/uni/AreaChart.vue.d.ts +5 -1
- package/dist/uni/Badge.vue.d.ts +1 -1
- package/dist/uni/BarChart.vue.d.ts +5 -1
- package/dist/uni/BoxPlotChart.vue.d.ts +8 -0
- package/dist/uni/BubbleChart.vue.d.ts +4 -0
- package/dist/uni/BulletChart.vue.d.ts +4 -0
- package/dist/uni/CalendarHeatmap.vue.d.ts +2 -0
- package/dist/uni/CandlestickChart.vue.d.ts +4 -0
- package/dist/uni/Chart.vue.d.ts +4 -0
- package/dist/uni/ChordChart.vue +93 -0
- package/dist/uni/ChordChart.vue.d.ts +136 -0
- package/dist/uni/DonutChart.vue.d.ts +4 -0
- package/dist/uni/FunnelChart.vue.d.ts +4 -0
- package/dist/uni/GanttChart.vue.d.ts +4 -0
- package/dist/uni/GaugeChart.vue.d.ts +4 -0
- package/dist/uni/HeatmapChart.vue.d.ts +8 -2
- package/dist/uni/HistogramChart.vue.d.ts +4 -0
- package/dist/uni/HorizontalBarChart.vue.d.ts +3 -1
- package/dist/uni/LineChart.vue.d.ts +4 -0
- package/dist/uni/MixedChart.vue.d.ts +4 -0
- package/dist/uni/PieChart.vue.d.ts +4 -0
- package/dist/uni/QuadrantChart.vue.d.ts +4 -0
- package/dist/uni/RadarChart.vue.d.ts +4 -0
- package/dist/uni/RadialBarChart.vue.d.ts +4 -0
- package/dist/uni/RangeAreaChart.vue.d.ts +4 -0
- package/dist/uni/SankeyChart.vue.d.ts +4 -0
- package/dist/uni/ScatterChart.vue.d.ts +4 -0
- package/dist/uni/Sparkline.vue.d.ts +4 -0
- package/dist/uni/SunburstChart.vue.d.ts +4 -0
- package/dist/uni/ToastProvider.vue.d.ts +1 -1
- package/dist/uni/TreemapChart.vue.d.ts +4 -0
- package/dist/uni/WaterfallChart.vue.d.ts +9 -0
- package/dist/uni/chart-canvas.d.ts +3 -0
- package/dist/uni/chart-canvas.js +4 -0
- package/dist/uni/chart-types.d.ts +28 -4
- package/dist/uni/chart-types.js +26 -2
- package/dist/uni/charts-canvas.js +1 -1
- package/dist/uni/index.d.ts +2 -1
- package/dist/uni/index.js +1 -0
- package/dist/uni/manifest.d.ts +7 -0
- package/dist/uni/manifest.js +10 -0
- package/dist/uni/named-chart-options.d.ts +9 -2
- package/dist/uni/named-chart-options.js +18 -1
- package/dist/uni/shape-chart-canvas.d.ts +3 -1
- package/dist/uni/shape-chart-canvas.js +15 -24
- package/dist/uni/shape-chart-types.d.ts +52 -2
- package/dist/uni/shape-chart-types.js +44 -0
- package/dist/vue/charts-global.d.ts +48 -0
- package/dist/vue/charts.d.ts +18 -0
- package/dist/vue/charts.js +56 -0
- package/dist/vue/charts.js.map +1 -0
- package/dist/vue/components/Chart/BoxPlotChart.vue.d.ts +8 -0
- package/dist/vue/components/Chart/BoxPlotChart.vue.js.map +1 -1
- package/dist/vue/components/Chart/BoxPlotChart.vue_vue_type_script_setup_true_lang.js +8 -2
- package/dist/vue/components/Chart/BoxPlotChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/vue/components/Chart/ChordChart.vue.d.ts +153 -0
- package/dist/vue/components/Chart/ChordChart.vue.js +7 -0
- package/dist/vue/components/Chart/ChordChart.vue.js.map +1 -0
- package/dist/vue/components/Chart/ChordChart.vue_vue_type_script_setup_true_lang.js +81 -0
- package/dist/vue/components/Chart/ChordChart.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/vue/components/Chart/DependencyGraph.vue.d.ts +179 -0
- package/dist/vue/components/Chart/DependencyGraph.vue.js +7 -0
- package/dist/vue/components/Chart/DependencyGraph.vue.js.map +1 -0
- package/dist/vue/components/Chart/DependencyGraph.vue_vue_type_script_setup_true_lang.js +65 -0
- package/dist/vue/components/Chart/DependencyGraph.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/vue/components/Chart/GanttChart.vue.d.ts +4 -0
- package/dist/vue/components/Chart/GanttChart.vue.js.map +1 -1
- package/dist/vue/components/Chart/GanttChart.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/vue/components/Chart/GanttChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/vue/components/Chart/GraphChart.vue.d.ts +184 -0
- package/dist/vue/components/Chart/GraphChart.vue.js +7 -0
- package/dist/vue/components/Chart/GraphChart.vue.js.map +1 -0
- package/dist/vue/components/Chart/GraphChart.vue_vue_type_script_setup_true_lang.js +62 -0
- package/dist/vue/components/Chart/GraphChart.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/vue/components/Chart/HeatmapChart.vue.d.ts +9 -5
- package/dist/vue/components/Chart/HeatmapChart.vue.js.map +1 -1
- package/dist/vue/components/Chart/HeatmapChart.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/vue/components/Chart/HeatmapChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/vue/components/Chart/OrderBookHeatmap.vue.d.ts +2 -0
- package/dist/vue/components/Chart/TimeAndSales.vue.d.ts +2 -0
- package/dist/vue/components/Chart/TradingChart.vue.d.ts +49 -1
- package/dist/vue/components/Chart/TradingChart.vue.js.map +1 -1
- package/dist/vue/components/Chart/TradingChart.vue_vue_type_script_setup_true_lang.js +31 -0
- package/dist/vue/components/Chart/TradingChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/vue/components/Chart/TreeChart.vue.d.ts +172 -0
- package/dist/vue/components/Chart/TreeChart.vue.js +7 -0
- package/dist/vue/components/Chart/TreeChart.vue.js.map +1 -0
- package/dist/vue/components/Chart/TreeChart.vue_vue_type_script_setup_true_lang.js +56 -0
- package/dist/vue/components/Chart/TreeChart.vue_vue_type_script_setup_true_lang.js.map +1 -0
- package/dist/vue/components/Chart/WaterfallChart.vue.d.ts +12 -1
- package/dist/vue/components/Chart/WaterfallChart.vue.js.map +1 -1
- package/dist/vue/components/Chart/WaterfallChart.vue_vue_type_script_setup_true_lang.js +8 -2
- package/dist/vue/components/Chart/WaterfallChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
- package/dist/vue/components/Chart/graph.d.ts +153 -0
- package/dist/vue/components/Chart/graph.js +135 -0
- package/dist/vue/components/Chart/graph.js.map +1 -0
- package/dist/vue/components/Chart/index.d.ts +5 -1
- package/dist/vue/components/Chart/index.js +5 -1
- package/dist/vue/components/Chart/orderbook.d.ts +5 -1
- package/dist/vue/components/Chart/orderbook.js +2 -0
- package/dist/vue/components/Chart/orderbook.js.map +1 -1
- package/dist/vue/components/Chart/trading.d.ts +24 -2
- package/dist/vue/components/Chart/trading.js +8 -0
- package/dist/vue/components/Chart/trading.js.map +1 -1
- package/dist/vue/components/Chart/types.d.ts +74 -2
- package/dist/vue/global.d.ts +2 -38
- package/dist/vue/groups/charts.js +10 -2
- package/dist/vue/groups/charts.js.map +1 -1
- package/dist/vue/index.js +6 -2
- package/dist/vue/internal/register.d.ts +7 -0
- package/dist/vue/internal/register.js +14 -0
- package/dist/vue/internal/register.js.map +1 -0
- package/dist/vue/plugin.d.ts +9 -4
- package/dist/vue/plugin.js +6 -11
- package/dist/vue/plugin.js.map +1 -1
- package/dist/weapp/charts/canvas.js +1687 -147
- package/dist/weapp/charts/core.js +1 -0
- package/dist/weapp/chord-chart/index.js +1 -0
- package/dist/weapp/chord-chart/index.json +1 -0
- package/dist/weapp/chord-chart/index.wxml +1 -0
- package/dist/weapp/chord-chart/index.wxss +1 -0
- package/dist/weapp/controls.js +92 -32
- package/dist/weapp/types.d.ts +87 -4
- package/dist/web-components/components/chart/charts.d.ts +4 -2
- package/dist/web-components/components/chart/charts.js +8 -1
- package/dist/web-components/components/chart/charts.js.map +1 -1
- package/dist/web-components/components/chart/extended.d.ts +17 -7
- package/dist/web-components/components/chart/extended.js +23 -9
- package/dist/web-components/components/chart/extended.js.map +1 -1
- package/dist/web-components/components/chart/shapes-extended.d.ts +37 -1
- package/dist/web-components/components/chart/shapes-extended.js +27 -1
- package/dist/web-components/components/chart/shapes-extended.js.map +1 -1
- package/dist/web-components/components/graph/graph.d.ts +154 -0
- package/dist/web-components/components/graph/graph.js +149 -0
- package/dist/web-components/components/graph/graph.js.map +1 -0
- package/dist/web-components/components/trading-chart/trading-chart.d.ts +49 -2
- package/dist/web-components/components/trading-chart/trading-chart.js +62 -0
- package/dist/web-components/components/trading-chart/trading-chart.js.map +1 -1
- package/dist/web-components/elements/chart.d.ts +1 -1
- package/dist/web-components/elements/chart.js +6 -5
- package/dist/web-components/elements/chart.js.map +1 -1
- package/dist/web-components/elements/graph.d.ts +2 -0
- package/dist/web-components/elements/graph.js +12 -0
- package/dist/web-components/elements/graph.js.map +1 -0
- package/dist/web-components/html-custom-data.json +273 -4
- package/dist/web-components/types/react.d.ts +63 -4
- package/dist/web-components/types/solid.d.ts +55 -8
- package/dist/web-components/types/svelte.d.ts +55 -8
- package/dist/web-components/types/vue.d.ts +55 -4
- package/package.json +16 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model.js","names":["firstX","data","xs","list","i","item","detectXType","datas","x","axisModel","options","gridDefault","definedEntries","out","value","key","extent","min","max","values","v","smallestStep","step","columns","sorted","k","d","bandOf","category","axis","s","stackValues","totals","percent","byX","stack","count","y","t","running","members","base","top","valid","sums","total","b","DEFAULT_UP","DEFAULT_DOWN","hasDateY","precise","nextStep","power","f","alignedDomain","a0","a1","left","stepL","tickStep","n","lo","hi","ensureSpan","niceDomain","start","mapped","mapColumns","map","hit","raw","column","a","cols","buildModel","resolve","resolver","theme","resolveStaticColor","fallback","input","locale","resolveLocale","tooltipOptions","labels","chartLabels","xType","categories","collectCategories","categoryMap","c","resolveX","xResolver","name","yOpts","heatmapData","yCategories","collectYCategories","yType","yCategoryMap","resolveY","resolverKey","horizontal","usedKeys","series","index","entry","cache","normalizeData","type","paletteColor","color","pointColors","resolved","rgba","colorScale","valueRange","cellColors","mix","span","packColor","rampColor","id","toCss","hidden","visible","allScatter","slotted","bars","band","slots","stackId","share","w","group","slotWidth","slot","stackedBars","stacked","percentStacked","p","y0","stackedLines","candles","candleBand","heatmaps","cx","cy","xOpts","xRange","pad","pointsOnly","valuesOf","listBars","zero","leftVisible","leftSeries","leftBars","yRange","yValues","filled","y2Opts","y2","y2Map","rightSeries","domain","scale","rawBase","zoomOption","zoomAxes","yFormat","formatPercent","valueFormatter","plottedY","grids","gridOf","grid","GridIndex"],"sources":["../../../../../../charts/src/engine/model.ts"],"sourcesContent":["// Options -> chart model: normalized data, colors, bar layout, stacks and\n// the full ranges of the axes. Pure (colors go through the theme's resolver).\n\nimport {\n mix,\n packColor,\n rampColor,\n resolveStaticColor,\n toCss,\n type ColorResolver,\n type Rgba,\n} from \"./color\";\nimport {\n collectCategories,\n collectYCategories,\n normalizeData,\n xResolver,\n type SeriesColumns,\n type YResolver,\n} from \"./data\";\nimport { formatPercent, valueFormatter } from \"./format\";\nimport { chartLabels } from \"./labels\";\nimport { resolveLocale } from \"./locale\";\nimport { ensureSpan, niceDomain, tickStep } from \"./scale\";\nimport { GridIndex } from \"./spatial\";\nimport type { ChartTheme } from \"./theme\";\nimport type {\n ChartAxisOptions,\n ChartAxisType,\n ChartCurve,\n ChartOptions,\n ChartSeries,\n ChartSeriesData,\n ChartLabels,\n ChartSeriesType,\n ChartTimeZone,\n} from \"./types\";\nimport type { Range } from \"./viewport\";\n\nexport interface AxisModel {\n type: ChartAxisType;\n reverse: boolean;\n categories: string[];\n title?: string;\n format?: (value: number) => string;\n grid: boolean;\n visible: boolean;\n tickCount?: number;\n /** Locale of the tick and tooltip labels (historical English texts when omitted) */\n locale?: string;\n /** Calendar of a time axis */\n timeZone?: ChartTimeZone;\n}\n\nexport interface SeriesModel {\n index: number;\n /** Key of the GPU resources and of the data cache */\n key: string;\n id: string;\n name: string;\n type: ChartSeriesType;\n color: Rgba;\n colorCss: string;\n lineWidth: number;\n pointSize: number;\n opacity: number;\n hidden: boolean;\n showLabels: boolean;\n curve: ChartCurve;\n /**\n * Plotted columns: the data, mapped onto the left axis for the series of\n * the right axis (`raw` keeps the values of the data)\n */\n cols: SeriesColumns;\n /** Columns of the data (shown in tooltips and labels) */\n raw: SeriesColumns;\n /** Value axis of the series */\n yAxis: \"left\" | \"right\";\n /** Bars with a start (`y0`): drawn from it, never stacked */\n floating: boolean;\n /** Bars / candlesticks: x offset of the series inside a group and half of the bar width */\n barOffset: number;\n barHalfWidth: number;\n /** Bars: bottom / top of every bar (stacks included) */\n barBase: Float64Array | null;\n barTop: Float64Array | null;\n /** Stacked lines / areas: bottom / top of every point */\n stackBase: Float64Array | null;\n stackTop: Float64Array | null;\n /** Scatter / bar: resolved per-point colors */\n pointColors: (Rgba | undefined)[] | null;\n /** Candlesticks: colors of the rising / falling candles */\n upColor: Rgba;\n downColor: Rgba;\n /** Heatmaps: packed color of every cell (0 = no cell) and half of a cell, in data units */\n cellColors: Uint32Array | null;\n cellHalf: { x: number; y: number };\n /** Heatmaps: ramp of the colors and the values at its ends */\n colorScale: Rgba[];\n valueRange: Range;\n /** Corner radius in CSS pixels (bars, heatmap cells) */\n radius: number;\n /** Tooltip format of the values */\n format?: (value: number) => string;\n /** Scatter: name of the `value` of the points */\n valueName?: string;\n}\n\n/** Linear map of the right axis onto the left one: `left = right * scale + offset` */\nexport interface AxisMap {\n scale: number;\n offset: number;\n}\n\nexport interface ChartModel {\n series: SeriesModel[];\n x: AxisModel;\n y: AxisModel;\n /** Right value axis (`yAxis2`), `null` when no series uses it */\n y2: AxisModel | null;\n /** Right axis values -> left axis values */\n y2Map: AxisMap | null;\n /** The x axis runs down the left side, the values along the bottom */\n horizontal: boolean;\n /** Resolved locale (`locale` option, else the page language) */\n locale: string;\n /** Texts of the locale with the `labels` overrides */\n labels: ChartLabels;\n /** Tooltip value of the locale (series without `format`) */\n formatValue: (value: number) => string;\n /** Full ranges (zoomed out) */\n base: { x: Range; y: Range };\n /** Every series is a scatter (or a heatmap): nearest tooltips, xy zoom */\n allScatter: boolean;\n zoom: { x: boolean; y: boolean };\n tooltipMode: \"nearest\" | \"axis\";\n /** Y value the areas are filled to */\n baseline: number;\n /** Smallest zoomed spans */\n minSpan: { x: number; y: number };\n /** Stacks are scaled to 100% */\n percent: boolean;\n /** Stack id of every series (`null` when not stacked) */\n stacks: (string | null)[];\n}\n\nexport interface DataCacheEntry {\n data: ChartSeriesData;\n resolverKey: string;\n cols: SeriesColumns;\n}\n\nexport type DataCache = Map<string, DataCacheEntry>;\n\nconst firstX = (data: ChartSeriesData): unknown => {\n if (typeof data === \"object\" && data !== null && !(\"length\" in data)) {\n const xs = (data as { x?: ArrayLike<unknown> }).x;\n return xs && xs.length ? xs[0] : undefined;\n }\n const list = data as ArrayLike<unknown>;\n for (let i = 0; i < Math.min(list.length, 8); i++) {\n const item = list[i];\n if (Array.isArray(item)) return item[0];\n if (item && typeof item === \"object\") return (item as { x?: unknown }).x;\n }\n return undefined;\n};\n\n/** Axis type when not given: dates -> time, strings -> category */\nexport const detectXType = (\n datas: readonly ChartSeriesData[],\n): ChartAxisType => {\n for (const data of datas) {\n const x = firstX(data);\n if (x instanceof Date) return \"time\";\n if (typeof x === \"string\") return \"category\";\n }\n return \"linear\";\n};\n\nconst axisModel = (\n options: ChartAxisOptions | undefined,\n type: ChartAxisType,\n categories: string[],\n gridDefault: boolean,\n locale: string,\n): AxisModel => ({\n type,\n reverse: !!options?.reverse,\n categories,\n title: options?.title,\n format: options?.format,\n grid: options?.grid ?? gridDefault,\n visible: options?.visible ?? true,\n tickCount: options?.tickCount,\n locale,\n timeZone: options?.timeZone ?? \"local\",\n});\n\n/** Defined entries only (`{ open: undefined }` keeps the built-in text) */\nconst definedEntries = <T extends object>(value: T | undefined): Partial<T> => {\n const out: Partial<T> = {};\n if (!value) return out;\n for (const key of Object.keys(value) as (keyof T)[]) {\n if (value[key] !== undefined) out[key] = value[key];\n }\n return out;\n};\n\nconst extent = (values: ArrayLike<number>): Range => {\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < values.length; i++) {\n const v = values[i];\n if (!Number.isFinite(v)) continue;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n return [min, max];\n};\n\n/** Smallest positive gap between consecutive values (bar width on numeric axes) */\nconst smallestStep = (columns: ArrayLike<number>[], sorted: boolean[]) => {\n let step = Infinity;\n columns.forEach((values, k) => {\n const xs = sorted[k] ? values : Float64Array.from(values).sort();\n for (let i = 1; i < xs.length; i++) {\n const d = xs[i] - xs[i - 1];\n if (d > 0 && d < step) step = d;\n }\n });\n return step;\n};\n\nconst bandOf = (list: SeriesModel[], axis: \"x\" | \"y\", category: boolean) => {\n if (category) return 1;\n const step = smallestStep(\n list.map((s) => (axis === \"x\" ? s.cols.x : s.cols.y)),\n list.map((s) => axis === \"x\" && s.cols.sorted),\n );\n return Number.isFinite(step) ? step : 1;\n};\n\n/**\n * Stacks the y values of series sharing a stack id (positive and negative\n * values separately); `percent` scales every stack to 100 at each x\n */\nconst stackValues = (\n list: { s: SeriesModel; stack: string }[],\n percent: boolean,\n): { base: Float64Array; top: Float64Array }[] => {\n const totals = new Map<string, Map<number, [number, number]>>();\n if (percent) {\n for (const { s, stack } of list) {\n let byX = totals.get(stack);\n if (!byX) totals.set(stack, (byX = new Map()));\n const { x, y, count } = s.cols;\n for (let i = 0; i < count; i++) {\n const v = y[i];\n if (!Number.isFinite(v)) continue;\n const t = byX.get(x[i]) ?? [0, 0];\n if (v >= 0) t[0] += v;\n else t[1] -= v;\n byX.set(x[i], t);\n }\n }\n }\n const running = new Map<string, Map<number, [number, number]>>();\n const members = new Map<string, number>();\n for (const { stack } of list)\n members.set(stack, (members.get(stack) ?? 0) + 1);\n return list.map(({ s, stack }) => {\n const { x, y, count } = s.cols;\n if (!percent && members.get(stack) === 1) {\n // alone in its stack (e.g. grouped bars): from zero, no bookkeeping\n const base = new Float64Array(count);\n const top = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n const v = y[i];\n const valid = Number.isFinite(v);\n base[i] = valid ? 0 : NaN;\n top[i] = valid ? v : NaN;\n }\n return { base, top };\n }\n let byX = running.get(stack);\n if (!byX) running.set(stack, (byX = new Map()));\n const sums = totals.get(stack);\n const base = new Float64Array(count);\n const top = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n let v = y[i];\n if (!Number.isFinite(v)) {\n base[i] = NaN;\n top[i] = NaN;\n continue;\n }\n if (sums) {\n const t = sums.get(x[i]);\n const total = t ? (v >= 0 ? t[0] : t[1]) : 0;\n v = total > 0 ? (v / total) * 100 : 0;\n }\n const t = byX.get(x[i]) ?? [0, 0];\n const b = v >= 0 ? t[0] : t[1];\n base[i] = b;\n top[i] = b + v;\n if (v >= 0) t[0] += v;\n else t[1] += v;\n byX.set(x[i], t);\n }\n return { base, top };\n });\n};\n\nconst DEFAULT_UP = \"var(--success-color, #16a34a)\";\nconst DEFAULT_DOWN = \"var(--danger-color, #dc2626)\";\n\n/** Dates in the y values (or starts) of objects: a time value axis */\nconst hasDateY = (datas: readonly ChartSeriesData[]): boolean => {\n for (const data of datas) {\n if (typeof data !== \"object\" || data === null || !(\"length\" in data))\n continue;\n const list = data as ArrayLike<unknown>;\n for (let i = 0; i < Math.min(list.length, 8); i++) {\n const item = list[i];\n if (item && typeof item === \"object\" && !Array.isArray(item)) {\n const d = item as { y?: unknown; y0?: unknown };\n if (d.y instanceof Date || d.y0 instanceof Date) return true;\n }\n }\n }\n return false;\n};\n\nconst precise = (v: number) => Number(v.toPrecision(12));\n\n/** Next step of the 1, 2, 5 × 10^k sequence */\nconst nextStep = (step: number) => {\n const power = 10 ** Math.floor(Math.log10(step) + 1e-9);\n const f = step / power;\n return (f < 1.5 ? 2 : f < 3.5 ? 5 : 10) * power;\n};\n\n/**\n * Range of the right axis covering [lo, hi] with as many tick intervals as\n * the left range has (its ticks then line up with the left grid)\n */\nexport const alignedDomain = (\n lo: number,\n hi: number,\n left: Range,\n count: number,\n): Range => {\n const [a0, a1] = left;\n const stepL = tickStep(a0, a1, count);\n const n = stepL > 0 ? Math.round((a1 - a0) / stepL) : 0;\n [lo, hi] = ensureSpan(lo, hi);\n if (n < 1 || Math.abs(n * stepL - (a1 - a0)) > stepL * 1e-6) {\n return niceDomain(lo, hi, count);\n }\n let step = tickStep(lo, hi, n);\n for (let k = 0; k < 40 && step > 0; k++) {\n const start = Math.floor(lo / step + 1e-9) * step;\n if (start + n * step >= hi - step * 1e-9) {\n return [precise(start), precise(start + n * step)];\n }\n step = nextStep(step);\n }\n return niceDomain(lo, hi, count);\n};\n\nconst mapped = new WeakMap<\n SeriesColumns,\n { key: string; cols: SeriesColumns }\n>();\n\n/** Columns of a right-axis series in left axis units (cached with the data) */\nconst mapColumns = (raw: SeriesColumns, map: AxisMap): SeriesColumns => {\n const key = `${map.scale},${map.offset}`;\n const hit = mapped.get(raw);\n if (hit && hit.key === key) return hit.cols;\n const f = (v: number) => v * map.scale + map.offset;\n const column = (a: Float64Array | null) => (a ? a.map(f) : null);\n const lo = f(raw.yMin);\n const hi = f(raw.yMax);\n const cols: SeriesColumns = {\n ...raw,\n y: raw.y.map(f),\n open: column(raw.open),\n high: column(raw.high),\n low: column(raw.low),\n y0: column(raw.y0),\n q1: column(raw.q1),\n q3: column(raw.q3),\n outliers: raw.outliers ? raw.outliers.map((list) => list?.map(f)) : null,\n yMin: Math.min(lo, hi),\n yMax: Math.max(lo, hi),\n };\n mapped.set(raw, { key, cols });\n return cols;\n};\n\nexport const buildModel = (\n options: ChartOptions,\n theme: ChartTheme,\n hidden: ReadonlySet<string>,\n cache: DataCache,\n resolver: ColorResolver | null = null,\n): ChartModel => {\n const resolve: ColorResolver =\n resolver ??\n theme.resolve ??\n ((value, fallback) => resolveStaticColor(value, {}, fallback));\n const input = options.series;\n // resolved at every build: a page language switch shows on the next update\n const locale = resolveLocale(options.locale);\n const tooltipOptions =\n typeof options.tooltip === \"object\" ? options.tooltip : undefined;\n const labels = chartLabels(locale, {\n ...definedEntries(tooltipOptions?.labels),\n ...definedEntries(options.labels),\n });\n const datas = input.map((s) => s.data);\n const xType = options.xAxis?.type ?? detectXType(datas);\n const categories =\n xType === \"category\"\n ? [...(options.xAxis?.categories ?? collectCategories(datas))]\n : [];\n const categoryMap = new Map(categories.map((c, i) => [c, i]));\n const resolveX = xResolver(xType, (name) => categoryMap.get(name) ?? NaN);\n\n // category y axis (heatmap rows): explicit, or detected from string y values\n const yOpts = options.yAxis;\n const heatmapData = input\n .filter((s) => s.type === \"heatmap\")\n .map((s) => s.data);\n const yCategories =\n yOpts?.type === \"category\" || (!yOpts?.type && heatmapData.length)\n ? [...(yOpts?.categories ?? collectYCategories(heatmapData))]\n : [];\n const yType: ChartAxisType =\n yOpts?.type === \"category\" || yCategories.length\n ? \"category\"\n : yOpts?.type === \"time\" || (!yOpts?.type && hasDateY(datas))\n ? \"time\"\n : \"linear\";\n const yCategoryMap = new Map(yCategories.map((c, i) => [c, i]));\n const resolveY: YResolver = (v) =>\n typeof v === \"number\"\n ? v\n : typeof v === \"string\"\n ? yType === \"category\"\n ? (yCategoryMap.get(v) ?? NaN)\n : yType === \"time\"\n ? Date.parse(v)\n : Number(v)\n : v instanceof Date\n ? v.getTime()\n : NaN;\n const resolverKey = `${xType}|${categories.join(\"\\u0001\")}|${yType}|${yCategories.join(\"\\u0001\")}`;\n const percent = options.stackMode === \"percent\";\n const horizontal = options.orientation === \"horizontal\";\n\n const usedKeys = new Set<string>();\n const series: SeriesModel[] = input.map((s: ChartSeries, index) => {\n let key = s.id ?? `#${index}`;\n while (usedKeys.has(key)) key += \"'\";\n usedKeys.add(key);\n let entry = cache.get(key);\n if (!entry || entry.data !== s.data || entry.resolverKey !== resolverKey) {\n entry = {\n data: s.data,\n resolverKey,\n cols: normalizeData(s.data, resolveX, resolveY),\n };\n cache.set(key, entry);\n }\n const type = s.type ?? \"line\";\n const paletteColor = theme.palette[index % theme.palette.length];\n const color = s.color ? resolve(s.color, paletteColor) : paletteColor;\n const cols = entry.cols;\n let pointColors: (Rgba | undefined)[] | null = null;\n if (\n (type === \"scatter\" || type === \"bar\" || type === \"boxplot\") &&\n cols.colors\n ) {\n const resolved = new Map<string, Rgba>();\n pointColors = cols.colors.map((c) => {\n if (c === undefined) return undefined;\n let rgba = resolved.get(c);\n if (!rgba) resolved.set(c, (rgba = resolve(c, color)));\n return rgba;\n });\n }\n let colorScale: Rgba[] = [];\n let valueRange: Range = [0, 1];\n let cellColors: Uint32Array | null = null;\n if (type === \"heatmap\") {\n colorScale =\n s.colorScale && s.colorScale.length\n ? s.colorScale.map((c) => resolve(c, color))\n : [mix(theme.background, color, 0.08), color];\n valueRange = s.valueRange\n ? [s.valueRange[0], s.valueRange[1]]\n : [cols.valueMin, cols.valueMax];\n if (!Number.isFinite(valueRange[0])) valueRange = [0, 1];\n const values = cols.value ?? cols.y;\n const [lo, hi] = valueRange;\n const span = hi - lo || 1;\n cellColors = new Uint32Array(cols.count);\n for (let i = 0; i < cols.count; i++) {\n const v = values[i];\n if (!Number.isFinite(v) || !Number.isFinite(cols.y[i])) continue;\n // 0 means \"no cell\": a fully transparent color packs to 0 as well\n cellColors[i] = packColor(rampColor(colorScale, (v - lo) / span));\n }\n }\n const id = s.id ?? String(index);\n return {\n index,\n key,\n id,\n name: s.name ?? `${labels.series} ${index + 1}`,\n type,\n color,\n colorCss: toCss(color),\n lineWidth:\n s.lineWidth ??\n (type === \"candlestick\" ? 1 : type === \"boxplot\" ? 1.5 : 2),\n pointSize: s.pointSize ?? (type === \"boxplot\" ? 6 : 8),\n opacity:\n s.opacity ??\n (type === \"area\"\n ? 0.28\n : type === \"scatter\"\n ? 0.78\n : type === \"boxplot\"\n ? 0.22\n : 1),\n hidden: !!s.hidden || hidden.has(id),\n showLabels: !!s.showLabels,\n curve: s.curve ?? \"linear\",\n cols,\n raw: cols,\n yAxis: s.yAxis === \"right\" && !horizontal ? \"right\" : \"left\",\n floating: type === \"bar\" && !!cols.y0,\n barOffset: 0,\n barHalfWidth: 0,\n barBase: null,\n barTop: null,\n stackBase: null,\n stackTop: null,\n pointColors,\n upColor:\n type === \"candlestick\"\n ? resolve(s.upColor ?? DEFAULT_UP, [0.09, 0.64, 0.29, 1])\n : color,\n downColor:\n type === \"candlestick\"\n ? resolve(s.downColor ?? DEFAULT_DOWN, [0.86, 0.15, 0.15, 1])\n : color,\n cellColors,\n cellHalf: { x: 0.5, y: 0.5 },\n colorScale,\n valueRange,\n radius: s.radius ?? (type === \"heatmap\" ? 2 : type === \"boxplot\" ? 0 : 3),\n format: s.format,\n valueName: s.valueName,\n };\n });\n\n const visible = series.filter((s) => !s.hidden);\n const allScatter =\n series.length > 0 &&\n series.every((s) => s.type === \"scatter\" || s.type === \"heatmap\");\n\n // Bars and box plots: groups (one slot per stack) and stacking; floating\n // bars (with starts) are drawn from their starts\n const slotted = visible.filter(\n (s) => s.type === \"bar\" || s.type === \"boxplot\",\n );\n const bars = visible.filter((s) => s.type === \"bar\");\n const band = bandOf(slotted, \"x\", xType === \"category\");\n if (slotted.length) {\n const slots = new Map<string, number>();\n const stackId = (s: SeriesModel) =>\n input[s.index].stack ?? `\\u0000${s.key}`;\n for (const s of slotted) {\n if (!slots.has(stackId(s))) slots.set(stackId(s), slots.size);\n }\n let share = 0;\n for (const s of slotted) {\n const w = input[s.index].barWidth;\n if (w !== undefined && w > share) share = Math.min(1, w);\n }\n const group = band * (share || (slots.size > 1 ? 0.78 : 0.62));\n const slotWidth = group / slots.size;\n for (const s of slotted) {\n const slot = slots.get(stackId(s)) ?? 0;\n s.barOffset = -group / 2 + slotWidth * (slot + 0.5);\n s.barHalfWidth = (slotWidth / 2) * (slots.size > 1 ? 0.86 : 1);\n }\n const stackedBars = bars.filter((s) => !s.floating);\n const stacked = stackValues(\n stackedBars.map((s) => ({ s, stack: stackId(s) })),\n false,\n );\n const percentStacked = percent\n ? stackValues(\n stackedBars\n .filter((s) => input[s.index].stack !== undefined)\n .map((s) => ({ s, stack: stackId(s) })),\n true,\n )\n : [];\n let p = 0;\n stackedBars.forEach((s, k) => {\n const values =\n percent && input[s.index].stack !== undefined\n ? percentStacked[p++]\n : stacked[k];\n s.barBase = values.base;\n s.barTop = values.top;\n });\n for (const s of bars) {\n const { y, y0, count } = s.cols;\n if (!s.floating || !y0) continue;\n const base = new Float64Array(count);\n const top = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n const valid = Number.isFinite(y[i]);\n base[i] = valid ? (Number.isFinite(y0[i]) ? y0[i] : 0) : NaN;\n top[i] = valid ? y[i] : NaN;\n }\n s.barBase = base;\n s.barTop = top;\n }\n }\n\n // Range areas: filled down to their lower edges\n for (const s of visible) {\n if (s.type === \"area\" && s.cols.y0 && input[s.index].stack === undefined)\n s.stackBase = s.cols.y0;\n }\n\n // Stacked lines / areas\n const stackedLines = visible.filter(\n (s) =>\n (s.type === \"line\" || s.type === \"area\") &&\n input[s.index].stack !== undefined,\n );\n if (stackedLines.length) {\n const values = stackValues(\n stackedLines.map((s) => ({ s, stack: input[s.index].stack ?? \"\" })),\n percent,\n );\n stackedLines.forEach((s, k) => {\n s.stackBase = values[k].base;\n s.stackTop = values[k].top;\n });\n }\n\n // Candlesticks: one band per x, bodies of 60%\n const candles = visible.filter((s) => s.type === \"candlestick\");\n const candleBand = bandOf(candles, \"x\", xType === \"category\");\n for (const s of candles) s.barHalfWidth = candleBand * 0.3;\n\n // Heatmaps: cells of the size of the smallest step\n const heatmaps = visible.filter((s) => s.type === \"heatmap\");\n if (heatmaps.length) {\n const cx = bandOf(heatmaps, \"x\", xType === \"category\") / 2;\n const cy = bandOf(heatmaps, \"y\", yType === \"category\") / 2;\n for (const s of heatmaps) s.cellHalf = { x: cx, y: cy };\n }\n\n // X range\n const xOpts = options.xAxis;\n let xRange: Range;\n if (xType === \"category\") {\n xRange = [-0.5, Math.max(1, categories.length) - 0.5];\n } else {\n const values: number[] = [];\n for (const s of visible) {\n values.push(s.cols.xMin, s.cols.xMax);\n const pad =\n s.type === \"bar\" || s.type === \"boxplot\"\n ? band / 2\n : s.type === \"candlestick\"\n ? candleBand / 2\n : s.type === \"heatmap\"\n ? s.cellHalf.x\n : 0;\n if (pad) values.push(s.cols.xMin - pad, s.cols.xMax + pad);\n }\n xRange = ensureSpan(\n ...extent(values),\n xType === \"time\" ? [Date.now() - 86400000, Date.now()] : [0, 1],\n );\n const pointsOnly = series.every((s) => s.type === \"scatter\");\n if (pointsOnly) {\n const pad = (xRange[1] - xRange[0]) * 0.04;\n xRange = [xRange[0] - pad, xRange[1] + pad];\n }\n const nice = xOpts?.nice ?? (pointsOnly && xType === \"linear\");\n if (nice && xType === \"linear\") {\n xRange = niceDomain(xRange[0], xRange[1], xOpts?.tickCount ?? 6);\n }\n }\n if (xOpts?.min !== undefined) xRange[0] = xOpts.min;\n if (xOpts?.max !== undefined) xRange[1] = xOpts.max;\n xRange = ensureSpan(xRange[0], xRange[1]);\n\n // Y range (left axis: the series of the right axis are mapped onto it)\n const valuesOf = (list: SeriesModel[], zero: boolean | undefined) => {\n const values: number[] = [];\n for (const s of list) {\n if (s.type === \"bar\" && s.barBase && s.barTop) {\n values.push(...extent(s.barBase), ...extent(s.barTop));\n } else if (s.stackBase && s.stackTop) {\n values.push(...extent(s.stackBase), ...extent(s.stackTop));\n } else if (s.type === \"heatmap\") {\n values.push(s.cols.yMin - s.cellHalf.y, s.cols.yMax + s.cellHalf.y);\n } else {\n values.push(s.cols.yMin, s.cols.yMax);\n }\n }\n const listBars = list.filter((s) => s.type === \"bar\");\n if (listBars.some((s) => !s.floating) || zero) values.push(0);\n if (listBars.some((s) => s.showLabels)) {\n // room for the value labels above the tallest bar\n const [lo, hi] = extent(values);\n if (hi > 0) values.push(hi + (hi - Math.min(0, lo)) * 0.1);\n if (lo < 0) values.push(lo - (Math.max(0, hi) - lo) * 0.1);\n }\n return values;\n };\n const leftVisible = visible.filter((s) => s.yAxis === \"left\");\n const leftSeries = leftVisible.length ? leftVisible : visible;\n const leftBars = leftSeries.filter((s) => s.type === \"bar\");\n let yRange: Range;\n if (yType === \"category\") {\n yRange = [-0.5, Math.max(1, yCategories.length) - 0.5];\n } else {\n const yValues = valuesOf(leftSeries, yOpts?.zero);\n const filled =\n leftBars.length > 0 || leftSeries.some((s) => s.type === \"area\");\n yRange = ensureSpan(...extent(yValues));\n if (series.every((s) => s.type === \"scatter\")) {\n const pad = (yRange[1] - yRange[0]) * 0.06;\n yRange = [yRange[0] - pad, yRange[1] + pad];\n } else if (\n (candles.length || leftSeries.some((s) => s.type === \"boxplot\")) &&\n !leftBars.length\n ) {\n // room above / below the wicks and the outliers\n const pad = (yRange[1] - yRange[0]) * 0.04;\n yRange = [yRange[0] - pad, yRange[1] + pad];\n }\n if ((yOpts?.nice ?? !heatmaps.length) && yType === \"linear\") {\n yRange = niceDomain(yRange[0], yRange[1], yOpts?.tickCount ?? 5);\n }\n if (percent && (bars.length || stackedLines.length)) {\n // 100% stacks: exactly 0-100 (or -100-100)\n yRange = [extent(yValues)[0] < 0 ? -100 : 0, 100];\n }\n if (filled && !yOpts?.zero) {\n // bars start at zero: no padding below / above it\n if (yRange[0] < 0 && extent(yValues)[0] >= 0) yRange[0] = 0;\n }\n }\n if (yOpts?.min !== undefined) yRange[0] = yOpts.min;\n if (yOpts?.max !== undefined) yRange[1] = yOpts.max;\n yRange = ensureSpan(yRange[0], yRange[1]);\n\n // Right axis: a range aligned on the left ticks; its series are mapped\n // onto the left axis\n const y2Opts = options.yAxis2;\n let y2: AxisModel | null = null;\n let y2Map: AxisMap | null = null;\n const rightSeries = series.filter((s) => s.yAxis === \"right\");\n if (rightSeries.length && yType !== \"category\") {\n const rightVisible = rightSeries.filter((s) => !s.hidden);\n const values = valuesOf(rightVisible, y2Opts?.zero);\n const [lo, hi] = ensureSpan(...extent(values));\n let domain: Range =\n y2Opts?.nice === false\n ? [lo, hi]\n : alignedDomain(lo, hi, yRange, yOpts?.tickCount ?? 5);\n if (y2Opts?.min !== undefined) domain[0] = y2Opts.min;\n if (y2Opts?.max !== undefined) domain[1] = y2Opts.max;\n domain = ensureSpan(domain[0], domain[1]);\n const scale = (yRange[1] - yRange[0]) / (domain[1] - domain[0]);\n const map: AxisMap = { scale, offset: yRange[0] - domain[0] * scale };\n y2Map = map;\n const f = (v: number) => v * map.scale + map.offset;\n const column = (a: Float64Array | null) => (a ? a.map(f) : null);\n const zero = f(Math.min(Math.max(0, domain[0]), domain[1]));\n for (const s of rightSeries) {\n const rawBase = s.stackBase;\n s.cols = mapColumns(s.raw, map);\n s.barBase = column(s.barBase);\n s.barTop = column(s.barTop);\n s.stackTop = column(s.stackTop);\n s.stackBase =\n rawBase && rawBase === s.raw.y0\n ? s.cols.y0\n : rawBase\n ? column(rawBase)\n : s.type === \"area\"\n ? new Float64Array(s.cols.count).fill(zero)\n : null;\n }\n y2 = axisModel(y2Opts, \"linear\", [], false, locale);\n }\n\n const zoomOption =\n options.interaction === false\n ? false\n : options.interaction === true || options.interaction === undefined\n ? true\n : (options.interaction.zoom ?? true);\n const zoomAxes =\n zoomOption === false\n ? { x: false, y: false }\n : zoomOption === true\n ? { x: true, y: allScatter }\n : { x: zoomOption.includes(\"x\"), y: zoomOption.includes(\"y\") };\n\n const yFormat =\n yOpts?.format ??\n (percent && (bars.length || stackedLines.length)\n ? (v: number) => formatPercent(v, locale)\n : undefined);\n\n return {\n series,\n x: axisModel(xOpts, xType, categories, false, locale),\n y: {\n ...axisModel(yOpts, yType, yCategories, yType !== \"category\", locale),\n format: yFormat,\n },\n y2,\n y2Map,\n horizontal,\n locale,\n labels,\n formatValue: valueFormatter(locale),\n base: { x: xRange, y: yRange },\n allScatter,\n zoom: zoomAxes,\n tooltipMode: tooltipOptions?.mode ?? (allScatter ? \"nearest\" : \"axis\"),\n baseline: Math.min(Math.max(0, yRange[0]), yRange[1]),\n minSpan: {\n x: xType === \"category\" ? 1 : (xRange[1] - xRange[0]) * 1e-7,\n y: yType === \"category\" ? 1 : (yRange[1] - yRange[0]) * 1e-7,\n },\n percent,\n stacks: input.map((s) =>\n s.stack !== undefined &&\n (s.type === \"bar\" || s.type === \"line\" || s.type === \"area\" || !s.type)\n ? `${s.type === \"bar\" ? \"bar\" : \"line\"}:${s.stack}`\n : null,\n ),\n };\n};\n\n/** Y value drawn for a point: its stacked top for stacks, the close for candles */\nexport const plottedY = (s: SeriesModel, i: number): number =>\n s.barTop ? s.barTop[i] : s.stackTop ? s.stackTop[i] : s.cols.y[i];\n\nconst grids = new WeakMap<SeriesColumns, GridIndex>();\n\n/** Spatial index of a scatter series, built on first use and kept with its data */\nexport const gridOf = (s: SeriesModel): GridIndex => {\n let grid = grids.get(s.cols);\n if (!grid) {\n grid = new GridIndex(s.cols.x, s.cols.y, s.cols.count);\n grids.set(s.cols, grid);\n }\n return grid;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"model.js","names":["LOG_MAP","firstX","data","xs","list","i","item","detectXType","datas","x","axisModel","options","gridDefault","definedEntries","out","value","key","extent","min","max","values","v","smallestStep","step","columns","sorted","k","d","bandOf","category","axis","s","stackValues","totals","percent","byX","stack","count","y","t","running","members","base","top","valid","sums","total","b","DEFAULT_UP","DEFAULT_DOWN","hasDateY","precise","nextStep","power","f","alignedDomain","a0","a1","left","stepL","tickStep","n","lo","hi","ensureSpan","niceDomain","start","mapped","mapColumns","map","hit","raw","mapper","column","a","cols","range","add","c","decades","logColumns","rawBase","zero","toPlotY","model","fromPlotY","floorBases","floor","heatPosition","mid","heatmapStops","dark","luminance","theme","scheme","neutral","mixOklab","end","withLightness","side","negative","color","buildModel","resolve","resolver","resolveStaticColor","fallback","input","locale","resolveLocale","tooltipOptions","labels","chartLabels","xType","categories","collectCategories","categoryMap","resolveX","xResolver","name","yOpts","heatmapData","yCategories","collectYCategories","yType","yLog","yCategoryMap","resolveY","resolverKey","horizontal","usedKeys","series","index","entry","cache","normalizeData","type","paletteColor","pointColors","resolved","rgba","colorScale","valueRange","cellColors","colorMidpoint","colorLut","scale","lut","oklabRamp","ramp","connector","id","toCss","hidden","visible","allScatter","slotted","bars","band","slots","stackId","share","w","group","slotWidth","slot","stackedBars","stacked","percentStacked","p","y0","stackedLines","candles","candleBand","heatmaps","cx","cy","xOpts","xRange","pad","pointsOnly","valuesOf","listBars","log","leftVisible","leftSeries","leftBars","yRange","yValues","filled","yBound","y2Opts","y2","y2Map","rightSeries","y2Log","rightVisible","domain","y2Bound","timeline","zoomOption","zoomAxes","yFormat","formatPercent","valueFormatter","plottedY","grids","gridOf","grid","GridIndex"],"sources":["../../../../../../charts/src/engine/model.ts"],"sourcesContent":["// Options -> chart model: normalized data, colors, bar layout, stacks and\n// the full ranges of the axes. Pure (colors go through the theme's resolver).\n\nimport {\n luminance,\n mixOklab,\n oklabRamp,\n resolveStaticColor,\n toCss,\n withLightness,\n type ColorResolver,\n type Rgba,\n} from \"./color\";\nimport {\n collectCategories,\n collectYCategories,\n normalizeData,\n xResolver,\n type SeriesColumns,\n type YResolver,\n} from \"./data\";\nimport { formatPercent, valueFormatter } from \"./format\";\nimport { chartLabels } from \"./labels\";\nimport { resolveLocale } from \"./locale\";\nimport { ensureSpan, niceDomain, tickStep } from \"./scale\";\nimport { GridIndex } from \"./spatial\";\nimport type { ChartTheme } from \"./theme\";\nimport type {\n ChartAxisOptions,\n ChartAxisType,\n ChartColorScheme,\n ChartCurve,\n ChartOptions,\n ChartSeries,\n ChartSeriesData,\n ChartLabels,\n ChartSeriesType,\n ChartTimeZone,\n} from \"./types\";\nimport type { Range } from \"./viewport\";\n\nexport interface AxisModel {\n type: ChartAxisType;\n reverse: boolean;\n categories: string[];\n title?: string;\n format?: (value: number) => string;\n grid: boolean;\n visible: boolean;\n tickCount?: number;\n /** Locale of the tick and tooltip labels (historical English texts when omitted) */\n locale?: string;\n /** Calendar of a time axis */\n timeZone?: ChartTimeZone;\n}\n\nexport interface SeriesModel {\n index: number;\n /** Key of the GPU resources and of the data cache */\n key: string;\n id: string;\n name: string;\n type: ChartSeriesType;\n color: Rgba;\n colorCss: string;\n lineWidth: number;\n pointSize: number;\n opacity: number;\n hidden: boolean;\n showLabels: boolean;\n curve: ChartCurve;\n /**\n * Plotted columns: the data, mapped onto the left axis for the series of\n * the right axis (`raw` keeps the values of the data)\n */\n cols: SeriesColumns;\n /** Columns of the data (shown in tooltips and labels) */\n raw: SeriesColumns;\n /** Value axis of the series */\n yAxis: \"left\" | \"right\";\n /** Bars with a start (`y0`): drawn from it, never stacked */\n floating: boolean;\n /** Bars / candlesticks: x offset of the series inside a group and half of the bar width */\n barOffset: number;\n barHalfWidth: number;\n /** Bars: bottom / top of every bar (stacks included) */\n barBase: Float64Array | null;\n barTop: Float64Array | null;\n /** Stacked lines / areas: bottom / top of every point */\n stackBase: Float64Array | null;\n stackTop: Float64Array | null;\n /** Scatter / bar: resolved per-point colors */\n pointColors: (Rgba | undefined)[] | null;\n /** Candlesticks: colors of the rising / falling candles */\n upColor: Rgba;\n downColor: Rgba;\n /** Heatmaps: packed color of every cell (0 = no cell) and half of a cell, in data units */\n cellColors: Uint32Array | null;\n cellHalf: { x: number; y: number };\n /** Heatmaps: ramp of the colors and the values at its ends */\n colorScale: Rgba[];\n valueRange: Range;\n /** Heatmaps: value at the middle of the ramp (`null`: linear over the range) */\n colorMidpoint: number | null;\n /** Heatmaps: 256 packed colors along the ramp (OKLab) */\n colorLut: Uint32Array | null;\n /** Hit tests and tooltips include the series */\n tooltip: boolean;\n /** Box plots: outlier rings or dots, and their diameter */\n outlierShape: \"hollow\" | \"filled\";\n outlierSize: number;\n /** Bars: lines from the end of every bar to the next one */\n connector: { color: Rgba; dash: number[]; width: number } | null;\n /** Corner radius in CSS pixels (bars, heatmap cells) */\n radius: number;\n /** Tooltip format of the values */\n format?: (value: number) => string;\n /** Scatter: name of the `value` of the points */\n valueName?: string;\n}\n\n/**\n * Map of the values of a series onto the plotted (left axis) units:\n * `left = (log ? log10(value) : value) * scale + offset`\n */\nexport interface AxisMap {\n scale: number;\n offset: number;\n /** Logarithmic axis: the values are plotted as their base-10 logarithm */\n log?: boolean;\n}\n\n/** Plotted units of a log axis: the base-10 logarithm of the values */\nconst LOG_MAP: AxisMap = { scale: 1, offset: 0, log: true };\n\nexport interface ChartModel {\n series: SeriesModel[];\n x: AxisModel;\n y: AxisModel;\n /** Right value axis (`yAxis2`), `null` when no series uses it */\n y2: AxisModel | null;\n /** Right axis values -> left axis values */\n y2Map: AxisMap | null;\n /** The x axis runs down the left side, the values along the bottom */\n horizontal: boolean;\n /** Resolved locale (`locale` option, else the page language) */\n locale: string;\n /** Texts of the locale with the `labels` overrides */\n labels: ChartLabels;\n /** Tooltip value of the locale (series without `format`) */\n formatValue: (value: number) => string;\n /** Full ranges (zoomed out) */\n base: { x: Range; y: Range };\n /** Every series is a scatter (or a heatmap): nearest tooltips, xy zoom */\n allScatter: boolean;\n zoom: { x: boolean; y: boolean };\n tooltipMode: \"nearest\" | \"axis\" | \"item\";\n /** Y value the areas are filled to */\n baseline: number;\n /** Smallest zoomed spans */\n minSpan: { x: number; y: number };\n /** Stacks are scaled to 100% */\n percent: boolean;\n /** Stack id of every series (`null` when not stacked) */\n stacks: (string | null)[];\n}\n\nexport interface DataCacheEntry {\n data: ChartSeriesData;\n resolverKey: string;\n cols: SeriesColumns;\n}\n\nexport type DataCache = Map<string, DataCacheEntry>;\n\nconst firstX = (data: ChartSeriesData): unknown => {\n if (typeof data === \"object\" && data !== null && !(\"length\" in data)) {\n const xs = (data as { x?: ArrayLike<unknown> }).x;\n return xs && xs.length ? xs[0] : undefined;\n }\n const list = data as ArrayLike<unknown>;\n for (let i = 0; i < Math.min(list.length, 8); i++) {\n const item = list[i];\n if (Array.isArray(item)) return item[0];\n if (item && typeof item === \"object\") return (item as { x?: unknown }).x;\n }\n return undefined;\n};\n\n/** Axis type when not given: dates -> time, strings -> category */\nexport const detectXType = (\n datas: readonly ChartSeriesData[],\n): ChartAxisType => {\n for (const data of datas) {\n const x = firstX(data);\n if (x instanceof Date) return \"time\";\n if (typeof x === \"string\") return \"category\";\n }\n return \"linear\";\n};\n\nconst axisModel = (\n options: ChartAxisOptions | undefined,\n type: ChartAxisType,\n categories: string[],\n gridDefault: boolean,\n locale: string,\n): AxisModel => ({\n type,\n reverse: !!options?.reverse,\n categories,\n title: options?.title,\n format: options?.format,\n grid: options?.grid ?? gridDefault,\n visible: options?.visible ?? true,\n tickCount: options?.tickCount,\n locale,\n timeZone: options?.timeZone ?? \"local\",\n});\n\n/** Defined entries only (`{ open: undefined }` keeps the built-in text) */\nconst definedEntries = <T extends object>(value: T | undefined): Partial<T> => {\n const out: Partial<T> = {};\n if (!value) return out;\n for (const key of Object.keys(value) as (keyof T)[]) {\n if (value[key] !== undefined) out[key] = value[key];\n }\n return out;\n};\n\nconst extent = (values: ArrayLike<number>): Range => {\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < values.length; i++) {\n const v = values[i];\n if (!Number.isFinite(v)) continue;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n return [min, max];\n};\n\n/** Smallest positive gap between consecutive values (bar width on numeric axes) */\nconst smallestStep = (columns: ArrayLike<number>[], sorted: boolean[]) => {\n let step = Infinity;\n columns.forEach((values, k) => {\n const xs = sorted[k] ? values : Float64Array.from(values).sort();\n for (let i = 1; i < xs.length; i++) {\n const d = xs[i] - xs[i - 1];\n if (d > 0 && d < step) step = d;\n }\n });\n return step;\n};\n\nconst bandOf = (list: SeriesModel[], axis: \"x\" | \"y\", category: boolean) => {\n if (category) return 1;\n const step = smallestStep(\n list.map((s) => (axis === \"x\" ? s.cols.x : s.cols.y)),\n list.map((s) => axis === \"x\" && s.cols.sorted),\n );\n return Number.isFinite(step) ? step : 1;\n};\n\n/**\n * Stacks the y values of series sharing a stack id (positive and negative\n * values separately); `percent` scales every stack to 100 at each x\n */\nconst stackValues = (\n list: { s: SeriesModel; stack: string }[],\n percent: boolean,\n): { base: Float64Array; top: Float64Array }[] => {\n const totals = new Map<string, Map<number, [number, number]>>();\n if (percent) {\n for (const { s, stack } of list) {\n let byX = totals.get(stack);\n if (!byX) totals.set(stack, (byX = new Map()));\n const { x, y, count } = s.cols;\n for (let i = 0; i < count; i++) {\n const v = y[i];\n if (!Number.isFinite(v)) continue;\n const t = byX.get(x[i]) ?? [0, 0];\n if (v >= 0) t[0] += v;\n else t[1] -= v;\n byX.set(x[i], t);\n }\n }\n }\n const running = new Map<string, Map<number, [number, number]>>();\n const members = new Map<string, number>();\n for (const { stack } of list)\n members.set(stack, (members.get(stack) ?? 0) + 1);\n return list.map(({ s, stack }) => {\n const { x, y, count } = s.cols;\n if (!percent && members.get(stack) === 1) {\n // alone in its stack (e.g. grouped bars): from zero, no bookkeeping\n const base = new Float64Array(count);\n const top = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n const v = y[i];\n const valid = Number.isFinite(v);\n base[i] = valid ? 0 : NaN;\n top[i] = valid ? v : NaN;\n }\n return { base, top };\n }\n let byX = running.get(stack);\n if (!byX) running.set(stack, (byX = new Map()));\n const sums = totals.get(stack);\n const base = new Float64Array(count);\n const top = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n let v = y[i];\n if (!Number.isFinite(v)) {\n base[i] = NaN;\n top[i] = NaN;\n continue;\n }\n if (sums) {\n const t = sums.get(x[i]);\n const total = t ? (v >= 0 ? t[0] : t[1]) : 0;\n v = total > 0 ? (v / total) * 100 : 0;\n }\n const t = byX.get(x[i]) ?? [0, 0];\n const b = v >= 0 ? t[0] : t[1];\n base[i] = b;\n top[i] = b + v;\n if (v >= 0) t[0] += v;\n else t[1] += v;\n byX.set(x[i], t);\n }\n return { base, top };\n });\n};\n\nconst DEFAULT_UP = \"var(--success-color, #16a34a)\";\nconst DEFAULT_DOWN = \"var(--danger-color, #dc2626)\";\n\n/** Dates in the y values (or starts) of objects: a time value axis */\nconst hasDateY = (datas: readonly ChartSeriesData[]): boolean => {\n for (const data of datas) {\n if (typeof data !== \"object\" || data === null || !(\"length\" in data))\n continue;\n const list = data as ArrayLike<unknown>;\n for (let i = 0; i < Math.min(list.length, 8); i++) {\n const item = list[i];\n if (item && typeof item === \"object\" && !Array.isArray(item)) {\n const d = item as { y?: unknown; y0?: unknown };\n if (d.y instanceof Date || d.y0 instanceof Date) return true;\n }\n }\n }\n return false;\n};\n\nconst precise = (v: number) => Number(v.toPrecision(12));\n\n/** Next step of the 1, 2, 5 × 10^k sequence */\nconst nextStep = (step: number) => {\n const power = 10 ** Math.floor(Math.log10(step) + 1e-9);\n const f = step / power;\n return (f < 1.5 ? 2 : f < 3.5 ? 5 : 10) * power;\n};\n\n/**\n * Range of the right axis covering [lo, hi] with as many tick intervals as\n * the left range has (its ticks then line up with the left grid)\n */\nexport const alignedDomain = (\n lo: number,\n hi: number,\n left: Range,\n count: number,\n): Range => {\n const [a0, a1] = left;\n const stepL = tickStep(a0, a1, count);\n const n = stepL > 0 ? Math.round((a1 - a0) / stepL) : 0;\n [lo, hi] = ensureSpan(lo, hi);\n if (n < 1 || Math.abs(n * stepL - (a1 - a0)) > stepL * 1e-6) {\n return niceDomain(lo, hi, count);\n }\n let step = tickStep(lo, hi, n);\n for (let k = 0; k < 40 && step > 0; k++) {\n const start = Math.floor(lo / step + 1e-9) * step;\n if (start + n * step >= hi - step * 1e-9) {\n return [precise(start), precise(start + n * step)];\n }\n step = nextStep(step);\n }\n return niceDomain(lo, hi, count);\n};\n\nconst mapped = new WeakMap<\n SeriesColumns,\n { key: string; cols: SeriesColumns }\n>();\n\n/** Columns of a right-axis series in left axis units (cached with the data) */\nconst mapColumns = (raw: SeriesColumns, map: AxisMap): SeriesColumns => {\n const key = `${map.scale},${map.offset},${!!map.log}`;\n const hit = mapped.get(raw);\n if (hit && hit.key === key) return hit.cols;\n const f = mapper(map);\n const column = (a: Float64Array | null) => (a ? a.map(f) : null);\n const cols: SeriesColumns = {\n ...raw,\n y: raw.y.map(f),\n open: column(raw.open),\n high: column(raw.high),\n low: column(raw.low),\n y0: column(raw.y0),\n q1: column(raw.q1),\n q3: column(raw.q3),\n outliers: raw.outliers ? raw.outliers.map((list) => list?.map(f)) : null,\n };\n if (map.log) {\n // zeros and negatives have no logarithm: the extent of the others\n const range: Range = [Infinity, -Infinity];\n const add = (a: ArrayLike<number> | null | undefined) => {\n if (!a) return;\n for (let i = 0; i < a.length; i++) {\n const v = a[i];\n if (!Number.isFinite(v)) continue;\n if (v < range[0]) range[0] = v;\n if (v > range[1]) range[1] = v;\n }\n };\n for (const c of [cols.y, cols.y0, cols.high, cols.low, cols.q1, cols.q3])\n add(c);\n cols.outliers?.forEach((list) => add(list));\n cols.yMin = range[0] <= range[1] ? range[0] : NaN;\n cols.yMax = range[0] <= range[1] ? range[1] : NaN;\n } else {\n const lo = f(raw.yMin);\n const hi = f(raw.yMax);\n cols.yMin = Math.min(lo, hi);\n cols.yMax = Math.max(lo, hi);\n }\n mapped.set(raw, { key, cols });\n return cols;\n};\n\n/** A log range widened to whole decades (`[0.3, 2.4]` -> `[0, 3]`) */\nconst decades = (range: Range): Range => {\n const lo = Math.floor(range[0] + 1e-9);\n const hi = Math.ceil(range[1] - 1e-9);\n return [lo, hi > lo ? hi : lo + 1];\n};\n\n/**\n * Plots a series through a map: its columns, bars, stacks and lower\n * edges (bars / areas of the right axis start at `zero`)\n */\nconst logColumns = (s: SeriesModel, map: AxisMap, zero = -Infinity) => {\n const f = mapper(map);\n const column = (a: Float64Array | null) => (a ? a.map(f) : null);\n const rawBase = s.stackBase;\n s.cols = mapColumns(s.raw, map);\n s.barBase =\n s.barBase && !s.floating\n ? s.barBase.map((v) => (v === 0 ? (map.log ? -Infinity : f(0)) : f(v)))\n : column(s.barBase);\n s.barTop = column(s.barTop);\n s.stackTop = column(s.stackTop);\n s.stackBase =\n rawBase && rawBase === s.raw.y0\n ? s.cols.y0\n : rawBase\n ? column(rawBase)\n : s.type === \"area\"\n ? new Float64Array(s.cols.count).fill(zero)\n : null;\n};\n\n/** Value -> plotted units of a map (`-Infinity` for 0 on log axes) */\nconst mapper =\n (map: AxisMap) =>\n (v: number): number =>\n (map.log ? Math.log10(v) : v) * map.scale + map.offset;\n\n/** Value of the y axis -> plotted y (the logarithm on log axes) */\nexport const toPlotY = (model: { y: AxisModel }, value: number): number =>\n model.y.type === \"log\" ? Math.log10(value) : value;\n\n/** Plotted y -> value of the y axis */\nexport const fromPlotY = (model: { y: AxisModel }, value: number): number =>\n model.y.type === \"log\" ? 10 ** value : value;\n\n/** Replaces the bases of bars / areas on log axes (`-Infinity`) by the bottom of the axis */\nconst floorBases = (s: SeriesModel, floor: number) => {\n for (const a of [s.barBase, s.stackBase]) {\n if (!a) continue;\n for (let i = 0; i < a.length; i++) if (a[i] === -Infinity) a[i] = floor;\n }\n};\n\n/** Position (0-1) of a heatmap value on its color ramp */\nexport const heatPosition = (\n s: Pick<SeriesModel, \"valueRange\" | \"colorMidpoint\">,\n v: number,\n): number => {\n const [lo, hi] = s.valueRange;\n const mid = s.colorMidpoint;\n let t: number;\n if (mid !== null && mid > lo && mid < hi) {\n t =\n v < mid\n ? ((v - lo) / (mid - lo)) * 0.5\n : 0.5 + ((v - mid) / (hi - mid)) * 0.5;\n } else {\n t = (v - lo) / (hi - lo || 1);\n }\n return t < 0 ? 0 : t > 1 ? 1 : t;\n};\n\n/**\n * Built-in ramps of heatmaps, perceptual (OKLab) and theme-aware: light\n * themes go from a near-white tint to a deep hue, dark themes from a dark\n * tint of the surface to a bright saturated hue; diverging ramps meet in a\n * neutral middle\n */\nexport const heatmapStops = (\n scheme: ChartColorScheme,\n color: Rgba,\n theme: ChartTheme,\n negative: Rgba,\n): Rgba[] => {\n const dark = luminance(theme.background) < 0.4;\n if (scheme === \"diverging\") {\n const neutral = mixOklab(\n theme.surface,\n theme.textMuted,\n dark ? 0.12 : 0.08,\n );\n const end = (c: Rgba) =>\n dark ? withLightness(c, 0.7, 1.25) : withLightness(c, 0.5, 1.05);\n const side = (c: Rgba) => mixOklab(neutral, end(c), 0.5);\n return [end(negative), side(negative), neutral, side(color), end(color)];\n }\n return dark\n ? [\n mixOklab(theme.surface, color, 0.14),\n withLightness(color, 0.46, 0.95),\n withLightness(color, 0.64, 1.2),\n withLightness(color, 0.8, 1.15),\n ]\n : [\n mixOklab(theme.surface, color, 0.06),\n withLightness(color, 0.8, 0.6),\n withLightness(color, 0.58, 1),\n withLightness(color, 0.36, 0.9),\n ];\n};\n\nexport const buildModel = (\n options: ChartOptions,\n theme: ChartTheme,\n hidden: ReadonlySet<string>,\n cache: DataCache,\n resolver: ColorResolver | null = null,\n): ChartModel => {\n const resolve: ColorResolver =\n resolver ??\n theme.resolve ??\n ((value, fallback) => resolveStaticColor(value, {}, fallback));\n const input = options.series;\n // resolved at every build: a page language switch shows on the next update\n const locale = resolveLocale(options.locale);\n const tooltipOptions =\n typeof options.tooltip === \"object\" ? options.tooltip : undefined;\n const labels = chartLabels(locale, {\n ...definedEntries(tooltipOptions?.labels),\n ...definedEntries(options.labels),\n });\n const datas = input.map((s) => s.data);\n const xType = options.xAxis?.type ?? detectXType(datas);\n const categories =\n xType === \"category\"\n ? [...(options.xAxis?.categories ?? collectCategories(datas))]\n : [];\n const categoryMap = new Map(categories.map((c, i) => [c, i]));\n const resolveX = xResolver(xType, (name) => categoryMap.get(name) ?? NaN);\n\n // category y axis (heatmap rows): explicit, or detected from string y values\n const yOpts = options.yAxis;\n const heatmapData = input\n .filter((s) => s.type === \"heatmap\")\n .map((s) => s.data);\n const yCategories =\n yOpts?.type === \"category\" || (!yOpts?.type && heatmapData.length)\n ? [...(yOpts?.categories ?? collectYCategories(heatmapData))]\n : [];\n const yType: ChartAxisType =\n yOpts?.type === \"category\" || yCategories.length\n ? \"category\"\n : yOpts?.type === \"time\" || (!yOpts?.type && hasDateY(datas))\n ? \"time\"\n : yOpts?.type === \"log\"\n ? \"log\"\n : \"linear\";\n const yLog = yType === \"log\";\n const yCategoryMap = new Map(yCategories.map((c, i) => [c, i]));\n const resolveY: YResolver = (v) =>\n typeof v === \"number\"\n ? v\n : typeof v === \"string\"\n ? yType === \"category\"\n ? (yCategoryMap.get(v) ?? NaN)\n : yType === \"time\"\n ? Date.parse(v)\n : Number(v)\n : v instanceof Date\n ? v.getTime()\n : NaN;\n const resolverKey = `${xType}|${categories.join(\"\\u0001\")}|${yType}|${yCategories.join(\"\\u0001\")}`;\n const percent = options.stackMode === \"percent\";\n const horizontal = options.orientation === \"horizontal\";\n\n const usedKeys = new Set<string>();\n const series: SeriesModel[] = input.map((s: ChartSeries, index) => {\n let key = s.id ?? `#${index}`;\n while (usedKeys.has(key)) key += \"'\";\n usedKeys.add(key);\n let entry = cache.get(key);\n if (!entry || entry.data !== s.data || entry.resolverKey !== resolverKey) {\n entry = {\n data: s.data,\n resolverKey,\n cols: normalizeData(s.data, resolveX, resolveY),\n };\n cache.set(key, entry);\n }\n const type = s.type ?? \"line\";\n const paletteColor = theme.palette[index % theme.palette.length];\n const color = s.color ? resolve(s.color, paletteColor) : paletteColor;\n const cols = entry.cols;\n let pointColors: (Rgba | undefined)[] | null = null;\n if (\n (type === \"scatter\" || type === \"bar\" || type === \"boxplot\") &&\n cols.colors\n ) {\n const resolved = new Map<string, Rgba>();\n pointColors = cols.colors.map((c) => {\n if (c === undefined) return undefined;\n let rgba = resolved.get(c);\n if (!rgba) resolved.set(c, (rgba = resolve(c, color)));\n return rgba;\n });\n }\n let colorScale: Rgba[] = [];\n let valueRange: Range = [0, 1];\n let cellColors: Uint32Array | null = null;\n let colorMidpoint: number | null = null;\n let colorLut: Uint32Array | null = null;\n if (type === \"heatmap\") {\n const scale = s.colorScale;\n const scheme: ChartColorScheme =\n scale === \"diverging\" ? \"diverging\" : \"sequential\";\n colorScale =\n typeof scale === \"object\" && scale.length\n ? scale.map((c) => resolve(c, color))\n : heatmapStops(\n scheme,\n color,\n theme,\n resolve(DEFAULT_DOWN, [0.86, 0.15, 0.15, 1]),\n );\n valueRange = s.valueRange\n ? [s.valueRange[0], s.valueRange[1]]\n : [cols.valueMin, cols.valueMax];\n if (!Number.isFinite(valueRange[0])) valueRange = [0, 1];\n const [lo, hi] = valueRange;\n colorMidpoint =\n s.colorMidpoint ??\n (scheme === \"diverging\" && typeof scale !== \"object\"\n ? lo < 0 && hi > 0\n ? 0\n : (lo + hi) / 2\n : null);\n const lut = oklabRamp(colorScale);\n colorLut = lut;\n const values = cols.value ?? cols.y;\n const ramp = { valueRange, colorMidpoint };\n cellColors = new Uint32Array(cols.count);\n for (let i = 0; i < cols.count; i++) {\n const v = values[i];\n if (!Number.isFinite(v) || !Number.isFinite(cols.y[i])) continue;\n // 0 means \"no cell\": the ramp never packs to 0\n cellColors[i] = lut[Math.round(heatPosition(ramp, v) * 255)];\n }\n }\n const connector = s.connector\n ? typeof s.connector === \"object\"\n ? s.connector\n : {}\n : null;\n const id = s.id ?? String(index);\n return {\n index,\n key,\n id,\n name: s.name ?? `${labels.series} ${index + 1}`,\n type,\n color,\n colorCss: toCss(color),\n lineWidth:\n s.lineWidth ??\n (type === \"candlestick\" ? 1 : type === \"boxplot\" ? 1.5 : 2),\n pointSize: s.pointSize ?? (type === \"boxplot\" ? 6 : 8),\n opacity:\n s.opacity ??\n (type === \"area\"\n ? 0.28\n : type === \"scatter\"\n ? 0.78\n : type === \"boxplot\"\n ? 0.22\n : 1),\n hidden: !!s.hidden || hidden.has(id),\n showLabels: !!s.showLabels,\n curve: s.curve ?? \"linear\",\n cols,\n raw: cols,\n yAxis: s.yAxis === \"right\" && !horizontal ? \"right\" : \"left\",\n floating: type === \"bar\" && !!cols.y0,\n barOffset: 0,\n barHalfWidth: 0,\n barBase: null,\n barTop: null,\n stackBase: null,\n stackTop: null,\n pointColors,\n upColor:\n type === \"candlestick\"\n ? resolve(s.upColor ?? DEFAULT_UP, [0.09, 0.64, 0.29, 1])\n : color,\n downColor:\n type === \"candlestick\"\n ? resolve(s.downColor ?? DEFAULT_DOWN, [0.86, 0.15, 0.15, 1])\n : color,\n cellColors,\n cellHalf: { x: 0.5, y: 0.5 },\n colorScale,\n valueRange,\n colorMidpoint,\n colorLut,\n tooltip: s.tooltip !== false,\n outlierShape: s.outlierShape ?? \"hollow\",\n outlierSize: s.outlierSize ?? s.pointSize ?? 7,\n connector:\n connector && type === \"bar\"\n ? {\n color: connector.color\n ? resolve(connector.color, theme.textMuted)\n : theme.textMuted,\n dash: [...(connector.dash ?? [3, 3])],\n width: connector.width ?? 1,\n }\n : null,\n radius: s.radius ?? (type === \"heatmap\" ? 2 : type === \"boxplot\" ? 0 : 3),\n format: s.format,\n valueName: s.valueName,\n };\n });\n\n const visible = series.filter((s) => !s.hidden);\n const allScatter =\n series.length > 0 &&\n series.every((s) => s.type === \"scatter\" || s.type === \"heatmap\");\n\n // Bars and box plots: groups (one slot per stack) and stacking; floating\n // bars (with starts) are drawn from their starts\n const slotted = visible.filter(\n (s) => s.type === \"bar\" || s.type === \"boxplot\",\n );\n const bars = visible.filter((s) => s.type === \"bar\");\n const band = bandOf(slotted, \"x\", xType === \"category\");\n if (slotted.length) {\n const slots = new Map<string, number>();\n const stackId = (s: SeriesModel) =>\n input[s.index].stack ?? `\\u0000${s.key}`;\n for (const s of slotted) {\n if (!slots.has(stackId(s))) slots.set(stackId(s), slots.size);\n }\n let share = 0;\n for (const s of slotted) {\n const w = input[s.index].barWidth;\n if (w !== undefined && w > share) share = Math.min(1, w);\n }\n const group = band * (share || (slots.size > 1 ? 0.78 : 0.62));\n const slotWidth = group / slots.size;\n for (const s of slotted) {\n const slot = slots.get(stackId(s)) ?? 0;\n s.barOffset = -group / 2 + slotWidth * (slot + 0.5);\n s.barHalfWidth = (slotWidth / 2) * (slots.size > 1 ? 0.86 : 1);\n }\n const stackedBars = bars.filter((s) => !s.floating);\n const stacked = stackValues(\n stackedBars.map((s) => ({ s, stack: stackId(s) })),\n false,\n );\n const percentStacked = percent\n ? stackValues(\n stackedBars\n .filter((s) => input[s.index].stack !== undefined)\n .map((s) => ({ s, stack: stackId(s) })),\n true,\n )\n : [];\n let p = 0;\n stackedBars.forEach((s, k) => {\n const values =\n percent && input[s.index].stack !== undefined\n ? percentStacked[p++]\n : stacked[k];\n s.barBase = values.base;\n s.barTop = values.top;\n });\n for (const s of bars) {\n const { y, y0, count } = s.cols;\n if (!s.floating || !y0) continue;\n const base = new Float64Array(count);\n const top = new Float64Array(count);\n for (let i = 0; i < count; i++) {\n const valid = Number.isFinite(y[i]);\n base[i] = valid ? (Number.isFinite(y0[i]) ? y0[i] : 0) : NaN;\n top[i] = valid ? y[i] : NaN;\n }\n s.barBase = base;\n s.barTop = top;\n }\n }\n\n // Range areas: filled down to their lower edges\n for (const s of visible) {\n if (s.type === \"area\" && s.cols.y0 && input[s.index].stack === undefined)\n s.stackBase = s.cols.y0;\n }\n\n // Stacked lines / areas\n const stackedLines = visible.filter(\n (s) =>\n (s.type === \"line\" || s.type === \"area\") &&\n input[s.index].stack !== undefined,\n );\n if (stackedLines.length) {\n const values = stackValues(\n stackedLines.map((s) => ({ s, stack: input[s.index].stack ?? \"\" })),\n percent,\n );\n stackedLines.forEach((s, k) => {\n s.stackBase = values[k].base;\n s.stackTop = values[k].top;\n });\n }\n\n // Candlesticks: one band per x, bodies of 60%\n const candles = visible.filter((s) => s.type === \"candlestick\");\n const candleBand = bandOf(candles, \"x\", xType === \"category\");\n for (const s of candles) s.barHalfWidth = candleBand * 0.3;\n\n // Heatmaps: cells of the size of the smallest step\n const heatmaps = visible.filter((s) => s.type === \"heatmap\");\n if (heatmaps.length) {\n const cx = bandOf(heatmaps, \"x\", xType === \"category\") / 2;\n const cy = bandOf(heatmaps, \"y\", yType === \"category\") / 2;\n for (const s of heatmaps) s.cellHalf = { x: cx, y: cy };\n }\n\n // X range\n const xOpts = options.xAxis;\n let xRange: Range;\n if (xType === \"category\") {\n xRange = [-0.5, Math.max(1, categories.length) - 0.5];\n } else {\n const values: number[] = [];\n for (const s of visible) {\n values.push(s.cols.xMin, s.cols.xMax);\n const pad =\n s.type === \"bar\" || s.type === \"boxplot\"\n ? band / 2\n : s.type === \"candlestick\"\n ? candleBand / 2\n : s.type === \"heatmap\"\n ? s.cellHalf.x\n : 0;\n if (pad) values.push(s.cols.xMin - pad, s.cols.xMax + pad);\n }\n xRange = ensureSpan(\n ...extent(values),\n xType === \"time\" ? [Date.now() - 86400000, Date.now()] : [0, 1],\n );\n const pointsOnly = series.every((s) => s.type === \"scatter\");\n if (pointsOnly) {\n const pad = (xRange[1] - xRange[0]) * 0.04;\n xRange = [xRange[0] - pad, xRange[1] + pad];\n }\n const nice = xOpts?.nice ?? (pointsOnly && xType === \"linear\");\n if (nice && xType === \"linear\") {\n xRange = niceDomain(xRange[0], xRange[1], xOpts?.tickCount ?? 6);\n }\n }\n if (xOpts?.min !== undefined) xRange[0] = xOpts.min;\n if (xOpts?.max !== undefined) xRange[1] = xOpts.max;\n xRange = ensureSpan(xRange[0], xRange[1]);\n\n // Log axis: the left series are plotted as logarithms (stacks are summed\n // first); bars and areas from zero start at the bottom of the axis\n if (yLog) {\n for (const s of series) {\n if (s.yAxis === \"right\" || s.type === \"heatmap\") continue;\n logColumns(s, LOG_MAP);\n }\n }\n\n // Y range (left axis: the series of the right axis are mapped onto it)\n const valuesOf = (\n list: SeriesModel[],\n zero: boolean | undefined,\n log = false,\n ) => {\n const values: number[] = [];\n for (const s of list) {\n if (s.type === \"bar\" && s.barBase && s.barTop) {\n values.push(...extent(s.barBase), ...extent(s.barTop));\n } else if (s.stackBase && s.stackTop) {\n values.push(...extent(s.stackBase), ...extent(s.stackTop));\n } else if (s.type === \"heatmap\") {\n values.push(s.cols.yMin - s.cellHalf.y, s.cols.yMax + s.cellHalf.y);\n } else {\n values.push(s.cols.yMin, s.cols.yMax);\n }\n }\n const listBars = list.filter((s) => s.type === \"bar\");\n if (!log && (listBars.some((s) => !s.floating) || zero)) values.push(0);\n if (listBars.some((s) => s.showLabels)) {\n // room for the value labels above the tallest bar\n const [lo, hi] = extent(values);\n if (hi > 0) values.push(hi + (hi - Math.min(0, lo)) * 0.1);\n if (lo < 0) values.push(lo - (Math.max(0, hi) - lo) * 0.1);\n }\n return values;\n };\n const leftVisible = visible.filter((s) => s.yAxis === \"left\");\n const leftSeries = leftVisible.length ? leftVisible : visible;\n const leftBars = leftSeries.filter((s) => s.type === \"bar\");\n let yRange: Range;\n if (yType === \"category\") {\n yRange = [-0.5, Math.max(1, yCategories.length) - 0.5];\n } else {\n const yValues = valuesOf(leftSeries, yOpts?.zero, yLog);\n const filled =\n leftBars.length > 0 || leftSeries.some((s) => s.type === \"area\");\n yRange = ensureSpan(...extent(yValues));\n if (series.every((s) => s.type === \"scatter\")) {\n const pad = (yRange[1] - yRange[0]) * 0.06;\n yRange = [yRange[0] - pad, yRange[1] + pad];\n } else if (\n (candles.length || leftSeries.some((s) => s.type === \"boxplot\")) &&\n !leftBars.length\n ) {\n // room above / below the wicks and the outliers\n const pad = (yRange[1] - yRange[0]) * 0.04;\n yRange = [yRange[0] - pad, yRange[1] + pad];\n }\n if ((yOpts?.nice ?? !heatmaps.length) && yType === \"linear\") {\n yRange = niceDomain(yRange[0], yRange[1], yOpts?.tickCount ?? 5);\n }\n if (yLog && yOpts?.nice !== false) yRange = decades(yRange);\n if (percent && (bars.length || stackedLines.length)) {\n // 100% stacks: exactly 0-100 (or -100-100)\n yRange = [extent(yValues)[0] < 0 ? -100 : 0, 100];\n }\n if (filled && !yOpts?.zero && !yLog) {\n // bars start at zero: no padding below / above it\n if (yRange[0] < 0 && extent(yValues)[0] >= 0) yRange[0] = 0;\n }\n }\n const yBound = (v: number) => (yLog ? Math.log10(v) : v);\n if (yOpts?.min !== undefined) yRange[0] = yBound(yOpts.min);\n if (yOpts?.max !== undefined) yRange[1] = yBound(yOpts.max);\n yRange = ensureSpan(yRange[0], yRange[1]);\n if (yLog) {\n for (const s of series) if (s.yAxis === \"left\") floorBases(s, yRange[0]);\n }\n\n // Right axis: a range aligned on the left ticks; its series are mapped\n // onto the left axis\n const y2Opts = options.yAxis2;\n let y2: AxisModel | null = null;\n let y2Map: AxisMap | null = null;\n const rightSeries = series.filter((s) => s.yAxis === \"right\");\n if (rightSeries.length && yType !== \"category\") {\n const y2Log = y2Opts?.type === \"log\";\n const rightVisible = rightSeries.filter((s) => !s.hidden);\n // log: the extent of the logarithms\n const values = y2Log\n ? rightVisible.flatMap((s) => {\n const c = mapColumns(s.raw, LOG_MAP);\n return [c.yMin, c.yMax];\n })\n : valuesOf(rightVisible, y2Opts?.zero);\n const [lo, hi] = ensureSpan(...extent(values));\n let domain: Range =\n y2Opts?.nice === false\n ? [lo, hi]\n : y2Log\n ? decades([lo, hi])\n : alignedDomain(lo, hi, yRange, yOpts?.tickCount ?? 5);\n const y2Bound = (v: number) => (y2Log ? Math.log10(v) : v);\n if (y2Opts?.min !== undefined) domain[0] = y2Bound(y2Opts.min);\n if (y2Opts?.max !== undefined) domain[1] = y2Bound(y2Opts.max);\n domain = ensureSpan(domain[0], domain[1]);\n const scale = (yRange[1] - yRange[0]) / (domain[1] - domain[0]);\n const map: AxisMap = {\n scale,\n offset: yRange[0] - domain[0] * scale,\n log: y2Log,\n };\n y2Map = map;\n const zero = y2Log\n ? yRange[0]\n : mapper(map)(Math.min(Math.max(0, domain[0]), domain[1]));\n for (const s of rightSeries) {\n logColumns(s, map, zero);\n floorBases(s, yRange[0]);\n }\n y2 = axisModel(y2Opts, y2Log ? \"log\" : \"linear\", [], false, locale);\n }\n\n // range bars on a time axis (Gantt charts): rows are unrelated, the\n // tooltip shows the task under the pointer\n const timeline =\n yType === \"time\" &&\n series.some((s) => s.type === \"bar\") &&\n series.every((s) => (s.type === \"bar\" ? s.floating : s.type === \"scatter\"));\n\n const zoomOption =\n options.interaction === false\n ? false\n : options.interaction === true || options.interaction === undefined\n ? true\n : (options.interaction.zoom ?? true);\n const zoomAxes =\n zoomOption === false\n ? { x: false, y: false }\n : zoomOption === true\n ? { x: true, y: allScatter }\n : { x: zoomOption.includes(\"x\"), y: zoomOption.includes(\"y\") };\n\n const yFormat =\n yOpts?.format ??\n (percent && (bars.length || stackedLines.length)\n ? (v: number) => formatPercent(v, locale)\n : undefined);\n\n return {\n series,\n x: axisModel(xOpts, xType, categories, false, locale),\n y: {\n ...axisModel(yOpts, yType, yCategories, yType !== \"category\", locale),\n format: yFormat,\n },\n y2,\n y2Map,\n horizontal,\n locale,\n labels,\n formatValue: valueFormatter(locale),\n base: { x: xRange, y: yRange },\n allScatter,\n zoom: zoomAxes,\n tooltipMode:\n tooltipOptions?.mode ??\n (allScatter ? \"nearest\" : timeline ? \"item\" : \"axis\"),\n baseline: yLog ? yRange[0] : Math.min(Math.max(0, yRange[0]), yRange[1]),\n minSpan: {\n x: xType === \"category\" ? 1 : (xRange[1] - xRange[0]) * 1e-7,\n y: yType === \"category\" ? 1 : (yRange[1] - yRange[0]) * 1e-7,\n },\n percent,\n stacks: input.map((s) =>\n s.stack !== undefined &&\n (s.type === \"bar\" || s.type === \"line\" || s.type === \"area\" || !s.type)\n ? `${s.type === \"bar\" ? \"bar\" : \"line\"}:${s.stack}`\n : null,\n ),\n };\n};\n\n/** Y value drawn for a point: its stacked top for stacks, the close for candles */\nexport const plottedY = (s: SeriesModel, i: number): number =>\n s.barTop ? s.barTop[i] : s.stackTop ? s.stackTop[i] : s.cols.y[i];\n\nconst grids = new WeakMap<SeriesColumns, GridIndex>();\n\n/** Spatial index of a scatter series, built on first use and kept with its data */\nexport const gridOf = (s: SeriesModel): GridIndex => {\n let grid = grids.get(s.cols);\n if (!grid) {\n grid = new GridIndex(s.cols.x, s.cols.y, s.cols.count);\n grids.set(s.cols, grid);\n }\n return grid;\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.cjs","names":["toScreen","screenRect","require_layout","font","theme","weight","size","textBox","s","at","a","free","px","plot","py","x","width","y","height","rectOf","xLo","xHi","yLo","yHi","along","lo","hi","lineOf","overlaps","b","inside","r","placeLabels","placed","label","labels","w","measure","gap","above","below","right","left","box","c","occupied","o"],"sources":["../../../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport { screenRect, toScreen, type Rect, type Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport interface ResolvedText {\n type: \"text\";\n x?: number;\n y?: number;\n text: string;\n anchor: \"center\" | \"top\" | \"bottom\" | \"left\" | \"right\";\n color: Rgba;\n weight: number;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine | ResolvedText;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n /**\n * Fixed side (bar values: above / below, left / right of horizontal\n * bars); any free side around the dot otherwise\n */\n placement?: \"above\" | \"below\" | \"left\" | \"right\";\n}\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\n/** Box of a text annotation, kept inside the plot */\nexport const textBox = (\n a: ResolvedText,\n s: Scales,\n width: number,\n height: number,\n): Rect => {\n const { plot } = s;\n const at = toScreen(s, a.x ?? 0, a.y ?? 0);\n const free = s.horizontal\n ? { x: a.y === undefined, y: a.x === undefined }\n : { x: a.x === undefined, y: a.y === undefined };\n const px = free.x ? plot.x + plot.width / 2 : at.x;\n const py = free.y ? plot.y + plot.height / 2 : at.y;\n const gap = 6;\n let x = px - width / 2;\n let y = py - height / 2;\n if (a.anchor === \"top\") y = py + gap;\n else if (a.anchor === \"bottom\") y = py - gap - height;\n else if (a.anchor === \"left\") x = px + gap;\n else if (a.anchor === \"right\") x = px - gap - width;\n x = Math.max(plot.x + gap, Math.min(x, plot.x + plot.width - gap - width));\n y = Math.max(plot.y + 2, Math.min(y, plot.y + plot.height - 2 - height));\n return { x, y, width, height };\n};\n\n/** Screen box of an area annotation, clipped to the plot */\nexport const rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n // clamp every edge to the plot first: an open edge maps to ±Infinity and\n // `Infinity - Infinity` would make the size NaN (nothing drawn)\n const [xLo, xHi] = s.horizontal\n ? [plot.y, plot.y + plot.height]\n : [plot.x, plot.x + plot.width];\n const [yLo, yHi] = s.horizontal\n ? [plot.x, plot.x + plot.width]\n : [plot.y, plot.y + plot.height];\n const along = (px: number, lo: number, hi: number) =>\n px < lo ? lo : px > hi ? hi : px;\n return screenRect(\n s,\n along(s.xToPx(a.x0 ?? -Infinity), xLo, xHi),\n along(s.xToPx(a.x1 ?? Infinity), xLo, xHi),\n along(s.yToPx(a.y0 ?? -Infinity), yLo, yHi),\n along(s.yToPx(a.y1 ?? Infinity), yLo, yHi),\n );\n};\n\n/**\n * Where a reference line goes: `vertical` lines run at screen x `at`,\n * horizontal ones at screen y `at`\n */\nexport const lineOf = (\n a: ResolvedLine,\n s: Scales,\n): { vertical: boolean; at: number } => {\n const vertical = (a.axis === \"x\") !== s.horizontal;\n return {\n vertical,\n at: a.axis === \"x\" ? s.xToPx(a.value) : s.yToPx(a.value),\n };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n /** Right axis (dual axis charts) */\n y2?: AxisModel | null;\n y2Ticks?: AxisTicks | null;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, xTicks, yTicks } = input;\n const { plot } = scales;\n // horizontal charts: the value axis along the bottom, the x axis on the left\n const x = scales.horizontal ? input.y : input.x;\n const y = scales.horizontal ? input.x : input.y;\n const bottomTicks = scales.horizontal ? yTicks : xTicks;\n const leftTicks = scales.horizontal ? xTicks : yTicks;\n const bottomPx = scales.horizontal ? scales.yToPx : scales.xToPx;\n const leftPx = scales.horizontal ? scales.xToPx : scales.yToPx;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of leftTicks.values) {\n const py = crisp(leftPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of bottomTicks.values) {\n const px = crisp(bottomPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = bottomTicks.values\n .map((v, i) => ({ px: bottomPx(v), text: bottomTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n let lastBottom = -Infinity;\n // top to bottom: category rows of horizontal charts never overlap\n const rows = leftTicks.values\n .map((v, i) => ({ py: leftPx(v), text: leftTicks.labels[i] }))\n .sort((a, b) => a.py - b.py);\n const rowHeight = theme.fontSize + 2;\n for (const { py, text } of rows) {\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) continue;\n if (scales.horizontal) {\n if (py - rowHeight / 2 < lastBottom) continue;\n lastBottom = py + rowHeight / 2;\n }\n ctx.fillText(text, plot.x - 8, py);\n }\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n\n // right axis\n const y2 = scales.horizontal ? null : input.y2;\n const y2Ticks = input.y2Ticks;\n if (y2 && y2Ticks && y2.visible) {\n const right = plot.x + plot.width;\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n y2Ticks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(y2Ticks.labels[i], right + 8, py);\n });\n if (y2.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(input.width - line / 2 - 4, plot.y + plot.height / 2);\n ctx.rotate(Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y2.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n for (const label of labels) {\n const w = measure(label.text);\n const gap = label.r + 4;\n const above = {\n x: label.x - w / 2,\n y: label.y - gap - height,\n width: w,\n height,\n };\n const below = { x: label.x - w / 2, y: label.y + gap, width: w, height };\n const right = {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const left = {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const candidates: Rect[] =\n label.placement === \"above\"\n ? [above]\n : label.placement === \"below\"\n ? [below]\n : label.placement === \"right\"\n ? [right, left]\n : label.placement === \"left\"\n ? [left, right]\n : [\n {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n },\n {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n },\n above,\n below,\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n /**\n * Clears the canvas first (off when the layers share one canvas)\n * @default true\n */\n clear?: boolean;\n}\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n if (input.clear !== false) ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n const where = lineOf(a, scales);\n if (!where.vertical) {\n const py = crisp(where.at);\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(where.at);\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n ctx.font = font(theme, theme.fontSize + 1, 600);\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !a.label) continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n const pad = 10;\n const w = ctx.measureText(a.label).width;\n const pos = a.labelPosition;\n const tx = pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - w\n : r.x + (r.width - w) / 2;\n const ty = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - labelHeight\n : r.y + (r.height - labelHeight) / 2;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillStyle = toCss(a.labelColor);\n ctx.fillText(a.label, tx, ty);\n occupied.push({ x: tx, y: ty, width: w, height: labelHeight });\n }\n\n // free texts\n for (const a of input.annotations) {\n if (a.type !== \"text\" || !a.text) continue;\n ctx.font = font(theme, theme.fontSize, a.weight);\n const box = textBox(a, scales, ctx.measureText(a.text).width, labelHeight);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n haloText(ctx, a.text, box.x, box.y + box.height / 2, toCss(a.color), halo);\n occupied.push(box);\n }\n\n // point labels\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n const placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n haloText(ctx, label.text, box.x, box.y + box.height / 2, textColor, halo);\n }\n }\n ctx.restore();\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"overlay.cjs","names":["toScreen","screenRect","require_layout","font","theme","weight","size","textBox","s","at","a","free","px","plot","py","x","width","y","height","rectOf","xLo","xHi","yLo","yHi","along","lo","hi","lineOf","overlaps","b","inside","r","placeLabels","placed","label","labels","w","measure","gap","above","below","right","left","box","c","occupied","o"],"sources":["../../../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport { screenRect, toScreen, type Rect, type Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport interface ResolvedText {\n type: \"text\";\n x?: number;\n y?: number;\n text: string;\n anchor: \"center\" | \"top\" | \"bottom\" | \"left\" | \"right\";\n color: Rgba;\n weight: number;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine | ResolvedText;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n /**\n * Fixed side (bar values: above / below, left / right of horizontal\n * bars); any free side around the dot otherwise\n */\n placement?: \"above\" | \"below\" | \"left\" | \"right\";\n}\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\n/** Box of a text annotation, kept inside the plot */\nexport const textBox = (\n a: ResolvedText,\n s: Scales,\n width: number,\n height: number,\n): Rect => {\n const { plot } = s;\n const at = toScreen(s, a.x ?? 0, a.y ?? 0);\n const free = s.horizontal\n ? { x: a.y === undefined, y: a.x === undefined }\n : { x: a.x === undefined, y: a.y === undefined };\n const px = free.x ? plot.x + plot.width / 2 : at.x;\n const py = free.y ? plot.y + plot.height / 2 : at.y;\n const gap = 6;\n let x = px - width / 2;\n let y = py - height / 2;\n if (a.anchor === \"top\") y = py + gap;\n else if (a.anchor === \"bottom\") y = py - gap - height;\n else if (a.anchor === \"left\") x = px + gap;\n else if (a.anchor === \"right\") x = px - gap - width;\n x = Math.max(plot.x + gap, Math.min(x, plot.x + plot.width - gap - width));\n y = Math.max(plot.y + 2, Math.min(y, plot.y + plot.height - 2 - height));\n return { x, y, width, height };\n};\n\n/** Screen box of an area annotation, clipped to the plot */\nexport const rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n // clamp every edge to the plot first: an open edge maps to ±Infinity and\n // `Infinity - Infinity` would make the size NaN (nothing drawn)\n const [xLo, xHi] = s.horizontal\n ? [plot.y, plot.y + plot.height]\n : [plot.x, plot.x + plot.width];\n const [yLo, yHi] = s.horizontal\n ? [plot.x, plot.x + plot.width]\n : [plot.y, plot.y + plot.height];\n const along = (px: number, lo: number, hi: number) =>\n px < lo ? lo : px > hi ? hi : px;\n return screenRect(\n s,\n along(s.xToPx(a.x0 ?? -Infinity), xLo, xHi),\n along(s.xToPx(a.x1 ?? Infinity), xLo, xHi),\n along(s.yToPx(a.y0 ?? -Infinity), yLo, yHi),\n along(s.yToPx(a.y1 ?? Infinity), yLo, yHi),\n );\n};\n\n/**\n * Where a reference line goes: `vertical` lines run at screen x `at`,\n * horizontal ones at screen y `at`\n */\nexport const lineOf = (\n a: ResolvedLine,\n s: Scales,\n): { vertical: boolean; at: number } => {\n const vertical = (a.axis === \"x\") !== s.horizontal;\n return {\n vertical,\n at: a.axis === \"x\" ? s.xToPx(a.value) : s.yToPx(a.value),\n };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n /** Right axis (dual axis charts) */\n y2?: AxisModel | null;\n y2Ticks?: AxisTicks | null;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, xTicks, yTicks } = input;\n const { plot } = scales;\n // horizontal charts: the value axis along the bottom, the x axis on the left\n const x = scales.horizontal ? input.y : input.x;\n const y = scales.horizontal ? input.x : input.y;\n const bottomTicks = scales.horizontal ? yTicks : xTicks;\n const leftTicks = scales.horizontal ? xTicks : yTicks;\n const bottomPx = scales.horizontal ? scales.yToPx : scales.xToPx;\n const leftPx = scales.horizontal ? scales.xToPx : scales.yToPx;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of leftTicks.values) {\n const py = crisp(leftPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of bottomTicks.values) {\n const px = crisp(bottomPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = bottomTicks.values\n .map((v, i) => ({ px: bottomPx(v), text: bottomTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n let lastBottom = -Infinity;\n // top to bottom: category rows of horizontal charts never overlap\n const rows = leftTicks.values\n .map((v, i) => ({ py: leftPx(v), text: leftTicks.labels[i] }))\n .sort((a, b) => a.py - b.py);\n const rowHeight = theme.fontSize + 2;\n for (const { py, text } of rows) {\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) continue;\n if (scales.horizontal) {\n if (py - rowHeight / 2 < lastBottom) continue;\n lastBottom = py + rowHeight / 2;\n }\n ctx.fillText(text, plot.x - 8, py);\n }\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n\n // right axis\n const y2 = scales.horizontal ? null : input.y2;\n const y2Ticks = input.y2Ticks;\n if (y2 && y2Ticks && y2.visible) {\n const right = plot.x + plot.width;\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n y2Ticks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(y2Ticks.labels[i], right + 8, py);\n });\n if (y2.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(input.width - line / 2 - 4, plot.y + plot.height / 2);\n ctx.rotate(Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y2.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n for (const label of labels) {\n const w = measure(label.text);\n const gap = label.r + 4;\n const above = {\n x: label.x - w / 2,\n y: label.y - gap - height,\n width: w,\n height,\n };\n const below = { x: label.x - w / 2, y: label.y + gap, width: w, height };\n const right = {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const left = {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const candidates: Rect[] =\n label.placement === \"above\"\n ? [above]\n : label.placement === \"below\"\n ? [below]\n : label.placement === \"right\"\n ? [right, left]\n : label.placement === \"left\"\n ? [left, right]\n : [\n {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n },\n {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n },\n above,\n below,\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n /**\n * Clears the canvas first (off when the layers share one canvas)\n * @default true\n */\n clear?: boolean;\n /** Lines between consecutive bars (waterfall connectors), drawn first */\n connectors?: readonly {\n x0: number;\n y0: number;\n x1: number;\n y1: number;\n color: string;\n width: number;\n dash: readonly number[];\n }[];\n}\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n if (input.clear !== false) ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n for (const c of input.connectors ?? []) {\n ctx.strokeStyle = c.color;\n ctx.lineWidth = c.width;\n ctx.setLineDash([...c.dash]);\n ctx.beginPath();\n // crisp hairlines along the pixel grid\n const along = c.y0 === c.y1;\n const x0 = along ? c.x0 : crisp(c.x0);\n const y0 = along ? crisp(c.y0) : c.y0;\n ctx.moveTo(x0, y0);\n ctx.lineTo(along ? c.x1 : x0, along ? y0 : c.y1);\n ctx.stroke();\n }\n ctx.setLineDash([]);\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n const where = lineOf(a, scales);\n if (!where.vertical) {\n const py = crisp(where.at);\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(where.at);\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n ctx.font = font(theme, theme.fontSize + 1, 600);\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !a.label) continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n const pad = 10;\n const w = ctx.measureText(a.label).width;\n const pos = a.labelPosition;\n const tx = pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - w\n : r.x + (r.width - w) / 2;\n const ty = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - labelHeight\n : r.y + (r.height - labelHeight) / 2;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillStyle = toCss(a.labelColor);\n ctx.fillText(a.label, tx, ty);\n occupied.push({ x: tx, y: ty, width: w, height: labelHeight });\n }\n\n // free texts\n for (const a of input.annotations) {\n if (a.type !== \"text\" || !a.text) continue;\n ctx.font = font(theme, theme.fontSize, a.weight);\n const box = textBox(a, scales, ctx.measureText(a.text).width, labelHeight);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n haloText(ctx, a.text, box.x, box.y + box.height / 2, toCss(a.color), halo);\n occupied.push(box);\n }\n\n // point labels\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n const placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n haloText(ctx, label.text, box.x, box.y + box.height / 2, textColor, halo);\n }\n }\n ctx.restore();\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.js","names":["font","theme","weight","size","textBox","s","at","toScreen","a","free","px","plot","py","x","width","y","height","rectOf","xLo","xHi","yLo","yHi","along","lo","hi","screenRect","lineOf","overlaps","b","inside","r","placeLabels","placed","label","labels","w","measure","gap","above","below","right","left","box","c","occupied","o"],"sources":["../../../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport { screenRect, toScreen, type Rect, type Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport interface ResolvedText {\n type: \"text\";\n x?: number;\n y?: number;\n text: string;\n anchor: \"center\" | \"top\" | \"bottom\" | \"left\" | \"right\";\n color: Rgba;\n weight: number;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine | ResolvedText;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n /**\n * Fixed side (bar values: above / below, left / right of horizontal\n * bars); any free side around the dot otherwise\n */\n placement?: \"above\" | \"below\" | \"left\" | \"right\";\n}\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\n/** Box of a text annotation, kept inside the plot */\nexport const textBox = (\n a: ResolvedText,\n s: Scales,\n width: number,\n height: number,\n): Rect => {\n const { plot } = s;\n const at = toScreen(s, a.x ?? 0, a.y ?? 0);\n const free = s.horizontal\n ? { x: a.y === undefined, y: a.x === undefined }\n : { x: a.x === undefined, y: a.y === undefined };\n const px = free.x ? plot.x + plot.width / 2 : at.x;\n const py = free.y ? plot.y + plot.height / 2 : at.y;\n const gap = 6;\n let x = px - width / 2;\n let y = py - height / 2;\n if (a.anchor === \"top\") y = py + gap;\n else if (a.anchor === \"bottom\") y = py - gap - height;\n else if (a.anchor === \"left\") x = px + gap;\n else if (a.anchor === \"right\") x = px - gap - width;\n x = Math.max(plot.x + gap, Math.min(x, plot.x + plot.width - gap - width));\n y = Math.max(plot.y + 2, Math.min(y, plot.y + plot.height - 2 - height));\n return { x, y, width, height };\n};\n\n/** Screen box of an area annotation, clipped to the plot */\nexport const rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n // clamp every edge to the plot first: an open edge maps to ±Infinity and\n // `Infinity - Infinity` would make the size NaN (nothing drawn)\n const [xLo, xHi] = s.horizontal\n ? [plot.y, plot.y + plot.height]\n : [plot.x, plot.x + plot.width];\n const [yLo, yHi] = s.horizontal\n ? [plot.x, plot.x + plot.width]\n : [plot.y, plot.y + plot.height];\n const along = (px: number, lo: number, hi: number) =>\n px < lo ? lo : px > hi ? hi : px;\n return screenRect(\n s,\n along(s.xToPx(a.x0 ?? -Infinity), xLo, xHi),\n along(s.xToPx(a.x1 ?? Infinity), xLo, xHi),\n along(s.yToPx(a.y0 ?? -Infinity), yLo, yHi),\n along(s.yToPx(a.y1 ?? Infinity), yLo, yHi),\n );\n};\n\n/**\n * Where a reference line goes: `vertical` lines run at screen x `at`,\n * horizontal ones at screen y `at`\n */\nexport const lineOf = (\n a: ResolvedLine,\n s: Scales,\n): { vertical: boolean; at: number } => {\n const vertical = (a.axis === \"x\") !== s.horizontal;\n return {\n vertical,\n at: a.axis === \"x\" ? s.xToPx(a.value) : s.yToPx(a.value),\n };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n /** Right axis (dual axis charts) */\n y2?: AxisModel | null;\n y2Ticks?: AxisTicks | null;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, xTicks, yTicks } = input;\n const { plot } = scales;\n // horizontal charts: the value axis along the bottom, the x axis on the left\n const x = scales.horizontal ? input.y : input.x;\n const y = scales.horizontal ? input.x : input.y;\n const bottomTicks = scales.horizontal ? yTicks : xTicks;\n const leftTicks = scales.horizontal ? xTicks : yTicks;\n const bottomPx = scales.horizontal ? scales.yToPx : scales.xToPx;\n const leftPx = scales.horizontal ? scales.xToPx : scales.yToPx;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of leftTicks.values) {\n const py = crisp(leftPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of bottomTicks.values) {\n const px = crisp(bottomPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = bottomTicks.values\n .map((v, i) => ({ px: bottomPx(v), text: bottomTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n let lastBottom = -Infinity;\n // top to bottom: category rows of horizontal charts never overlap\n const rows = leftTicks.values\n .map((v, i) => ({ py: leftPx(v), text: leftTicks.labels[i] }))\n .sort((a, b) => a.py - b.py);\n const rowHeight = theme.fontSize + 2;\n for (const { py, text } of rows) {\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) continue;\n if (scales.horizontal) {\n if (py - rowHeight / 2 < lastBottom) continue;\n lastBottom = py + rowHeight / 2;\n }\n ctx.fillText(text, plot.x - 8, py);\n }\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n\n // right axis\n const y2 = scales.horizontal ? null : input.y2;\n const y2Ticks = input.y2Ticks;\n if (y2 && y2Ticks && y2.visible) {\n const right = plot.x + plot.width;\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n y2Ticks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(y2Ticks.labels[i], right + 8, py);\n });\n if (y2.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(input.width - line / 2 - 4, plot.y + plot.height / 2);\n ctx.rotate(Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y2.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n for (const label of labels) {\n const w = measure(label.text);\n const gap = label.r + 4;\n const above = {\n x: label.x - w / 2,\n y: label.y - gap - height,\n width: w,\n height,\n };\n const below = { x: label.x - w / 2, y: label.y + gap, width: w, height };\n const right = {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const left = {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const candidates: Rect[] =\n label.placement === \"above\"\n ? [above]\n : label.placement === \"below\"\n ? [below]\n : label.placement === \"right\"\n ? [right, left]\n : label.placement === \"left\"\n ? [left, right]\n : [\n {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n },\n {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n },\n above,\n below,\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n /**\n * Clears the canvas first (off when the layers share one canvas)\n * @default true\n */\n clear?: boolean;\n}\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n if (input.clear !== false) ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n const where = lineOf(a, scales);\n if (!where.vertical) {\n const py = crisp(where.at);\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(where.at);\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n ctx.font = font(theme, theme.fontSize + 1, 600);\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !a.label) continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n const pad = 10;\n const w = ctx.measureText(a.label).width;\n const pos = a.labelPosition;\n const tx = pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - w\n : r.x + (r.width - w) / 2;\n const ty = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - labelHeight\n : r.y + (r.height - labelHeight) / 2;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillStyle = toCss(a.labelColor);\n ctx.fillText(a.label, tx, ty);\n occupied.push({ x: tx, y: ty, width: w, height: labelHeight });\n }\n\n // free texts\n for (const a of input.annotations) {\n if (a.type !== \"text\" || !a.text) continue;\n ctx.font = font(theme, theme.fontSize, a.weight);\n const box = textBox(a, scales, ctx.measureText(a.text).width, labelHeight);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n haloText(ctx, a.text, box.x, box.y + box.height / 2, toCss(a.color), halo);\n occupied.push(box);\n }\n\n // point labels\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n const placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n haloText(ctx, label.text, box.x, box.y + box.height / 2, textColor, halo);\n }\n }\n ctx.restore();\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"overlay.js","names":["font","theme","weight","size","textBox","s","at","toScreen","a","free","px","plot","py","x","width","y","height","rectOf","xLo","xHi","yLo","yHi","along","lo","hi","screenRect","lineOf","overlaps","b","inside","r","placeLabels","placed","label","labels","w","measure","gap","above","below","right","left","box","c","occupied","o"],"sources":["../../../../../../charts/src/engine/overlay.ts"],"sourcesContent":["// Canvas2D layers around the data: background (areas, grid, axes, tick\n// labels) and foreground (reference lines, annotation and point labels).\n\nimport { toCss, type Rgba } from \"./color\";\nimport type { AxisTicks } from \"./axis\";\nimport { screenRect, toScreen, type Rect, type Scales } from \"./layout\";\nimport type { AxisModel } from \"./model\";\nimport type { ChartTheme } from \"./theme\";\nimport type { ChartLabelPosition } from \"./types\";\n\nexport interface ResolvedRect {\n type: \"rect\";\n x0?: number;\n x1?: number;\n y0?: number;\n y1?: number;\n color: Rgba;\n opacity: number;\n label?: string;\n labelPosition: ChartLabelPosition;\n labelColor: Rgba;\n}\n\nexport interface ResolvedLine {\n type: \"line\";\n axis: \"x\" | \"y\";\n value: number;\n color: Rgba;\n width: number;\n dash: number[];\n label?: string;\n}\n\nexport interface ResolvedText {\n type: \"text\";\n x?: number;\n y?: number;\n text: string;\n anchor: \"center\" | \"top\" | \"bottom\" | \"left\" | \"right\";\n color: Rgba;\n weight: number;\n}\n\nexport type ResolvedAnnotation = ResolvedRect | ResolvedLine | ResolvedText;\n\nexport interface PointLabel {\n x: number;\n y: number;\n /** Radius of the dot */\n r: number;\n text: string;\n /**\n * Fixed side (bar values: above / below, left / right of horizontal\n * bars); any free side around the dot otherwise\n */\n placement?: \"above\" | \"below\" | \"left\" | \"right\";\n}\n\nexport const font = (theme: ChartTheme, size = theme.fontSize, weight = 400) =>\n `${weight} ${size}px ${theme.fontFamily}`;\n\nconst crisp = (v: number) => Math.round(v) + 0.5;\n\n/** Box of a text annotation, kept inside the plot */\nexport const textBox = (\n a: ResolvedText,\n s: Scales,\n width: number,\n height: number,\n): Rect => {\n const { plot } = s;\n const at = toScreen(s, a.x ?? 0, a.y ?? 0);\n const free = s.horizontal\n ? { x: a.y === undefined, y: a.x === undefined }\n : { x: a.x === undefined, y: a.y === undefined };\n const px = free.x ? plot.x + plot.width / 2 : at.x;\n const py = free.y ? plot.y + plot.height / 2 : at.y;\n const gap = 6;\n let x = px - width / 2;\n let y = py - height / 2;\n if (a.anchor === \"top\") y = py + gap;\n else if (a.anchor === \"bottom\") y = py - gap - height;\n else if (a.anchor === \"left\") x = px + gap;\n else if (a.anchor === \"right\") x = px - gap - width;\n x = Math.max(plot.x + gap, Math.min(x, plot.x + plot.width - gap - width));\n y = Math.max(plot.y + 2, Math.min(y, plot.y + plot.height - 2 - height));\n return { x, y, width, height };\n};\n\n/** Screen box of an area annotation, clipped to the plot */\nexport const rectOf = (a: ResolvedRect, s: Scales): Rect => {\n const { plot } = s;\n // clamp every edge to the plot first: an open edge maps to ±Infinity and\n // `Infinity - Infinity` would make the size NaN (nothing drawn)\n const [xLo, xHi] = s.horizontal\n ? [plot.y, plot.y + plot.height]\n : [plot.x, plot.x + plot.width];\n const [yLo, yHi] = s.horizontal\n ? [plot.x, plot.x + plot.width]\n : [plot.y, plot.y + plot.height];\n const along = (px: number, lo: number, hi: number) =>\n px < lo ? lo : px > hi ? hi : px;\n return screenRect(\n s,\n along(s.xToPx(a.x0 ?? -Infinity), xLo, xHi),\n along(s.xToPx(a.x1 ?? Infinity), xLo, xHi),\n along(s.yToPx(a.y0 ?? -Infinity), yLo, yHi),\n along(s.yToPx(a.y1 ?? Infinity), yLo, yHi),\n );\n};\n\n/**\n * Where a reference line goes: `vertical` lines run at screen x `at`,\n * horizontal ones at screen y `at`\n */\nexport const lineOf = (\n a: ResolvedLine,\n s: Scales,\n): { vertical: boolean; at: number } => {\n const vertical = (a.axis === \"x\") !== s.horizontal;\n return {\n vertical,\n at: a.axis === \"x\" ? s.xToPx(a.value) : s.yToPx(a.value),\n };\n};\n\nexport interface BackgroundInput {\n width: number;\n height: number;\n scales: Scales;\n x: AxisModel;\n y: AxisModel;\n xTicks: AxisTicks;\n yTicks: AxisTicks;\n /** Right axis (dual axis charts) */\n y2?: AxisModel | null;\n y2Ticks?: AxisTicks | null;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n}\n\nexport const drawBackground = (\n ctx: CanvasRenderingContext2D,\n input: BackgroundInput,\n) => {\n const { scales, theme, xTicks, yTicks } = input;\n const { plot } = scales;\n // horizontal charts: the value axis along the bottom, the x axis on the left\n const x = scales.horizontal ? input.y : input.x;\n const y = scales.horizontal ? input.x : input.y;\n const bottomTicks = scales.horizontal ? yTicks : xTicks;\n const leftTicks = scales.horizontal ? xTicks : yTicks;\n const bottomPx = scales.horizontal ? scales.yToPx : scales.xToPx;\n const leftPx = scales.horizontal ? scales.xToPx : scales.yToPx;\n ctx.clearRect(0, 0, input.width, input.height);\n\n // areas\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n for (const a of input.annotations) {\n if (a.type !== \"rect\") continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n ctx.fillStyle = toCss(a.color, a.opacity);\n ctx.fillRect(r.x, r.y, r.width, r.height);\n }\n ctx.restore();\n\n // grid\n ctx.lineWidth = 1;\n ctx.strokeStyle = toCss(theme.grid);\n ctx.beginPath();\n if (y.grid) {\n for (const v of leftTicks.values) {\n const py = crisp(leftPx(v));\n if (py < plot.y - 1 || py > plot.y + plot.height + 1) continue;\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n }\n }\n if (x.grid) {\n for (const v of bottomTicks.values) {\n const px = crisp(bottomPx(v));\n if (px < plot.x - 1 || px > plot.x + plot.width + 1) continue;\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n }\n }\n ctx.stroke();\n\n const line = Math.ceil(theme.fontSize * 1.4);\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n\n // x axis\n if (x.visible) {\n ctx.strokeStyle = toCss(theme.axis);\n ctx.beginPath();\n const base = crisp(plot.y + plot.height);\n ctx.moveTo(plot.x, base);\n ctx.lineTo(plot.x + plot.width, base);\n ctx.stroke();\n ctx.textBaseline = \"top\";\n ctx.textAlign = \"center\";\n let lastRight = -Infinity;\n // left to right (reversed axes list their ticks right to left)\n const order = bottomTicks.values\n .map((v, i) => ({ px: bottomPx(v), text: bottomTicks.labels[i] }))\n .sort((a, b) => a.px - b.px);\n for (const { px, text } of order) {\n if (px < plot.x - 0.5 || px > plot.x + plot.width + 0.5) continue;\n const w = ctx.measureText(text).width;\n const left = Math.max(0, Math.min(input.width - w, px - w / 2));\n if (left < lastRight + 6) continue;\n lastRight = left + w;\n ctx.fillText(text, left + w / 2, plot.y + plot.height + 7);\n }\n if (x.title) {\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.fillText(\n x.title,\n plot.x + plot.width / 2,\n plot.y + plot.height + line + 10,\n );\n }\n }\n\n // y axis\n if (y.visible) {\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"middle\";\n let lastBottom = -Infinity;\n // top to bottom: category rows of horizontal charts never overlap\n const rows = leftTicks.values\n .map((v, i) => ({ py: leftPx(v), text: leftTicks.labels[i] }))\n .sort((a, b) => a.py - b.py);\n const rowHeight = theme.fontSize + 2;\n for (const { py, text } of rows) {\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) continue;\n if (scales.horizontal) {\n if (py - rowHeight / 2 < lastBottom) continue;\n lastBottom = py + rowHeight / 2;\n }\n ctx.fillText(text, plot.x - 8, py);\n }\n if (y.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(line / 2 + 4, plot.y + plot.height / 2);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y.title, 0, 0);\n ctx.restore();\n }\n }\n\n // right axis\n const y2 = scales.horizontal ? null : input.y2;\n const y2Ticks = input.y2Ticks;\n if (y2 && y2Ticks && y2.visible) {\n const right = plot.x + plot.width;\n ctx.font = font(theme);\n ctx.fillStyle = toCss(theme.textMuted);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n y2Ticks.values.forEach((v, i) => {\n const py = scales.yToPx(v);\n if (py < plot.y - 0.5 || py > plot.y + plot.height + 0.5) return;\n ctx.fillText(y2Ticks.labels[i], right + 8, py);\n });\n if (y2.title) {\n ctx.save();\n ctx.font = font(theme, theme.fontSize + 1, 500);\n ctx.fillStyle = toCss(theme.text, 0.8);\n ctx.translate(input.width - line / 2 - 4, plot.y + plot.height / 2);\n ctx.rotate(Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.fillText(y2.title, 0, 0);\n ctx.restore();\n }\n }\n};\n\nconst overlaps = (a: Rect, b: Rect) =>\n a.x < b.x + b.width &&\n b.x < a.x + a.width &&\n a.y < b.y + b.height &&\n b.y < a.y + a.height;\n\nconst inside = (r: Rect, plot: Rect) =>\n r.x >= plot.x &&\n r.y >= plot.y &&\n r.x + r.width <= plot.x + plot.width &&\n r.y + r.height <= plot.y + plot.height;\n\n/** Text with a halo in the background color (readable over data) */\nconst haloText = (\n ctx: CanvasRenderingContext2D,\n text: string,\n x: number,\n y: number,\n color: string,\n halo: string,\n) => {\n ctx.lineWidth = 3;\n ctx.lineJoin = \"round\";\n ctx.strokeStyle = halo;\n ctx.strokeText(text, x, y);\n ctx.fillStyle = color;\n ctx.fillText(text, x, y);\n};\n\n/** Greedy placement: right, left, above, below the dot; skipped when no slot is free */\nexport const placeLabels = (\n labels: readonly PointLabel[],\n plot: Rect,\n measure: (text: string) => number,\n height: number,\n occupied: Rect[] = [],\n): { label: PointLabel; box: Rect }[] => {\n const placed: { label: PointLabel; box: Rect }[] = [];\n for (const label of labels) {\n const w = measure(label.text);\n const gap = label.r + 4;\n const above = {\n x: label.x - w / 2,\n y: label.y - gap - height,\n width: w,\n height,\n };\n const below = { x: label.x - w / 2, y: label.y + gap, width: w, height };\n const right = {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const left = {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n };\n const candidates: Rect[] =\n label.placement === \"above\"\n ? [above]\n : label.placement === \"below\"\n ? [below]\n : label.placement === \"right\"\n ? [right, left]\n : label.placement === \"left\"\n ? [left, right]\n : [\n {\n x: label.x + gap,\n y: label.y - height / 2,\n width: w,\n height,\n },\n {\n x: label.x - gap - w,\n y: label.y - height / 2,\n width: w,\n height,\n },\n above,\n below,\n ];\n const box = candidates.find(\n (c) => inside(c, plot) && !occupied.some((o) => overlaps(o, c)),\n );\n if (!box) continue;\n occupied.push(box);\n placed.push({ label, box });\n }\n return placed;\n};\n\nexport interface ForegroundInput {\n width: number;\n height: number;\n scales: Scales;\n theme: ChartTheme;\n annotations: readonly ResolvedAnnotation[];\n pointLabels: readonly PointLabel[];\n /**\n * Clears the canvas first (off when the layers share one canvas)\n * @default true\n */\n clear?: boolean;\n /** Lines between consecutive bars (waterfall connectors), drawn first */\n connectors?: readonly {\n x0: number;\n y0: number;\n x1: number;\n y1: number;\n color: string;\n width: number;\n dash: readonly number[];\n }[];\n}\n\nexport const drawForeground = (\n ctx: CanvasRenderingContext2D,\n input: ForegroundInput,\n) => {\n const { scales, theme } = input;\n const { plot } = scales;\n if (input.clear !== false) ctx.clearRect(0, 0, input.width, input.height);\n ctx.save();\n ctx.beginPath();\n ctx.rect(plot.x, plot.y, plot.width, plot.height);\n ctx.clip();\n\n for (const c of input.connectors ?? []) {\n ctx.strokeStyle = c.color;\n ctx.lineWidth = c.width;\n ctx.setLineDash([...c.dash]);\n ctx.beginPath();\n // crisp hairlines along the pixel grid\n const along = c.y0 === c.y1;\n const x0 = along ? c.x0 : crisp(c.x0);\n const y0 = along ? crisp(c.y0) : c.y0;\n ctx.moveTo(x0, y0);\n ctx.lineTo(along ? c.x1 : x0, along ? y0 : c.y1);\n ctx.stroke();\n }\n ctx.setLineDash([]);\n\n const halo = toCss(theme.background, 0.9);\n const occupied: Rect[] = [];\n const labelHeight = theme.fontSize + 4;\n\n for (const a of input.annotations) {\n if (a.type !== \"line\") continue;\n const color = toCss(a.color);\n ctx.strokeStyle = color;\n ctx.lineWidth = a.width;\n ctx.setLineDash(a.dash);\n ctx.beginPath();\n const where = lineOf(a, scales);\n if (!where.vertical) {\n const py = crisp(where.at);\n ctx.moveTo(plot.x, py);\n ctx.lineTo(plot.x + plot.width, py);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"right\";\n ctx.textBaseline = \"bottom\";\n haloText(ctx, a.label, plot.x + plot.width - 6, py - 3, color, halo);\n }\n } else {\n const px = crisp(where.at);\n ctx.moveTo(px, plot.y);\n ctx.lineTo(px, plot.y + plot.height);\n ctx.stroke();\n if (a.label) {\n ctx.setLineDash([]);\n ctx.font = font(theme, theme.fontSize, 500);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n haloText(ctx, a.label, px + 5, plot.y + 5, color, halo);\n }\n }\n }\n ctx.setLineDash([]);\n\n // labels of areas\n ctx.font = font(theme, theme.fontSize + 1, 600);\n for (const a of input.annotations) {\n if (a.type !== \"rect\" || !a.label) continue;\n const r = rectOf(a, scales);\n if (r.width <= 0 || r.height <= 0) continue;\n const pad = 10;\n const w = ctx.measureText(a.label).width;\n const pos = a.labelPosition;\n const tx = pos.endsWith(\"left\")\n ? r.x + pad\n : pos.endsWith(\"right\")\n ? r.x + r.width - pad - w\n : r.x + (r.width - w) / 2;\n const ty = pos.startsWith(\"top\")\n ? r.y + pad\n : pos.startsWith(\"bottom\")\n ? r.y + r.height - pad - labelHeight\n : r.y + (r.height - labelHeight) / 2;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"top\";\n ctx.fillStyle = toCss(a.labelColor);\n ctx.fillText(a.label, tx, ty);\n occupied.push({ x: tx, y: ty, width: w, height: labelHeight });\n }\n\n // free texts\n for (const a of input.annotations) {\n if (a.type !== \"text\" || !a.text) continue;\n ctx.font = font(theme, theme.fontSize, a.weight);\n const box = textBox(a, scales, ctx.measureText(a.text).width, labelHeight);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n haloText(ctx, a.text, box.x, box.y + box.height / 2, toCss(a.color), halo);\n occupied.push(box);\n }\n\n // point labels\n if (input.pointLabels.length) {\n ctx.font = font(theme);\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const textColor = toCss(theme.text, 0.85);\n const placed = placeLabels(\n input.pointLabels,\n plot,\n (t) => ctx.measureText(t).width,\n labelHeight - 2,\n occupied,\n );\n for (const { label, box } of placed) {\n haloText(ctx, label.text, box.x, box.y + box.height / 2, textColor, halo);\n }\n }\n ctx.restore();\n};\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const e=require("./locale.cjs"),t=require("./scale.cjs");var
|
|
2
|
-
`)}}),xAxis:{min:n,max:r,title:e.xLabel,reverse:c,nice:!1,grid:!1,tickCount:4,visible:C||!!e.xLabel,...C?{}:{format:()=>``}},yAxis:{min:i,max:a,title:e.yLabel,nice:!1,grid:!1,tickCount:4,visible:C||!!e.yLabel,...C?{}:{format:()=>``}},legend:t.legend??!1,padding:t.padding??(C?void 0:{top:4,right:4,bottom:4,left:4}),interaction:w}},
|
|
1
|
+
const e=require("./locale.cjs"),t=require("./scale.cjs"),n=require("./labels.cjs");var r={en:{value:`Value`,values:`Values`,count:`Count`,change:`Change`,tasks:`Tasks`,progress:`Progress`,milestones:`Milestones`},zh:{value:`数值`,values:`数值`,count:`数量`,change:`变化`,tasks:`任务`,progress:`进度`,milestones:`里程碑`},ja:{value:`値`,values:`値`,count:`件数`,change:`増減`,tasks:`タスク`,progress:`進捗`,milestones:`マイルストーン`},fr:{value:`Valeur`,values:`Valeurs`,count:`Effectif`,change:`Variation`,tasks:`Tâches`,progress:`Avancement`,milestones:`Jalons`}},i=t=>e.localeLabels(r,t),a=(e,t,n,r)=>e.map(e=>{let i=e.type??t;return{...e,type:i,...n!==void 0&&i===t?{stack:e.stack??n}:{},...r!==void 0&&(i===`line`||i===`area`)?{curve:e.curve??r}:{}}}),o=(e,t=!1,n={})=>a(e,t?`area`:`line`,n.stacked?`stack`:void 0,n.curve),s=(e,t={})=>o(e,!0,t),c=(e,t=!1,n=!1)=>a(e,`bar`,t?`stack`:void 0).map(e=>n&&e.type===`bar`?{...e,showLabels:e.showLabels??!0}:e),l=e=>a(e,`scatter`),u=e=>a(e,`candlestick`),d=(e,t={})=>{let n=e.data.some(e=>typeof e.x==`number`),r=e.data.some(e=>typeof e.y==`number`);return{...t,series:[{id:`heatmap`,name:e.name??i(t.locale).value,type:`heatmap`,data:e.data.map(e=>({x:e.x,y:e.y,value:e.value})),colorScale:e.colorScale,valueRange:e.valueRange,colorMidpoint:e.colorMidpoint,radius:e.radius,format:e.format}],xAxis:{...n?{}:{type:`category`,categories:e.xCategories},grid:!1,...t.xAxis},yAxis:{...r?{}:{type:`category`,categories:e.yCategories},grid:!1,...t.yAxis},legend:t.legend??!0,interaction:t.interaction??{zoom:!1},tooltip:t.tooltip??{mode:`nearest`}}},f=(e,t={})=>{let n=e.type??`line`;return{...t,series:[{id:`sparkline`,name:e.name??i(t.locale).value,type:n,data:e.data,color:e.color,curve:n===`bar`?void 0:e.curve??`smooth`,lineWidth:1.5,opacity:n===`area`?.22:void 0,radius:n===`bar`?1.5:void 0,format:e.format}],xAxis:{visible:!1,grid:!1,...t.xAxis},yAxis:{visible:!1,grid:!1,nice:!1,...t.yAxis},legend:!1,padding:t.padding??{top:4,right:4,bottom:4,left:4},interaction:t.interaction??{zoom:!1},annotations:e.reference===void 0?t.annotations:[...t.annotations??[],{type:`line`,axis:`y`,value:e.reference,dash:[2,3]}]}},p={topLeft:`var(--danger-color, #ef4444)`,topRight:`var(--primary-color, #4f46e5)`,bottomLeft:`var(--warning-color, #f59e0b)`,bottomRight:`var(--text-secondary-color, #64748b)`},m=`var(--border-strong-color, var(--border-color, #cbd5e1))`,h=e=>{let[t,n]=e.xDomain??[0,10],[r,i]=e.yDomain??[0,10];return{x0:t,x1:n,y0:r,y1:i,xs:e.xSplit??(t+n)/2,ys:e.ySplit??(r+i)/2}},g=(e,t,n)=>{let{xs:r,ys:i}=h(e),a=e.reverseX?t<r:t>=r;return n>=i?a?`topRight`:`topLeft`:a?`bottomRight`:`bottomLeft`},_=(e,t={})=>{let{x0:n,x1:r,y0:i,y1:a,xs:o,ys:s}=h(e),c=!!e.reverseX,l=t=>e.quadrants?.[t]?.color??p[t],u=[{type:`scatter`,name:e.name??``,pointSize:e.pointSize??12,showLabels:e.showLabels??!0,opacity:.9,data:e.points.map(t=>({x:t.x,y:t.y,label:t.label,size:t.size,color:t.color??l(g(e,t.x,t.y))}))}],d=c?[o,r]:[n,o],f=c?[n,o]:[o,r],_=(t,[n,r],[i,a],o)=>({type:`rect`,x0:n,x1:r,y0:i,y1:a,color:l(t),opacity:.07,label:e.quadrants?.[t]?.label,labelPosition:o}),v=e.axisLabels??{},y=c?r:n,b=c?n:r,x=[...v.top?[{type:`text`,x:o,y:a,text:v.top,anchor:`top`}]:[],...v.bottom?[{type:`text`,x:o,y:i,text:v.bottom,anchor:`bottom`}]:[],...v.left?[{type:`text`,x:y,y:s,text:v.left,anchor:`left`}]:[],...v.right?[{type:`text`,x:b,y:s,text:v.right,anchor:`right`}]:[]],S=[_(`topLeft`,d,[s,a],`top-left`),_(`topRight`,f,[s,a],`top-right`),_(`bottomLeft`,d,[i,s],`bottom-left`),_(`bottomRight`,f,[i,s],`bottom-right`),{type:`line`,axis:`x`,value:o,dash:[],color:m},{type:`line`,axis:`y`,value:s,dash:[],color:m},...x,...t.annotations??[]],C=e.showTicks??!0,w=t.interaction!==!1&&{zoom:!1,...typeof t.interaction==`object`?t.interaction:{},...e.draggable?{dragPoints:!0}:{}};return{...t,series:u,annotations:S,tooltip:t.tooltip??(C?void 0:{render:t=>{let n=t.items[0];if(!n)return null;let r=e.quadrants?.[g(e,n.x,n.y)]?.label;return[n.label??e.name??``,r??``].filter(Boolean).join(`
|
|
2
|
+
`)}}),xAxis:{min:n,max:r,title:e.xLabel,reverse:c,nice:!1,grid:!1,tickCount:4,visible:C||!!e.xLabel,...C?{}:{format:()=>``}},yAxis:{min:i,max:a,title:e.yLabel,nice:!1,grid:!1,tickCount:4,visible:C||!!e.yLabel,...C?{}:{format:()=>``}},legend:t.legend??!1,padding:t.padding??(C?void 0:{top:4,right:4,bottom:4,left:4}),interaction:w}},v=e=>{let t=0;for(let n=0;n<e.length;n++)Number.isFinite(e[n])&&t++;let n=new Float64Array(t),r=0;for(let t=0;t<e.length;t++){let i=e[t];Number.isFinite(i)&&(n[r++]=i)}return n.sort()},y=(e,t)=>{let n=e.length;if(!n)return NaN;let r=Math.min(1,Math.max(0,t))*(n-1),i=Math.floor(r),a=Math.min(n-1,i+1);return e[i]+(e[a]-e[i])*(r-i)},b=1e5,x=(e,n={})=>{let r=0,i=1/0,a=-1/0;for(let t=0;t<e.length;t++){let n=e[t];Number.isFinite(n)&&(r++,n<i&&(i=n),n>a&&(a=n))}let[o,s]=n.domain??[i,a];if(!r||!Number.isFinite(o)||!Number.isFinite(s))return{edges:[0,1],counts:[0],width:1,total:0};o>s&&([o,s]=[s,o]),s===o&&(o-=.5,s+=.5);let c=s-o,l=n.bins??`auto`,u=Math.ceil(Math.log2(r))+1,d;if(typeof l==`number`)d=Math.round(l);else if(l===`sturges`)d=u;else{let t=Math.max(1,Math.floor(e.length/b)),n=[];for(let r=0;r<e.length;r+=t){let t=e[r];Number.isFinite(t)&&n.push(t)}let i=Float64Array.from(n).sort(),a=2*(y(i,.75)-y(i,.25))/Math.cbrt(r);d=a>0?Math.ceil(c/a):u}d=Math.max(1,Math.min(1e3,d||1));let f=c/d,p=o;(n.nice??!0)&&(f=t.tickStep(o,s,d)||f,p=Math.floor(o/f+1e-9)*f,d=Math.max(1,Math.ceil((s-p)/f-1e-9)));let m=p+d*f,h=Array(d).fill(0),g=0;for(let t=0;t<e.length;t++){let n=e[t];if(!(n>=p&&n<=m))continue;let r=Math.min(d-1,Math.floor((n-p)/f));h[r]++,g++}let _=[];for(let e=0;e<=d;e++)_.push(Number((p+e*f).toPrecision(12)));return{edges:_,counts:h,width:f,total:g}},S=(t,n={})=>{let r=n.binned??x(t,n),a=e.resolveLocale(n.locale),o=n.format??(e=>C(e,a));return{id:`histogram`,name:n.name??i(a).count,type:`bar`,color:n.color,barWidth:1,radius:1,data:r.counts.map((e,t)=>{let n=r.edges[t]??0,i=r.edges[t+1]??n;return{x:(n+i)/2,y:e,label:`${o(n)} – ${o(i)}`}})}},C=(t,n)=>e.numberFormat(n,{maximumSignificantDigits:6}).format(t),w=(e,t={})=>{let n=v(e),r=n.length;if(!r)return{low:NaN,q1:NaN,median:NaN,q3:NaN,high:NaN,outliers:[],min:NaN,max:NaN,mean:NaN,count:0};let i=y(n,.25),a=y(n,.5),o=y(n,.75),s=n[0],c=n[r-1],l=0;for(let e=0;e<r;e++)l+=n[e];let u=t.whisker??1.5,d=s,f=c,p=[];if(u!==`minmax`){let e=(o-i)*u,t=i-e,a=o+e,s=0;for(;s<r&&n[s]<t;)p.push(n[s++]);d=s<r?n[s]:i;let c=r-1,l=[];for(;c>=0&&n[c]>a;)l.push(n[c--]);f=c>=0?n[c]:o,p.push(...l.reverse())}return{low:Math.min(d,i),q1:i,median:a,q3:o,high:Math.max(f,o),outliers:p,min:s,max:c,mean:l/r,count:r}},T=(e,t={})=>e.map(e=>{let n=w(e.values,t);return{x:e.x,y:Number.isFinite(n.median)?n.median:null,low:n.low,q1:n.q1,q3:n.q3,high:n.high,outliers:n.outliers,...e.color?{color:e.color}:{}}}),E=e=>a(e,`boxplot`),D=(e,t={})=>{let n=t.upColor??`var(--success-color, #16a34a)`,r=t.downColor??`var(--danger-color, #dc2626)`,a=t.totalColor??`var(--primary-color, #4f46e5)`,o=t.start??0,s=e.map(e=>{if(e.kind===`total`||e.kind===`subtotal`)return{x:e.label,y:o,color:e.color??a};let t=e.value??0,i=o;return o+=t,{x:e.label,y0:i,y:o,color:e.color??(t>=0?n:r)}});return{id:`waterfall`,name:t.name??i(t.locale).change,type:`bar`,color:a,data:s,showLabels:t.labels??!1,format:t.format,connector:t.connector??!0}},O=(e,t={})=>{let n=t.minSize??6,r=t.maxSize??48,i=e=>{if(typeof e!=`object`||!e)return null;if(!(`length`in e))return e.value??null;let t=e,n=new Float64Array(t.length).fill(NaN);for(let e=0;e<t.length;e++){let r=t[e];if(r&&typeof r==`object`&&!Array.isArray(r)){let t=r.value;typeof t==`number`&&(n[e]=t)}}return n},a=t.maxValue??0;if(t.maxValue===void 0)for(let t of e){let e=i(t.data);if(e)for(let t=0;t<e.length;t++){let n=Math.abs(e[t]);n>a&&(a=n)}}let o=e=>Number.isFinite(e)&&a>0?Math.max(n,r*Math.sqrt(Math.min(1,Math.abs(e)/a))):n;return e.map(e=>{let t={...e,type:e.type??`scatter`,opacity:e.opacity??.68};if(t.type!==`scatter`)return t;let n=e.data;if(typeof n==`object`&&n&&!(`length`in n)){let e=n.value;if(!e)return t;let r=new Float32Array(e.length);for(let t=0;t<e.length;t++)r[t]=o(e[t]);return{...t,data:{...n,size:r}}}let r=n,i=[];for(let e=0;e<r.length;e++){let t=r[e];if(!t||typeof t!=`object`||Array.isArray(t))continue;let n=t;i.push({...n,size:n.size??o(typeof n.value==`number`?n.value:NaN)})}return i.sort((e,t)=>(t.size??0)-(e.size??0)),{...t,data:i}})},k=[`--primary-color`,`--success-color`,`--warning-color`,`--danger-color`,`--info-color`],A=[`#4f46e5`,`#10b981`,`#f59e0b`,`#ef4444`,`#0ea5e9`,`#8b5cf6`,`#14b8a6`,`#f97316`],j=e=>{let t=e%8,n=A[t]??`#4f46e5`,r=k[t];return r?`var(--chart-series-${t+1}, var(${r}, ${n}))`:`var(--chart-series-${t+1}, ${n})`},M=e=>e instanceof Date?e.getTime():e===void 0?NaN:e,N=(t,r={})=>{let a=e.resolveLocale(r.locale),o=i(a),s=n.chartLabels(a),c=r.taskName??o.tasks,l=r.progressName??o.progress,u=/^(zh|ja)\b/i.test(a)?`、`:`, `,d=[];for(let e of t){let t=e.group??c;!e.milestone&&!d.includes(t)&&d.push(t)}let f=e=>{let t=Math.max(0,d.indexOf(e));return r.colors?.[t]??j(t)},p=r.formatProgress??(t=>e.numberFormat(a,{style:`percent`,maximumFractionDigits:0}).format(t)),m=d.map(e=>({id:`gantt:${e}`,name:e,type:`bar`,stack:`gantt`,color:f(e),opacity:.3,barWidth:.62,radius:4,data:t.filter(t=>!t.milestone&&(t.group??c)===e).map(e=>{let t=[];return e.progress!==void 0&&t.push({name:l,value:p(Math.min(1,Math.max(0,e.progress)))}),e.dependencies?.length&&t.push({name:r.dependenciesName??s.dependencies,value:e.dependencies.join(u)}),{x:e.name,y0:M(e.start),y:M(e.end??e.start),...e.color?{color:e.color}:{},...t.length?{details:t}:{}}})})),h=t.filter(e=>!e.milestone&&e.progress!==void 0&&e.progress>0);h.length&&m.push({id:`gantt:progress`,name:l,type:`bar`,stack:`gantt`,tooltip:!1,color:`var(--text-secondary-color, #6b7280)`,radius:4,data:h.map(e=>{let t=M(e.start),n=M(e.end??e.start),r=Math.min(1,Math.max(0,e.progress??0));return{x:e.name,y0:t,y:t+(n-t)*r,label:p(r),color:e.color??f(e.group??c)}})});let g=t.filter(e=>e.milestone);g.length&&m.push({id:`gantt:milestones`,name:r.milestoneName??o.milestones,type:`scatter`,color:`var(--text-color, #1f2937)`,pointSize:13,opacity:1,data:g.map(e=>({x:e.name,y:M(e.start),...e.color?{color:e.color}:{}}))});let _=1/0,v=-1/0;for(let e of t)for(let t of[M(e.start),M(e.end??e.start)])t<_&&(_=t),t>v&&(v=t);let y=Number.isFinite(v-_)?Math.max((v-_)*.025,1):0;return{series:m,categories:t.map(e=>e.name),domain:Number.isFinite(_)?[_-y,v+y]:[0,1]}},P=(e,t)=>a(e,`area`,void 0,t).map(e=>e.type===`area`?{...e,lineWidth:e.lineWidth??1.5}:e);exports.DEFAULT_QUADRANT_COLORS=p,exports.areaSeries=s,exports.barSeries=c,exports.binValues=x,exports.boxplotData=T,exports.boxplotSeries=E,exports.boxplotStats=w,exports.bubbleSeries=O,exports.candlestickSeries=u,exports.ganttSeries=N,exports.heatmapChartOptions=d,exports.histogramSeries=S,exports.lineSeries=o,exports.paletteColor=j,exports.presetLabels=i,exports.quadrantChartOptions=_,exports.quadrantOf=g,exports.rangeAreaSeries=P,exports.scatterSeries=l,exports.sparklineOptions=f,exports.waterfallSeries=D,exports.withSeriesType=a;
|
|
3
3
|
//# sourceMappingURL=presets.cjs.map
|