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":["emptyExtent","extentOf","values","min","max","count","v","merge","other","target","isColumns","data","pointCache","pointColumns","cached","columns","list","x","y","z","size","value","colors","labels","i","item","tuple","point","result","gridCache","indices","out","surfaceGrid","cols","rows","valid","grid","barDatum","CategoryIndex","categories","name","found","barColumns","positive","negative","series","s","n","xi","yi","z0","z1","source","zExtent","heightExtent","valueExtent","d","cx","xCategories","cy","yCategories","h","key","stack","base","toWorld","axis","buildAxis","o","options","ticks","extent","includeZero","ensureSpan","nMin","nMax","niceDomain","linearTicks","step","tickStep","tick","locale","seriesType","clamp01","fallback","boxHalf","safe","aspect","largest","buildModel","locale3D","half","barSeries","bars","barIndex","models","type","index","common","color","colorFromZ","usesScale","m","byValue","e","colorDomain"],"sources":["../../../../../charts/src/engine/three-d/model.ts"],"sourcesContent":["// Options -> model: data columns (cached per data object), axis domains,\n// ticks and the world mapping of the 3D charts. The box spans\n// [-half, half] on every axis; the largest side is 2 world units.\n\nimport { ensureSpan, linearTicks, niceDomain, tickStep } from \"../scale\";\nimport { locale3D, type Locale3D } from \"./labels\";\nimport type {\n Bar3DDatum,\n Bar3DSeries,\n Chart3DAxisOptions,\n Chart3DColorBy,\n Chart3DColumnData,\n Chart3DOptions,\n Chart3DPoint,\n Chart3DPointData,\n Chart3DSeries,\n Chart3DSeriesType,\n Line3DSeries,\n Scatter3DSeries,\n Surface3DData,\n Surface3DSeries,\n} from \"./types\";\n\nexport type AxisKey = \"x\" | \"y\" | \"z\";\n\nexport interface Extent {\n min: number;\n max: number;\n}\n\nconst emptyExtent = (): Extent => ({ min: Infinity, max: -Infinity });\n\nconst extentOf = (values: ArrayLike<number>, count = values.length) => {\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < count; i++) {\n const v = values[i];\n if (v < min) min = v;\n if (v > max) max = v;\n }\n return { min, max };\n};\n\nconst merge = (target: Extent, other: Extent) => {\n if (other.min < target.min) target.min = other.min;\n if (other.max > target.max) target.max = other.max;\n};\n\n// ------------------------------------------------------------------ points\n\n/** Columns of a scatter / line series */\nexport interface PointColumns {\n count: number;\n x: ArrayLike<number>;\n y: ArrayLike<number>;\n z: ArrayLike<number>;\n size: ArrayLike<number> | null;\n value: ArrayLike<number> | null;\n colors: readonly (string | undefined)[] | null;\n labels: readonly (string | undefined)[] | null;\n extent: Record<AxisKey | \"value\", Extent>;\n}\n\nconst isColumns = (data: Chart3DPointData): data is Chart3DColumnData =>\n !Array.isArray(data) &&\n typeof (data as Chart3DColumnData).x === \"object\" &&\n (data as Chart3DColumnData).x !== null;\n\nconst pointCache = new WeakMap<object, PointColumns>();\n\n/** Columns of points written as objects, tuples or columns (cached per data object) */\nexport const pointColumns = (data: Chart3DPointData): PointColumns => {\n const cached = pointCache.get(data);\n if (cached) return cached;\n let columns: Omit<PointColumns, \"extent\">;\n if (isColumns(data)) {\n const count = Math.min(data.x.length, data.y.length, data.z.length);\n columns = {\n count,\n x: data.x,\n y: data.y,\n z: data.z,\n size: data.size ?? null,\n value: data.value ?? null,\n colors: null,\n labels: data.label ?? null,\n };\n } else {\n const list = data as readonly (\n Chart3DPoint | readonly [number, number, number]\n )[];\n const count = list.length;\n const x = new Float64Array(count);\n const y = new Float64Array(count);\n const z = new Float64Array(count);\n let size: Float32Array | null = null;\n let value: Float64Array | null = null;\n let colors: (string | undefined)[] | null = null;\n let labels: (string | undefined)[] | null = null;\n for (let i = 0; i < count; i++) {\n const item = list[i];\n if (Array.isArray(item)) {\n const tuple = item as readonly [number, number, number];\n x[i] = tuple[0] ?? NaN;\n y[i] = tuple[1] ?? NaN;\n z[i] = tuple[2] ?? NaN;\n continue;\n }\n const point = item as Chart3DPoint;\n x[i] = point.x;\n y[i] = point.y;\n z[i] = point.z;\n if (point.size !== undefined) {\n size ??= new Float32Array(count).fill(NaN);\n size[i] = point.size;\n }\n if (point.value !== undefined) {\n value ??= new Float64Array(count).fill(NaN);\n value[i] = point.value;\n }\n if (point.color !== undefined) {\n colors ??= new Array<string | undefined>(count);\n colors[i] = point.color;\n }\n if (point.label !== undefined) {\n labels ??= new Array<string | undefined>(count);\n labels[i] = point.label;\n }\n }\n columns = { count, x, y, z, size, value, colors, labels };\n }\n const result: PointColumns = {\n ...columns,\n extent: {\n x: extentOf(columns.x, columns.count),\n y: extentOf(columns.y, columns.count),\n z: extentOf(columns.z, columns.count),\n value: columns.value\n ? extentOf(columns.value, columns.count)\n : emptyExtent(),\n },\n };\n pointCache.set(data, result);\n return result;\n};\n\n// ----------------------------------------------------------------- surface\n\n/** A surface grid with its coordinates */\nexport interface SurfaceGrid {\n rows: number;\n cols: number;\n z: ArrayLike<number>;\n x: ArrayLike<number>;\n y: ArrayLike<number>;\n value: ArrayLike<number> | null;\n extent: Record<AxisKey | \"value\", Extent>;\n}\n\nconst gridCache = new WeakMap<object, SurfaceGrid>();\n\nconst indices = (count: number) => {\n const out = new Float64Array(count);\n for (let i = 0; i < count; i++) out[i] = i;\n return out;\n};\n\nexport const surfaceGrid = (data: Surface3DData): SurfaceGrid => {\n const cached = gridCache.get(data);\n if (cached) return cached;\n const cols = Math.max(0, Math.floor(data.cols));\n const rows = Math.max(0, Math.floor(data.rows));\n const valid = rows >= 2 && cols >= 2 && data.z.length >= rows * cols;\n const x = data.x && data.x.length >= cols ? data.x : indices(cols);\n const y = data.y && data.y.length >= rows ? data.y : indices(rows);\n const value =\n data.value && data.value.length >= rows * cols ? data.value : null;\n const grid: SurfaceGrid = {\n rows: valid ? rows : 0,\n cols: valid ? cols : 0,\n z: data.z,\n x,\n y,\n value,\n extent: {\n x: valid ? extentOf(x, cols) : emptyExtent(),\n y: valid ? extentOf(y, rows) : emptyExtent(),\n z: valid ? extentOf(data.z, rows * cols) : emptyExtent(),\n value: valid && value ? extentOf(value, rows * cols) : emptyExtent(),\n },\n };\n gridCache.set(data, grid);\n return grid;\n};\n\n// -------------------------------------------------------------------- bars\n\n/** Bars of a series resolved to category indices */\nexport interface BarColumns {\n count: number;\n /** Category index on x / y */\n xi: Int32Array;\n yi: Int32Array;\n /** Bottom and top of every bar (stacked on the series before) */\n z0: Float64Array;\n z1: Float64Array;\n /** Height of the datum itself */\n z: Float64Array;\n /** Index of the datum in the series data */\n source: Int32Array;\n value: Float64Array | null;\n colors: (string | undefined)[] | null;\n labels: (string | undefined)[] | null;\n /** `z`: bottoms and tops (stacks included), `height`: the heights of the data */\n extent: Record<\"z\" | \"height\" | \"value\", Extent>;\n}\n\ntype BarInput = Bar3DSeries[\"data\"][number];\n\nconst barDatum = (item: BarInput): Bar3DDatum =>\n Array.isArray(item)\n ? {\n x: (\n item as readonly [string | number, string | number, number | null]\n )[0],\n y: (\n item as readonly [string | number, string | number, number | null]\n )[1],\n z: (\n item as readonly [string | number, string | number, number | null]\n )[2],\n }\n : (item as Bar3DDatum);\n\n/** Category axis of the bars: names given by the axis or collected from the data */\nexport class CategoryIndex {\n readonly names: string[];\n private readonly lookup = new Map<string, number>();\n private readonly fixed: boolean;\n\n constructor(categories: readonly string[] | undefined) {\n this.names = categories ? [...categories] : [];\n this.fixed = !!categories;\n this.names.forEach((name, i) => this.lookup.set(name, i));\n }\n\n /** Index of a category name (numbers are indices when the categories are given) */\n index(value: string | number): number {\n if (typeof value === \"number\" && this.fixed) {\n return Number.isInteger(value) && value >= 0 && value < this.names.length\n ? value\n : -1;\n }\n const name = String(value);\n const found = this.lookup.get(name);\n if (found !== undefined) return found;\n if (this.fixed) return -1;\n this.names.push(name);\n this.lookup.set(name, this.names.length - 1);\n return this.names.length - 1;\n }\n}\n\n/** Bars of every bar series, stacked in series order where cells coincide */\nexport const barColumns = (\n series: readonly Bar3DSeries[],\n xCategories: CategoryIndex,\n yCategories: CategoryIndex,\n): BarColumns[] => {\n const positive = new Map<number, number>();\n const negative = new Map<number, number>();\n return series.map((s) => {\n const data = s.data as readonly BarInput[];\n const n = data.length;\n const xi = new Int32Array(n);\n const yi = new Int32Array(n);\n const z0 = new Float64Array(n);\n const z1 = new Float64Array(n);\n const z = new Float64Array(n);\n const source = new Int32Array(n);\n let value: Float64Array | null = null;\n let colors: (string | undefined)[] | null = null;\n let labels: (string | undefined)[] | null = null;\n const zExtent = emptyExtent();\n const heightExtent = emptyExtent();\n const valueExtent = emptyExtent();\n let count = 0;\n for (let i = 0; i < n; i++) {\n const d = barDatum(data[i]);\n const cx = xCategories.index(d.x);\n const cy = yCategories.index(d.y);\n const h = d.z;\n if (cx < 0 || cy < 0 || h === null || !Number.isFinite(h)) continue;\n const key = cy * 1_000_003 + cx;\n const stack = h >= 0 ? positive : negative;\n const base = s.hidden ? 0 : (stack.get(key) ?? 0);\n if (!s.hidden) stack.set(key, base + h);\n xi[count] = cx;\n yi[count] = cy;\n z0[count] = base;\n z1[count] = base + h;\n z[count] = h;\n source[count] = i;\n if (d.value !== undefined) {\n value ??= new Float64Array(n).fill(NaN);\n value[count] = d.value;\n merge(valueExtent, { min: d.value, max: d.value });\n }\n if (d.color !== undefined) {\n colors ??= new Array<string | undefined>(n);\n colors[count] = d.color;\n }\n if (d.label !== undefined) {\n labels ??= new Array<string | undefined>(n);\n labels[count] = d.label;\n }\n merge(zExtent, {\n min: Math.min(base, base + h),\n max: Math.max(base, base + h),\n });\n merge(heightExtent, { min: h, max: h });\n count++;\n }\n return {\n count,\n xi,\n yi,\n z0,\n z1,\n z,\n source,\n value,\n colors,\n labels,\n extent: { z: zExtent, height: heightExtent, value: valueExtent },\n };\n });\n};\n\n// -------------------------------------------------------------------- axes\n\nexport interface AxisModel {\n key: AxisKey;\n title: string;\n /** Category names (category axis) or `null` */\n categories: string[] | null;\n domain: [number, number];\n /** Half extent of the axis in world units */\n half: number;\n ticks: number[];\n labels: string[];\n /** Full label of any value (tooltips) */\n format: (value: number) => string;\n grid: boolean;\n visible: boolean;\n}\n\n/** World coordinate of a data value */\nexport const toWorld = (axis: AxisModel, value: number): number => {\n const [min, max] = axis.domain;\n return (((value - min) / (max - min || 1)) * 2 - 1) * axis.half;\n};\n\n/** Data value of a world coordinate */\nexport const fromWorld = (axis: AxisModel, world: number): number => {\n const [min, max] = axis.domain;\n return min + ((world / axis.half + 1) / 2) * (max - min);\n};\n\nconst buildAxis = (\n key: AxisKey,\n options: Chart3DAxisOptions | undefined,\n extent: Extent,\n half: number,\n categories: string[] | null,\n includeZero: boolean,\n locale: Locale3D,\n): AxisModel => {\n const o = options ?? {};\n const count = Math.max(2, o.tickCount ?? 5);\n if (categories) {\n const n = Math.max(1, categories.length);\n const name = (v: number) => {\n const i = Math.round(v);\n return o.format ? o.format(i) : (categories[i] ?? String(i));\n };\n const ticks = Array.from({ length: categories.length }, (_, i) => i);\n return {\n key,\n title: o.title ?? \"\",\n categories,\n domain: [-0.5, n - 0.5],\n half,\n ticks,\n labels: ticks.map(name),\n format: name,\n grid: o.grid ?? true,\n visible: o.visible ?? true,\n };\n }\n let min = o.min ?? extent.min;\n let max = o.max ?? extent.max;\n if (includeZero && o.min === undefined && min > 0) min = 0;\n if (includeZero && o.max === undefined && max < 0) max = 0;\n [min, max] = ensureSpan(min, max);\n if (o.nice ?? true) {\n const [nMin, nMax] = niceDomain(min, max, count);\n if (o.min === undefined) min = nMin;\n if (o.max === undefined) max = nMax;\n }\n const ticks = linearTicks(min, max, count);\n const step = tickStep(min, max, count);\n const tick =\n o.format ?? locale.ticks(step, Math.max(Math.abs(min), Math.abs(max)));\n return {\n key,\n title: o.title ?? \"\",\n categories: null,\n domain: [min, max],\n half,\n ticks,\n labels: ticks.map(tick),\n format: o.format ?? locale.value,\n grid: o.grid ?? true,\n visible: o.visible ?? true,\n };\n};\n\n// ------------------------------------------------------------------ series\n\nexport const seriesType = (series: Chart3DSeries): Chart3DSeriesType =>\n series.type ?? \"scatter\";\n\ninterface SeriesModelBase {\n index: number;\n id: string;\n name: string;\n hidden: boolean;\n /** Color option (resolved later with the theme) */\n color: string | undefined;\n colorBy: Chart3DColorBy;\n opacity: number;\n format: ((value: number) => string) | undefined;\n}\n\nexport interface ScatterModel extends SeriesModelBase {\n type: \"scatter\";\n series: Scatter3DSeries;\n cols: PointColumns;\n}\n\nexport interface LineModel extends SeriesModelBase {\n type: \"line\";\n series: Line3DSeries;\n cols: PointColumns;\n}\n\nexport interface SurfaceModel extends SeriesModelBase {\n type: \"surface\";\n series: Surface3DSeries;\n grid: SurfaceGrid;\n}\n\nexport interface BarModel extends SeriesModelBase {\n type: \"bar\";\n series: Bar3DSeries;\n bars: BarColumns;\n}\n\nexport type SeriesModel = ScatterModel | LineModel | SurfaceModel | BarModel;\n\nexport interface Model3D {\n series: SeriesModel[];\n x: AxisModel;\n y: AxisModel;\n z: AxisModel;\n /** Range mapped to the color scale; `null` when no visible series uses it */\n colorDomain: [number, number] | null;\n /** Whether the color domain comes from the heights only (the color bar reuses the z format) */\n colorFromZ: boolean;\n /** Texts and number formats of the `locale` / `labels` options */\n locale: Locale3D;\n}\n\nconst clamp01 = (v: number | undefined, fallback: number) =>\n v === undefined || !Number.isFinite(v)\n ? fallback\n : Math.max(0, Math.min(1, v));\n\n/** Half extents of the box: `aspect` scaled so the largest side is 2 */\nexport const boxHalf = (\n aspect: readonly [number, number, number] | undefined,\n): [number, number, number] => {\n const a = aspect ?? [1, 1, 0.7];\n const safe = a.map((v) => (Number.isFinite(v) && v > 0 ? v : 1)) as [\n number,\n number,\n number,\n ];\n const largest = Math.max(safe[0], safe[1], safe[2]);\n return [safe[0] / largest, safe[1] / largest, safe[2] / largest];\n};\n\nexport const buildModel = (\n options: Chart3DOptions,\n locale: Locale3D = locale3D(options.locale, options.labels),\n): Model3D => {\n const half = boxHalf(options.aspect);\n const extent = { x: emptyExtent(), y: emptyExtent(), z: emptyExtent() };\n const barSeries = options.series.filter((s) => seriesType(s) === \"bar\");\n const xCategories =\n barSeries.length || options.xAxis?.categories\n ? new CategoryIndex(options.xAxis?.categories)\n : null;\n const yCategories =\n barSeries.length || options.yAxis?.categories\n ? new CategoryIndex(options.yAxis?.categories)\n : null;\n const bars =\n xCategories && yCategories\n ? barColumns(barSeries as Bar3DSeries[], xCategories, yCategories)\n : [];\n let barIndex = 0;\n\n const models: SeriesModel[] = options.series.map((series, index) => {\n const type = seriesType(series);\n const base = {\n index,\n id: series.id ?? String(index),\n name: series.name ?? \"\",\n hidden: !!series.hidden,\n color: series.color,\n format: series.format,\n };\n switch (type) {\n case \"surface\": {\n const s = series as Surface3DSeries;\n const grid = surfaceGrid(s.data);\n merge(extent.x, grid.extent.x);\n merge(extent.y, grid.extent.y);\n merge(extent.z, grid.extent.z);\n return {\n ...base,\n type,\n series: s,\n grid,\n colorBy: s.colorBy ?? (grid.value ? \"value\" : \"z\"),\n opacity: clamp01(s.opacity, 1),\n };\n }\n case \"bar\": {\n const s = series as Bar3DSeries;\n const columns = bars[barIndex++]!;\n merge(extent.z, columns.extent.z);\n return {\n ...base,\n type,\n series: s,\n bars: columns,\n colorBy: s.colorBy ?? \"series\",\n opacity: clamp01(s.opacity, 1),\n };\n }\n default: {\n const s = series as Scatter3DSeries | Line3DSeries;\n const cols = pointColumns(s.data);\n merge(extent.x, cols.extent.x);\n merge(extent.y, cols.extent.y);\n merge(extent.z, cols.extent.z);\n const common = {\n ...base,\n cols,\n colorBy: s.colorBy ?? (cols.value ? \"value\" : \"series\"),\n opacity: clamp01(s.opacity, 1),\n } as const;\n return type === \"line\"\n ? { ...common, type: \"line\", series: s as Line3DSeries }\n : { ...common, type: \"scatter\", series: s as Scatter3DSeries };\n }\n }\n });\n\n const x = buildAxis(\n \"x\",\n options.xAxis,\n extent.x,\n half[0],\n xCategories ? xCategories.names : null,\n false,\n locale,\n );\n const y = buildAxis(\n \"y\",\n options.yAxis,\n extent.y,\n half[1],\n yCategories ? yCategories.names : null,\n false,\n locale,\n );\n const z = buildAxis(\n \"z\",\n options.zAxis,\n extent.z,\n half[2],\n null,\n barSeries.length > 0,\n locale,\n );\n\n // color domain: the colored quantity of every visible series using the scale\n const color = emptyExtent();\n let colorFromZ = true;\n let usesScale = false;\n for (const m of models) {\n if (m.hidden || m.colorBy === \"series\") continue;\n usesScale = true;\n const byValue = m.colorBy === \"value\";\n if (m.type === \"surface\") {\n const e = byValue && m.grid.value ? m.grid.extent.value : m.grid.extent.z;\n if (byValue && m.grid.value) colorFromZ = false;\n merge(color, e);\n } else if (m.type === \"bar\") {\n const e =\n byValue && m.bars.value ? m.bars.extent.value : m.bars.extent.height;\n if (byValue && m.bars.value) colorFromZ = false;\n merge(color, e);\n } else {\n const e = byValue && m.cols.value ? m.cols.extent.value : m.cols.extent.z;\n if (byValue && m.cols.value) colorFromZ = false;\n merge(color, e);\n }\n }\n let colorDomain: [number, number] | null = null;\n if (usesScale) {\n colorDomain = options.valueRange\n ? [options.valueRange[0], options.valueRange[1]]\n : ensureSpan(color.min, color.max);\n }\n return { series: models, x, y, z, colorDomain, colorFromZ, locale };\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"model.js","names":["emptyExtent","extentOf","values","min","max","count","v","merge","other","target","isColumns","data","pointCache","pointColumns","cached","columns","list","x","y","z","size","value","colors","labels","i","item","tuple","point","result","gridCache","indices","out","surfaceGrid","cols","rows","valid","grid","barDatum","CategoryIndex","categories","name","found","barColumns","positive","negative","series","s","n","xi","yi","z0","z1","source","zExtent","heightExtent","valueExtent","d","cx","xCategories","cy","yCategories","h","key","stack","base","toWorld","axis","buildAxis","o","options","ticks","extent","includeZero","ensureSpan","nMin","nMax","niceDomain","linearTicks","step","tickStep","tick","locale","seriesType","clamp01","fallback","boxHalf","safe","aspect","largest","buildModel","locale3D","half","barSeries","bars","barIndex","models","type","index","common","color","colorFromZ","usesScale","m","byValue","e","colorDomain"],"sources":["../../../../../charts/src/engine/three-d/model.ts"],"sourcesContent":["// Options -> model: data columns (cached per data object), axis domains,\n// ticks and the world mapping of the 3D charts. The box spans\n// [-half, half] on every axis; the largest side is 2 world units.\n\nimport { ensureSpan, linearTicks, niceDomain, tickStep } from \"../scale\";\nimport { locale3D, type Locale3D } from \"./labels\";\nimport type {\n Bar3DDatum,\n Bar3DSeries,\n Chart3DAxisOptions,\n Chart3DColorBy,\n Chart3DColumnData,\n Chart3DOptions,\n Chart3DPoint,\n Chart3DPointData,\n Chart3DSeries,\n Chart3DSeriesType,\n Line3DSeries,\n Scatter3DSeries,\n Surface3DData,\n Surface3DSeries,\n} from \"./types\";\n\nexport type AxisKey = \"x\" | \"y\" | \"z\";\n\nexport interface Extent {\n min: number;\n max: number;\n}\n\nconst emptyExtent = (): Extent => ({ min: Infinity, max: -Infinity });\n\nconst extentOf = (values: ArrayLike<number>, count = values.length) => {\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < count; i++) {\n const v = values[i];\n if (v < min) min = v;\n if (v > max) max = v;\n }\n return { min, max };\n};\n\nconst merge = (target: Extent, other: Extent) => {\n if (other.min < target.min) target.min = other.min;\n if (other.max > target.max) target.max = other.max;\n};\n\n// ------------------------------------------------------------------ points\n\n/** Columns of a scatter / line series */\nexport interface PointColumns {\n count: number;\n x: ArrayLike<number>;\n y: ArrayLike<number>;\n z: ArrayLike<number>;\n size: ArrayLike<number> | null;\n value: ArrayLike<number> | null;\n colors: readonly (string | undefined)[] | null;\n /** Per-point `0xRRGGBB` colors (column data) */\n rgb: ArrayLike<number> | null;\n labels: readonly (string | undefined)[] | null;\n extent: Record<AxisKey | \"value\", Extent>;\n}\n\nconst isColumns = (data: Chart3DPointData): data is Chart3DColumnData =>\n !Array.isArray(data) &&\n typeof (data as Chart3DColumnData).x === \"object\" &&\n (data as Chart3DColumnData).x !== null;\n\nconst pointCache = new WeakMap<object, PointColumns>();\n\n/** Columns of points written as objects, tuples or columns (cached per data object) */\nexport const pointColumns = (data: Chart3DPointData): PointColumns => {\n const cached = pointCache.get(data);\n if (cached) return cached;\n let columns: Omit<PointColumns, \"extent\">;\n if (isColumns(data)) {\n const count = Math.min(data.x.length, data.y.length, data.z.length);\n columns = {\n count,\n x: data.x,\n y: data.y,\n z: data.z,\n size: data.size ?? null,\n value: data.value ?? null,\n colors: null,\n rgb: data.color ?? null,\n labels: data.label ?? null,\n };\n } else {\n const list = data as readonly (\n Chart3DPoint | readonly [number, number, number]\n )[];\n const count = list.length;\n const x = new Float64Array(count);\n const y = new Float64Array(count);\n const z = new Float64Array(count);\n let size: Float32Array | null = null;\n let value: Float64Array | null = null;\n let colors: (string | undefined)[] | null = null;\n let labels: (string | undefined)[] | null = null;\n for (let i = 0; i < count; i++) {\n const item = list[i];\n if (Array.isArray(item)) {\n const tuple = item as readonly [number, number, number];\n x[i] = tuple[0] ?? NaN;\n y[i] = tuple[1] ?? NaN;\n z[i] = tuple[2] ?? NaN;\n continue;\n }\n const point = item as Chart3DPoint;\n x[i] = point.x;\n y[i] = point.y;\n z[i] = point.z;\n if (point.size !== undefined) {\n size ??= new Float32Array(count).fill(NaN);\n size[i] = point.size;\n }\n if (point.value !== undefined) {\n value ??= new Float64Array(count).fill(NaN);\n value[i] = point.value;\n }\n if (point.color !== undefined) {\n colors ??= new Array<string | undefined>(count);\n colors[i] = point.color;\n }\n if (point.label !== undefined) {\n labels ??= new Array<string | undefined>(count);\n labels[i] = point.label;\n }\n }\n columns = { count, x, y, z, size, value, colors, rgb: null, labels };\n }\n const result: PointColumns = {\n ...columns,\n extent: {\n x: extentOf(columns.x, columns.count),\n y: extentOf(columns.y, columns.count),\n z: extentOf(columns.z, columns.count),\n value: columns.value\n ? extentOf(columns.value, columns.count)\n : emptyExtent(),\n },\n };\n pointCache.set(data, result);\n return result;\n};\n\n// ----------------------------------------------------------------- surface\n\n/** A surface grid with its coordinates */\nexport interface SurfaceGrid {\n rows: number;\n cols: number;\n z: ArrayLike<number>;\n x: ArrayLike<number>;\n y: ArrayLike<number>;\n value: ArrayLike<number> | null;\n extent: Record<AxisKey | \"value\", Extent>;\n}\n\nconst gridCache = new WeakMap<object, SurfaceGrid>();\n\nconst indices = (count: number) => {\n const out = new Float64Array(count);\n for (let i = 0; i < count; i++) out[i] = i;\n return out;\n};\n\nexport const surfaceGrid = (data: Surface3DData): SurfaceGrid => {\n const cached = gridCache.get(data);\n if (cached) return cached;\n const cols = Math.max(0, Math.floor(data.cols));\n const rows = Math.max(0, Math.floor(data.rows));\n const valid = rows >= 2 && cols >= 2 && data.z.length >= rows * cols;\n const x = data.x && data.x.length >= cols ? data.x : indices(cols);\n const y = data.y && data.y.length >= rows ? data.y : indices(rows);\n const value =\n data.value && data.value.length >= rows * cols ? data.value : null;\n const grid: SurfaceGrid = {\n rows: valid ? rows : 0,\n cols: valid ? cols : 0,\n z: data.z,\n x,\n y,\n value,\n extent: {\n x: valid ? extentOf(x, cols) : emptyExtent(),\n y: valid ? extentOf(y, rows) : emptyExtent(),\n z: valid ? extentOf(data.z, rows * cols) : emptyExtent(),\n value: valid && value ? extentOf(value, rows * cols) : emptyExtent(),\n },\n };\n gridCache.set(data, grid);\n return grid;\n};\n\n// -------------------------------------------------------------------- bars\n\n/** Bars of a series resolved to category indices */\nexport interface BarColumns {\n count: number;\n /** Category index on x / y */\n xi: Int32Array;\n yi: Int32Array;\n /** Bottom and top of every bar (stacked on the series before) */\n z0: Float64Array;\n z1: Float64Array;\n /** Height of the datum itself */\n z: Float64Array;\n /** Index of the datum in the series data */\n source: Int32Array;\n value: Float64Array | null;\n colors: (string | undefined)[] | null;\n labels: (string | undefined)[] | null;\n /** `z`: bottoms and tops (stacks included), `height`: the heights of the data */\n extent: Record<\"z\" | \"height\" | \"value\", Extent>;\n}\n\ntype BarInput = Bar3DSeries[\"data\"][number];\n\nconst barDatum = (item: BarInput): Bar3DDatum =>\n Array.isArray(item)\n ? {\n x: (\n item as readonly [string | number, string | number, number | null]\n )[0],\n y: (\n item as readonly [string | number, string | number, number | null]\n )[1],\n z: (\n item as readonly [string | number, string | number, number | null]\n )[2],\n }\n : (item as Bar3DDatum);\n\n/** Category axis of the bars: names given by the axis or collected from the data */\nexport class CategoryIndex {\n readonly names: string[];\n private readonly lookup = new Map<string, number>();\n private readonly fixed: boolean;\n\n constructor(categories: readonly string[] | undefined) {\n this.names = categories ? [...categories] : [];\n this.fixed = !!categories;\n this.names.forEach((name, i) => this.lookup.set(name, i));\n }\n\n /** Index of a category name (numbers are indices when the categories are given) */\n index(value: string | number): number {\n if (typeof value === \"number\" && this.fixed) {\n return Number.isInteger(value) && value >= 0 && value < this.names.length\n ? value\n : -1;\n }\n const name = String(value);\n const found = this.lookup.get(name);\n if (found !== undefined) return found;\n if (this.fixed) return -1;\n this.names.push(name);\n this.lookup.set(name, this.names.length - 1);\n return this.names.length - 1;\n }\n}\n\n/** Bars of every bar series, stacked in series order where cells coincide */\nexport const barColumns = (\n series: readonly Bar3DSeries[],\n xCategories: CategoryIndex,\n yCategories: CategoryIndex,\n): BarColumns[] => {\n const positive = new Map<number, number>();\n const negative = new Map<number, number>();\n return series.map((s) => {\n const data = s.data as readonly BarInput[];\n const n = data.length;\n const xi = new Int32Array(n);\n const yi = new Int32Array(n);\n const z0 = new Float64Array(n);\n const z1 = new Float64Array(n);\n const z = new Float64Array(n);\n const source = new Int32Array(n);\n let value: Float64Array | null = null;\n let colors: (string | undefined)[] | null = null;\n let labels: (string | undefined)[] | null = null;\n const zExtent = emptyExtent();\n const heightExtent = emptyExtent();\n const valueExtent = emptyExtent();\n let count = 0;\n for (let i = 0; i < n; i++) {\n const d = barDatum(data[i]);\n const cx = xCategories.index(d.x);\n const cy = yCategories.index(d.y);\n const h = d.z;\n if (cx < 0 || cy < 0 || h === null || !Number.isFinite(h)) continue;\n const key = cy * 1_000_003 + cx;\n const stack = h >= 0 ? positive : negative;\n const base = s.hidden ? 0 : (stack.get(key) ?? 0);\n if (!s.hidden) stack.set(key, base + h);\n xi[count] = cx;\n yi[count] = cy;\n z0[count] = base;\n z1[count] = base + h;\n z[count] = h;\n source[count] = i;\n if (d.value !== undefined) {\n value ??= new Float64Array(n).fill(NaN);\n value[count] = d.value;\n merge(valueExtent, { min: d.value, max: d.value });\n }\n if (d.color !== undefined) {\n colors ??= new Array<string | undefined>(n);\n colors[count] = d.color;\n }\n if (d.label !== undefined) {\n labels ??= new Array<string | undefined>(n);\n labels[count] = d.label;\n }\n merge(zExtent, {\n min: Math.min(base, base + h),\n max: Math.max(base, base + h),\n });\n merge(heightExtent, { min: h, max: h });\n count++;\n }\n return {\n count,\n xi,\n yi,\n z0,\n z1,\n z,\n source,\n value,\n colors,\n labels,\n extent: { z: zExtent, height: heightExtent, value: valueExtent },\n };\n });\n};\n\n// -------------------------------------------------------------------- axes\n\nexport interface AxisModel {\n key: AxisKey;\n title: string;\n /** Category names (category axis) or `null` */\n categories: string[] | null;\n domain: [number, number];\n /** Half extent of the axis in world units */\n half: number;\n ticks: number[];\n labels: string[];\n /** Full label of any value (tooltips) */\n format: (value: number) => string;\n grid: boolean;\n visible: boolean;\n}\n\n/** World coordinate of a data value */\nexport const toWorld = (axis: AxisModel, value: number): number => {\n const [min, max] = axis.domain;\n return (((value - min) / (max - min || 1)) * 2 - 1) * axis.half;\n};\n\n/** Data value of a world coordinate */\nexport const fromWorld = (axis: AxisModel, world: number): number => {\n const [min, max] = axis.domain;\n return min + ((world / axis.half + 1) / 2) * (max - min);\n};\n\nconst buildAxis = (\n key: AxisKey,\n options: Chart3DAxisOptions | undefined,\n extent: Extent,\n half: number,\n categories: string[] | null,\n includeZero: boolean,\n locale: Locale3D,\n): AxisModel => {\n const o = options ?? {};\n const count = Math.max(2, o.tickCount ?? 5);\n if (categories) {\n const n = Math.max(1, categories.length);\n const name = (v: number) => {\n const i = Math.round(v);\n return o.format ? o.format(i) : (categories[i] ?? String(i));\n };\n const ticks = Array.from({ length: categories.length }, (_, i) => i);\n return {\n key,\n title: o.title ?? \"\",\n categories,\n domain: [-0.5, n - 0.5],\n half,\n ticks,\n labels: ticks.map(name),\n format: name,\n grid: o.grid ?? true,\n visible: o.visible ?? true,\n };\n }\n let min = o.min ?? extent.min;\n let max = o.max ?? extent.max;\n if (includeZero && o.min === undefined && min > 0) min = 0;\n if (includeZero && o.max === undefined && max < 0) max = 0;\n [min, max] = ensureSpan(min, max);\n if (o.nice ?? true) {\n const [nMin, nMax] = niceDomain(min, max, count);\n if (o.min === undefined) min = nMin;\n if (o.max === undefined) max = nMax;\n }\n const ticks = linearTicks(min, max, count);\n const step = tickStep(min, max, count);\n const tick =\n o.format ?? locale.ticks(step, Math.max(Math.abs(min), Math.abs(max)));\n return {\n key,\n title: o.title ?? \"\",\n categories: null,\n domain: [min, max],\n half,\n ticks,\n labels: ticks.map(tick),\n format: o.format ?? locale.value,\n grid: o.grid ?? true,\n visible: o.visible ?? true,\n };\n};\n\n// ------------------------------------------------------------------ series\n\nexport const seriesType = (series: Chart3DSeries): Chart3DSeriesType =>\n series.type ?? \"scatter\";\n\ninterface SeriesModelBase {\n index: number;\n id: string;\n name: string;\n hidden: boolean;\n /** Color option (resolved later with the theme) */\n color: string | undefined;\n colorBy: Chart3DColorBy;\n opacity: number;\n format: ((value: number) => string) | undefined;\n}\n\nexport interface ScatterModel extends SeriesModelBase {\n type: \"scatter\";\n series: Scatter3DSeries;\n cols: PointColumns;\n}\n\nexport interface LineModel extends SeriesModelBase {\n type: \"line\";\n series: Line3DSeries;\n cols: PointColumns;\n}\n\nexport interface SurfaceModel extends SeriesModelBase {\n type: \"surface\";\n series: Surface3DSeries;\n grid: SurfaceGrid;\n}\n\nexport interface BarModel extends SeriesModelBase {\n type: \"bar\";\n series: Bar3DSeries;\n bars: BarColumns;\n}\n\nexport type SeriesModel = ScatterModel | LineModel | SurfaceModel | BarModel;\n\nexport interface Model3D {\n series: SeriesModel[];\n x: AxisModel;\n y: AxisModel;\n z: AxisModel;\n /** Range mapped to the color scale; `null` when no visible series uses it */\n colorDomain: [number, number] | null;\n /** Whether the color domain comes from the heights only (the color bar reuses the z format) */\n colorFromZ: boolean;\n /** Texts and number formats of the `locale` / `labels` options */\n locale: Locale3D;\n}\n\nconst clamp01 = (v: number | undefined, fallback: number) =>\n v === undefined || !Number.isFinite(v)\n ? fallback\n : Math.max(0, Math.min(1, v));\n\n/** Half extents of the box: `aspect` scaled so the largest side is 2 */\nexport const boxHalf = (\n aspect: readonly [number, number, number] | undefined,\n): [number, number, number] => {\n const a = aspect ?? [1, 1, 0.7];\n const safe = a.map((v) => (Number.isFinite(v) && v > 0 ? v : 1)) as [\n number,\n number,\n number,\n ];\n const largest = Math.max(safe[0], safe[1], safe[2]);\n return [safe[0] / largest, safe[1] / largest, safe[2] / largest];\n};\n\nexport const buildModel = (\n options: Chart3DOptions,\n locale: Locale3D = locale3D(options.locale, options.labels),\n): Model3D => {\n const half = boxHalf(options.aspect);\n const extent = { x: emptyExtent(), y: emptyExtent(), z: emptyExtent() };\n const barSeries = options.series.filter((s) => seriesType(s) === \"bar\");\n const xCategories =\n barSeries.length || options.xAxis?.categories\n ? new CategoryIndex(options.xAxis?.categories)\n : null;\n const yCategories =\n barSeries.length || options.yAxis?.categories\n ? new CategoryIndex(options.yAxis?.categories)\n : null;\n const bars =\n xCategories && yCategories\n ? barColumns(barSeries as Bar3DSeries[], xCategories, yCategories)\n : [];\n let barIndex = 0;\n\n const models: SeriesModel[] = options.series.map((series, index) => {\n const type = seriesType(series);\n const base = {\n index,\n id: series.id ?? String(index),\n name: series.name ?? \"\",\n hidden: !!series.hidden,\n color: series.color,\n format: series.format,\n };\n switch (type) {\n case \"surface\": {\n const s = series as Surface3DSeries;\n const grid = surfaceGrid(s.data);\n merge(extent.x, grid.extent.x);\n merge(extent.y, grid.extent.y);\n merge(extent.z, grid.extent.z);\n return {\n ...base,\n type,\n series: s,\n grid,\n colorBy: s.colorBy ?? (grid.value ? \"value\" : \"z\"),\n opacity: clamp01(s.opacity, 1),\n };\n }\n case \"bar\": {\n const s = series as Bar3DSeries;\n const columns = bars[barIndex++]!;\n merge(extent.z, columns.extent.z);\n return {\n ...base,\n type,\n series: s,\n bars: columns,\n colorBy: s.colorBy ?? \"series\",\n opacity: clamp01(s.opacity, 1),\n };\n }\n default: {\n const s = series as Scatter3DSeries | Line3DSeries;\n const cols = pointColumns(s.data);\n merge(extent.x, cols.extent.x);\n merge(extent.y, cols.extent.y);\n merge(extent.z, cols.extent.z);\n const common = {\n ...base,\n cols,\n colorBy: s.colorBy ?? (cols.value ? \"value\" : \"series\"),\n opacity: clamp01(s.opacity, 1),\n } as const;\n return type === \"line\"\n ? { ...common, type: \"line\", series: s as Line3DSeries }\n : { ...common, type: \"scatter\", series: s as Scatter3DSeries };\n }\n }\n });\n\n const x = buildAxis(\n \"x\",\n options.xAxis,\n extent.x,\n half[0],\n xCategories ? xCategories.names : null,\n false,\n locale,\n );\n const y = buildAxis(\n \"y\",\n options.yAxis,\n extent.y,\n half[1],\n yCategories ? yCategories.names : null,\n false,\n locale,\n );\n const z = buildAxis(\n \"z\",\n options.zAxis,\n extent.z,\n half[2],\n null,\n barSeries.length > 0,\n locale,\n );\n\n // color domain: the colored quantity of every visible series using the scale\n const color = emptyExtent();\n let colorFromZ = true;\n let usesScale = false;\n for (const m of models) {\n if (m.hidden || m.colorBy === \"series\") continue;\n usesScale = true;\n const byValue = m.colorBy === \"value\";\n if (m.type === \"surface\") {\n const e = byValue && m.grid.value ? m.grid.extent.value : m.grid.extent.z;\n if (byValue && m.grid.value) colorFromZ = false;\n merge(color, e);\n } else if (m.type === \"bar\") {\n const e =\n byValue && m.bars.value ? m.bars.extent.value : m.bars.extent.height;\n if (byValue && m.bars.value) colorFromZ = false;\n merge(color, e);\n } else {\n const e = byValue && m.cols.value ? m.cols.extent.value : m.cols.extent.z;\n if (byValue && m.cols.value) colorFromZ = false;\n merge(color, e);\n }\n }\n let colorDomain: [number, number] | null = null;\n if (usesScale) {\n colorDomain = options.valueRange\n ? [options.valueRange[0], options.valueRange[1]]\n : ensureSpan(color.min, color.max);\n }\n return { series: models, x, y, z, colorDomain, colorFromZ, locale };\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../color.cjs"),t=require("../scale.cjs"),n=require("./model.cjs"),r=require("./math.cjs");var i=(t,n)=>({text:e.toCss(t.text),muted:e.toCss(t.textMuted),grid:e.toCss(t.grid),axis:e.toCss(t.axis),wall:e.toCss(t.text,n?.045:.025),background:e.toCss(t.background),font:t.fontFamily,fontSize:t.fontSize}),a=[`x`,`y`,`z`],o=e=>{if(e.categories){let t=[];for(let r=0;r<e.categories.length-1;r++)t.push(n.toWorld(e,r+.5));return t}return e.ticks.filter(t=>t>e.domain[0]&&t<e.domain[1]).map(t=>n.toWorld(e,t))},s=e=>[e.eye[0]>=0?-1:1,e.eye[1]>=0?-1:1,e.eye[2]>=0?-1:1],c=e=>[e.x.half,e.y.half,e.z.half],l=(e,t,n)=>{let r=[n[0],n[1],n[2]];return r[e]=t,r},u=(e,t,n,i)=>{let u=c(n),d=s(t),f=e=>r.project(t,e[0],e[1],e[2]);e.lineWidth=1;for(let t=0;t<3;t++){let r=(t+1)%3,s=(t+2)%3,c=[0,0,0];c[t]=d[t]*u[t];let p=(e,t)=>{let n=[c[0],c[1],c[2]];return n[r]=e*u[r],n[s]=t*u[s],f(n)},m=[p(-1,-1),p(1,-1),p(1,1),p(-1,1)];e.beginPath(),m.forEach((t,n)=>n?e.lineTo(t.x,t.y):e.moveTo(t.x,t.y)),e.closePath(),e.fillStyle=i.wall,e.fill(),e.beginPath();for(let[t,i]of[[r,s],[s,r]]){let r=n[a[t]];if(r.grid)for(let n of o(r)){let r=l(t,n,c),a=l(t,n,c);r[i]=-u[i],a[i]=u[i];let o=f(r),s=f(a);e.moveTo(o.x,o.y),e.lineTo(s.x,s.y)}}e.strokeStyle=i.grid,e.stroke(),e.beginPath(),m.forEach((t,n)=>n?e.lineTo(t.x,t.y):e.moveTo(t.x,t.y)),e.closePath(),e.strokeStyle=i.axis,e.stroke()}},d=(e,t,n=2)=>e.x<t.x+t.w+n&&t.x<e.x+e.w+n&&e.y<t.y+t.h+n&&t.y<e.y+e.h+n,f=(e,t,n)=>{let i=c(t),a=e.eye;if(n===0)return[0,(a[1]>=0?1:-1)*i[1],-i[2]];if(n===1)return[(a[0]>=0?1:-1)*i[0],0,-i[2]];let o=[-i[0],-i[1],0],s=1/0;for(let t of[-1,1])for(let n of[-1,1]){let a=r.project(e,t*i[0],n*i[1],0);a.x<s&&(s=a.x,o=[t*i[0],n*i[1],0])}return o},
|
|
1
|
+
const e=require("../color.cjs"),t=require("../scale.cjs"),n=require("./model.cjs"),r=require("./math.cjs");var i=(t,n)=>({text:e.toCss(t.text),muted:e.toCss(t.textMuted),grid:e.toCss(t.grid),axis:e.toCss(t.axis),wall:e.toCss(t.text,n?.045:.025),background:e.toCss(t.background),font:t.fontFamily,fontSize:t.fontSize}),a=[`x`,`y`,`z`],o=e=>{if(e.categories){let t=[];for(let r=0;r<e.categories.length-1;r++)t.push(n.toWorld(e,r+.5));return t}return e.ticks.filter(t=>t>e.domain[0]&&t<e.domain[1]).map(t=>n.toWorld(e,t))},s=e=>[e.eye[0]>=0?-1:1,e.eye[1]>=0?-1:1,e.eye[2]>=0?-1:1],c=e=>[e.x.half,e.y.half,e.z.half],l=(e,t,n)=>{let r=[n[0],n[1],n[2]];return r[e]=t,r},u=(e,t,n,i)=>{let u=c(n),d=s(t),f=e=>r.project(t,e[0],e[1],e[2]);e.lineWidth=1;for(let t=0;t<3;t++){let r=(t+1)%3,s=(t+2)%3,c=[0,0,0];c[t]=d[t]*u[t];let p=(e,t)=>{let n=[c[0],c[1],c[2]];return n[r]=e*u[r],n[s]=t*u[s],f(n)},m=[p(-1,-1),p(1,-1),p(1,1),p(-1,1)];e.beginPath(),m.forEach((t,n)=>n?e.lineTo(t.x,t.y):e.moveTo(t.x,t.y)),e.closePath(),e.fillStyle=i.wall,e.fill(),e.beginPath();for(let[t,i]of[[r,s],[s,r]]){let r=n[a[t]];if(r.grid)for(let n of o(r)){let r=l(t,n,c),a=l(t,n,c);r[i]=-u[i],a[i]=u[i];let o=f(r),s=f(a);e.moveTo(o.x,o.y),e.lineTo(s.x,s.y)}}e.strokeStyle=i.grid,e.stroke(),e.beginPath(),m.forEach((t,n)=>n?e.lineTo(t.x,t.y):e.moveTo(t.x,t.y)),e.closePath(),e.strokeStyle=i.axis,e.stroke()}},d=(e,t,n=2)=>e.x<t.x+t.w+n&&t.x<e.x+e.w+n&&e.y<t.y+t.h+n&&t.y<e.y+e.h+n,f=10,p=(e,t,n)=>{let i=c(t),a=e.eye;if(n===0)return[0,(a[1]>=0?1:-1)*i[1],-i[2]];if(n===1)return[(a[0]>=0?1:-1)*i[0],0,-i[2]];let o=[-i[0],-i[1],0],s=1/0;for(let t of[-1,1])for(let n of[-1,1]){let a=r.project(e,t*i[0],n*i[1],0);a.x<s&&(s=a.x,o=[t*i[0],n*i[1],0])}return o},m=(e,t,i,o,s={left:0,top:0,right:t.width,bottom:t.height})=>{let c=r.project(t,0,0,0),u=[],m=o.fontSize,h=`${m}px ${o.font}`,g=`600 ${m+1}px ${o.font}`;for(let _=0;_<3;_++){let v=i[a[_]];if(!v.visible)continue;let y=p(t,i,_),b=r.project(t,...l(_,-v.half,y)),x=r.project(t,...l(_,v.half,y)),S=x.x-b.x,C=x.y-b.y,w=Math.hypot(S,C);if(w<24)continue;S/=w,C/=w;let T=-C,E=S,D=(b.x+x.x)/2,O=(b.y+x.y)/2;T*(D-c.x)+E*(O-c.y)<0&&(T=-T,E=-E),_===2&&(T=D<c.x?-1:1,E=0);let k=T>.35?`left`:T<-.35?`right`:`center`,A=E>.35?`top`:E<-.35?`bottom`:`middle`;e.font=h,e.textAlign=k,e.textBaseline=A;let j=v.ticks.map((i,a)=>{let o=r.project(t,...l(_,n.toWorld(v,i),y)),s=v.labels[a]??``,c=e.measureText(s).width,u=o.x+T*8,d=o.y+E*8;return{tick:o,text:s,x:u,y:d,rect:{x:k===`left`?u:k===`right`?u-c:u-c/2,y:A===`top`?d:A===`bottom`?d-m:d-m/2,w:c,h:m}}}),M=1;for(;M<j.length;M++){let e=j.filter((e,t)=>t%M===0);if(e.every((t,n)=>!e.slice(0,n).some(e=>d(t.rect,e.rect))))break}let N=0;if(e.beginPath(),j.forEach((t,n)=>{n%M||u.some(e=>d(t.rect,e,f))||(u.push(t.rect),e.moveTo(t.tick.x,t.tick.y),e.lineTo(t.tick.x+T*4,t.tick.y+E*4),N=Math.max(N,Math.abs(T)*t.rect.w+Math.abs(E)*t.rect.h))}),e.strokeStyle=o.axis,e.lineWidth=1,e.stroke(),e.fillStyle=o.muted,j.forEach((t,n)=>{n%M||!u.includes(t.rect)||e.fillText(t.text,t.x,t.y)}),!v.title)continue;let P=8+N+10,F=D+T*P,I=O+E*P;e.font=g,e.fillStyle=o.text;let L=e.measureText(v.title).width,R=m+1;if(_===2)F=Math.max(s.left+R,Math.min(s.right-R,F)),I=Math.max(s.top+L/2,Math.min(s.bottom-L/2,I)),e.save(),e.translate(F,I),e.rotate(-Math.PI/2),e.textAlign=`center`,e.textBaseline=T<0?`bottom`:`top`,e.fillText(v.title,0,0),e.restore();else{let t=(e,t)=>({x:k===`left`?e:k===`right`?e-L:e-L/2,y:A===`top`?t:A===`bottom`?t-R:t-R/2,w:L,h:R});for(let e=0;e<12&&u.some(e=>d(t(F,I),e));e++)F+=T*3,I+=E*3;let{x:n,y:r}=t(F,I);F+=Math.max(0,s.left-n)-Math.max(0,n+L-s.right),I+=Math.max(0,s.top-r)-Math.max(0,r+R-s.bottom),u.push(t(F,I)),e.textAlign=k,e.textBaseline=A,e.fillText(v.title,F,I)}}},h=(n,r,i,a,o,s,c,l=1/0)=>{let u=n.createLinearGradient(0,r.y+r.h,0,r.y);for(let t=0;t<=24;t++){let n=i.rgba[Math.round(t/24*(i.rgba.length-1))];n&&u.addColorStop(t/24,e.toCss(n))}n.fillStyle=u,n.beginPath(),typeof n.roundRect==`function`?n.roundRect(r.x,r.y,r.w,r.h,3):n.rect(r.x,r.y,r.w,r.h),n.fill(),n.strokeStyle=c.axis,n.lineWidth=1,n.stroke();let[d,f]=a,p=f-d||1;n.font=`${c.fontSize}px ${c.font}`,n.fillStyle=c.muted,n.textAlign=`left`,n.textBaseline=`middle`;let m=t.linearTicks(d,f,Math.max(2,Math.round(r.h/40)));n.beginPath();for(let e of m){let t=r.y+r.h-(e-d)/p*r.h;t<r.y-.5||t>r.y+r.h+.5||(n.moveTo(r.x+r.w,t),n.lineTo(r.x+r.w+4,t),n.fillText(o(e),r.x+r.w+7,t))}if(n.strokeStyle=c.axis,n.stroke(),s){n.font=`600 ${c.fontSize}px ${c.font}`,n.fillStyle=c.text,n.textAlign=`left`,n.textBaseline=`bottom`;let e=n.measureText(s).width;n.fillText(s,Math.max(4,Math.min(r.x,l-4-e)),r.y-8)}},g=(e,t,n,i,a)=>{if(e.save(),i.kind===`point`)e.beginPath(),e.arc(i.x,i.y,i.radius+3,0,Math.PI*2),e.lineWidth=3,e.strokeStyle=a.background,e.stroke(),e.lineWidth=1.5,e.strokeStyle=a.text,e.stroke();else if(i.kind===`box`){let{min:n,max:o}=i,s=e=>r.project(t,e&1?o[0]:n[0],e&2?o[1]:n[1],e&4?o[2]:n[2]),c=Array.from({length:8},(e,t)=>s(t));e.beginPath();for(let t=0;t<8;t++)for(let n of[1,2,4]){if(t&n)continue;let r=c[t],i=c[t|n];e.moveTo(r.x,r.y),e.lineTo(i.x,i.y)}e.lineJoin=`round`,e.lineWidth=3.5,e.strokeStyle=a.background,e.stroke(),e.lineWidth=1.5,e.strokeStyle=a.text,e.stroke()}else{let[o,s,c]=i.world,l=r.project(t,o,s,c),u=r.project(t,o,s,-n.z.half);e.beginPath(),e.setLineDash([3,3]),e.moveTo(l.x,l.y),e.lineTo(u.x,u.y),e.lineWidth=1,e.strokeStyle=a.text,e.stroke(),e.setLineDash([]),e.beginPath(),e.arc(u.x,u.y,2.5,0,Math.PI*2),e.fillStyle=a.text,e.fill(),e.beginPath(),e.arc(l.x,l.y,5,0,Math.PI*2),e.fillStyle=i.color,e.fill(),e.lineWidth=2,e.strokeStyle=a.background,e.stroke(),e.beginPath(),e.arc(l.x,l.y,7,0,Math.PI*2),e.lineWidth=1.25,e.strokeStyle=a.text,e.stroke()}e.restore()};exports.drawAxes=m,exports.drawColorBar=h,exports.drawHighlight=g,exports.drawWalls=u,exports.farWalls=s,exports.gridPositions=o,exports.labelEdge=p,exports.overlayStyle=i;
|
|
2
2
|
//# sourceMappingURL=overlay.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.cjs","names":["toCss","toWorld","project","linearTicks","require_color","require_scale","require_model","require_math","overlayStyle","theme","dark","AXES","gridPositions","axis","out","i","farWalls","frame","half","axes","at","p","rest","value","drawWalls","h","walls","P","a","b","c","base","corner","sb","sc","quad","ctx","q","style","along","across","w","p0","p1","s0","s1","overlaps","pad","labelEdge","eye","best","left","sx","sy","drawAxes","center","placed","size","labelFont","titleFont","edge","e0","e1","dx","dy","length","ox","oy","mx","my","align","baseline","labels","s","tick","text","x","y","step","kept","l","o","extent","distance","tx","ty","tw","th","bounds","top","drawColorBar","gradient","rect","lut","min","max","domain","span","ticks","t","format","title","right","drawHighlight","shape","pts","bit","z","floor"],"sources":["../../../../../charts/src/engine/three-d/overlay.ts"],"sourcesContent":["// 2D overlay of the 3D charts: the far walls of the axis box with their grid\n// lines (below the data), then the tick labels, axis titles, color bar and\n// hover highlight (above the data). Text is always horizontal (screen\n// aligned) so it stays readable whatever the camera.\n\nimport { toCss, type Rgba } from \"../color\";\nimport { linearTicks } from \"../scale\";\nimport type { ColorLut } from \"./colormap\";\nimport { project, type CameraFrame, type Vec3 } from \"./math\";\nimport { toWorld, type AxisModel, type Model3D } from \"./model\";\n\nexport interface OverlayStyle {\n text: string;\n muted: string;\n grid: string;\n axis: string;\n /** Tint of the walls */\n wall: string;\n /** Background (rings of the hover marker) */\n background: string;\n font: string;\n fontSize: number;\n}\n\nexport const overlayStyle = (\n theme: {\n text: Rgba;\n textMuted: Rgba;\n grid: Rgba;\n axis: Rgba;\n background: Rgba;\n fontFamily: string;\n fontSize: number;\n },\n dark: boolean,\n): OverlayStyle => ({\n text: toCss(theme.text),\n muted: toCss(theme.textMuted),\n grid: toCss(theme.grid),\n axis: toCss(theme.axis),\n wall: toCss(theme.text, dark ? 0.045 : 0.025),\n background: toCss(theme.background),\n font: theme.fontFamily,\n fontSize: theme.fontSize,\n});\n\ntype Axes = Pick<Model3D, \"x\" | \"y\" | \"z\">;\n\nconst AXES: readonly (\"x\" | \"y\" | \"z\")[] = [\"x\", \"y\", \"z\"];\n\n/** World positions of the grid lines of an axis (category axes: between the categories) */\nexport const gridPositions = (axis: AxisModel): number[] => {\n if (axis.categories) {\n const out: number[] = [];\n for (let i = 0; i < axis.categories.length - 1; i++)\n out.push(toWorld(axis, i + 0.5));\n return out;\n }\n return axis.ticks\n .filter((t) => t > axis.domain[0] && t < axis.domain[1])\n .map((t) => toWorld(axis, t));\n};\n\n/** Side (-1 / 1) of the far wall perpendicular to every axis */\nexport const farWalls = (frame: CameraFrame): [number, number, number] => [\n frame.eye[0] >= 0 ? -1 : 1,\n frame.eye[1] >= 0 ? -1 : 1,\n frame.eye[2] >= 0 ? -1 : 1,\n];\n\nconst half = (axes: Axes): Vec3 => [axes.x.half, axes.y.half, axes.z.half];\n\nconst at = (axis: number, value: number, rest: Vec3): Vec3 => {\n const p: Vec3 = [rest[0], rest[1], rest[2]];\n p[axis] = value;\n return p;\n};\n\n/** Far walls, their grid lines and borders */\nexport const drawWalls = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n style: OverlayStyle,\n): void => {\n const h = half(axes);\n const walls = farWalls(frame);\n const P = (p: Vec3) => project(frame, p[0], p[1], p[2]);\n ctx.lineWidth = 1;\n for (let a = 0; a < 3; a++) {\n const b = (a + 1) % 3;\n const c = (a + 2) % 3;\n const base: Vec3 = [0, 0, 0];\n base[a] = walls[a] * h[a];\n const corner = (sb: number, sc: number) => {\n const p: Vec3 = [base[0], base[1], base[2]];\n p[b] = sb * h[b];\n p[c] = sc * h[c];\n return P(p);\n };\n const quad = [corner(-1, -1), corner(1, -1), corner(1, 1), corner(-1, 1)];\n ctx.beginPath();\n quad.forEach((q, i) => (i ? ctx.lineTo(q.x, q.y) : ctx.moveTo(q.x, q.y)));\n ctx.closePath();\n ctx.fillStyle = style.wall;\n ctx.fill();\n // grid lines of the two axes spanning the wall\n ctx.beginPath();\n for (const [along, across] of [\n [b, c],\n [c, b],\n ] as const) {\n const axis = axes[AXES[along]!];\n if (!axis.grid) continue;\n for (const w of gridPositions(axis)) {\n const p0 = at(along, w, base);\n const p1 = at(along, w, base);\n p0[across] = -h[across];\n p1[across] = h[across];\n const s0 = P(p0);\n const s1 = P(p1);\n ctx.moveTo(s0.x, s0.y);\n ctx.lineTo(s1.x, s1.y);\n }\n }\n ctx.strokeStyle = style.grid;\n ctx.stroke();\n ctx.beginPath();\n quad.forEach((q, i) => (i ? ctx.lineTo(q.x, q.y) : ctx.moveTo(q.x, q.y)));\n ctx.closePath();\n ctx.strokeStyle = style.axis;\n ctx.stroke();\n }\n};\n\ninterface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nconst overlaps = (a: Rect, b: Rect, pad = 2) =>\n a.x < b.x + b.w + pad &&\n b.x < a.x + a.w + pad &&\n a.y < b.y + b.h + pad &&\n b.y < a.y + a.h + pad;\n\n/** Edge (fixed coordinates of the two other axes) carrying the labels of an axis */\nexport const labelEdge = (\n frame: CameraFrame,\n axes: Axes,\n axis: number,\n): Vec3 => {\n const h = half(axes);\n const eye = frame.eye;\n if (axis === 0) return [0, (eye[1] >= 0 ? 1 : -1) * h[1], -h[2]];\n if (axis === 1) return [(eye[0] >= 0 ? 1 : -1) * h[0], 0, -h[2]];\n // vertical axis: the leftmost vertical edge on screen\n let best: Vec3 = [-h[0], -h[1], 0];\n let left = Infinity;\n for (const sx of [-1, 1]) {\n for (const sy of [-1, 1]) {\n const p = project(frame, sx * h[0], sy * h[1], 0);\n if (p.x < left) {\n left = p.x;\n best = [sx * h[0], sy * h[1], 0];\n }\n }\n }\n return best;\n};\n\n/** Area the labels and titles must stay in (CSS pixels of the stage) */\nexport interface OverlayBounds {\n left: number;\n top: number;\n right: number;\n bottom: number;\n}\n\n/** Tick labels and titles of the three axes */\nexport const drawAxes = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n style: OverlayStyle,\n bounds: OverlayBounds = {\n left: 0,\n top: 0,\n right: frame.width,\n bottom: frame.height,\n },\n): void => {\n const center = project(frame, 0, 0, 0);\n const placed: Rect[] = [];\n const size = style.fontSize;\n const labelFont = `${size}px ${style.font}`;\n const titleFont = `600 ${size + 1}px ${style.font}`;\n for (let a = 0; a < 3; a++) {\n const axis = axes[AXES[a]!];\n if (!axis.visible) continue;\n const edge = labelEdge(frame, axes, a);\n const e0 = project(frame, ...at(a, -axis.half, edge));\n const e1 = project(frame, ...at(a, axis.half, edge));\n let dx = e1.x - e0.x;\n let dy = e1.y - e0.y;\n const length = Math.hypot(dx, dy);\n // seen end-on: no room for labels\n if (length < 24) continue;\n dx /= length;\n dy /= length;\n let ox = -dy;\n let oy = dx;\n const mx = (e0.x + e1.x) / 2;\n const my = (e0.y + e1.y) / 2;\n if (ox * (mx - center.x) + oy * (my - center.y) < 0) {\n ox = -ox;\n oy = -oy;\n }\n // vertical axis: labels go sideways\n if (a === 2) {\n ox = mx < center.x ? -1 : 1;\n oy = 0;\n }\n const align: CanvasTextAlign =\n ox > 0.35 ? \"left\" : ox < -0.35 ? \"right\" : \"center\";\n const baseline: CanvasTextBaseline =\n oy > 0.35 ? \"top\" : oy < -0.35 ? \"bottom\" : \"middle\";\n ctx.font = labelFont;\n ctx.textAlign = align;\n ctx.textBaseline = baseline;\n const gap = 8;\n const labels = axis.ticks.map((tick, i) => {\n const s = project(frame, ...at(a, toWorld(axis, tick), edge));\n const text = axis.labels[i] ?? \"\";\n const w = ctx.measureText(text).width;\n const x = s.x + ox * gap;\n const y = s.y + oy * gap;\n const rx = align === \"left\" ? x : align === \"right\" ? x - w : x - w / 2;\n const ry =\n baseline === \"top\"\n ? y\n : baseline === \"bottom\"\n ? y - size\n : y - size / 2;\n return { tick: s, text, x, y, rect: { x: rx, y: ry, w, h: size } };\n });\n // thin the labels until they do not overlap\n let step = 1;\n for (; step < labels.length; step++) {\n const kept = labels.filter((_, i) => i % step === 0);\n if (\n kept.every(\n (l, i) => !kept.slice(0, i).some((o) => overlaps(l.rect, o.rect)),\n )\n ) {\n break;\n }\n }\n let extent = 0;\n ctx.beginPath();\n labels.forEach((l, i) => {\n if (i % step) return;\n if (placed.some((o) => overlaps(l.rect, o))) return;\n placed.push(l.rect);\n ctx.moveTo(l.tick.x, l.tick.y);\n ctx.lineTo(l.tick.x + ox * 4, l.tick.y + oy * 4);\n extent = Math.max(\n extent,\n Math.abs(ox) * l.rect.w + Math.abs(oy) * l.rect.h,\n );\n });\n ctx.strokeStyle = style.axis;\n ctx.lineWidth = 1;\n ctx.stroke();\n ctx.fillStyle = style.muted;\n labels.forEach((l, i) => {\n if (i % step || !placed.includes(l.rect)) return;\n ctx.fillText(l.text, l.x, l.y);\n });\n if (!axis.title) continue;\n const distance = gap + extent + 10;\n let tx = mx + ox * distance;\n let ty = my + oy * distance;\n ctx.font = titleFont;\n ctx.fillStyle = style.text;\n const tw = ctx.measureText(axis.title).width;\n const th = size + 1;\n if (a === 2) {\n tx = Math.max(bounds.left + th, Math.min(bounds.right - th, tx));\n ty = Math.max(bounds.top + tw / 2, Math.min(bounds.bottom - tw / 2, ty));\n ctx.save();\n ctx.translate(tx, ty);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.textBaseline = ox < 0 ? \"bottom\" : \"top\";\n ctx.fillText(axis.title, 0, 0);\n ctx.restore();\n } else {\n // keep the whole title inside the bounds\n const left =\n align === \"left\" ? tx : align === \"right\" ? tx - tw : tx - tw / 2;\n const top =\n baseline === \"top\" ? ty : baseline === \"bottom\" ? ty - th : ty - th / 2;\n tx +=\n Math.max(0, bounds.left - left) - Math.max(0, left + tw - bounds.right);\n ty +=\n Math.max(0, bounds.top - top) - Math.max(0, top + th - bounds.bottom);\n ctx.textAlign = align;\n ctx.textBaseline = baseline;\n ctx.fillText(axis.title, tx, ty);\n }\n }\n};\n\n/** Vertical color bar with its ticks and title */\nexport const drawColorBar = (\n ctx: CanvasRenderingContext2D,\n rect: Rect,\n lut: ColorLut,\n domain: readonly [number, number],\n format: (value: number) => string,\n title: string,\n style: OverlayStyle,\n /** Right end of the stage: the title is shifted left to fit */\n right = Infinity,\n): void => {\n const gradient = ctx.createLinearGradient(0, rect.y + rect.h, 0, rect.y);\n const samples = 24;\n for (let i = 0; i <= samples; i++) {\n const c = lut.rgba[Math.round((i / samples) * (lut.rgba.length - 1))];\n if (c) gradient.addColorStop(i / samples, toCss(c));\n }\n ctx.fillStyle = gradient;\n ctx.beginPath();\n if (typeof ctx.roundRect === \"function\")\n ctx.roundRect(rect.x, rect.y, rect.w, rect.h, 3);\n else ctx.rect(rect.x, rect.y, rect.w, rect.h);\n ctx.fill();\n ctx.strokeStyle = style.axis;\n ctx.lineWidth = 1;\n ctx.stroke();\n const [min, max] = domain;\n const span = max - min || 1;\n ctx.font = `${style.fontSize}px ${style.font}`;\n ctx.fillStyle = style.muted;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const ticks = linearTicks(min, max, Math.max(2, Math.round(rect.h / 40)));\n ctx.beginPath();\n for (const t of ticks) {\n const y = rect.y + rect.h - ((t - min) / span) * rect.h;\n if (y < rect.y - 0.5 || y > rect.y + rect.h + 0.5) continue;\n ctx.moveTo(rect.x + rect.w, y);\n ctx.lineTo(rect.x + rect.w + 4, y);\n ctx.fillText(format(t), rect.x + rect.w + 7, y);\n }\n ctx.strokeStyle = style.axis;\n ctx.stroke();\n if (title) {\n ctx.font = `600 ${style.fontSize}px ${style.font}`;\n ctx.fillStyle = style.text;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"bottom\";\n const w = ctx.measureText(title).width;\n ctx.fillText(\n title,\n Math.max(4, Math.min(rect.x, right - 4 - w)),\n rect.y - 8,\n );\n }\n};\n\n/** Highlight of the hovered item */\nexport type HighlightShape =\n | { kind: \"point\"; x: number; y: number; radius: number; color: string }\n | { kind: \"box\"; min: Vec3; max: Vec3; color: string }\n | { kind: \"vertex\"; world: Vec3; color: string };\n\nexport const drawHighlight = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n shape: HighlightShape,\n style: OverlayStyle,\n): void => {\n ctx.save();\n if (shape.kind === \"point\") {\n ctx.beginPath();\n ctx.arc(shape.x, shape.y, shape.radius + 3, 0, Math.PI * 2);\n ctx.lineWidth = 3;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.lineWidth = 1.5;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n } else if (shape.kind === \"box\") {\n const { min, max } = shape;\n const corner = (i: number) =>\n project(\n frame,\n i & 1 ? max[0] : min[0],\n i & 2 ? max[1] : min[1],\n i & 4 ? max[2] : min[2],\n );\n const pts = Array.from({ length: 8 }, (_, i) => corner(i));\n ctx.beginPath();\n for (let i = 0; i < 8; i++) {\n for (const bit of [1, 2, 4]) {\n if (i & bit) continue;\n const a = pts[i]!;\n const b = pts[i | bit]!;\n ctx.moveTo(a.x, a.y);\n ctx.lineTo(b.x, b.y);\n }\n }\n ctx.lineJoin = \"round\";\n ctx.lineWidth = 3.5;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.lineWidth = 1.5;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n } else {\n const [x, y, z] = shape.world;\n const top = project(frame, x, y, z);\n const floor = project(frame, x, y, -axes.z.half);\n ctx.beginPath();\n ctx.setLineDash([3, 3]);\n ctx.moveTo(top.x, top.y);\n ctx.lineTo(floor.x, floor.y);\n ctx.lineWidth = 1;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n ctx.setLineDash([]);\n ctx.beginPath();\n ctx.arc(floor.x, floor.y, 2.5, 0, Math.PI * 2);\n ctx.fillStyle = style.text;\n ctx.fill();\n ctx.beginPath();\n ctx.arc(top.x, top.y, 5, 0, Math.PI * 2);\n ctx.fillStyle = shape.color;\n ctx.fill();\n ctx.lineWidth = 2;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.beginPath();\n ctx.arc(top.x, top.y, 7, 0, Math.PI * 2);\n ctx.lineWidth = 1.25;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n }\n ctx.restore();\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"overlay.cjs","names":["toCss","toWorld","project","linearTicks","require_color","require_scale","require_model","require_math","overlayStyle","theme","dark","AXES","gridPositions","axis","out","i","farWalls","frame","half","axes","at","p","rest","value","drawWalls","h","walls","P","a","b","c","base","corner","sb","sc","quad","ctx","q","style","along","across","w","p0","p1","s0","s1","overlaps","pad","CROSS_AXIS_GAP","labelEdge","eye","best","left","sx","sy","drawAxes","center","placed","size","labelFont","titleFont","edge","e0","e1","dx","dy","length","ox","oy","mx","my","align","baseline","labels","s","tick","text","x","y","step","kept","l","o","extent","distance","tx","ty","tw","th","bounds","rectAt","k","top","drawColorBar","gradient","rect","lut","min","max","domain","span","ticks","t","format","title","right","drawHighlight","shape","pts","bit","z","floor"],"sources":["../../../../../charts/src/engine/three-d/overlay.ts"],"sourcesContent":["// 2D overlay of the 3D charts: the far walls of the axis box with their grid\n// lines (below the data), then the tick labels, axis titles, color bar and\n// hover highlight (above the data). Text is always horizontal (screen\n// aligned) so it stays readable whatever the camera.\n\nimport { toCss, type Rgba } from \"../color\";\nimport { linearTicks } from \"../scale\";\nimport type { ColorLut } from \"./colormap\";\nimport { project, type CameraFrame, type Vec3 } from \"./math\";\nimport { toWorld, type AxisModel, type Model3D } from \"./model\";\n\nexport interface OverlayStyle {\n text: string;\n muted: string;\n grid: string;\n axis: string;\n /** Tint of the walls */\n wall: string;\n /** Background (rings of the hover marker) */\n background: string;\n font: string;\n fontSize: number;\n}\n\nexport const overlayStyle = (\n theme: {\n text: Rgba;\n textMuted: Rgba;\n grid: Rgba;\n axis: Rgba;\n background: Rgba;\n fontFamily: string;\n fontSize: number;\n },\n dark: boolean,\n): OverlayStyle => ({\n text: toCss(theme.text),\n muted: toCss(theme.textMuted),\n grid: toCss(theme.grid),\n axis: toCss(theme.axis),\n wall: toCss(theme.text, dark ? 0.045 : 0.025),\n background: toCss(theme.background),\n font: theme.fontFamily,\n fontSize: theme.fontSize,\n});\n\ntype Axes = Pick<Model3D, \"x\" | \"y\" | \"z\">;\n\nconst AXES: readonly (\"x\" | \"y\" | \"z\")[] = [\"x\", \"y\", \"z\"];\n\n/** World positions of the grid lines of an axis (category axes: between the categories) */\nexport const gridPositions = (axis: AxisModel): number[] => {\n if (axis.categories) {\n const out: number[] = [];\n for (let i = 0; i < axis.categories.length - 1; i++)\n out.push(toWorld(axis, i + 0.5));\n return out;\n }\n return axis.ticks\n .filter((t) => t > axis.domain[0] && t < axis.domain[1])\n .map((t) => toWorld(axis, t));\n};\n\n/** Side (-1 / 1) of the far wall perpendicular to every axis */\nexport const farWalls = (frame: CameraFrame): [number, number, number] => [\n frame.eye[0] >= 0 ? -1 : 1,\n frame.eye[1] >= 0 ? -1 : 1,\n frame.eye[2] >= 0 ? -1 : 1,\n];\n\nconst half = (axes: Axes): Vec3 => [axes.x.half, axes.y.half, axes.z.half];\n\nconst at = (axis: number, value: number, rest: Vec3): Vec3 => {\n const p: Vec3 = [rest[0], rest[1], rest[2]];\n p[axis] = value;\n return p;\n};\n\n/** Far walls, their grid lines and borders */\nexport const drawWalls = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n style: OverlayStyle,\n): void => {\n const h = half(axes);\n const walls = farWalls(frame);\n const P = (p: Vec3) => project(frame, p[0], p[1], p[2]);\n ctx.lineWidth = 1;\n for (let a = 0; a < 3; a++) {\n const b = (a + 1) % 3;\n const c = (a + 2) % 3;\n const base: Vec3 = [0, 0, 0];\n base[a] = walls[a] * h[a];\n const corner = (sb: number, sc: number) => {\n const p: Vec3 = [base[0], base[1], base[2]];\n p[b] = sb * h[b];\n p[c] = sc * h[c];\n return P(p);\n };\n const quad = [corner(-1, -1), corner(1, -1), corner(1, 1), corner(-1, 1)];\n ctx.beginPath();\n quad.forEach((q, i) => (i ? ctx.lineTo(q.x, q.y) : ctx.moveTo(q.x, q.y)));\n ctx.closePath();\n ctx.fillStyle = style.wall;\n ctx.fill();\n // grid lines of the two axes spanning the wall\n ctx.beginPath();\n for (const [along, across] of [\n [b, c],\n [c, b],\n ] as const) {\n const axis = axes[AXES[along]!];\n if (!axis.grid) continue;\n for (const w of gridPositions(axis)) {\n const p0 = at(along, w, base);\n const p1 = at(along, w, base);\n p0[across] = -h[across];\n p1[across] = h[across];\n const s0 = P(p0);\n const s1 = P(p1);\n ctx.moveTo(s0.x, s0.y);\n ctx.lineTo(s1.x, s1.y);\n }\n }\n ctx.strokeStyle = style.grid;\n ctx.stroke();\n ctx.beginPath();\n quad.forEach((q, i) => (i ? ctx.lineTo(q.x, q.y) : ctx.moveTo(q.x, q.y)));\n ctx.closePath();\n ctx.strokeStyle = style.axis;\n ctx.stroke();\n }\n};\n\ninterface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nconst overlaps = (a: Rect, b: Rect, pad = 2) =>\n a.x < b.x + b.w + pad &&\n b.x < a.x + a.w + pad &&\n a.y < b.y + b.h + pad &&\n b.y < a.y + a.h + pad;\n\n/** Smallest gap (px) between tick labels of different axes */\nconst CROSS_AXIS_GAP = 10;\n\n/** Edge (fixed coordinates of the two other axes) carrying the labels of an axis */\nexport const labelEdge = (\n frame: CameraFrame,\n axes: Axes,\n axis: number,\n): Vec3 => {\n const h = half(axes);\n const eye = frame.eye;\n if (axis === 0) return [0, (eye[1] >= 0 ? 1 : -1) * h[1], -h[2]];\n if (axis === 1) return [(eye[0] >= 0 ? 1 : -1) * h[0], 0, -h[2]];\n // vertical axis: the leftmost vertical edge on screen\n let best: Vec3 = [-h[0], -h[1], 0];\n let left = Infinity;\n for (const sx of [-1, 1]) {\n for (const sy of [-1, 1]) {\n const p = project(frame, sx * h[0], sy * h[1], 0);\n if (p.x < left) {\n left = p.x;\n best = [sx * h[0], sy * h[1], 0];\n }\n }\n }\n return best;\n};\n\n/** Area the labels and titles must stay in (CSS pixels of the stage) */\nexport interface OverlayBounds {\n left: number;\n top: number;\n right: number;\n bottom: number;\n}\n\n/** Tick labels and titles of the three axes */\nexport const drawAxes = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n style: OverlayStyle,\n bounds: OverlayBounds = {\n left: 0,\n top: 0,\n right: frame.width,\n bottom: frame.height,\n },\n): void => {\n const center = project(frame, 0, 0, 0);\n const placed: Rect[] = [];\n const size = style.fontSize;\n const labelFont = `${size}px ${style.font}`;\n const titleFont = `600 ${size + 1}px ${style.font}`;\n for (let a = 0; a < 3; a++) {\n const axis = axes[AXES[a]!];\n if (!axis.visible) continue;\n const edge = labelEdge(frame, axes, a);\n const e0 = project(frame, ...at(a, -axis.half, edge));\n const e1 = project(frame, ...at(a, axis.half, edge));\n let dx = e1.x - e0.x;\n let dy = e1.y - e0.y;\n const length = Math.hypot(dx, dy);\n // seen end-on: no room for labels\n if (length < 24) continue;\n dx /= length;\n dy /= length;\n let ox = -dy;\n let oy = dx;\n const mx = (e0.x + e1.x) / 2;\n const my = (e0.y + e1.y) / 2;\n if (ox * (mx - center.x) + oy * (my - center.y) < 0) {\n ox = -ox;\n oy = -oy;\n }\n // vertical axis: labels go sideways\n if (a === 2) {\n ox = mx < center.x ? -1 : 1;\n oy = 0;\n }\n const align: CanvasTextAlign =\n ox > 0.35 ? \"left\" : ox < -0.35 ? \"right\" : \"center\";\n const baseline: CanvasTextBaseline =\n oy > 0.35 ? \"top\" : oy < -0.35 ? \"bottom\" : \"middle\";\n ctx.font = labelFont;\n ctx.textAlign = align;\n ctx.textBaseline = baseline;\n const gap = 8;\n const labels = axis.ticks.map((tick, i) => {\n const s = project(frame, ...at(a, toWorld(axis, tick), edge));\n const text = axis.labels[i] ?? \"\";\n const w = ctx.measureText(text).width;\n const x = s.x + ox * gap;\n const y = s.y + oy * gap;\n const rx = align === \"left\" ? x : align === \"right\" ? x - w : x - w / 2;\n const ry =\n baseline === \"top\"\n ? y\n : baseline === \"bottom\"\n ? y - size\n : y - size / 2;\n return { tick: s, text, x, y, rect: { x: rx, y: ry, w, h: size } };\n });\n // thin the labels until they do not overlap\n let step = 1;\n for (; step < labels.length; step++) {\n const kept = labels.filter((_, i) => i % step === 0);\n if (\n kept.every(\n (l, i) => !kept.slice(0, i).some((o) => overlaps(l.rect, o.rect)),\n )\n ) {\n break;\n }\n }\n let extent = 0;\n ctx.beginPath();\n labels.forEach((l, i) => {\n if (i % step) return;\n // wider gap to the labels of the other axes: at the shared corner, two\n // labels side by side would read as one (\"-2 -2\")\n if (placed.some((o) => overlaps(l.rect, o, CROSS_AXIS_GAP))) return;\n placed.push(l.rect);\n ctx.moveTo(l.tick.x, l.tick.y);\n ctx.lineTo(l.tick.x + ox * 4, l.tick.y + oy * 4);\n extent = Math.max(\n extent,\n Math.abs(ox) * l.rect.w + Math.abs(oy) * l.rect.h,\n );\n });\n ctx.strokeStyle = style.axis;\n ctx.lineWidth = 1;\n ctx.stroke();\n ctx.fillStyle = style.muted;\n labels.forEach((l, i) => {\n if (i % step || !placed.includes(l.rect)) return;\n ctx.fillText(l.text, l.x, l.y);\n });\n if (!axis.title) continue;\n const distance = gap + extent + 10;\n let tx = mx + ox * distance;\n let ty = my + oy * distance;\n ctx.font = titleFont;\n ctx.fillStyle = style.text;\n const tw = ctx.measureText(axis.title).width;\n const th = size + 1;\n if (a === 2) {\n tx = Math.max(bounds.left + th, Math.min(bounds.right - th, tx));\n ty = Math.max(bounds.top + tw / 2, Math.min(bounds.bottom - tw / 2, ty));\n ctx.save();\n ctx.translate(tx, ty);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.textBaseline = ox < 0 ? \"bottom\" : \"top\";\n ctx.fillText(axis.title, 0, 0);\n ctx.restore();\n } else {\n const rectAt = (x: number, y: number): Rect => ({\n x: align === \"left\" ? x : align === \"right\" ? x - tw : x - tw / 2,\n y: baseline === \"top\" ? y : baseline === \"bottom\" ? y - th : y - th / 2,\n w: tw,\n h: th,\n });\n // slanted axes: long titles move out until they clear the labels\n for (\n let k = 0;\n k < 12 && placed.some((o) => overlaps(rectAt(tx, ty), o));\n k++\n ) {\n tx += ox * 3;\n ty += oy * 3;\n }\n // keep the whole title inside the bounds\n const { x: left, y: top } = rectAt(tx, ty);\n tx +=\n Math.max(0, bounds.left - left) - Math.max(0, left + tw - bounds.right);\n ty +=\n Math.max(0, bounds.top - top) - Math.max(0, top + th - bounds.bottom);\n placed.push(rectAt(tx, ty));\n ctx.textAlign = align;\n ctx.textBaseline = baseline;\n ctx.fillText(axis.title, tx, ty);\n }\n }\n};\n\n/** Vertical color bar with its ticks and title */\nexport const drawColorBar = (\n ctx: CanvasRenderingContext2D,\n rect: Rect,\n lut: ColorLut,\n domain: readonly [number, number],\n format: (value: number) => string,\n title: string,\n style: OverlayStyle,\n /** Right end of the stage: the title is shifted left to fit */\n right = Infinity,\n): void => {\n const gradient = ctx.createLinearGradient(0, rect.y + rect.h, 0, rect.y);\n const samples = 24;\n for (let i = 0; i <= samples; i++) {\n const c = lut.rgba[Math.round((i / samples) * (lut.rgba.length - 1))];\n if (c) gradient.addColorStop(i / samples, toCss(c));\n }\n ctx.fillStyle = gradient;\n ctx.beginPath();\n if (typeof ctx.roundRect === \"function\")\n ctx.roundRect(rect.x, rect.y, rect.w, rect.h, 3);\n else ctx.rect(rect.x, rect.y, rect.w, rect.h);\n ctx.fill();\n ctx.strokeStyle = style.axis;\n ctx.lineWidth = 1;\n ctx.stroke();\n const [min, max] = domain;\n const span = max - min || 1;\n ctx.font = `${style.fontSize}px ${style.font}`;\n ctx.fillStyle = style.muted;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const ticks = linearTicks(min, max, Math.max(2, Math.round(rect.h / 40)));\n ctx.beginPath();\n for (const t of ticks) {\n const y = rect.y + rect.h - ((t - min) / span) * rect.h;\n if (y < rect.y - 0.5 || y > rect.y + rect.h + 0.5) continue;\n ctx.moveTo(rect.x + rect.w, y);\n ctx.lineTo(rect.x + rect.w + 4, y);\n ctx.fillText(format(t), rect.x + rect.w + 7, y);\n }\n ctx.strokeStyle = style.axis;\n ctx.stroke();\n if (title) {\n ctx.font = `600 ${style.fontSize}px ${style.font}`;\n ctx.fillStyle = style.text;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"bottom\";\n const w = ctx.measureText(title).width;\n ctx.fillText(\n title,\n Math.max(4, Math.min(rect.x, right - 4 - w)),\n rect.y - 8,\n );\n }\n};\n\n/** Highlight of the hovered item */\nexport type HighlightShape =\n | { kind: \"point\"; x: number; y: number; radius: number; color: string }\n | { kind: \"box\"; min: Vec3; max: Vec3; color: string }\n | { kind: \"vertex\"; world: Vec3; color: string };\n\nexport const drawHighlight = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n shape: HighlightShape,\n style: OverlayStyle,\n): void => {\n ctx.save();\n if (shape.kind === \"point\") {\n ctx.beginPath();\n ctx.arc(shape.x, shape.y, shape.radius + 3, 0, Math.PI * 2);\n ctx.lineWidth = 3;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.lineWidth = 1.5;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n } else if (shape.kind === \"box\") {\n const { min, max } = shape;\n const corner = (i: number) =>\n project(\n frame,\n i & 1 ? max[0] : min[0],\n i & 2 ? max[1] : min[1],\n i & 4 ? max[2] : min[2],\n );\n const pts = Array.from({ length: 8 }, (_, i) => corner(i));\n ctx.beginPath();\n for (let i = 0; i < 8; i++) {\n for (const bit of [1, 2, 4]) {\n if (i & bit) continue;\n const a = pts[i]!;\n const b = pts[i | bit]!;\n ctx.moveTo(a.x, a.y);\n ctx.lineTo(b.x, b.y);\n }\n }\n ctx.lineJoin = \"round\";\n ctx.lineWidth = 3.5;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.lineWidth = 1.5;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n } else {\n const [x, y, z] = shape.world;\n const top = project(frame, x, y, z);\n const floor = project(frame, x, y, -axes.z.half);\n ctx.beginPath();\n ctx.setLineDash([3, 3]);\n ctx.moveTo(top.x, top.y);\n ctx.lineTo(floor.x, floor.y);\n ctx.lineWidth = 1;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n ctx.setLineDash([]);\n ctx.beginPath();\n ctx.arc(floor.x, floor.y, 2.5, 0, Math.PI * 2);\n ctx.fillStyle = style.text;\n ctx.fill();\n ctx.beginPath();\n ctx.arc(top.x, top.y, 5, 0, Math.PI * 2);\n ctx.fillStyle = shape.color;\n ctx.fill();\n ctx.lineWidth = 2;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.beginPath();\n ctx.arc(top.x, top.y, 7, 0, Math.PI * 2);\n ctx.lineWidth = 1.25;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n }\n ctx.restore();\n};\n"],"mappings":"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"}
|
|
@@ -73,7 +73,7 @@ var i = (t, n) => ({
|
|
|
73
73
|
}
|
|
74
74
|
e.strokeStyle = i.grid, e.stroke(), e.beginPath(), m.forEach((t, n) => n ? e.lineTo(t.x, t.y) : e.moveTo(t.x, t.y)), e.closePath(), e.strokeStyle = i.axis, e.stroke();
|
|
75
75
|
}
|
|
76
|
-
}, d = (e, t, n = 2) => e.x < t.x + t.w + n && t.x < e.x + e.w + n && e.y < t.y + t.h + n && t.y < e.y + e.h + n, f = (e, t, n) => {
|
|
76
|
+
}, d = (e, t, n = 2) => e.x < t.x + t.w + n && t.x < e.x + e.w + n && e.y < t.y + t.h + n && t.y < e.y + e.h + n, f = 10, p = (e, t, n) => {
|
|
77
77
|
let i = c(t), a = e.eye;
|
|
78
78
|
if (n === 0) return [
|
|
79
79
|
0,
|
|
@@ -99,58 +99,65 @@ var i = (t, n) => ({
|
|
|
99
99
|
]);
|
|
100
100
|
}
|
|
101
101
|
return o;
|
|
102
|
-
},
|
|
102
|
+
}, m = (e, t, i, o, s = {
|
|
103
103
|
left: 0,
|
|
104
104
|
top: 0,
|
|
105
105
|
right: t.width,
|
|
106
106
|
bottom: t.height
|
|
107
107
|
}) => {
|
|
108
|
-
let c = r(t, 0, 0, 0), u = [],
|
|
109
|
-
for (let
|
|
110
|
-
let
|
|
111
|
-
if (!
|
|
112
|
-
let
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
let
|
|
116
|
-
|
|
117
|
-
let
|
|
118
|
-
e.font =
|
|
119
|
-
let
|
|
120
|
-
let o = r(t, ...l(
|
|
108
|
+
let c = r(t, 0, 0, 0), u = [], m = o.fontSize, h = `${m}px ${o.font}`, g = `600 ${m + 1}px ${o.font}`;
|
|
109
|
+
for (let _ = 0; _ < 3; _++) {
|
|
110
|
+
let v = i[a[_]];
|
|
111
|
+
if (!v.visible) continue;
|
|
112
|
+
let y = p(t, i, _), b = r(t, ...l(_, -v.half, y)), x = r(t, ...l(_, v.half, y)), S = x.x - b.x, C = x.y - b.y, w = Math.hypot(S, C);
|
|
113
|
+
if (w < 24) continue;
|
|
114
|
+
S /= w, C /= w;
|
|
115
|
+
let T = -C, E = S, D = (b.x + x.x) / 2, O = (b.y + x.y) / 2;
|
|
116
|
+
T * (D - c.x) + E * (O - c.y) < 0 && (T = -T, E = -E), _ === 2 && (T = D < c.x ? -1 : 1, E = 0);
|
|
117
|
+
let k = T > .35 ? "left" : T < -.35 ? "right" : "center", A = E > .35 ? "top" : E < -.35 ? "bottom" : "middle";
|
|
118
|
+
e.font = h, e.textAlign = k, e.textBaseline = A;
|
|
119
|
+
let j = v.ticks.map((i, a) => {
|
|
120
|
+
let o = r(t, ...l(_, n(v, i), y)), s = v.labels[a] ?? "", c = e.measureText(s).width, u = o.x + T * 8, d = o.y + E * 8;
|
|
121
121
|
return {
|
|
122
122
|
tick: o,
|
|
123
123
|
text: s,
|
|
124
124
|
x: u,
|
|
125
125
|
y: d,
|
|
126
126
|
rect: {
|
|
127
|
-
x:
|
|
128
|
-
y:
|
|
127
|
+
x: k === "left" ? u : k === "right" ? u - c : u - c / 2,
|
|
128
|
+
y: A === "top" ? d : A === "bottom" ? d - m : d - m / 2,
|
|
129
129
|
w: c,
|
|
130
|
-
h:
|
|
130
|
+
h: m
|
|
131
131
|
}
|
|
132
132
|
};
|
|
133
|
-
}),
|
|
134
|
-
for (;
|
|
135
|
-
let e =
|
|
133
|
+
}), M = 1;
|
|
134
|
+
for (; M < j.length; M++) {
|
|
135
|
+
let e = j.filter((e, t) => t % M === 0);
|
|
136
136
|
if (e.every((t, n) => !e.slice(0, n).some((e) => d(t.rect, e.rect)))) break;
|
|
137
137
|
}
|
|
138
|
-
let
|
|
139
|
-
if (e.beginPath(),
|
|
140
|
-
n %
|
|
141
|
-
}), e.strokeStyle = o.axis, e.lineWidth = 1, e.stroke(), e.fillStyle = o.muted,
|
|
142
|
-
n %
|
|
143
|
-
}), !
|
|
144
|
-
let
|
|
145
|
-
e.font =
|
|
146
|
-
let
|
|
147
|
-
if (
|
|
138
|
+
let N = 0;
|
|
139
|
+
if (e.beginPath(), j.forEach((t, n) => {
|
|
140
|
+
n % M || u.some((e) => d(t.rect, e, f)) || (u.push(t.rect), e.moveTo(t.tick.x, t.tick.y), e.lineTo(t.tick.x + T * 4, t.tick.y + E * 4), N = Math.max(N, Math.abs(T) * t.rect.w + Math.abs(E) * t.rect.h));
|
|
141
|
+
}), e.strokeStyle = o.axis, e.lineWidth = 1, e.stroke(), e.fillStyle = o.muted, j.forEach((t, n) => {
|
|
142
|
+
n % M || !u.includes(t.rect) || e.fillText(t.text, t.x, t.y);
|
|
143
|
+
}), !v.title) continue;
|
|
144
|
+
let P = 8 + N + 10, F = D + T * P, I = O + E * P;
|
|
145
|
+
e.font = g, e.fillStyle = o.text;
|
|
146
|
+
let L = e.measureText(v.title).width, R = m + 1;
|
|
147
|
+
if (_ === 2) F = Math.max(s.left + R, Math.min(s.right - R, F)), I = Math.max(s.top + L / 2, Math.min(s.bottom - L / 2, I)), e.save(), e.translate(F, I), e.rotate(-Math.PI / 2), e.textAlign = "center", e.textBaseline = T < 0 ? "bottom" : "top", e.fillText(v.title, 0, 0), e.restore();
|
|
148
148
|
else {
|
|
149
|
-
let t =
|
|
150
|
-
|
|
149
|
+
let t = (e, t) => ({
|
|
150
|
+
x: k === "left" ? e : k === "right" ? e - L : e - L / 2,
|
|
151
|
+
y: A === "top" ? t : A === "bottom" ? t - R : t - R / 2,
|
|
152
|
+
w: L,
|
|
153
|
+
h: R
|
|
154
|
+
});
|
|
155
|
+
for (let e = 0; e < 12 && u.some((e) => d(t(F, I), e)); e++) F += T * 3, I += E * 3;
|
|
156
|
+
let { x: n, y: r } = t(F, I);
|
|
157
|
+
F += Math.max(0, s.left - n) - Math.max(0, n + L - s.right), I += Math.max(0, s.top - r) - Math.max(0, r + R - s.bottom), u.push(t(F, I)), e.textAlign = k, e.textBaseline = A, e.fillText(v.title, F, I);
|
|
151
158
|
}
|
|
152
159
|
}
|
|
153
|
-
},
|
|
160
|
+
}, h = (n, r, i, a, o, s, c, l = Infinity) => {
|
|
154
161
|
let u = n.createLinearGradient(0, r.y + r.h, 0, r.y);
|
|
155
162
|
for (let t = 0; t <= 24; t++) {
|
|
156
163
|
let n = i.rgba[Math.round(t / 24 * (i.rgba.length - 1))];
|
|
@@ -170,7 +177,7 @@ var i = (t, n) => ({
|
|
|
170
177
|
let e = n.measureText(s).width;
|
|
171
178
|
n.fillText(s, Math.max(4, Math.min(r.x, l - 4 - e)), r.y - 8);
|
|
172
179
|
}
|
|
173
|
-
},
|
|
180
|
+
}, g = (e, t, n, i, a) => {
|
|
174
181
|
if (e.save(), i.kind === "point") e.beginPath(), e.arc(i.x, i.y, i.radius + 3, 0, Math.PI * 2), e.lineWidth = 3, e.strokeStyle = a.background, e.stroke(), e.lineWidth = 1.5, e.strokeStyle = a.text, e.stroke();
|
|
175
182
|
else if (i.kind === "box") {
|
|
176
183
|
let { min: n, max: o } = i, s = (e) => r(t, e & 1 ? o[0] : n[0], e & 2 ? o[1] : n[1], e & 4 ? o[2] : n[2]), c = Array.from({ length: 8 }, (e, t) => s(t));
|
|
@@ -192,6 +199,6 @@ var i = (t, n) => ({
|
|
|
192
199
|
e.restore();
|
|
193
200
|
};
|
|
194
201
|
//#endregion
|
|
195
|
-
export {
|
|
202
|
+
export { m as drawAxes, h as drawColorBar, g as drawHighlight, u as drawWalls, s as farWalls, o as gridPositions, p as labelEdge, i as overlayStyle };
|
|
196
203
|
|
|
197
204
|
//# sourceMappingURL=overlay.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.js","names":["overlayStyle","toCss","theme","dark","AXES","gridPositions","axis","out","i","toWorld","farWalls","frame","half","axes","at","p","rest","value","drawWalls","h","walls","P","project","a","b","c","base","corner","sb","sc","quad","ctx","q","style","along","across","w","p0","p1","s0","s1","overlaps","pad","labelEdge","eye","best","left","sx","sy","drawAxes","center","placed","size","labelFont","titleFont","edge","e0","e1","dx","dy","length","ox","oy","mx","my","align","baseline","labels","s","tick","text","x","y","step","kept","l","o","extent","distance","tx","ty","tw","th","bounds","top","drawColorBar","gradient","rect","lut","min","max","domain","span","ticks","linearTicks","t","format","title","right","drawHighlight","shape","pts","bit","z","floor"],"sources":["../../../../../charts/src/engine/three-d/overlay.ts"],"sourcesContent":["// 2D overlay of the 3D charts: the far walls of the axis box with their grid\n// lines (below the data), then the tick labels, axis titles, color bar and\n// hover highlight (above the data). Text is always horizontal (screen\n// aligned) so it stays readable whatever the camera.\n\nimport { toCss, type Rgba } from \"../color\";\nimport { linearTicks } from \"../scale\";\nimport type { ColorLut } from \"./colormap\";\nimport { project, type CameraFrame, type Vec3 } from \"./math\";\nimport { toWorld, type AxisModel, type Model3D } from \"./model\";\n\nexport interface OverlayStyle {\n text: string;\n muted: string;\n grid: string;\n axis: string;\n /** Tint of the walls */\n wall: string;\n /** Background (rings of the hover marker) */\n background: string;\n font: string;\n fontSize: number;\n}\n\nexport const overlayStyle = (\n theme: {\n text: Rgba;\n textMuted: Rgba;\n grid: Rgba;\n axis: Rgba;\n background: Rgba;\n fontFamily: string;\n fontSize: number;\n },\n dark: boolean,\n): OverlayStyle => ({\n text: toCss(theme.text),\n muted: toCss(theme.textMuted),\n grid: toCss(theme.grid),\n axis: toCss(theme.axis),\n wall: toCss(theme.text, dark ? 0.045 : 0.025),\n background: toCss(theme.background),\n font: theme.fontFamily,\n fontSize: theme.fontSize,\n});\n\ntype Axes = Pick<Model3D, \"x\" | \"y\" | \"z\">;\n\nconst AXES: readonly (\"x\" | \"y\" | \"z\")[] = [\"x\", \"y\", \"z\"];\n\n/** World positions of the grid lines of an axis (category axes: between the categories) */\nexport const gridPositions = (axis: AxisModel): number[] => {\n if (axis.categories) {\n const out: number[] = [];\n for (let i = 0; i < axis.categories.length - 1; i++)\n out.push(toWorld(axis, i + 0.5));\n return out;\n }\n return axis.ticks\n .filter((t) => t > axis.domain[0] && t < axis.domain[1])\n .map((t) => toWorld(axis, t));\n};\n\n/** Side (-1 / 1) of the far wall perpendicular to every axis */\nexport const farWalls = (frame: CameraFrame): [number, number, number] => [\n frame.eye[0] >= 0 ? -1 : 1,\n frame.eye[1] >= 0 ? -1 : 1,\n frame.eye[2] >= 0 ? -1 : 1,\n];\n\nconst half = (axes: Axes): Vec3 => [axes.x.half, axes.y.half, axes.z.half];\n\nconst at = (axis: number, value: number, rest: Vec3): Vec3 => {\n const p: Vec3 = [rest[0], rest[1], rest[2]];\n p[axis] = value;\n return p;\n};\n\n/** Far walls, their grid lines and borders */\nexport const drawWalls = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n style: OverlayStyle,\n): void => {\n const h = half(axes);\n const walls = farWalls(frame);\n const P = (p: Vec3) => project(frame, p[0], p[1], p[2]);\n ctx.lineWidth = 1;\n for (let a = 0; a < 3; a++) {\n const b = (a + 1) % 3;\n const c = (a + 2) % 3;\n const base: Vec3 = [0, 0, 0];\n base[a] = walls[a] * h[a];\n const corner = (sb: number, sc: number) => {\n const p: Vec3 = [base[0], base[1], base[2]];\n p[b] = sb * h[b];\n p[c] = sc * h[c];\n return P(p);\n };\n const quad = [corner(-1, -1), corner(1, -1), corner(1, 1), corner(-1, 1)];\n ctx.beginPath();\n quad.forEach((q, i) => (i ? ctx.lineTo(q.x, q.y) : ctx.moveTo(q.x, q.y)));\n ctx.closePath();\n ctx.fillStyle = style.wall;\n ctx.fill();\n // grid lines of the two axes spanning the wall\n ctx.beginPath();\n for (const [along, across] of [\n [b, c],\n [c, b],\n ] as const) {\n const axis = axes[AXES[along]!];\n if (!axis.grid) continue;\n for (const w of gridPositions(axis)) {\n const p0 = at(along, w, base);\n const p1 = at(along, w, base);\n p0[across] = -h[across];\n p1[across] = h[across];\n const s0 = P(p0);\n const s1 = P(p1);\n ctx.moveTo(s0.x, s0.y);\n ctx.lineTo(s1.x, s1.y);\n }\n }\n ctx.strokeStyle = style.grid;\n ctx.stroke();\n ctx.beginPath();\n quad.forEach((q, i) => (i ? ctx.lineTo(q.x, q.y) : ctx.moveTo(q.x, q.y)));\n ctx.closePath();\n ctx.strokeStyle = style.axis;\n ctx.stroke();\n }\n};\n\ninterface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nconst overlaps = (a: Rect, b: Rect, pad = 2) =>\n a.x < b.x + b.w + pad &&\n b.x < a.x + a.w + pad &&\n a.y < b.y + b.h + pad &&\n b.y < a.y + a.h + pad;\n\n/** Edge (fixed coordinates of the two other axes) carrying the labels of an axis */\nexport const labelEdge = (\n frame: CameraFrame,\n axes: Axes,\n axis: number,\n): Vec3 => {\n const h = half(axes);\n const eye = frame.eye;\n if (axis === 0) return [0, (eye[1] >= 0 ? 1 : -1) * h[1], -h[2]];\n if (axis === 1) return [(eye[0] >= 0 ? 1 : -1) * h[0], 0, -h[2]];\n // vertical axis: the leftmost vertical edge on screen\n let best: Vec3 = [-h[0], -h[1], 0];\n let left = Infinity;\n for (const sx of [-1, 1]) {\n for (const sy of [-1, 1]) {\n const p = project(frame, sx * h[0], sy * h[1], 0);\n if (p.x < left) {\n left = p.x;\n best = [sx * h[0], sy * h[1], 0];\n }\n }\n }\n return best;\n};\n\n/** Area the labels and titles must stay in (CSS pixels of the stage) */\nexport interface OverlayBounds {\n left: number;\n top: number;\n right: number;\n bottom: number;\n}\n\n/** Tick labels and titles of the three axes */\nexport const drawAxes = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n style: OverlayStyle,\n bounds: OverlayBounds = {\n left: 0,\n top: 0,\n right: frame.width,\n bottom: frame.height,\n },\n): void => {\n const center = project(frame, 0, 0, 0);\n const placed: Rect[] = [];\n const size = style.fontSize;\n const labelFont = `${size}px ${style.font}`;\n const titleFont = `600 ${size + 1}px ${style.font}`;\n for (let a = 0; a < 3; a++) {\n const axis = axes[AXES[a]!];\n if (!axis.visible) continue;\n const edge = labelEdge(frame, axes, a);\n const e0 = project(frame, ...at(a, -axis.half, edge));\n const e1 = project(frame, ...at(a, axis.half, edge));\n let dx = e1.x - e0.x;\n let dy = e1.y - e0.y;\n const length = Math.hypot(dx, dy);\n // seen end-on: no room for labels\n if (length < 24) continue;\n dx /= length;\n dy /= length;\n let ox = -dy;\n let oy = dx;\n const mx = (e0.x + e1.x) / 2;\n const my = (e0.y + e1.y) / 2;\n if (ox * (mx - center.x) + oy * (my - center.y) < 0) {\n ox = -ox;\n oy = -oy;\n }\n // vertical axis: labels go sideways\n if (a === 2) {\n ox = mx < center.x ? -1 : 1;\n oy = 0;\n }\n const align: CanvasTextAlign =\n ox > 0.35 ? \"left\" : ox < -0.35 ? \"right\" : \"center\";\n const baseline: CanvasTextBaseline =\n oy > 0.35 ? \"top\" : oy < -0.35 ? \"bottom\" : \"middle\";\n ctx.font = labelFont;\n ctx.textAlign = align;\n ctx.textBaseline = baseline;\n const gap = 8;\n const labels = axis.ticks.map((tick, i) => {\n const s = project(frame, ...at(a, toWorld(axis, tick), edge));\n const text = axis.labels[i] ?? \"\";\n const w = ctx.measureText(text).width;\n const x = s.x + ox * gap;\n const y = s.y + oy * gap;\n const rx = align === \"left\" ? x : align === \"right\" ? x - w : x - w / 2;\n const ry =\n baseline === \"top\"\n ? y\n : baseline === \"bottom\"\n ? y - size\n : y - size / 2;\n return { tick: s, text, x, y, rect: { x: rx, y: ry, w, h: size } };\n });\n // thin the labels until they do not overlap\n let step = 1;\n for (; step < labels.length; step++) {\n const kept = labels.filter((_, i) => i % step === 0);\n if (\n kept.every(\n (l, i) => !kept.slice(0, i).some((o) => overlaps(l.rect, o.rect)),\n )\n ) {\n break;\n }\n }\n let extent = 0;\n ctx.beginPath();\n labels.forEach((l, i) => {\n if (i % step) return;\n if (placed.some((o) => overlaps(l.rect, o))) return;\n placed.push(l.rect);\n ctx.moveTo(l.tick.x, l.tick.y);\n ctx.lineTo(l.tick.x + ox * 4, l.tick.y + oy * 4);\n extent = Math.max(\n extent,\n Math.abs(ox) * l.rect.w + Math.abs(oy) * l.rect.h,\n );\n });\n ctx.strokeStyle = style.axis;\n ctx.lineWidth = 1;\n ctx.stroke();\n ctx.fillStyle = style.muted;\n labels.forEach((l, i) => {\n if (i % step || !placed.includes(l.rect)) return;\n ctx.fillText(l.text, l.x, l.y);\n });\n if (!axis.title) continue;\n const distance = gap + extent + 10;\n let tx = mx + ox * distance;\n let ty = my + oy * distance;\n ctx.font = titleFont;\n ctx.fillStyle = style.text;\n const tw = ctx.measureText(axis.title).width;\n const th = size + 1;\n if (a === 2) {\n tx = Math.max(bounds.left + th, Math.min(bounds.right - th, tx));\n ty = Math.max(bounds.top + tw / 2, Math.min(bounds.bottom - tw / 2, ty));\n ctx.save();\n ctx.translate(tx, ty);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.textBaseline = ox < 0 ? \"bottom\" : \"top\";\n ctx.fillText(axis.title, 0, 0);\n ctx.restore();\n } else {\n // keep the whole title inside the bounds\n const left =\n align === \"left\" ? tx : align === \"right\" ? tx - tw : tx - tw / 2;\n const top =\n baseline === \"top\" ? ty : baseline === \"bottom\" ? ty - th : ty - th / 2;\n tx +=\n Math.max(0, bounds.left - left) - Math.max(0, left + tw - bounds.right);\n ty +=\n Math.max(0, bounds.top - top) - Math.max(0, top + th - bounds.bottom);\n ctx.textAlign = align;\n ctx.textBaseline = baseline;\n ctx.fillText(axis.title, tx, ty);\n }\n }\n};\n\n/** Vertical color bar with its ticks and title */\nexport const drawColorBar = (\n ctx: CanvasRenderingContext2D,\n rect: Rect,\n lut: ColorLut,\n domain: readonly [number, number],\n format: (value: number) => string,\n title: string,\n style: OverlayStyle,\n /** Right end of the stage: the title is shifted left to fit */\n right = Infinity,\n): void => {\n const gradient = ctx.createLinearGradient(0, rect.y + rect.h, 0, rect.y);\n const samples = 24;\n for (let i = 0; i <= samples; i++) {\n const c = lut.rgba[Math.round((i / samples) * (lut.rgba.length - 1))];\n if (c) gradient.addColorStop(i / samples, toCss(c));\n }\n ctx.fillStyle = gradient;\n ctx.beginPath();\n if (typeof ctx.roundRect === \"function\")\n ctx.roundRect(rect.x, rect.y, rect.w, rect.h, 3);\n else ctx.rect(rect.x, rect.y, rect.w, rect.h);\n ctx.fill();\n ctx.strokeStyle = style.axis;\n ctx.lineWidth = 1;\n ctx.stroke();\n const [min, max] = domain;\n const span = max - min || 1;\n ctx.font = `${style.fontSize}px ${style.font}`;\n ctx.fillStyle = style.muted;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const ticks = linearTicks(min, max, Math.max(2, Math.round(rect.h / 40)));\n ctx.beginPath();\n for (const t of ticks) {\n const y = rect.y + rect.h - ((t - min) / span) * rect.h;\n if (y < rect.y - 0.5 || y > rect.y + rect.h + 0.5) continue;\n ctx.moveTo(rect.x + rect.w, y);\n ctx.lineTo(rect.x + rect.w + 4, y);\n ctx.fillText(format(t), rect.x + rect.w + 7, y);\n }\n ctx.strokeStyle = style.axis;\n ctx.stroke();\n if (title) {\n ctx.font = `600 ${style.fontSize}px ${style.font}`;\n ctx.fillStyle = style.text;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"bottom\";\n const w = ctx.measureText(title).width;\n ctx.fillText(\n title,\n Math.max(4, Math.min(rect.x, right - 4 - w)),\n rect.y - 8,\n );\n }\n};\n\n/** Highlight of the hovered item */\nexport type HighlightShape =\n | { kind: \"point\"; x: number; y: number; radius: number; color: string }\n | { kind: \"box\"; min: Vec3; max: Vec3; color: string }\n | { kind: \"vertex\"; world: Vec3; color: string };\n\nexport const drawHighlight = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n shape: HighlightShape,\n style: OverlayStyle,\n): void => {\n ctx.save();\n if (shape.kind === \"point\") {\n ctx.beginPath();\n ctx.arc(shape.x, shape.y, shape.radius + 3, 0, Math.PI * 2);\n ctx.lineWidth = 3;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.lineWidth = 1.5;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n } else if (shape.kind === \"box\") {\n const { min, max } = shape;\n const corner = (i: number) =>\n project(\n frame,\n i & 1 ? max[0] : min[0],\n i & 2 ? max[1] : min[1],\n i & 4 ? max[2] : min[2],\n );\n const pts = Array.from({ length: 8 }, (_, i) => corner(i));\n ctx.beginPath();\n for (let i = 0; i < 8; i++) {\n for (const bit of [1, 2, 4]) {\n if (i & bit) continue;\n const a = pts[i]!;\n const b = pts[i | bit]!;\n ctx.moveTo(a.x, a.y);\n ctx.lineTo(b.x, b.y);\n }\n }\n ctx.lineJoin = \"round\";\n ctx.lineWidth = 3.5;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.lineWidth = 1.5;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n } else {\n const [x, y, z] = shape.world;\n const top = project(frame, x, y, z);\n const floor = project(frame, x, y, -axes.z.half);\n ctx.beginPath();\n ctx.setLineDash([3, 3]);\n ctx.moveTo(top.x, top.y);\n ctx.lineTo(floor.x, floor.y);\n ctx.lineWidth = 1;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n ctx.setLineDash([]);\n ctx.beginPath();\n ctx.arc(floor.x, floor.y, 2.5, 0, Math.PI * 2);\n ctx.fillStyle = style.text;\n ctx.fill();\n ctx.beginPath();\n ctx.arc(top.x, top.y, 5, 0, Math.PI * 2);\n ctx.fillStyle = shape.color;\n ctx.fill();\n ctx.lineWidth = 2;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.beginPath();\n ctx.arc(top.x, top.y, 7, 0, Math.PI * 2);\n ctx.lineWidth = 1.25;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n }\n ctx.restore();\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"overlay.js","names":["overlayStyle","toCss","theme","dark","AXES","gridPositions","axis","out","i","toWorld","farWalls","frame","half","axes","at","p","rest","value","drawWalls","h","walls","P","project","a","b","c","base","corner","sb","sc","quad","ctx","q","style","along","across","w","p0","p1","s0","s1","overlaps","pad","CROSS_AXIS_GAP","labelEdge","eye","best","left","sx","sy","drawAxes","center","placed","size","labelFont","titleFont","edge","e0","e1","dx","dy","length","ox","oy","mx","my","align","baseline","labels","s","tick","text","x","y","step","kept","l","o","extent","distance","tx","ty","tw","th","bounds","rectAt","k","top","drawColorBar","gradient","rect","lut","min","max","domain","span","ticks","linearTicks","t","format","title","right","drawHighlight","shape","pts","bit","z","floor"],"sources":["../../../../../charts/src/engine/three-d/overlay.ts"],"sourcesContent":["// 2D overlay of the 3D charts: the far walls of the axis box with their grid\n// lines (below the data), then the tick labels, axis titles, color bar and\n// hover highlight (above the data). Text is always horizontal (screen\n// aligned) so it stays readable whatever the camera.\n\nimport { toCss, type Rgba } from \"../color\";\nimport { linearTicks } from \"../scale\";\nimport type { ColorLut } from \"./colormap\";\nimport { project, type CameraFrame, type Vec3 } from \"./math\";\nimport { toWorld, type AxisModel, type Model3D } from \"./model\";\n\nexport interface OverlayStyle {\n text: string;\n muted: string;\n grid: string;\n axis: string;\n /** Tint of the walls */\n wall: string;\n /** Background (rings of the hover marker) */\n background: string;\n font: string;\n fontSize: number;\n}\n\nexport const overlayStyle = (\n theme: {\n text: Rgba;\n textMuted: Rgba;\n grid: Rgba;\n axis: Rgba;\n background: Rgba;\n fontFamily: string;\n fontSize: number;\n },\n dark: boolean,\n): OverlayStyle => ({\n text: toCss(theme.text),\n muted: toCss(theme.textMuted),\n grid: toCss(theme.grid),\n axis: toCss(theme.axis),\n wall: toCss(theme.text, dark ? 0.045 : 0.025),\n background: toCss(theme.background),\n font: theme.fontFamily,\n fontSize: theme.fontSize,\n});\n\ntype Axes = Pick<Model3D, \"x\" | \"y\" | \"z\">;\n\nconst AXES: readonly (\"x\" | \"y\" | \"z\")[] = [\"x\", \"y\", \"z\"];\n\n/** World positions of the grid lines of an axis (category axes: between the categories) */\nexport const gridPositions = (axis: AxisModel): number[] => {\n if (axis.categories) {\n const out: number[] = [];\n for (let i = 0; i < axis.categories.length - 1; i++)\n out.push(toWorld(axis, i + 0.5));\n return out;\n }\n return axis.ticks\n .filter((t) => t > axis.domain[0] && t < axis.domain[1])\n .map((t) => toWorld(axis, t));\n};\n\n/** Side (-1 / 1) of the far wall perpendicular to every axis */\nexport const farWalls = (frame: CameraFrame): [number, number, number] => [\n frame.eye[0] >= 0 ? -1 : 1,\n frame.eye[1] >= 0 ? -1 : 1,\n frame.eye[2] >= 0 ? -1 : 1,\n];\n\nconst half = (axes: Axes): Vec3 => [axes.x.half, axes.y.half, axes.z.half];\n\nconst at = (axis: number, value: number, rest: Vec3): Vec3 => {\n const p: Vec3 = [rest[0], rest[1], rest[2]];\n p[axis] = value;\n return p;\n};\n\n/** Far walls, their grid lines and borders */\nexport const drawWalls = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n style: OverlayStyle,\n): void => {\n const h = half(axes);\n const walls = farWalls(frame);\n const P = (p: Vec3) => project(frame, p[0], p[1], p[2]);\n ctx.lineWidth = 1;\n for (let a = 0; a < 3; a++) {\n const b = (a + 1) % 3;\n const c = (a + 2) % 3;\n const base: Vec3 = [0, 0, 0];\n base[a] = walls[a] * h[a];\n const corner = (sb: number, sc: number) => {\n const p: Vec3 = [base[0], base[1], base[2]];\n p[b] = sb * h[b];\n p[c] = sc * h[c];\n return P(p);\n };\n const quad = [corner(-1, -1), corner(1, -1), corner(1, 1), corner(-1, 1)];\n ctx.beginPath();\n quad.forEach((q, i) => (i ? ctx.lineTo(q.x, q.y) : ctx.moveTo(q.x, q.y)));\n ctx.closePath();\n ctx.fillStyle = style.wall;\n ctx.fill();\n // grid lines of the two axes spanning the wall\n ctx.beginPath();\n for (const [along, across] of [\n [b, c],\n [c, b],\n ] as const) {\n const axis = axes[AXES[along]!];\n if (!axis.grid) continue;\n for (const w of gridPositions(axis)) {\n const p0 = at(along, w, base);\n const p1 = at(along, w, base);\n p0[across] = -h[across];\n p1[across] = h[across];\n const s0 = P(p0);\n const s1 = P(p1);\n ctx.moveTo(s0.x, s0.y);\n ctx.lineTo(s1.x, s1.y);\n }\n }\n ctx.strokeStyle = style.grid;\n ctx.stroke();\n ctx.beginPath();\n quad.forEach((q, i) => (i ? ctx.lineTo(q.x, q.y) : ctx.moveTo(q.x, q.y)));\n ctx.closePath();\n ctx.strokeStyle = style.axis;\n ctx.stroke();\n }\n};\n\ninterface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nconst overlaps = (a: Rect, b: Rect, pad = 2) =>\n a.x < b.x + b.w + pad &&\n b.x < a.x + a.w + pad &&\n a.y < b.y + b.h + pad &&\n b.y < a.y + a.h + pad;\n\n/** Smallest gap (px) between tick labels of different axes */\nconst CROSS_AXIS_GAP = 10;\n\n/** Edge (fixed coordinates of the two other axes) carrying the labels of an axis */\nexport const labelEdge = (\n frame: CameraFrame,\n axes: Axes,\n axis: number,\n): Vec3 => {\n const h = half(axes);\n const eye = frame.eye;\n if (axis === 0) return [0, (eye[1] >= 0 ? 1 : -1) * h[1], -h[2]];\n if (axis === 1) return [(eye[0] >= 0 ? 1 : -1) * h[0], 0, -h[2]];\n // vertical axis: the leftmost vertical edge on screen\n let best: Vec3 = [-h[0], -h[1], 0];\n let left = Infinity;\n for (const sx of [-1, 1]) {\n for (const sy of [-1, 1]) {\n const p = project(frame, sx * h[0], sy * h[1], 0);\n if (p.x < left) {\n left = p.x;\n best = [sx * h[0], sy * h[1], 0];\n }\n }\n }\n return best;\n};\n\n/** Area the labels and titles must stay in (CSS pixels of the stage) */\nexport interface OverlayBounds {\n left: number;\n top: number;\n right: number;\n bottom: number;\n}\n\n/** Tick labels and titles of the three axes */\nexport const drawAxes = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n style: OverlayStyle,\n bounds: OverlayBounds = {\n left: 0,\n top: 0,\n right: frame.width,\n bottom: frame.height,\n },\n): void => {\n const center = project(frame, 0, 0, 0);\n const placed: Rect[] = [];\n const size = style.fontSize;\n const labelFont = `${size}px ${style.font}`;\n const titleFont = `600 ${size + 1}px ${style.font}`;\n for (let a = 0; a < 3; a++) {\n const axis = axes[AXES[a]!];\n if (!axis.visible) continue;\n const edge = labelEdge(frame, axes, a);\n const e0 = project(frame, ...at(a, -axis.half, edge));\n const e1 = project(frame, ...at(a, axis.half, edge));\n let dx = e1.x - e0.x;\n let dy = e1.y - e0.y;\n const length = Math.hypot(dx, dy);\n // seen end-on: no room for labels\n if (length < 24) continue;\n dx /= length;\n dy /= length;\n let ox = -dy;\n let oy = dx;\n const mx = (e0.x + e1.x) / 2;\n const my = (e0.y + e1.y) / 2;\n if (ox * (mx - center.x) + oy * (my - center.y) < 0) {\n ox = -ox;\n oy = -oy;\n }\n // vertical axis: labels go sideways\n if (a === 2) {\n ox = mx < center.x ? -1 : 1;\n oy = 0;\n }\n const align: CanvasTextAlign =\n ox > 0.35 ? \"left\" : ox < -0.35 ? \"right\" : \"center\";\n const baseline: CanvasTextBaseline =\n oy > 0.35 ? \"top\" : oy < -0.35 ? \"bottom\" : \"middle\";\n ctx.font = labelFont;\n ctx.textAlign = align;\n ctx.textBaseline = baseline;\n const gap = 8;\n const labels = axis.ticks.map((tick, i) => {\n const s = project(frame, ...at(a, toWorld(axis, tick), edge));\n const text = axis.labels[i] ?? \"\";\n const w = ctx.measureText(text).width;\n const x = s.x + ox * gap;\n const y = s.y + oy * gap;\n const rx = align === \"left\" ? x : align === \"right\" ? x - w : x - w / 2;\n const ry =\n baseline === \"top\"\n ? y\n : baseline === \"bottom\"\n ? y - size\n : y - size / 2;\n return { tick: s, text, x, y, rect: { x: rx, y: ry, w, h: size } };\n });\n // thin the labels until they do not overlap\n let step = 1;\n for (; step < labels.length; step++) {\n const kept = labels.filter((_, i) => i % step === 0);\n if (\n kept.every(\n (l, i) => !kept.slice(0, i).some((o) => overlaps(l.rect, o.rect)),\n )\n ) {\n break;\n }\n }\n let extent = 0;\n ctx.beginPath();\n labels.forEach((l, i) => {\n if (i % step) return;\n // wider gap to the labels of the other axes: at the shared corner, two\n // labels side by side would read as one (\"-2 -2\")\n if (placed.some((o) => overlaps(l.rect, o, CROSS_AXIS_GAP))) return;\n placed.push(l.rect);\n ctx.moveTo(l.tick.x, l.tick.y);\n ctx.lineTo(l.tick.x + ox * 4, l.tick.y + oy * 4);\n extent = Math.max(\n extent,\n Math.abs(ox) * l.rect.w + Math.abs(oy) * l.rect.h,\n );\n });\n ctx.strokeStyle = style.axis;\n ctx.lineWidth = 1;\n ctx.stroke();\n ctx.fillStyle = style.muted;\n labels.forEach((l, i) => {\n if (i % step || !placed.includes(l.rect)) return;\n ctx.fillText(l.text, l.x, l.y);\n });\n if (!axis.title) continue;\n const distance = gap + extent + 10;\n let tx = mx + ox * distance;\n let ty = my + oy * distance;\n ctx.font = titleFont;\n ctx.fillStyle = style.text;\n const tw = ctx.measureText(axis.title).width;\n const th = size + 1;\n if (a === 2) {\n tx = Math.max(bounds.left + th, Math.min(bounds.right - th, tx));\n ty = Math.max(bounds.top + tw / 2, Math.min(bounds.bottom - tw / 2, ty));\n ctx.save();\n ctx.translate(tx, ty);\n ctx.rotate(-Math.PI / 2);\n ctx.textAlign = \"center\";\n ctx.textBaseline = ox < 0 ? \"bottom\" : \"top\";\n ctx.fillText(axis.title, 0, 0);\n ctx.restore();\n } else {\n const rectAt = (x: number, y: number): Rect => ({\n x: align === \"left\" ? x : align === \"right\" ? x - tw : x - tw / 2,\n y: baseline === \"top\" ? y : baseline === \"bottom\" ? y - th : y - th / 2,\n w: tw,\n h: th,\n });\n // slanted axes: long titles move out until they clear the labels\n for (\n let k = 0;\n k < 12 && placed.some((o) => overlaps(rectAt(tx, ty), o));\n k++\n ) {\n tx += ox * 3;\n ty += oy * 3;\n }\n // keep the whole title inside the bounds\n const { x: left, y: top } = rectAt(tx, ty);\n tx +=\n Math.max(0, bounds.left - left) - Math.max(0, left + tw - bounds.right);\n ty +=\n Math.max(0, bounds.top - top) - Math.max(0, top + th - bounds.bottom);\n placed.push(rectAt(tx, ty));\n ctx.textAlign = align;\n ctx.textBaseline = baseline;\n ctx.fillText(axis.title, tx, ty);\n }\n }\n};\n\n/** Vertical color bar with its ticks and title */\nexport const drawColorBar = (\n ctx: CanvasRenderingContext2D,\n rect: Rect,\n lut: ColorLut,\n domain: readonly [number, number],\n format: (value: number) => string,\n title: string,\n style: OverlayStyle,\n /** Right end of the stage: the title is shifted left to fit */\n right = Infinity,\n): void => {\n const gradient = ctx.createLinearGradient(0, rect.y + rect.h, 0, rect.y);\n const samples = 24;\n for (let i = 0; i <= samples; i++) {\n const c = lut.rgba[Math.round((i / samples) * (lut.rgba.length - 1))];\n if (c) gradient.addColorStop(i / samples, toCss(c));\n }\n ctx.fillStyle = gradient;\n ctx.beginPath();\n if (typeof ctx.roundRect === \"function\")\n ctx.roundRect(rect.x, rect.y, rect.w, rect.h, 3);\n else ctx.rect(rect.x, rect.y, rect.w, rect.h);\n ctx.fill();\n ctx.strokeStyle = style.axis;\n ctx.lineWidth = 1;\n ctx.stroke();\n const [min, max] = domain;\n const span = max - min || 1;\n ctx.font = `${style.fontSize}px ${style.font}`;\n ctx.fillStyle = style.muted;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"middle\";\n const ticks = linearTicks(min, max, Math.max(2, Math.round(rect.h / 40)));\n ctx.beginPath();\n for (const t of ticks) {\n const y = rect.y + rect.h - ((t - min) / span) * rect.h;\n if (y < rect.y - 0.5 || y > rect.y + rect.h + 0.5) continue;\n ctx.moveTo(rect.x + rect.w, y);\n ctx.lineTo(rect.x + rect.w + 4, y);\n ctx.fillText(format(t), rect.x + rect.w + 7, y);\n }\n ctx.strokeStyle = style.axis;\n ctx.stroke();\n if (title) {\n ctx.font = `600 ${style.fontSize}px ${style.font}`;\n ctx.fillStyle = style.text;\n ctx.textAlign = \"left\";\n ctx.textBaseline = \"bottom\";\n const w = ctx.measureText(title).width;\n ctx.fillText(\n title,\n Math.max(4, Math.min(rect.x, right - 4 - w)),\n rect.y - 8,\n );\n }\n};\n\n/** Highlight of the hovered item */\nexport type HighlightShape =\n | { kind: \"point\"; x: number; y: number; radius: number; color: string }\n | { kind: \"box\"; min: Vec3; max: Vec3; color: string }\n | { kind: \"vertex\"; world: Vec3; color: string };\n\nexport const drawHighlight = (\n ctx: CanvasRenderingContext2D,\n frame: CameraFrame,\n axes: Axes,\n shape: HighlightShape,\n style: OverlayStyle,\n): void => {\n ctx.save();\n if (shape.kind === \"point\") {\n ctx.beginPath();\n ctx.arc(shape.x, shape.y, shape.radius + 3, 0, Math.PI * 2);\n ctx.lineWidth = 3;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.lineWidth = 1.5;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n } else if (shape.kind === \"box\") {\n const { min, max } = shape;\n const corner = (i: number) =>\n project(\n frame,\n i & 1 ? max[0] : min[0],\n i & 2 ? max[1] : min[1],\n i & 4 ? max[2] : min[2],\n );\n const pts = Array.from({ length: 8 }, (_, i) => corner(i));\n ctx.beginPath();\n for (let i = 0; i < 8; i++) {\n for (const bit of [1, 2, 4]) {\n if (i & bit) continue;\n const a = pts[i]!;\n const b = pts[i | bit]!;\n ctx.moveTo(a.x, a.y);\n ctx.lineTo(b.x, b.y);\n }\n }\n ctx.lineJoin = \"round\";\n ctx.lineWidth = 3.5;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.lineWidth = 1.5;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n } else {\n const [x, y, z] = shape.world;\n const top = project(frame, x, y, z);\n const floor = project(frame, x, y, -axes.z.half);\n ctx.beginPath();\n ctx.setLineDash([3, 3]);\n ctx.moveTo(top.x, top.y);\n ctx.lineTo(floor.x, floor.y);\n ctx.lineWidth = 1;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n ctx.setLineDash([]);\n ctx.beginPath();\n ctx.arc(floor.x, floor.y, 2.5, 0, Math.PI * 2);\n ctx.fillStyle = style.text;\n ctx.fill();\n ctx.beginPath();\n ctx.arc(top.x, top.y, 5, 0, Math.PI * 2);\n ctx.fillStyle = shape.color;\n ctx.fill();\n ctx.lineWidth = 2;\n ctx.strokeStyle = style.background;\n ctx.stroke();\n ctx.beginPath();\n ctx.arc(top.x, top.y, 7, 0, Math.PI * 2);\n ctx.lineWidth = 1.25;\n ctx.strokeStyle = style.text;\n ctx.stroke();\n }\n ctx.restore();\n};\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=e=>{let t
|
|
1
|
+
var e=e=>e.opacity<1?!1:e.kind===`mesh`?!e.transparent:e.kind!==`points`||!e.additive&&e.style!==2,t=t=>{let n=t=>t.kind===`mesh`?e(t)?0:3:t.kind===`points`?e(t)?1:2:4;return t.map((e,t)=>({item:e,i:t,r:n(e)})).sort((e,t)=>e.r-t.r||e.i-t.i).map(e=>e.item)};exports.drawOrder=t,exports.writesDepth=e;
|
|
2
2
|
//# sourceMappingURL=render-types.cjs.map
|