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
|
@@ -163,12 +163,84 @@ var unpackColor = (packed) => [
|
|
|
163
163
|
(packed >>> 16 & 255) / 255,
|
|
164
164
|
(packed >>> 24 & 255) / 255
|
|
165
165
|
];
|
|
166
|
-
/**
|
|
167
|
-
var
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
166
|
+
/** Relative luminance (sRGB approximation) */
|
|
167
|
+
var luminance = (c) => .2126 * c[0] + .7152 * c[1] + .0722 * c[2];
|
|
168
|
+
var toLinear = (v) => v <= .04045 ? v / 12.92 : ((v + .055) / 1.055) ** 2.4;
|
|
169
|
+
var toGamma = (v) => v <= .0031308 ? v * 12.92 : 1.055 * Math.max(0, v) ** (1 / 2.4) - .055;
|
|
170
|
+
/** sRGB -> OKLab (perceptually uniform: even steps look even) */
|
|
171
|
+
var toOklab = (c) => {
|
|
172
|
+
const r = toLinear(c[0]);
|
|
173
|
+
const g = toLinear(c[1]);
|
|
174
|
+
const b = toLinear(c[2]);
|
|
175
|
+
const l = Math.cbrt(.4122214708 * r + .5363325363 * g + .0514459929 * b);
|
|
176
|
+
const m = Math.cbrt(.2119034982 * r + .6806995451 * g + .1073969566 * b);
|
|
177
|
+
const s = Math.cbrt(.0883024619 * r + .2817188376 * g + .6299787005 * b);
|
|
178
|
+
return [
|
|
179
|
+
.2104542553 * l + .793617785 * m - .0040720468 * s,
|
|
180
|
+
1.9779984951 * l - 2.428592205 * m + .4505937099 * s,
|
|
181
|
+
.0259040371 * l + .7827717662 * m - .808675766 * s,
|
|
182
|
+
c[3]
|
|
183
|
+
];
|
|
184
|
+
};
|
|
185
|
+
/** OKLab -> sRGB, clamped to the gamut */
|
|
186
|
+
var fromOklab = (c) => {
|
|
187
|
+
const l = (c[0] + .3963377774 * c[1] + .2158037573 * c[2]) ** 3;
|
|
188
|
+
const m = (c[0] - .1055613458 * c[1] - .0638541728 * c[2]) ** 3;
|
|
189
|
+
const s = (c[0] - .0894841775 * c[1] - 1.291485548 * c[2]) ** 3;
|
|
190
|
+
return [
|
|
191
|
+
clamp01(toGamma(4.0767416621 * l - 3.3077115913 * m + .2309699292 * s)),
|
|
192
|
+
clamp01(toGamma(-1.2684380046 * l + 2.6097574011 * m - .3413193965 * s)),
|
|
193
|
+
clamp01(toGamma(-.0041960863 * l - .7034186147 * m + 1.707614701 * s)),
|
|
194
|
+
c[3]
|
|
195
|
+
];
|
|
196
|
+
};
|
|
197
|
+
/** Mixes two colors in OKLab (no muddy gray middle) */
|
|
198
|
+
var mixOklab = (a, b, t) => {
|
|
199
|
+
const p = toOklab(a);
|
|
200
|
+
const q = toOklab(b);
|
|
201
|
+
return fromOklab([
|
|
202
|
+
p[0] + (q[0] - p[0]) * t,
|
|
203
|
+
p[1] + (q[1] - p[1]) * t,
|
|
204
|
+
p[2] + (q[2] - p[2]) * t,
|
|
205
|
+
p[3] + (q[3] - p[3]) * t
|
|
206
|
+
]);
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* A color with another OKLab lightness (0-1) and its chroma scaled by
|
|
210
|
+
* `chroma` (the hue is kept)
|
|
211
|
+
*/
|
|
212
|
+
var withLightness = (c, lightness, chroma = 1) => {
|
|
213
|
+
const [, a, b, alpha] = toOklab(c);
|
|
214
|
+
return fromOklab([
|
|
215
|
+
lightness,
|
|
216
|
+
a * chroma,
|
|
217
|
+
b * chroma,
|
|
218
|
+
alpha
|
|
219
|
+
]);
|
|
220
|
+
};
|
|
221
|
+
/**
|
|
222
|
+
* Packed colors (`packColor`) of `size` even steps along a ramp through
|
|
223
|
+
* `stops`, interpolated in OKLab: a lookup table for many values
|
|
224
|
+
*/
|
|
225
|
+
var oklabRamp = (stops, size = 256) => {
|
|
226
|
+
const lut = new Uint32Array(size);
|
|
227
|
+
if (!stops.length) return lut;
|
|
228
|
+
const lab = stops.map(toOklab);
|
|
229
|
+
for (let k = 0; k < size; k++) {
|
|
230
|
+
const p = k / Math.max(1, size - 1) * (lab.length - 1);
|
|
231
|
+
const i = Math.min(lab.length - 2, Math.floor(p));
|
|
232
|
+
const a = lab[Math.max(0, i)];
|
|
233
|
+
const b = lab[Math.min(lab.length - 1, i + 1)];
|
|
234
|
+
const t = lab.length === 1 ? 0 : p - i;
|
|
235
|
+
const c = fromOklab([
|
|
236
|
+
a[0] + (b[0] - a[0]) * t,
|
|
237
|
+
a[1] + (b[1] - a[1]) * t,
|
|
238
|
+
a[2] + (b[2] - a[2]) * t,
|
|
239
|
+
a[3] + (b[3] - a[3]) * t
|
|
240
|
+
]);
|
|
241
|
+
lut[k] = packColor(c) || 1;
|
|
242
|
+
}
|
|
243
|
+
return lut;
|
|
172
244
|
};
|
|
173
245
|
/**
|
|
174
246
|
* Points of the curve through `x[i], y[i]` (`i` in `[start, end)`), as
|
|
@@ -422,7 +494,8 @@ var normalizeData = (data, resolveX, resolveY = toNumber) => {
|
|
|
422
494
|
y0: null,
|
|
423
495
|
q1: null,
|
|
424
496
|
q3: null,
|
|
425
|
-
outliers: null
|
|
497
|
+
outliers: null,
|
|
498
|
+
details: null
|
|
426
499
|
};
|
|
427
500
|
if (isColumns(data)) {
|
|
428
501
|
const count = data.y.length;
|
|
@@ -472,6 +545,7 @@ var normalizeData = (data, resolveX, resolveY = toNumber) => {
|
|
|
472
545
|
let q1 = null;
|
|
473
546
|
let q3 = null;
|
|
474
547
|
let outliers = null;
|
|
548
|
+
let details = null;
|
|
475
549
|
const nanColumn = () => new Float64Array(count).fill(NaN);
|
|
476
550
|
for (let i = 0; i < count; i++) {
|
|
477
551
|
const item = list[i];
|
|
@@ -508,6 +582,10 @@ var normalizeData = (data, resolveX, resolveY = toNumber) => {
|
|
|
508
582
|
outliers ??= new Array(count);
|
|
509
583
|
outliers[i] = d.outliers;
|
|
510
584
|
}
|
|
585
|
+
if (d.details !== void 0 && d.details.length) {
|
|
586
|
+
details ??= new Array(count);
|
|
587
|
+
details[i] = d.details;
|
|
588
|
+
}
|
|
511
589
|
} else {
|
|
512
590
|
x[i] = i;
|
|
513
591
|
y[i] = NaN;
|
|
@@ -524,7 +602,8 @@ var normalizeData = (data, resolveX, resolveY = toNumber) => {
|
|
|
524
602
|
y0,
|
|
525
603
|
q1,
|
|
526
604
|
q3,
|
|
527
|
-
outliers
|
|
605
|
+
outliers,
|
|
606
|
+
details
|
|
528
607
|
});
|
|
529
608
|
};
|
|
530
609
|
/** First index whose x is >= value (sorted x) */
|
|
@@ -691,6 +770,22 @@ var screenRect = (s, xa, xb, ya, yb) => {
|
|
|
691
770
|
height: d - c
|
|
692
771
|
};
|
|
693
772
|
};
|
|
773
|
+
/**
|
|
774
|
+
* Inset (per side) and corner radius of heatmap cells of `width` ×
|
|
775
|
+
* `height` CSS pixels: a hairline apart (1px, 2px on large cells), corners
|
|
776
|
+
* of `radius` at most 20% of the cell; tiny cells touch
|
|
777
|
+
*/
|
|
778
|
+
var heatCellStyle = (width, height, radius) => {
|
|
779
|
+
const size = Math.min(Math.abs(width), Math.abs(height));
|
|
780
|
+
if (!(size >= 4)) return {
|
|
781
|
+
inset: 0,
|
|
782
|
+
radius: 0
|
|
783
|
+
};
|
|
784
|
+
return {
|
|
785
|
+
inset: Math.round(Math.min(1, .5 + size / 96) * 4) / 4,
|
|
786
|
+
radius: Math.round(Math.max(0, Math.min(radius, size * .2)) * 4) / 4
|
|
787
|
+
};
|
|
788
|
+
};
|
|
694
789
|
/** Room for the axes, then the plot area */
|
|
695
790
|
var computePlot = (input) => {
|
|
696
791
|
const { width, height, padding, fontSize } = input;
|
|
@@ -941,6 +1036,31 @@ var formatValue = (value, locale) => {
|
|
|
941
1036
|
};
|
|
942
1037
|
/** `formatValue` bound to a locale */
|
|
943
1038
|
var valueFormatter = (locale) => (value) => formatValue(value, locale);
|
|
1039
|
+
var MINUTE$1 = 6e4;
|
|
1040
|
+
var HOUR$1 = 36e5;
|
|
1041
|
+
var DAY$1 = 864e5;
|
|
1042
|
+
/**
|
|
1043
|
+
* Length of a time range in its natural unit, in the words of a locale:
|
|
1044
|
+
* whole weeks (`4 weeks`, `4周`), else days (`26 days`, `26 jours`), hours
|
|
1045
|
+
* or minutes
|
|
1046
|
+
*/
|
|
1047
|
+
var formatDuration = (ms, locale) => {
|
|
1048
|
+
if (!Number.isFinite(ms)) return "–";
|
|
1049
|
+
const abs = Math.abs(ms);
|
|
1050
|
+
const days = abs / DAY$1;
|
|
1051
|
+
const weeks = days / 7;
|
|
1052
|
+
const [value, unit] = days >= 7 && Math.abs(weeks - Math.round(weeks)) < 1e-6 ? [Math.round(weeks), "week"] : days >= 1 ? [Math.round(days * 10) / 10, "day"] : abs >= HOUR$1 ? [Math.round(abs / HOUR$1 * 10) / 10, "hour"] : [Math.round(abs / MINUTE$1), "minute"];
|
|
1053
|
+
try {
|
|
1054
|
+
return numberFormat(locale, {
|
|
1055
|
+
style: "unit",
|
|
1056
|
+
unit,
|
|
1057
|
+
unitDisplay: "long",
|
|
1058
|
+
maximumFractionDigits: 1
|
|
1059
|
+
}).format(value);
|
|
1060
|
+
} catch {
|
|
1061
|
+
return `${value} ${unit}${value === 1 ? "" : "s"}`;
|
|
1062
|
+
}
|
|
1063
|
+
};
|
|
944
1064
|
/**
|
|
945
1065
|
* `12.5` -> `12.5%` (`12,5 %` in French): one decimal at most, exactly one
|
|
946
1066
|
* with `fixed` (`75.0%`)
|
|
@@ -969,7 +1089,13 @@ var CHART_LABELS = {
|
|
|
969
1089
|
y: "y",
|
|
970
1090
|
series: "Series",
|
|
971
1091
|
chart: "Chart",
|
|
972
|
-
chartOf: "Chart: {series}"
|
|
1092
|
+
chartOf: "Chart: {series}",
|
|
1093
|
+
start: "Start",
|
|
1094
|
+
end: "End",
|
|
1095
|
+
duration: "Duration",
|
|
1096
|
+
progress: "Progress",
|
|
1097
|
+
dependencies: "Depends on",
|
|
1098
|
+
outlier: "Outlier"
|
|
973
1099
|
},
|
|
974
1100
|
zh: {
|
|
975
1101
|
open: "开盘",
|
|
@@ -985,7 +1111,13 @@ var CHART_LABELS = {
|
|
|
985
1111
|
value: "数值",
|
|
986
1112
|
series: "系列",
|
|
987
1113
|
chart: "图表",
|
|
988
|
-
chartOf: "图表:{series}"
|
|
1114
|
+
chartOf: "图表:{series}",
|
|
1115
|
+
start: "开始",
|
|
1116
|
+
end: "结束",
|
|
1117
|
+
duration: "时长",
|
|
1118
|
+
progress: "进度",
|
|
1119
|
+
dependencies: "前置任务",
|
|
1120
|
+
outlier: "异常值"
|
|
989
1121
|
},
|
|
990
1122
|
ja: {
|
|
991
1123
|
open: "始値",
|
|
@@ -1001,7 +1133,13 @@ var CHART_LABELS = {
|
|
|
1001
1133
|
value: "値",
|
|
1002
1134
|
series: "系列",
|
|
1003
1135
|
chart: "グラフ",
|
|
1004
|
-
chartOf: "グラフ:{series}"
|
|
1136
|
+
chartOf: "グラフ:{series}",
|
|
1137
|
+
start: "開始",
|
|
1138
|
+
end: "終了",
|
|
1139
|
+
duration: "期間",
|
|
1140
|
+
progress: "進捗",
|
|
1141
|
+
dependencies: "先行タスク",
|
|
1142
|
+
outlier: "外れ値"
|
|
1005
1143
|
},
|
|
1006
1144
|
fr: {
|
|
1007
1145
|
open: "Ouverture",
|
|
@@ -1017,7 +1155,13 @@ var CHART_LABELS = {
|
|
|
1017
1155
|
value: "Valeur",
|
|
1018
1156
|
series: "Série",
|
|
1019
1157
|
chart: "Graphique",
|
|
1020
|
-
chartOf: "Graphique : {series}"
|
|
1158
|
+
chartOf: "Graphique : {series}",
|
|
1159
|
+
start: "Début",
|
|
1160
|
+
end: "Fin",
|
|
1161
|
+
duration: "Durée",
|
|
1162
|
+
progress: "Avancement",
|
|
1163
|
+
dependencies: "Dépend de",
|
|
1164
|
+
outlier: "Valeur aberrante"
|
|
1021
1165
|
}
|
|
1022
1166
|
};
|
|
1023
1167
|
/** Texts of a locale with the overrides */
|
|
@@ -1100,6 +1244,12 @@ var GridIndex = class {
|
|
|
1100
1244
|
};
|
|
1101
1245
|
//#endregion
|
|
1102
1246
|
//#region ../charts/src/engine/model.ts
|
|
1247
|
+
/** Plotted units of a log axis: the base-10 logarithm of the values */
|
|
1248
|
+
var LOG_MAP = {
|
|
1249
|
+
scale: 1,
|
|
1250
|
+
offset: 0,
|
|
1251
|
+
log: true
|
|
1252
|
+
};
|
|
1103
1253
|
var firstX = (data) => {
|
|
1104
1254
|
if (typeof data === "object" && data !== null && !("length" in data)) {
|
|
1105
1255
|
const xs = data.x;
|
|
@@ -1282,13 +1432,11 @@ var alignedDomain = (lo, hi, left, count) => {
|
|
|
1282
1432
|
var mapped = /* @__PURE__ */ new WeakMap();
|
|
1283
1433
|
/** Columns of a right-axis series in left axis units (cached with the data) */
|
|
1284
1434
|
var mapColumns = (raw, map) => {
|
|
1285
|
-
const key = `${map.scale},${map.offset}`;
|
|
1435
|
+
const key = `${map.scale},${map.offset},${!!map.log}`;
|
|
1286
1436
|
const hit = mapped.get(raw);
|
|
1287
1437
|
if (hit && hit.key === key) return hit.cols;
|
|
1288
|
-
const f = (
|
|
1438
|
+
const f = mapper(map);
|
|
1289
1439
|
const column = (a) => a ? a.map(f) : null;
|
|
1290
|
-
const lo = f(raw.yMin);
|
|
1291
|
-
const hi = f(raw.yMax);
|
|
1292
1440
|
const cols = {
|
|
1293
1441
|
...raw,
|
|
1294
1442
|
y: raw.y.map(f),
|
|
@@ -1298,16 +1446,116 @@ var mapColumns = (raw, map) => {
|
|
|
1298
1446
|
y0: column(raw.y0),
|
|
1299
1447
|
q1: column(raw.q1),
|
|
1300
1448
|
q3: column(raw.q3),
|
|
1301
|
-
outliers: raw.outliers ? raw.outliers.map((list) => list?.map(f)) : null
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1449
|
+
outliers: raw.outliers ? raw.outliers.map((list) => list?.map(f)) : null
|
|
1450
|
+
};
|
|
1451
|
+
if (map.log) {
|
|
1452
|
+
const range = [Infinity, -Infinity];
|
|
1453
|
+
const add = (a) => {
|
|
1454
|
+
if (!a) return;
|
|
1455
|
+
for (let i = 0; i < a.length; i++) {
|
|
1456
|
+
const v = a[i];
|
|
1457
|
+
if (!Number.isFinite(v)) continue;
|
|
1458
|
+
if (v < range[0]) range[0] = v;
|
|
1459
|
+
if (v > range[1]) range[1] = v;
|
|
1460
|
+
}
|
|
1461
|
+
};
|
|
1462
|
+
for (const c of [
|
|
1463
|
+
cols.y,
|
|
1464
|
+
cols.y0,
|
|
1465
|
+
cols.high,
|
|
1466
|
+
cols.low,
|
|
1467
|
+
cols.q1,
|
|
1468
|
+
cols.q3
|
|
1469
|
+
]) add(c);
|
|
1470
|
+
cols.outliers?.forEach((list) => add(list));
|
|
1471
|
+
cols.yMin = range[0] <= range[1] ? range[0] : NaN;
|
|
1472
|
+
cols.yMax = range[0] <= range[1] ? range[1] : NaN;
|
|
1473
|
+
} else {
|
|
1474
|
+
const lo = f(raw.yMin);
|
|
1475
|
+
const hi = f(raw.yMax);
|
|
1476
|
+
cols.yMin = Math.min(lo, hi);
|
|
1477
|
+
cols.yMax = Math.max(lo, hi);
|
|
1478
|
+
}
|
|
1305
1479
|
mapped.set(raw, {
|
|
1306
1480
|
key,
|
|
1307
1481
|
cols
|
|
1308
1482
|
});
|
|
1309
1483
|
return cols;
|
|
1310
1484
|
};
|
|
1485
|
+
/** A log range widened to whole decades (`[0.3, 2.4]` -> `[0, 3]`) */
|
|
1486
|
+
var decades = (range) => {
|
|
1487
|
+
const lo = Math.floor(range[0] + 1e-9);
|
|
1488
|
+
const hi = Math.ceil(range[1] - 1e-9);
|
|
1489
|
+
return [lo, hi > lo ? hi : lo + 1];
|
|
1490
|
+
};
|
|
1491
|
+
/**
|
|
1492
|
+
* Plots a series through a map: its columns, bars, stacks and lower
|
|
1493
|
+
* edges (bars / areas of the right axis start at `zero`)
|
|
1494
|
+
*/
|
|
1495
|
+
var logColumns = (s, map, zero = -Infinity) => {
|
|
1496
|
+
const f = mapper(map);
|
|
1497
|
+
const column = (a) => a ? a.map(f) : null;
|
|
1498
|
+
const rawBase = s.stackBase;
|
|
1499
|
+
s.cols = mapColumns(s.raw, map);
|
|
1500
|
+
s.barBase = s.barBase && !s.floating ? s.barBase.map((v) => v === 0 ? map.log ? -Infinity : f(0) : f(v)) : column(s.barBase);
|
|
1501
|
+
s.barTop = column(s.barTop);
|
|
1502
|
+
s.stackTop = column(s.stackTop);
|
|
1503
|
+
s.stackBase = rawBase && rawBase === s.raw.y0 ? s.cols.y0 : rawBase ? column(rawBase) : s.type === "area" ? new Float64Array(s.cols.count).fill(zero) : null;
|
|
1504
|
+
};
|
|
1505
|
+
/** Value -> plotted units of a map (`-Infinity` for 0 on log axes) */
|
|
1506
|
+
var mapper = (map) => (v) => (map.log ? Math.log10(v) : v) * map.scale + map.offset;
|
|
1507
|
+
/** Value of the y axis -> plotted y (the logarithm on log axes) */
|
|
1508
|
+
var toPlotY = (model, value) => model.y.type === "log" ? Math.log10(value) : value;
|
|
1509
|
+
/** Plotted y -> value of the y axis */
|
|
1510
|
+
var fromPlotY = (model, value) => model.y.type === "log" ? 10 ** value : value;
|
|
1511
|
+
/** Replaces the bases of bars / areas on log axes (`-Infinity`) by the bottom of the axis */
|
|
1512
|
+
var floorBases = (s, floor) => {
|
|
1513
|
+
for (const a of [s.barBase, s.stackBase]) {
|
|
1514
|
+
if (!a) continue;
|
|
1515
|
+
for (let i = 0; i < a.length; i++) if (a[i] === -Infinity) a[i] = floor;
|
|
1516
|
+
}
|
|
1517
|
+
};
|
|
1518
|
+
/** Position (0-1) of a heatmap value on its color ramp */
|
|
1519
|
+
var heatPosition = (s, v) => {
|
|
1520
|
+
const [lo, hi] = s.valueRange;
|
|
1521
|
+
const mid = s.colorMidpoint;
|
|
1522
|
+
let t;
|
|
1523
|
+
if (mid !== null && mid > lo && mid < hi) t = v < mid ? (v - lo) / (mid - lo) * .5 : .5 + (v - mid) / (hi - mid) * .5;
|
|
1524
|
+
else t = (v - lo) / (hi - lo || 1);
|
|
1525
|
+
return t < 0 ? 0 : t > 1 ? 1 : t;
|
|
1526
|
+
};
|
|
1527
|
+
/**
|
|
1528
|
+
* Built-in ramps of heatmaps, perceptual (OKLab) and theme-aware: light
|
|
1529
|
+
* themes go from a near-white tint to a deep hue, dark themes from a dark
|
|
1530
|
+
* tint of the surface to a bright saturated hue; diverging ramps meet in a
|
|
1531
|
+
* neutral middle
|
|
1532
|
+
*/
|
|
1533
|
+
var heatmapStops = (scheme, color, theme, negative) => {
|
|
1534
|
+
const dark = luminance(theme.background) < .4;
|
|
1535
|
+
if (scheme === "diverging") {
|
|
1536
|
+
const neutral = mixOklab(theme.surface, theme.textMuted, dark ? .12 : .08);
|
|
1537
|
+
const end = (c) => dark ? withLightness(c, .7, 1.25) : withLightness(c, .5, 1.05);
|
|
1538
|
+
const side = (c) => mixOklab(neutral, end(c), .5);
|
|
1539
|
+
return [
|
|
1540
|
+
end(negative),
|
|
1541
|
+
side(negative),
|
|
1542
|
+
neutral,
|
|
1543
|
+
side(color),
|
|
1544
|
+
end(color)
|
|
1545
|
+
];
|
|
1546
|
+
}
|
|
1547
|
+
return dark ? [
|
|
1548
|
+
mixOklab(theme.surface, color, .14),
|
|
1549
|
+
withLightness(color, .46, .95),
|
|
1550
|
+
withLightness(color, .64, 1.2),
|
|
1551
|
+
withLightness(color, .8, 1.15)
|
|
1552
|
+
] : [
|
|
1553
|
+
mixOklab(theme.surface, color, .06),
|
|
1554
|
+
withLightness(color, .8, .6),
|
|
1555
|
+
withLightness(color, .58, 1),
|
|
1556
|
+
withLightness(color, .36, .9)
|
|
1557
|
+
];
|
|
1558
|
+
};
|
|
1311
1559
|
var buildModel = (options, theme, hidden, cache, resolver = null) => {
|
|
1312
1560
|
const resolve = resolver ?? theme.resolve ?? ((value, fallback) => resolveStaticColor(value, {}, fallback));
|
|
1313
1561
|
const input = options.series;
|
|
@@ -1325,7 +1573,8 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
|
|
|
1325
1573
|
const yOpts = options.yAxis;
|
|
1326
1574
|
const heatmapData = input.filter((s) => s.type === "heatmap").map((s) => s.data);
|
|
1327
1575
|
const yCategories = yOpts?.type === "category" || !yOpts?.type && heatmapData.length ? [...yOpts?.categories ?? collectYCategories(heatmapData)] : [];
|
|
1328
|
-
const yType = yOpts?.type === "category" || yCategories.length ? "category" : yOpts?.type === "time" || !yOpts?.type && hasDateY(datas) ? "time" : "linear";
|
|
1576
|
+
const yType = yOpts?.type === "category" || yCategories.length ? "category" : yOpts?.type === "time" || !yOpts?.type && hasDateY(datas) ? "time" : yOpts?.type === "log" ? "log" : "linear";
|
|
1577
|
+
const yLog = yType === "log";
|
|
1329
1578
|
const yCategoryMap = new Map(yCategories.map((c, i) => [c, i]));
|
|
1330
1579
|
const resolveY = (v) => typeof v === "number" ? v : typeof v === "string" ? yType === "category" ? yCategoryMap.get(v) ?? NaN : yType === "time" ? Date.parse(v) : Number(v) : v instanceof Date ? v.getTime() : NaN;
|
|
1331
1580
|
const resolverKey = `${xType}|${categories.join("")}|${yType}|${yCategories.join("")}`;
|
|
@@ -1362,20 +1611,36 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
|
|
|
1362
1611
|
let colorScale = [];
|
|
1363
1612
|
let valueRange = [0, 1];
|
|
1364
1613
|
let cellColors = null;
|
|
1614
|
+
let colorMidpoint = null;
|
|
1615
|
+
let colorLut = null;
|
|
1365
1616
|
if (type === "heatmap") {
|
|
1366
|
-
|
|
1617
|
+
const scale = s.colorScale;
|
|
1618
|
+
const scheme = scale === "diverging" ? "diverging" : "sequential";
|
|
1619
|
+
colorScale = typeof scale === "object" && scale.length ? scale.map((c) => resolve(c, color)) : heatmapStops(scheme, color, theme, resolve(DEFAULT_DOWN, [
|
|
1620
|
+
.86,
|
|
1621
|
+
.15,
|
|
1622
|
+
.15,
|
|
1623
|
+
1
|
|
1624
|
+
]));
|
|
1367
1625
|
valueRange = s.valueRange ? [s.valueRange[0], s.valueRange[1]] : [cols.valueMin, cols.valueMax];
|
|
1368
1626
|
if (!Number.isFinite(valueRange[0])) valueRange = [0, 1];
|
|
1369
|
-
const values = cols.value ?? cols.y;
|
|
1370
1627
|
const [lo, hi] = valueRange;
|
|
1371
|
-
|
|
1628
|
+
colorMidpoint = s.colorMidpoint ?? (scheme === "diverging" && typeof scale !== "object" ? lo < 0 && hi > 0 ? 0 : (lo + hi) / 2 : null);
|
|
1629
|
+
const lut = oklabRamp(colorScale);
|
|
1630
|
+
colorLut = lut;
|
|
1631
|
+
const values = cols.value ?? cols.y;
|
|
1632
|
+
const ramp = {
|
|
1633
|
+
valueRange,
|
|
1634
|
+
colorMidpoint
|
|
1635
|
+
};
|
|
1372
1636
|
cellColors = new Uint32Array(cols.count);
|
|
1373
1637
|
for (let i = 0; i < cols.count; i++) {
|
|
1374
1638
|
const v = values[i];
|
|
1375
1639
|
if (!Number.isFinite(v) || !Number.isFinite(cols.y[i])) continue;
|
|
1376
|
-
cellColors[i] =
|
|
1640
|
+
cellColors[i] = lut[Math.round(heatPosition(ramp, v) * 255)];
|
|
1377
1641
|
}
|
|
1378
1642
|
}
|
|
1643
|
+
const connector = s.connector ? typeof s.connector === "object" ? s.connector : {} : null;
|
|
1379
1644
|
const id = s.id ?? String(index);
|
|
1380
1645
|
return {
|
|
1381
1646
|
index,
|
|
@@ -1421,6 +1686,16 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
|
|
|
1421
1686
|
},
|
|
1422
1687
|
colorScale,
|
|
1423
1688
|
valueRange,
|
|
1689
|
+
colorMidpoint,
|
|
1690
|
+
colorLut,
|
|
1691
|
+
tooltip: s.tooltip !== false,
|
|
1692
|
+
outlierShape: s.outlierShape ?? "hollow",
|
|
1693
|
+
outlierSize: s.outlierSize ?? s.pointSize ?? 7,
|
|
1694
|
+
connector: connector && type === "bar" ? {
|
|
1695
|
+
color: connector.color ? resolve(connector.color, theme.textMuted) : theme.textMuted,
|
|
1696
|
+
dash: [...connector.dash ?? [3, 3]],
|
|
1697
|
+
width: connector.width ?? 1
|
|
1698
|
+
} : null,
|
|
1424
1699
|
radius: s.radius ?? (type === "heatmap" ? 2 : type === "boxplot" ? 0 : 3),
|
|
1425
1700
|
format: s.format,
|
|
1426
1701
|
valueName: s.valueName
|
|
@@ -1521,14 +1796,18 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
|
|
|
1521
1796
|
if (xOpts?.min !== void 0) xRange[0] = xOpts.min;
|
|
1522
1797
|
if (xOpts?.max !== void 0) xRange[1] = xOpts.max;
|
|
1523
1798
|
xRange = ensureSpan(xRange[0], xRange[1]);
|
|
1524
|
-
|
|
1799
|
+
if (yLog) for (const s of series) {
|
|
1800
|
+
if (s.yAxis === "right" || s.type === "heatmap") continue;
|
|
1801
|
+
logColumns(s, LOG_MAP);
|
|
1802
|
+
}
|
|
1803
|
+
const valuesOf = (list, zero, log = false) => {
|
|
1525
1804
|
const values = [];
|
|
1526
1805
|
for (const s of list) if (s.type === "bar" && s.barBase && s.barTop) values.push(...extent(s.barBase), ...extent(s.barTop));
|
|
1527
1806
|
else if (s.stackBase && s.stackTop) values.push(...extent(s.stackBase), ...extent(s.stackTop));
|
|
1528
1807
|
else if (s.type === "heatmap") values.push(s.cols.yMin - s.cellHalf.y, s.cols.yMax + s.cellHalf.y);
|
|
1529
1808
|
else values.push(s.cols.yMin, s.cols.yMax);
|
|
1530
1809
|
const listBars = list.filter((s) => s.type === "bar");
|
|
1531
|
-
if (listBars.some((s) => !s.floating) || zero) values.push(0);
|
|
1810
|
+
if (!log && (listBars.some((s) => !s.floating) || zero)) values.push(0);
|
|
1532
1811
|
if (listBars.some((s) => s.showLabels)) {
|
|
1533
1812
|
const [lo, hi] = extent(values);
|
|
1534
1813
|
if (hi > 0) values.push(hi + (hi - Math.min(0, lo)) * .1);
|
|
@@ -1542,7 +1821,7 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
|
|
|
1542
1821
|
let yRange;
|
|
1543
1822
|
if (yType === "category") yRange = [-.5, Math.max(1, yCategories.length) - .5];
|
|
1544
1823
|
else {
|
|
1545
|
-
const yValues = valuesOf(leftSeries, yOpts?.zero);
|
|
1824
|
+
const yValues = valuesOf(leftSeries, yOpts?.zero, yLog);
|
|
1546
1825
|
const filled = leftBars.length > 0 || leftSeries.some((s) => s.type === "area");
|
|
1547
1826
|
yRange = ensureSpan(...extent(yValues));
|
|
1548
1827
|
if (series.every((s) => s.type === "scatter")) {
|
|
@@ -1553,43 +1832,50 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
|
|
|
1553
1832
|
yRange = [yRange[0] - pad, yRange[1] + pad];
|
|
1554
1833
|
}
|
|
1555
1834
|
if ((yOpts?.nice ?? !heatmaps.length) && yType === "linear") yRange = niceDomain(yRange[0], yRange[1], yOpts?.tickCount ?? 5);
|
|
1835
|
+
if (yLog && yOpts?.nice !== false) yRange = decades(yRange);
|
|
1556
1836
|
if (percent && (bars.length || stackedLines.length)) yRange = [extent(yValues)[0] < 0 ? -100 : 0, 100];
|
|
1557
|
-
if (filled && !yOpts?.zero) {
|
|
1837
|
+
if (filled && !yOpts?.zero && !yLog) {
|
|
1558
1838
|
if (yRange[0] < 0 && extent(yValues)[0] >= 0) yRange[0] = 0;
|
|
1559
1839
|
}
|
|
1560
1840
|
}
|
|
1561
|
-
|
|
1562
|
-
if (yOpts?.
|
|
1841
|
+
const yBound = (v) => yLog ? Math.log10(v) : v;
|
|
1842
|
+
if (yOpts?.min !== void 0) yRange[0] = yBound(yOpts.min);
|
|
1843
|
+
if (yOpts?.max !== void 0) yRange[1] = yBound(yOpts.max);
|
|
1563
1844
|
yRange = ensureSpan(yRange[0], yRange[1]);
|
|
1845
|
+
if (yLog) {
|
|
1846
|
+
for (const s of series) if (s.yAxis === "left") floorBases(s, yRange[0]);
|
|
1847
|
+
}
|
|
1564
1848
|
const y2Opts = options.yAxis2;
|
|
1565
1849
|
let y2 = null;
|
|
1566
1850
|
let y2Map = null;
|
|
1567
1851
|
const rightSeries = series.filter((s) => s.yAxis === "right");
|
|
1568
1852
|
if (rightSeries.length && yType !== "category") {
|
|
1569
|
-
const
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1853
|
+
const y2Log = y2Opts?.type === "log";
|
|
1854
|
+
const rightVisible = rightSeries.filter((s) => !s.hidden);
|
|
1855
|
+
const [lo, hi] = ensureSpan(...extent(y2Log ? rightVisible.flatMap((s) => {
|
|
1856
|
+
const c = mapColumns(s.raw, LOG_MAP);
|
|
1857
|
+
return [c.yMin, c.yMax];
|
|
1858
|
+
}) : valuesOf(rightVisible, y2Opts?.zero)));
|
|
1859
|
+
let domain = y2Opts?.nice === false ? [lo, hi] : y2Log ? decades([lo, hi]) : alignedDomain(lo, hi, yRange, yOpts?.tickCount ?? 5);
|
|
1860
|
+
const y2Bound = (v) => y2Log ? Math.log10(v) : v;
|
|
1861
|
+
if (y2Opts?.min !== void 0) domain[0] = y2Bound(y2Opts.min);
|
|
1862
|
+
if (y2Opts?.max !== void 0) domain[1] = y2Bound(y2Opts.max);
|
|
1573
1863
|
domain = ensureSpan(domain[0], domain[1]);
|
|
1574
1864
|
const scale = (yRange[1] - yRange[0]) / (domain[1] - domain[0]);
|
|
1575
1865
|
const map = {
|
|
1576
1866
|
scale,
|
|
1577
|
-
offset: yRange[0] - domain[0] * scale
|
|
1867
|
+
offset: yRange[0] - domain[0] * scale,
|
|
1868
|
+
log: y2Log
|
|
1578
1869
|
};
|
|
1579
1870
|
y2Map = map;
|
|
1580
|
-
const
|
|
1581
|
-
const column = (a) => a ? a.map(f) : null;
|
|
1582
|
-
const zero = f(Math.min(Math.max(0, domain[0]), domain[1]));
|
|
1871
|
+
const zero = y2Log ? yRange[0] : mapper(map)(Math.min(Math.max(0, domain[0]), domain[1]));
|
|
1583
1872
|
for (const s of rightSeries) {
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
s.barBase = column(s.barBase);
|
|
1587
|
-
s.barTop = column(s.barTop);
|
|
1588
|
-
s.stackTop = column(s.stackTop);
|
|
1589
|
-
s.stackBase = rawBase && rawBase === s.raw.y0 ? s.cols.y0 : rawBase ? column(rawBase) : s.type === "area" ? new Float64Array(s.cols.count).fill(zero) : null;
|
|
1873
|
+
logColumns(s, map, zero);
|
|
1874
|
+
floorBases(s, yRange[0]);
|
|
1590
1875
|
}
|
|
1591
|
-
y2 = axisModel(y2Opts, "linear", [], false, locale);
|
|
1876
|
+
y2 = axisModel(y2Opts, y2Log ? "log" : "linear", [], false, locale);
|
|
1592
1877
|
}
|
|
1878
|
+
const timeline = yType === "time" && series.some((s) => s.type === "bar") && series.every((s) => s.type === "bar" ? s.floating : s.type === "scatter");
|
|
1593
1879
|
const zoomOption = options.interaction === false ? false : options.interaction === true || options.interaction === void 0 ? true : options.interaction.zoom ?? true;
|
|
1594
1880
|
const zoomAxes = zoomOption === false ? {
|
|
1595
1881
|
x: false,
|
|
@@ -1621,8 +1907,8 @@ var buildModel = (options, theme, hidden, cache, resolver = null) => {
|
|
|
1621
1907
|
},
|
|
1622
1908
|
allScatter,
|
|
1623
1909
|
zoom: zoomAxes,
|
|
1624
|
-
tooltipMode: tooltipOptions?.mode ?? (allScatter ? "nearest" : "axis"),
|
|
1625
|
-
baseline: Math.min(Math.max(0, yRange[0]), yRange[1]),
|
|
1910
|
+
tooltipMode: tooltipOptions?.mode ?? (allScatter ? "nearest" : timeline ? "item" : "axis"),
|
|
1911
|
+
baseline: yLog ? yRange[0] : Math.min(Math.max(0, yRange[0]), yRange[1]),
|
|
1626
1912
|
minSpan: {
|
|
1627
1913
|
x: xType === "category" ? 1 : (xRange[1] - xRange[0]) * 1e-7,
|
|
1628
1914
|
y: yType === "category" ? 1 : (yRange[1] - yRange[0]) * 1e-7
|
|
@@ -1892,6 +2178,19 @@ var drawForeground = (ctx, input) => {
|
|
|
1892
2178
|
ctx.beginPath();
|
|
1893
2179
|
ctx.rect(plot.x, plot.y, plot.width, plot.height);
|
|
1894
2180
|
ctx.clip();
|
|
2181
|
+
for (const c of input.connectors ?? []) {
|
|
2182
|
+
ctx.strokeStyle = c.color;
|
|
2183
|
+
ctx.lineWidth = c.width;
|
|
2184
|
+
ctx.setLineDash([...c.dash]);
|
|
2185
|
+
ctx.beginPath();
|
|
2186
|
+
const along = c.y0 === c.y1;
|
|
2187
|
+
const x0 = along ? c.x0 : crisp(c.x0);
|
|
2188
|
+
const y0 = along ? crisp(c.y0) : c.y0;
|
|
2189
|
+
ctx.moveTo(x0, y0);
|
|
2190
|
+
ctx.lineTo(along ? c.x1 : x0, along ? y0 : c.y1);
|
|
2191
|
+
ctx.stroke();
|
|
2192
|
+
}
|
|
2193
|
+
ctx.setLineDash([]);
|
|
1895
2194
|
const halo = toCss(theme.background, .9);
|
|
1896
2195
|
const occupied = [];
|
|
1897
2196
|
const labelHeight = theme.fontSize + 4;
|
|
@@ -2302,6 +2601,7 @@ var axisTicks = (axis, range, count) => {
|
|
|
2302
2601
|
}
|
|
2303
2602
|
const values = linearTicks(min, max, count);
|
|
2304
2603
|
const step = tickStep(min, max, count);
|
|
2604
|
+
if (axis.type === "log") return logTicks(axis, min, max, count);
|
|
2305
2605
|
const tick = axis.format ?? tickFormatter(step, Math.max(Math.abs(min), Math.abs(max)), axis.locale);
|
|
2306
2606
|
return {
|
|
2307
2607
|
values,
|
|
@@ -2309,6 +2609,41 @@ var axisTicks = (axis, range, count) => {
|
|
|
2309
2609
|
formatValue: axis.format ?? ((value) => formatValue(value, axis.locale))
|
|
2310
2610
|
};
|
|
2311
2611
|
};
|
|
2612
|
+
/**
|
|
2613
|
+
* Ticks of a log axis (`min` / `max` are exponents): every decade, with 2
|
|
2614
|
+
* and 5 between them on short ranges, every few decades on long ones;
|
|
2615
|
+
* labelled with the values (`1k`, `10k`)
|
|
2616
|
+
*/
|
|
2617
|
+
var logTicks = (axis, min, max, count) => {
|
|
2618
|
+
const span = max - min;
|
|
2619
|
+
const values = [];
|
|
2620
|
+
const raw = [];
|
|
2621
|
+
const push = (v) => {
|
|
2622
|
+
const e = Math.log10(v);
|
|
2623
|
+
if (e >= min - 1e-9 && e <= max + 1e-9) {
|
|
2624
|
+
values.push(e);
|
|
2625
|
+
raw.push(v);
|
|
2626
|
+
}
|
|
2627
|
+
};
|
|
2628
|
+
if (span < 1) {
|
|
2629
|
+
for (const v of linearTicks(10 ** min, 10 ** max, count)) if (v > 0) push(v);
|
|
2630
|
+
} else {
|
|
2631
|
+
const every = Math.max(1, Math.ceil(span / Math.max(1, count)));
|
|
2632
|
+
const between = span * 3 <= count * 1.6 ? [2, 5] : [];
|
|
2633
|
+
for (let e = Math.floor(min); e <= Math.ceil(max); e++) {
|
|
2634
|
+
if (e % every !== 0) continue;
|
|
2635
|
+
const decade = Number((10 ** e).toPrecision(12));
|
|
2636
|
+
push(decade);
|
|
2637
|
+
for (const m of between) push(Number((m * decade).toPrecision(12)));
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
const label = axis.format ?? ((v) => formatCompact(v, 2, axis.locale));
|
|
2641
|
+
return {
|
|
2642
|
+
values,
|
|
2643
|
+
labels: raw.map(label),
|
|
2644
|
+
formatValue: axis.format ?? ((value) => formatValue(value, axis.locale))
|
|
2645
|
+
};
|
|
2646
|
+
};
|
|
2312
2647
|
var DEFAULT_PADDING = {
|
|
2313
2648
|
top: 12,
|
|
2314
2649
|
right: 16,
|
|
@@ -2316,9 +2651,13 @@ var DEFAULT_PADDING = {
|
|
|
2316
2651
|
left: 4
|
|
2317
2652
|
};
|
|
2318
2653
|
var fallbackResolve = (_value, fallback) => fallback;
|
|
2319
|
-
/**
|
|
2320
|
-
|
|
2654
|
+
/**
|
|
2655
|
+
* Annotation colors resolved against the theme; `mapY` turns y values into
|
|
2656
|
+
* plotted units (log axes)
|
|
2657
|
+
*/
|
|
2658
|
+
var resolveAnnotations = (annotations, theme, mapY) => {
|
|
2321
2659
|
const resolve = theme.resolve ?? fallbackResolve;
|
|
2660
|
+
const y = (v) => mapY && v !== void 0 ? mapY(v) : v;
|
|
2322
2661
|
return (annotations ?? []).map((a) => {
|
|
2323
2662
|
if (a.type === "rect") {
|
|
2324
2663
|
const color = a.color ? resolve(a.color, theme.primary) : theme.primary;
|
|
@@ -2326,8 +2665,8 @@ var resolveAnnotations = (annotations, theme) => {
|
|
|
2326
2665
|
type: "rect",
|
|
2327
2666
|
x0: a.x0,
|
|
2328
2667
|
x1: a.x1,
|
|
2329
|
-
y0: a.y0,
|
|
2330
|
-
y1: a.y1,
|
|
2668
|
+
y0: y(a.y0),
|
|
2669
|
+
y1: y(a.y1),
|
|
2331
2670
|
color,
|
|
2332
2671
|
opacity: a.opacity ?? .08,
|
|
2333
2672
|
label: a.label,
|
|
@@ -2338,7 +2677,7 @@ var resolveAnnotations = (annotations, theme) => {
|
|
|
2338
2677
|
if (a.type === "text") return {
|
|
2339
2678
|
type: "text",
|
|
2340
2679
|
x: a.x,
|
|
2341
|
-
y: a.y,
|
|
2680
|
+
y: y(a.y),
|
|
2342
2681
|
text: a.text,
|
|
2343
2682
|
anchor: a.anchor ?? "center",
|
|
2344
2683
|
color: a.color ? resolve(a.color, theme.textMuted) : theme.textMuted,
|
|
@@ -2347,7 +2686,7 @@ var resolveAnnotations = (annotations, theme) => {
|
|
|
2347
2686
|
return {
|
|
2348
2687
|
type: "line",
|
|
2349
2688
|
axis: a.axis,
|
|
2350
|
-
value: a.value,
|
|
2689
|
+
value: a.axis === "y" ? y(a.value) : a.value,
|
|
2351
2690
|
color: a.color ? resolve(a.color, theme.textMuted) : theme.textMuted,
|
|
2352
2691
|
width: a.width ?? 1,
|
|
2353
2692
|
dash: [...a.dash ?? [4, 4]],
|
|
@@ -2363,7 +2702,7 @@ var layoutChart = (input) => {
|
|
|
2363
2702
|
const yTicks = axisTicks(model.y, view.y, yCount);
|
|
2364
2703
|
let yLabelWidth = 0;
|
|
2365
2704
|
if (model.y.visible) for (const label of yTicks.labels) yLabelWidth = Math.max(yLabelWidth, measure(label));
|
|
2366
|
-
const y2Ticks = rightTicks(model, yTicks);
|
|
2705
|
+
const y2Ticks = rightTicks(model, yTicks, view.y, yCount);
|
|
2367
2706
|
let y2LabelWidth = 0;
|
|
2368
2707
|
if (y2Ticks && model.y2?.visible) for (const label of y2Ticks.labels) y2LabelWidth = Math.max(y2LabelWidth, measure(label));
|
|
2369
2708
|
let categoryWidth = 48;
|
|
@@ -2398,11 +2737,23 @@ var layoutChart = (input) => {
|
|
|
2398
2737
|
y2Ticks
|
|
2399
2738
|
};
|
|
2400
2739
|
};
|
|
2401
|
-
/**
|
|
2402
|
-
|
|
2740
|
+
/**
|
|
2741
|
+
* Right axis ticks: the left ticks labelled in right axis units; log axes
|
|
2742
|
+
* get their own decades
|
|
2743
|
+
*/
|
|
2744
|
+
var rightTicks = (model, yTicks, view, count) => {
|
|
2403
2745
|
const axis = model.y2;
|
|
2404
2746
|
const map = model.y2Map;
|
|
2405
2747
|
if (!axis || !map || !map.scale) return null;
|
|
2748
|
+
if (map.log) {
|
|
2749
|
+
const a = (view[0] - map.offset) / map.scale;
|
|
2750
|
+
const b = (view[1] - map.offset) / map.scale;
|
|
2751
|
+
const ticks = axisTicks(axis, [Math.min(a, b), Math.max(a, b)], count);
|
|
2752
|
+
return {
|
|
2753
|
+
...ticks,
|
|
2754
|
+
values: ticks.values.map((e) => e * map.scale + map.offset)
|
|
2755
|
+
};
|
|
2756
|
+
}
|
|
2406
2757
|
const raw = yTicks.values.map((v) => (v - map.offset) / map.scale);
|
|
2407
2758
|
const step = raw.length > 1 ? Math.abs(raw[1] - raw[0]) : 1;
|
|
2408
2759
|
let maxAbs = 0;
|
|
@@ -2546,6 +2897,25 @@ var candidateOf = (s, i, px, py, sc) => {
|
|
|
2546
2897
|
inside
|
|
2547
2898
|
};
|
|
2548
2899
|
};
|
|
2900
|
+
/** Outlier of a box under a pixel (`undefined` when none is in reach) */
|
|
2901
|
+
var outlierAt = (s, i, px, py, sc, slop) => {
|
|
2902
|
+
const list = s.cols.outliers?.[i];
|
|
2903
|
+
if (!list) return void 0;
|
|
2904
|
+
const center = sc.xToPx(s.cols.x[i] + slotOffset(s));
|
|
2905
|
+
const ax = alongX(sc, px, py) - center;
|
|
2906
|
+
const ay = alongY(sc, px, py);
|
|
2907
|
+
const reach = s.outlierSize / 2 + 4 + slop;
|
|
2908
|
+
let best;
|
|
2909
|
+
let bestDist = reach;
|
|
2910
|
+
list.forEach((v, k) => {
|
|
2911
|
+
const d = Math.hypot(ax, sc.yToPx(v) - ay);
|
|
2912
|
+
if (d <= bestDist) {
|
|
2913
|
+
bestDist = d;
|
|
2914
|
+
best = s.raw.outliers?.[i]?.[k] ?? v;
|
|
2915
|
+
}
|
|
2916
|
+
});
|
|
2917
|
+
return best;
|
|
2918
|
+
};
|
|
2549
2919
|
/** Diameter of a scatter dot */
|
|
2550
2920
|
var dotSize = (s, i) => s.cols.size && s.cols.size[i] > 0 ? s.cols.size[i] : s.pointSize;
|
|
2551
2921
|
var maxSizes = /* @__PURE__ */ new WeakMap();
|
|
@@ -2648,7 +3018,11 @@ var hoverItemOf = (s, index) => {
|
|
|
2648
3018
|
var eventOf = (candidates, xTicks) => {
|
|
2649
3019
|
if (!candidates.length) return null;
|
|
2650
3020
|
candidates.sort((a, b) => a.series.index - b.series.index);
|
|
2651
|
-
const items = candidates.map((c) =>
|
|
3021
|
+
const items = candidates.map((c) => {
|
|
3022
|
+
const item = hoverItemOf(c.series, c.index);
|
|
3023
|
+
if (c.outlier !== void 0) item.outlier = c.outlier;
|
|
3024
|
+
return item;
|
|
3025
|
+
});
|
|
2652
3026
|
const x = items[0].x;
|
|
2653
3027
|
return {
|
|
2654
3028
|
items,
|
|
@@ -2669,7 +3043,7 @@ var hitTest = (model, sc, xTicks, px, py, slop = 0) => {
|
|
|
2669
3043
|
const scatter = [];
|
|
2670
3044
|
const others = [];
|
|
2671
3045
|
for (const s of model.series) {
|
|
2672
|
-
if (s.hidden || s.cols.count === 0) continue;
|
|
3046
|
+
if (s.hidden || !s.tooltip || s.cols.count === 0) continue;
|
|
2673
3047
|
if (s.type === "scatter") {
|
|
2674
3048
|
const i = nearestScatter(s, px, py, sc, slop);
|
|
2675
3049
|
if (i >= 0) scatter.push(candidateOf(s, i, px, py, sc));
|
|
@@ -2683,9 +3057,23 @@ var hitTest = (model, sc, xTicks, px, py, slop = 0) => {
|
|
|
2683
3057
|
}
|
|
2684
3058
|
} else {
|
|
2685
3059
|
const i = nearestX(s, at.x);
|
|
2686
|
-
if (i
|
|
3060
|
+
if (i < 0) continue;
|
|
3061
|
+
const c = candidateOf(s, i, px, py, sc);
|
|
3062
|
+
if (s.type === "boxplot") {
|
|
3063
|
+
c.outlier = outlierAt(s, i, px, py, sc, slop);
|
|
3064
|
+
if (c.outlier !== void 0) {
|
|
3065
|
+
c.inside = true;
|
|
3066
|
+
c.dist = 0;
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
others.push(c);
|
|
2687
3070
|
}
|
|
2688
3071
|
}
|
|
3072
|
+
if (model.tooltipMode === "item") {
|
|
3073
|
+
const all = [...scatter, ...others].filter((c) => c.inside || c.series.type === "scatter" || (c.series.type === "line" || c.series.type === "area") && c.dist <= 8 + slop);
|
|
3074
|
+
if (!all.length) return null;
|
|
3075
|
+
return eventOf([all.reduce((a, b) => b.dist < a.dist || b.dist === a.dist && b.series.index > a.series.index ? b : a)], xTicks);
|
|
3076
|
+
}
|
|
2689
3077
|
if (model.tooltipMode === "nearest") {
|
|
2690
3078
|
const all = [...scatter, ...others].filter((c) => c.inside || c.series.type === "scatter" || c.dist <= 32 + slop);
|
|
2691
3079
|
if (!all.length) return null;
|
|
@@ -2718,6 +3106,12 @@ var CHANGE_PERCENT = {
|
|
|
2718
3106
|
minimumFractionDigits: 2,
|
|
2719
3107
|
maximumFractionDigits: 2
|
|
2720
3108
|
};
|
|
3109
|
+
/** Extra rows of a point (`details` of its datum) */
|
|
3110
|
+
var detailRows = (s, index) => s.raw.details?.[index]?.map((d) => ({
|
|
3111
|
+
color: null,
|
|
3112
|
+
name: d.name,
|
|
3113
|
+
value: d.value
|
|
3114
|
+
})) ?? [];
|
|
2721
3115
|
/**
|
|
2722
3116
|
* Default tooltip content of a hover payload; `y2Ticks` formats the values
|
|
2723
3117
|
* of the right axis series
|
|
@@ -2728,6 +3122,32 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
|
|
|
2728
3122
|
const names = model.labels;
|
|
2729
3123
|
const first = event.items[0];
|
|
2730
3124
|
const firstSeries = first ? model.series[first.seriesIndex] : null;
|
|
3125
|
+
if (event.items.length === 1 && first && firstSeries?.type === "bar" && first.y0 !== void 0 && model.y.type === "time") {
|
|
3126
|
+
const format = formatOf(firstSeries);
|
|
3127
|
+
return {
|
|
3128
|
+
title: first.label ?? event.xLabel,
|
|
3129
|
+
titleColor: first.color,
|
|
3130
|
+
subtitle: first.label !== void 0 ? `${event.xLabel} · ${firstSeries.name}` : firstSeries.name,
|
|
3131
|
+
rows: [
|
|
3132
|
+
{
|
|
3133
|
+
color: null,
|
|
3134
|
+
name: names.start,
|
|
3135
|
+
value: format(first.y0)
|
|
3136
|
+
},
|
|
3137
|
+
{
|
|
3138
|
+
color: null,
|
|
3139
|
+
name: names.end,
|
|
3140
|
+
value: format(first.y)
|
|
3141
|
+
},
|
|
3142
|
+
{
|
|
3143
|
+
color: null,
|
|
3144
|
+
name: names.duration,
|
|
3145
|
+
value: formatDuration(first.y - first.y0, model.locale)
|
|
3146
|
+
},
|
|
3147
|
+
...detailRows(firstSeries, first.index)
|
|
3148
|
+
]
|
|
3149
|
+
};
|
|
3150
|
+
}
|
|
2731
3151
|
if (event.items.length === 1 && firstSeries?.type === "heatmap") {
|
|
2732
3152
|
const yName = model.y.type === "category" ? model.y.categories[Math.round(first.y)] ?? yFormat(first.y) : yFormat(first.y);
|
|
2733
3153
|
return {
|
|
@@ -2737,7 +3157,7 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
|
|
|
2737
3157
|
color: first.color,
|
|
2738
3158
|
name: first.label ?? firstSeries.name,
|
|
2739
3159
|
value: first.value === void 0 ? "–" : (firstSeries.format ?? model.formatValue)(first.value)
|
|
2740
|
-
}]
|
|
3160
|
+
}, ...detailRows(firstSeries, first.index)]
|
|
2741
3161
|
};
|
|
2742
3162
|
}
|
|
2743
3163
|
if (event.items.every((it) => model.series[it.seriesIndex].type === "scatter") && event.items.length === 1) {
|
|
@@ -2751,11 +3171,15 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
|
|
|
2751
3171
|
if (model.x.type === "category") return {
|
|
2752
3172
|
title: it.label ?? event.xLabel,
|
|
2753
3173
|
titleColor: null,
|
|
2754
|
-
rows: [
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
3174
|
+
rows: [
|
|
3175
|
+
{
|
|
3176
|
+
color: it.color,
|
|
3177
|
+
name: it.seriesName,
|
|
3178
|
+
value: formatOf(s)(it.y)
|
|
3179
|
+
},
|
|
3180
|
+
...valueRow,
|
|
3181
|
+
...detailRows(s, it.index)
|
|
3182
|
+
]
|
|
2759
3183
|
};
|
|
2760
3184
|
const rows = [
|
|
2761
3185
|
{
|
|
@@ -2768,7 +3192,8 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
|
|
|
2768
3192
|
name: (s.yAxis === "right" ? model.y2?.title : model.y.title) ?? names.y,
|
|
2769
3193
|
value: formatOf(s)(it.y)
|
|
2770
3194
|
},
|
|
2771
|
-
...valueRow
|
|
3195
|
+
...valueRow,
|
|
3196
|
+
...detailRows(s, it.index)
|
|
2772
3197
|
];
|
|
2773
3198
|
if (it.label !== void 0 && model.series.length > 1) rows.push({
|
|
2774
3199
|
color: null,
|
|
@@ -2810,6 +3235,18 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
|
|
|
2810
3235
|
continue;
|
|
2811
3236
|
}
|
|
2812
3237
|
if (s.type === "boxplot") {
|
|
3238
|
+
if (it.outlier !== void 0) {
|
|
3239
|
+
rows.push({
|
|
3240
|
+
color: it.color,
|
|
3241
|
+
name: it.label ? `${it.seriesName} · ${it.label}` : it.seriesName,
|
|
3242
|
+
value: ""
|
|
3243
|
+
}, {
|
|
3244
|
+
color: null,
|
|
3245
|
+
name: names.outlier,
|
|
3246
|
+
value: format(it.outlier)
|
|
3247
|
+
});
|
|
3248
|
+
continue;
|
|
3249
|
+
}
|
|
2813
3250
|
rows.push({
|
|
2814
3251
|
color: it.color,
|
|
2815
3252
|
name: it.label ? `${it.seriesName} · ${it.label}` : it.seriesName,
|
|
@@ -2844,6 +3281,7 @@ var tooltipContent$1 = (model, event, yTicks, y2Ticks = null) => {
|
|
|
2844
3281
|
name: it.label && binTitle === null ? `${it.seriesName} · ${it.label}` : it.seriesName,
|
|
2845
3282
|
value
|
|
2846
3283
|
});
|
|
3284
|
+
rows.push(...detailRows(s, it.index));
|
|
2847
3285
|
}
|
|
2848
3286
|
if (model.percent) {
|
|
2849
3287
|
const totals = /* @__PURE__ */ new Map();
|
|
@@ -2874,6 +3312,18 @@ var hoverMarks = (model, sc, event) => {
|
|
|
2874
3312
|
let bandHi = -Infinity;
|
|
2875
3313
|
for (const it of event.items) {
|
|
2876
3314
|
const s = model.series[it.seriesIndex];
|
|
3315
|
+
if (s.type === "boxplot" && it.outlier !== void 0) {
|
|
3316
|
+
const p = toScreen(sc, it.x + slotOffset(s), plottedOutlier(s, it));
|
|
3317
|
+
marks.push({
|
|
3318
|
+
kind: "dot",
|
|
3319
|
+
x: p.x,
|
|
3320
|
+
y: p.y,
|
|
3321
|
+
size: s.outlierSize + 3,
|
|
3322
|
+
color: it.color,
|
|
3323
|
+
halo: toCss(s.pointColors?.[it.index] ?? s.color, .2)
|
|
3324
|
+
});
|
|
3325
|
+
continue;
|
|
3326
|
+
}
|
|
2877
3327
|
if (s.type === "bar" || s.type === "candlestick" || s.type === "boxplot") {
|
|
2878
3328
|
const c = sc.xToPx(it.x + slotOffset(s));
|
|
2879
3329
|
const half = Math.max(s.barHalfWidth / Math.abs(sc.xPerPx), 1);
|
|
@@ -2886,9 +3336,37 @@ var hoverMarks = (model, sc, event) => {
|
|
|
2886
3336
|
const cy = sc.yToPx(it.y);
|
|
2887
3337
|
const hw = Math.abs(s.cellHalf.x / sc.xPerPx);
|
|
2888
3338
|
const hh = Math.abs(s.cellHalf.y / sc.yPerPx);
|
|
3339
|
+
const cell = screenRect(sc, cx - hw, cx + hw, cy - hh, cy + hh);
|
|
3340
|
+
const style = heatCellStyle(cell.width, cell.height, s.radius);
|
|
3341
|
+
const top = Math.max(plot.y, cell.y);
|
|
3342
|
+
const bottom = Math.min(plot.y + plot.height, cell.y + cell.height);
|
|
3343
|
+
const left = Math.max(plot.x, cell.x);
|
|
3344
|
+
const right = Math.min(plot.x + plot.width, cell.x + cell.width);
|
|
3345
|
+
if (bottom > top) marks.push({
|
|
3346
|
+
kind: "guide",
|
|
3347
|
+
x: plot.x,
|
|
3348
|
+
y: top,
|
|
3349
|
+
width: plot.width,
|
|
3350
|
+
height: bottom - top
|
|
3351
|
+
});
|
|
3352
|
+
if (right > left) marks.push({
|
|
3353
|
+
kind: "guide",
|
|
3354
|
+
x: left,
|
|
3355
|
+
y: plot.y,
|
|
3356
|
+
width: right - left,
|
|
3357
|
+
height: plot.height
|
|
3358
|
+
});
|
|
3359
|
+
const packed = s.cellColors?.[it.index];
|
|
3360
|
+
const fill = packed ? unpackColor(packed) : s.color;
|
|
2889
3361
|
marks.push({
|
|
2890
3362
|
kind: "cell",
|
|
2891
|
-
|
|
3363
|
+
x: cell.x + style.inset,
|
|
3364
|
+
y: cell.y + style.inset,
|
|
3365
|
+
width: Math.max(1, cell.width - style.inset * 2),
|
|
3366
|
+
height: Math.max(1, cell.height - style.inset * 2),
|
|
3367
|
+
color: it.color,
|
|
3368
|
+
ring: contrastRing(fill),
|
|
3369
|
+
radius: style.radius
|
|
2892
3370
|
});
|
|
2893
3371
|
continue;
|
|
2894
3372
|
}
|
|
@@ -2928,6 +3406,86 @@ var hoverMarks = (model, sc, event) => {
|
|
|
2928
3406
|
}
|
|
2929
3407
|
return marks;
|
|
2930
3408
|
};
|
|
3409
|
+
/** Ring of a hovered cell: light on dark fills, dark on light ones */
|
|
3410
|
+
var contrastRing = (fill) => luminance(fill) > .45 ? "rgba(15, 23, 42, 0.78)" : "rgba(255, 255, 255, 0.9)";
|
|
3411
|
+
/** Plotted value of the hovered outlier of a box */
|
|
3412
|
+
var plottedOutlier = (s, it) => {
|
|
3413
|
+
const raw = s.raw.outliers?.[it.index];
|
|
3414
|
+
const k = raw ? raw.indexOf(it.outlier ?? NaN) : -1;
|
|
3415
|
+
return (k >= 0 ? s.cols.outliers?.[it.index]?.[k] : void 0) ?? it.outlier ?? 0;
|
|
3416
|
+
};
|
|
3417
|
+
/**
|
|
3418
|
+
* Connectors of the bar series (`connector`, waterfalls): from the end of
|
|
3419
|
+
* every bar to the next bar, at the value where the next one starts
|
|
3420
|
+
*/
|
|
3421
|
+
var connectorSegments = (model, sc) => {
|
|
3422
|
+
const out = [];
|
|
3423
|
+
for (const s of model.series) {
|
|
3424
|
+
const c = s.connector;
|
|
3425
|
+
if (!c || s.hidden || s.type !== "bar" || !s.barTop) continue;
|
|
3426
|
+
const { x, count } = s.cols;
|
|
3427
|
+
const top = s.barTop;
|
|
3428
|
+
const half = s.barHalfWidth;
|
|
3429
|
+
const [v0, v1] = sc.view.x[0] <= sc.view.x[1] ? sc.view.x : [sc.view.x[1], sc.view.x[0]];
|
|
3430
|
+
const color = toCss(c.color, .75);
|
|
3431
|
+
let prev = -1;
|
|
3432
|
+
for (let i = 0; i < count && out.length < 1200; i++) {
|
|
3433
|
+
if (!Number.isFinite(top[i]) || !Number.isFinite(x[i])) continue;
|
|
3434
|
+
if (prev >= 0 && x[i] + half >= v0 && x[prev] - half <= v1) {
|
|
3435
|
+
const a = toScreen(sc, x[prev] + s.barOffset + half, top[prev]);
|
|
3436
|
+
const b = toScreen(sc, x[i] + s.barOffset - half, top[prev]);
|
|
3437
|
+
out.push({
|
|
3438
|
+
x0: a.x,
|
|
3439
|
+
y0: a.y,
|
|
3440
|
+
x1: b.x,
|
|
3441
|
+
y1: b.y,
|
|
3442
|
+
color,
|
|
3443
|
+
width: c.width,
|
|
3444
|
+
dash: c.dash
|
|
3445
|
+
});
|
|
3446
|
+
}
|
|
3447
|
+
prev = i;
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
return out;
|
|
3451
|
+
};
|
|
3452
|
+
var COLOR_STOPS = 12;
|
|
3453
|
+
/**
|
|
3454
|
+
* Color legend of a heatmap chart (every series is a heatmap; the first
|
|
3455
|
+
* visible one), `null` otherwise
|
|
3456
|
+
*/
|
|
3457
|
+
var colorLegend = (model) => {
|
|
3458
|
+
if (!model.series.length || model.series.some((s) => s.type !== "heatmap")) return null;
|
|
3459
|
+
const s = model.series.find((it) => !it.hidden && it.colorLut);
|
|
3460
|
+
const lut = s?.colorLut;
|
|
3461
|
+
if (!s || !lut) return null;
|
|
3462
|
+
const stops = [];
|
|
3463
|
+
for (let k = 0; k < COLOR_STOPS; k++) {
|
|
3464
|
+
const packed = lut[Math.round(k / 11 * (lut.length - 1))];
|
|
3465
|
+
stops.push(toCss(unpackColor(packed ?? 0)));
|
|
3466
|
+
}
|
|
3467
|
+
const format = s.format ?? model.formatValue;
|
|
3468
|
+
const [lo, hi] = s.valueRange;
|
|
3469
|
+
const labels = [{
|
|
3470
|
+
at: 0,
|
|
3471
|
+
text: format(lo)
|
|
3472
|
+
}, {
|
|
3473
|
+
at: 1,
|
|
3474
|
+
text: format(hi)
|
|
3475
|
+
}];
|
|
3476
|
+
const mid = s.colorMidpoint;
|
|
3477
|
+
if (mid !== null && mid > lo && mid < hi) labels.splice(1, 0, {
|
|
3478
|
+
at: .5,
|
|
3479
|
+
text: format(mid)
|
|
3480
|
+
});
|
|
3481
|
+
return {
|
|
3482
|
+
seriesIndex: s.index,
|
|
3483
|
+
stops,
|
|
3484
|
+
labels
|
|
3485
|
+
};
|
|
3486
|
+
};
|
|
3487
|
+
/** Whether the legend shows (`legend` option; heatmaps get their color legend) */
|
|
3488
|
+
var legendShown = (option, model, named) => option === void 0 ? named > 1 || colorLegend(model) !== null : !!option;
|
|
2931
3489
|
/** Swatch of a series in the legend */
|
|
2932
3490
|
var legendShape = (type) => type === "scatter" ? "dot" : type === "line" ? "line" : "square";
|
|
2933
3491
|
/** Whether the guide line follows the pointer */
|
|
@@ -3112,7 +3670,7 @@ var createChartController = (config) => {
|
|
|
3112
3670
|
};
|
|
3113
3671
|
zoomed = !sameRange(view.x, base.x) || !sameRange(view.y, base.y);
|
|
3114
3672
|
}
|
|
3115
|
-
annotations = resolveAnnotations(options.annotations, theme);
|
|
3673
|
+
annotations = resolveAnnotations(options.annotations, theme, model.y.type === "log" ? Math.log10 : void 0);
|
|
3116
3674
|
if (hover) {
|
|
3117
3675
|
if (!hover.event.items.every((it) => model.series[it.seriesIndex] && !model.series[it.seriesIndex].hidden && it.index < model.series[it.seriesIndex].cols.count)) setHover(null);
|
|
3118
3676
|
}
|
|
@@ -3121,9 +3679,46 @@ var createChartController = (config) => {
|
|
|
3121
3679
|
const legendLayout = () => {
|
|
3122
3680
|
const option = options.legend;
|
|
3123
3681
|
const named = options.series.filter((s) => s.name).length;
|
|
3124
|
-
if (!(option
|
|
3682
|
+
if (!legendShown(option, model, named)) return null;
|
|
3125
3683
|
const cfg = typeof option === "object" ? option : {};
|
|
3126
3684
|
const position = cfg.position === "bottom" ? "bottom" : "top";
|
|
3685
|
+
const ramp = colorLegend(model);
|
|
3686
|
+
if (ramp) {
|
|
3687
|
+
const first = ramp.labels[0]?.text ?? "";
|
|
3688
|
+
const last = ramp.labels[ramp.labels.length - 1]?.text ?? "";
|
|
3689
|
+
const barWidth = Math.max(60, Math.min(160, width * .32));
|
|
3690
|
+
const right = width - 4 - measure(last, 11) - 8;
|
|
3691
|
+
const barX = right - barWidth;
|
|
3692
|
+
const cy = (position === "bottom" ? height - LEGEND_ROW$1 : 0) + LEGEND_ROW$1 / 2;
|
|
3693
|
+
return {
|
|
3694
|
+
entries: [],
|
|
3695
|
+
colors: {
|
|
3696
|
+
bar: {
|
|
3697
|
+
x: barX,
|
|
3698
|
+
y: cy - 4,
|
|
3699
|
+
width: barWidth,
|
|
3700
|
+
height: 8
|
|
3701
|
+
},
|
|
3702
|
+
stops: ramp.stops,
|
|
3703
|
+
labels: [{
|
|
3704
|
+
text: first,
|
|
3705
|
+
x: barX - 8,
|
|
3706
|
+
y: cy,
|
|
3707
|
+
align: "right"
|
|
3708
|
+
}, {
|
|
3709
|
+
text: last,
|
|
3710
|
+
x: right + 8,
|
|
3711
|
+
y: cy,
|
|
3712
|
+
align: "left"
|
|
3713
|
+
}],
|
|
3714
|
+
ticks: ramp.labels.filter((l) => l.at > 0 && l.at < 1).map((l) => barX + l.at * barWidth),
|
|
3715
|
+
caret: null
|
|
3716
|
+
},
|
|
3717
|
+
position,
|
|
3718
|
+
toggle: false,
|
|
3719
|
+
height: 26
|
|
3720
|
+
};
|
|
3721
|
+
}
|
|
3127
3722
|
const entries = [];
|
|
3128
3723
|
let x = 4;
|
|
3129
3724
|
let row = 0;
|
|
@@ -3152,6 +3747,7 @@ var createChartController = (config) => {
|
|
|
3152
3747
|
if (position === "bottom") for (const e of entries) e.box.y += height - legendHeight + 6;
|
|
3153
3748
|
return {
|
|
3154
3749
|
entries,
|
|
3750
|
+
colors: null,
|
|
3155
3751
|
position,
|
|
3156
3752
|
toggle: cfg.toggle ?? true,
|
|
3157
3753
|
height: legendHeight
|
|
@@ -3172,13 +3768,21 @@ var createChartController = (config) => {
|
|
|
3172
3768
|
const padding = 8;
|
|
3173
3769
|
let w = 0;
|
|
3174
3770
|
let lines;
|
|
3771
|
+
const swatchWidth = content.rows.some((row) => row.color) ? 14 : 0;
|
|
3175
3772
|
if (text) {
|
|
3176
3773
|
for (const line of text) w = Math.max(w, measure(line, 12));
|
|
3177
3774
|
lines = text.length;
|
|
3178
3775
|
} else {
|
|
3179
3776
|
w = measure(content.title, 12, 600) + (content.titleColor ? 14 : 0);
|
|
3180
|
-
|
|
3181
|
-
|
|
3777
|
+
if (content.subtitle) w = Math.max(w, measure(content.subtitle, 11) + (content.titleColor ? 14 : 0));
|
|
3778
|
+
let names = 0;
|
|
3779
|
+
let values = 0;
|
|
3780
|
+
for (const row of content.rows) {
|
|
3781
|
+
names = Math.max(names, measure(row.name, 12));
|
|
3782
|
+
values = Math.max(values, measure(row.value, 12, 600));
|
|
3783
|
+
}
|
|
3784
|
+
if (content.rows.length) w = Math.max(w, swatchWidth + names + 16 + values);
|
|
3785
|
+
lines = 1 + (content.subtitle ? 1 : 0) + content.rows.length;
|
|
3182
3786
|
}
|
|
3183
3787
|
const boxW = Math.ceil(Math.max(w, 96) + 16 + 4);
|
|
3184
3788
|
const boxH = lines * lineHeight + 16;
|
|
@@ -3196,7 +3800,8 @@ var createChartController = (config) => {
|
|
|
3196
3800
|
height: boxH
|
|
3197
3801
|
},
|
|
3198
3802
|
lineHeight,
|
|
3199
|
-
padding
|
|
3803
|
+
padding,
|
|
3804
|
+
swatchWidth
|
|
3200
3805
|
};
|
|
3201
3806
|
};
|
|
3202
3807
|
const computeScene = () => {
|
|
@@ -3245,7 +3850,8 @@ var createChartController = (config) => {
|
|
|
3245
3850
|
pointLabels,
|
|
3246
3851
|
legend,
|
|
3247
3852
|
hover: null,
|
|
3248
|
-
dragging: null
|
|
3853
|
+
dragging: null,
|
|
3854
|
+
connectors: connectorSegments(model, layout.scales)
|
|
3249
3855
|
};
|
|
3250
3856
|
scene = next;
|
|
3251
3857
|
if (hover) {
|
|
@@ -3258,6 +3864,10 @@ var createChartController = (config) => {
|
|
|
3258
3864
|
crosshairY: horizontal ? guide : null,
|
|
3259
3865
|
tooltip: gesture?.kind === "pan" || gesture?.kind === "point" ? null : tooltipLayout(hover.event, hover.x, hover.y)
|
|
3260
3866
|
};
|
|
3867
|
+
const colors = legend?.colors;
|
|
3868
|
+
const it = hover.event.items[0];
|
|
3869
|
+
const s = it ? model.series[it.seriesIndex] : void 0;
|
|
3870
|
+
if (colors && it && s?.type === "heatmap" && it.value !== void 0) colors.caret = colors.bar.x + heatPosition(s, it.value) * colors.bar.width;
|
|
3261
3871
|
}
|
|
3262
3872
|
if (gesture?.kind === "point") {
|
|
3263
3873
|
const s = model.series[gesture.item.seriesIndex];
|
|
@@ -3302,7 +3912,11 @@ var createChartController = (config) => {
|
|
|
3302
3912
|
const sc = scales();
|
|
3303
3913
|
if (!sc) return null;
|
|
3304
3914
|
const { plot } = sc;
|
|
3305
|
-
|
|
3915
|
+
const p = toData(sc, Math.max(plot.x, Math.min(plot.x + plot.width, x)), Math.max(plot.y, Math.min(plot.y + plot.height, y)));
|
|
3916
|
+
return {
|
|
3917
|
+
x: p.x,
|
|
3918
|
+
y: fromPlotY(model, p.y)
|
|
3919
|
+
};
|
|
3306
3920
|
};
|
|
3307
3921
|
const setViewInternal = (next, notify) => {
|
|
3308
3922
|
const { base, minSpan } = model;
|
|
@@ -3592,11 +4206,16 @@ var createChartController = (config) => {
|
|
|
3592
4206
|
},
|
|
3593
4207
|
toPixel(x, y) {
|
|
3594
4208
|
const sc = scales();
|
|
3595
|
-
return sc ? toScreen(sc, x, y) : null;
|
|
4209
|
+
return sc ? toScreen(sc, x, toPlotY(model, y)) : null;
|
|
3596
4210
|
},
|
|
3597
4211
|
fromPixel(x, y) {
|
|
3598
4212
|
const sc = scales();
|
|
3599
|
-
|
|
4213
|
+
if (!sc) return null;
|
|
4214
|
+
const p = toData(sc, x, y);
|
|
4215
|
+
return {
|
|
4216
|
+
x: p.x,
|
|
4217
|
+
y: fromPlotY(model, p.y)
|
|
4218
|
+
};
|
|
3600
4219
|
},
|
|
3601
4220
|
on(type, listener) {
|
|
3602
4221
|
let set = listeners[type];
|
|
@@ -3853,7 +4472,8 @@ var scenePrimitives = (scene, limits = {}) => {
|
|
|
3853
4472
|
const hh = Math.abs(s.cellHalf.y / sc.yPerPx);
|
|
3854
4473
|
const rects = [];
|
|
3855
4474
|
const colors = [];
|
|
3856
|
-
const
|
|
4475
|
+
const style = heatCellStyle(hw * 2, hh * 2, s.radius);
|
|
4476
|
+
const inset = style.inset;
|
|
3857
4477
|
for (let i = 0; i < count && rects.length / 4 < maxBars * 4; i++) {
|
|
3858
4478
|
const c = s.cellColors?.[i];
|
|
3859
4479
|
if (!c) continue;
|
|
@@ -3868,7 +4488,7 @@ var scenePrimitives = (scene, limits = {}) => {
|
|
|
3868
4488
|
color: s.colorCss,
|
|
3869
4489
|
rects,
|
|
3870
4490
|
colors,
|
|
3871
|
-
radius:
|
|
4491
|
+
radius: style.radius
|
|
3872
4492
|
});
|
|
3873
4493
|
continue;
|
|
3874
4494
|
}
|
|
@@ -3970,7 +4590,7 @@ var boxPrimitives = (s, sc, range, xLo, xHi, maxBars) => {
|
|
|
3970
4590
|
x: cx,
|
|
3971
4591
|
y: sc.yToPx(v)
|
|
3972
4592
|
};
|
|
3973
|
-
dots.push(p.x, p.y, s.
|
|
4593
|
+
dots.push(p.x, p.y, s.outlierSize);
|
|
3974
4594
|
dotColors.push(color);
|
|
3975
4595
|
}
|
|
3976
4596
|
}
|
|
@@ -3991,9 +4611,10 @@ var boxPrimitives = (s, sc, range, xLo, xHi, maxBars) => {
|
|
|
3991
4611
|
if (dots.length) prims.push({
|
|
3992
4612
|
kind: "dots",
|
|
3993
4613
|
seriesIndex: s.index,
|
|
3994
|
-
opacity: .85,
|
|
4614
|
+
opacity: s.outlierShape === "hollow" ? 0 : .85,
|
|
3995
4615
|
dots,
|
|
3996
|
-
colors: dotColors
|
|
4616
|
+
colors: dotColors,
|
|
4617
|
+
stroke: 1.25
|
|
3997
4618
|
});
|
|
3998
4619
|
return prims;
|
|
3999
4620
|
};
|
|
@@ -4049,8 +4670,39 @@ var barItem = (key, version, s, count, write, extra) => {
|
|
|
4049
4670
|
...extra
|
|
4050
4671
|
};
|
|
4051
4672
|
};
|
|
4052
|
-
/**
|
|
4053
|
-
|
|
4673
|
+
/**
|
|
4674
|
+
* Inset and radius of the cells of a heatmap at a pixel density; the
|
|
4675
|
+
* renderers fade small insets out and overlap tiny cells (no seams)
|
|
4676
|
+
*/
|
|
4677
|
+
var cellStyleOf = (s, density) => {
|
|
4678
|
+
if (!density) return {
|
|
4679
|
+
inset: .5,
|
|
4680
|
+
radius: Math.min(s.radius, 2)
|
|
4681
|
+
};
|
|
4682
|
+
const style = heatCellStyle(s.cellHalf.x * 2 * density.x, s.cellHalf.y * 2 * density.y, s.radius);
|
|
4683
|
+
return {
|
|
4684
|
+
inset: Math.max(.5, style.inset),
|
|
4685
|
+
radius: style.radius
|
|
4686
|
+
};
|
|
4687
|
+
};
|
|
4688
|
+
/**
|
|
4689
|
+
* What the heatmap items depend on besides the model: their cell style at
|
|
4690
|
+
* the current pixel density (`""` without heatmaps)
|
|
4691
|
+
*/
|
|
4692
|
+
var cellStyleKey = (model, density) => {
|
|
4693
|
+
let key = "";
|
|
4694
|
+
for (const s of model.series) {
|
|
4695
|
+
if (s.type !== "heatmap" || s.hidden) continue;
|
|
4696
|
+
const style = cellStyleOf(s, density);
|
|
4697
|
+
key += `${style.inset}/${style.radius};`;
|
|
4698
|
+
}
|
|
4699
|
+
return key;
|
|
4700
|
+
};
|
|
4701
|
+
/**
|
|
4702
|
+
* Render items of the visible series, back to front; `density` sizes the
|
|
4703
|
+
* gaps and corners of heatmap cells
|
|
4704
|
+
*/
|
|
4705
|
+
var buildItems = (model, origin, version, density) => {
|
|
4054
4706
|
const items = [];
|
|
4055
4707
|
/** Outlines of the areas are drawn with the lines, above the bars */
|
|
4056
4708
|
const outlines = [];
|
|
@@ -4195,6 +4847,7 @@ var buildItems = (model, origin, version) => {
|
|
|
4195
4847
|
case "heatmap": {
|
|
4196
4848
|
const colors = s.cellColors;
|
|
4197
4849
|
const hy = s.cellHalf.y;
|
|
4850
|
+
const style = cellStyleOf(s, density);
|
|
4198
4851
|
items.push(barItem(`${s.key}:cells`, version, s, count, (i, f, u) => {
|
|
4199
4852
|
const c = colors ? colors[i] : 0;
|
|
4200
4853
|
const valid = c !== 0 && Number.isFinite(x[i]);
|
|
@@ -4204,8 +4857,8 @@ var buildItems = (model, origin, version) => {
|
|
|
4204
4857
|
u[i * 4 + 3] = c;
|
|
4205
4858
|
}, {
|
|
4206
4859
|
halfWidth: s.cellHalf.x,
|
|
4207
|
-
radius:
|
|
4208
|
-
inset:
|
|
4860
|
+
radius: style.radius,
|
|
4861
|
+
inset: style.inset,
|
|
4209
4862
|
minHalf: 0,
|
|
4210
4863
|
sorted
|
|
4211
4864
|
}));
|
|
@@ -4395,7 +5048,7 @@ var boxItems = (s, origin, version) => {
|
|
|
4395
5048
|
const valid = Number.isFinite(v) && Number.isFinite(x[i]);
|
|
4396
5049
|
f[j * 4] = valid ? ox(i) : GAP;
|
|
4397
5050
|
f[j * 4 + 1] = valid ? oy(v) : GAP;
|
|
4398
|
-
f[j * 4 + 2] = s.
|
|
5051
|
+
f[j * 4 + 2] = s.outlierSize;
|
|
4399
5052
|
u[j * 4 + 3] = colorAt(i);
|
|
4400
5053
|
j++;
|
|
4401
5054
|
}
|
|
@@ -4407,8 +5060,8 @@ var boxItems = (s, origin, version) => {
|
|
|
4407
5060
|
color: s.color,
|
|
4408
5061
|
instances: buffer,
|
|
4409
5062
|
count: n,
|
|
4410
|
-
opacity: .85,
|
|
4411
|
-
stroke: n <= 5e3 ? 1.25 : 0
|
|
5063
|
+
opacity: s.outlierShape === "hollow" ? 0 : .85,
|
|
5064
|
+
stroke: s.outlierShape === "hollow" || n <= 5e3 ? 1.25 : 0
|
|
4412
5065
|
});
|
|
4413
5066
|
}
|
|
4414
5067
|
}
|
|
@@ -4806,7 +5459,8 @@ var itemsSignature = (model, themeKey, stackOf) => {
|
|
|
4806
5459
|
for (const s of model.series) {
|
|
4807
5460
|
signature += `\n${s.key}|${s.type}|${idOf(s.cols)}|${s.colorCss}|${s.hidden}|${s.lineWidth}|${s.pointSize}|${s.opacity}|${s.barOffset}|${s.barHalfWidth}|${stackOf(s.index) ?? ""}|${s.curve}|${s.radius}`;
|
|
4808
5461
|
if (s.type === "candlestick") signature += `|${s.upColor}/${s.downColor}`;
|
|
4809
|
-
else if (s.type === "heatmap") signature += `|${s.colorScale.join(";")}/${s.valueRange[0]},${s.valueRange[1]}/${s.cellHalf.x},${s.cellHalf.y}`;
|
|
5462
|
+
else if (s.type === "heatmap") signature += `|${s.colorScale.join(";")}/${s.valueRange[0]},${s.valueRange[1]}/${s.colorMidpoint}/${s.cellHalf.x},${s.cellHalf.y}`;
|
|
5463
|
+
else if (s.type === "boxplot") signature += `|${s.outlierShape}/${s.outlierSize}`;
|
|
4810
5464
|
}
|
|
4811
5465
|
return signature;
|
|
4812
5466
|
};
|
|
@@ -4882,17 +5536,64 @@ var drawPrimitives = (ctx, primitives, plot) => {
|
|
|
4882
5536
|
}
|
|
4883
5537
|
ctx.globalAlpha = 1;
|
|
4884
5538
|
} else {
|
|
4885
|
-
|
|
5539
|
+
const stroke = p.stroke ?? 0;
|
|
4886
5540
|
for (let k = 0; k < p.dots.length; k += 3) {
|
|
4887
|
-
|
|
5541
|
+
const color = p.colors[k / 3] ?? "#888";
|
|
5542
|
+
const r = p.dots[k + 2] / 2;
|
|
4888
5543
|
ctx.beginPath();
|
|
4889
|
-
ctx.arc(p.dots[k], p.dots[k + 1],
|
|
4890
|
-
|
|
5544
|
+
ctx.arc(p.dots[k], p.dots[k + 1], Math.max(0, r - stroke / 2), 0, Math.PI * 2);
|
|
5545
|
+
if (p.opacity > 0) {
|
|
5546
|
+
ctx.globalAlpha = p.opacity;
|
|
5547
|
+
ctx.fillStyle = color;
|
|
5548
|
+
ctx.fill();
|
|
5549
|
+
}
|
|
5550
|
+
if (stroke > 0) {
|
|
5551
|
+
ctx.globalAlpha = 1;
|
|
5552
|
+
ctx.lineWidth = stroke;
|
|
5553
|
+
ctx.strokeStyle = color;
|
|
5554
|
+
ctx.stroke();
|
|
5555
|
+
}
|
|
4891
5556
|
}
|
|
4892
5557
|
ctx.globalAlpha = 1;
|
|
4893
5558
|
}
|
|
4894
5559
|
ctx.restore();
|
|
4895
5560
|
};
|
|
5561
|
+
/** The visual map of a heatmap: gradient bar, value labels, hover caret */
|
|
5562
|
+
var drawColorLegend = (ctx, ramp, scene) => {
|
|
5563
|
+
const { theme } = scene;
|
|
5564
|
+
const { bar, stops } = ramp;
|
|
5565
|
+
const n = stops.length;
|
|
5566
|
+
if (typeof ctx.createLinearGradient === "function") {
|
|
5567
|
+
const gradient = ctx.createLinearGradient(bar.x, 0, bar.x + bar.width, 0);
|
|
5568
|
+
stops.forEach((c, k) => gradient.addColorStop(k / Math.max(1, n - 1), c));
|
|
5569
|
+
ctx.fillStyle = gradient;
|
|
5570
|
+
roundedRect(ctx, bar.x, bar.y, bar.width, bar.height, bar.height / 2);
|
|
5571
|
+
ctx.fill();
|
|
5572
|
+
} else {
|
|
5573
|
+
const w = bar.width / n;
|
|
5574
|
+
stops.forEach((c, k) => {
|
|
5575
|
+
ctx.fillStyle = c;
|
|
5576
|
+
ctx.fillRect(bar.x + k * w, bar.y, w + .5, bar.height);
|
|
5577
|
+
});
|
|
5578
|
+
}
|
|
5579
|
+
ctx.fillStyle = toCss(theme.text, .35);
|
|
5580
|
+
for (const t of ramp.ticks) ctx.fillRect(Math.round(t), bar.y - 2, 1, bar.height + 4);
|
|
5581
|
+
ctx.font = font(theme, 11);
|
|
5582
|
+
ctx.textBaseline = "middle";
|
|
5583
|
+
ctx.fillStyle = toCss(theme.textMuted);
|
|
5584
|
+
for (const l of ramp.labels) {
|
|
5585
|
+
ctx.textAlign = l.align;
|
|
5586
|
+
ctx.fillText(l.text, l.x, l.y);
|
|
5587
|
+
}
|
|
5588
|
+
if (ramp.caret !== null) {
|
|
5589
|
+
roundedRect(ctx, ramp.caret - 2, bar.y - 3, 4, bar.height + 6, 2);
|
|
5590
|
+
ctx.fillStyle = toCss(theme.text);
|
|
5591
|
+
ctx.fill();
|
|
5592
|
+
ctx.lineWidth = 1.5;
|
|
5593
|
+
ctx.strokeStyle = toCss(theme.background);
|
|
5594
|
+
ctx.stroke();
|
|
5595
|
+
}
|
|
5596
|
+
};
|
|
4896
5597
|
/** Draws a scene (legend, axes, data, labels, hover) on a 2D context */
|
|
4897
5598
|
var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2dPainter(ctx)) => {
|
|
4898
5599
|
const { width, height, theme, model, view, layout } = scene;
|
|
@@ -4914,6 +5615,8 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
|
|
|
4914
5615
|
theme,
|
|
4915
5616
|
annotations: scene.annotations
|
|
4916
5617
|
});
|
|
5618
|
+
const ramp = scene.legend?.colors;
|
|
5619
|
+
if (ramp) drawColorLegend(ctx, ramp, scene);
|
|
4917
5620
|
if (scene.legend) {
|
|
4918
5621
|
ctx.font = font(theme, 12);
|
|
4919
5622
|
ctx.textBaseline = "middle";
|
|
@@ -4966,6 +5669,11 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
|
|
|
4966
5669
|
}, Math.round(plot.x * dpr), Math.round(plot.y * dpr));
|
|
4967
5670
|
}
|
|
4968
5671
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|
5672
|
+
for (const mark of scene.hover?.marks ?? []) {
|
|
5673
|
+
if (mark.kind !== "guide") continue;
|
|
5674
|
+
ctx.fillStyle = toCss(theme.text, .06);
|
|
5675
|
+
ctx.fillRect(mark.x, mark.y, mark.width, mark.height);
|
|
5676
|
+
}
|
|
4969
5677
|
drawForeground(ctx, {
|
|
4970
5678
|
width,
|
|
4971
5679
|
height,
|
|
@@ -4973,7 +5681,8 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
|
|
|
4973
5681
|
theme,
|
|
4974
5682
|
annotations: scene.annotations,
|
|
4975
5683
|
pointLabels: [],
|
|
4976
|
-
clear: false
|
|
5684
|
+
clear: false,
|
|
5685
|
+
connectors: scene.connectors
|
|
4977
5686
|
});
|
|
4978
5687
|
if (scene.pointLabels.length) {
|
|
4979
5688
|
ctx.save();
|
|
@@ -5017,15 +5726,25 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
|
|
|
5017
5726
|
ctx.restore();
|
|
5018
5727
|
}
|
|
5019
5728
|
for (const mark of hover.marks) {
|
|
5020
|
-
if (mark.kind === "band") continue;
|
|
5729
|
+
if (mark.kind === "band" || mark.kind === "guide") continue;
|
|
5021
5730
|
if (mark.kind === "cell") {
|
|
5022
|
-
|
|
5023
|
-
|
|
5024
|
-
ctx.
|
|
5025
|
-
ctx.
|
|
5026
|
-
ctx.
|
|
5027
|
-
ctx.
|
|
5028
|
-
ctx.
|
|
5731
|
+
const grow = Math.min(3, mark.width * .06, mark.height * .06);
|
|
5732
|
+
const r = Math.max(2, mark.radius);
|
|
5733
|
+
ctx.save();
|
|
5734
|
+
ctx.shadowColor = "rgba(15, 23, 42, 0.4)";
|
|
5735
|
+
ctx.shadowBlur = 12;
|
|
5736
|
+
ctx.shadowOffsetY = 4;
|
|
5737
|
+
roundedRect(ctx, mark.x - grow, mark.y - grow, mark.width + grow * 2, mark.height + grow * 2, r);
|
|
5738
|
+
ctx.fillStyle = mark.color;
|
|
5739
|
+
ctx.fill();
|
|
5740
|
+
ctx.restore();
|
|
5741
|
+
const inset = Math.min(2.75, mark.width / 5, mark.height / 5);
|
|
5742
|
+
if (mark.width > 8 && mark.height > 8) {
|
|
5743
|
+
roundedRect(ctx, mark.x + inset, mark.y + inset, mark.width - inset * 2, mark.height - inset * 2, Math.max(1, r - inset / 2));
|
|
5744
|
+
ctx.lineWidth = 1.5;
|
|
5745
|
+
ctx.strokeStyle = mark.ring;
|
|
5746
|
+
ctx.stroke();
|
|
5747
|
+
}
|
|
5029
5748
|
continue;
|
|
5030
5749
|
}
|
|
5031
5750
|
ctx.beginPath();
|
|
@@ -5095,6 +5814,12 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
|
|
|
5095
5814
|
ctx.textAlign = "left";
|
|
5096
5815
|
ctx.fillText(content.title, x, y);
|
|
5097
5816
|
y += lineHeight;
|
|
5817
|
+
if (content.subtitle) {
|
|
5818
|
+
ctx.font = font(theme, 11);
|
|
5819
|
+
ctx.fillStyle = toCss(theme.textMuted);
|
|
5820
|
+
ctx.fillText(content.subtitle, x, y - 2);
|
|
5821
|
+
y += lineHeight;
|
|
5822
|
+
}
|
|
5098
5823
|
for (const row of content.rows) {
|
|
5099
5824
|
x = left;
|
|
5100
5825
|
if (row.color) {
|
|
@@ -5102,8 +5827,8 @@ var drawScene = (ctx, scene, items, origin, pixelRatio, painter = createCanvas2d
|
|
|
5102
5827
|
ctx.beginPath();
|
|
5103
5828
|
ctx.arc(x + 4, y, 4, 0, Math.PI * 2);
|
|
5104
5829
|
ctx.fill();
|
|
5105
|
-
x += 14;
|
|
5106
5830
|
}
|
|
5831
|
+
x += tip.swatchWidth;
|
|
5107
5832
|
ctx.font = font(theme, 12);
|
|
5108
5833
|
ctx.textAlign = "left";
|
|
5109
5834
|
ctx.fillStyle = toCss(theme.textMuted);
|
|
@@ -5133,6 +5858,7 @@ var createCanvasChart = (config) => {
|
|
|
5133
5858
|
let frameId = null;
|
|
5134
5859
|
let items = [];
|
|
5135
5860
|
let itemsModel = null;
|
|
5861
|
+
let itemsKey0 = "";
|
|
5136
5862
|
let itemsKey = "";
|
|
5137
5863
|
let options = config.options;
|
|
5138
5864
|
/** Ids of the themes seen (the controller replaces its theme on changes) */
|
|
@@ -5171,15 +5897,21 @@ var createCanvasChart = (config) => {
|
|
|
5171
5897
|
fontSet = "";
|
|
5172
5898
|
if (itemsModel !== scene.model) {
|
|
5173
5899
|
itemsModel = scene.model;
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5900
|
+
itemsKey0 = itemsSignature(scene.model, themeId(scene.theme), (index) => options.series[index]?.stack);
|
|
5901
|
+
}
|
|
5902
|
+
const sc = scene.layout.scales;
|
|
5903
|
+
const density = {
|
|
5904
|
+
x: 1 / Math.abs(sc.xPerPx),
|
|
5905
|
+
y: 1 / Math.abs(sc.yPerPx)
|
|
5906
|
+
};
|
|
5907
|
+
const key = `${itemsKey0}|${cellStyleKey(scene.model, density)}`;
|
|
5908
|
+
if (key !== itemsKey) {
|
|
5909
|
+
itemsKey = key;
|
|
5910
|
+
origin = {
|
|
5911
|
+
x: mid(scene.model.base.x),
|
|
5912
|
+
y: mid(scene.model.base.y)
|
|
5913
|
+
};
|
|
5914
|
+
items = buildItems(scene.model, origin, ++version, density);
|
|
5183
5915
|
}
|
|
5184
5916
|
drawScene(ctx, scene, items, origin, dpr, painter);
|
|
5185
5917
|
fontSet = "";
|
|
@@ -5347,6 +6079,7 @@ var heatmapChartOptions = (config, base = {}) => {
|
|
|
5347
6079
|
})),
|
|
5348
6080
|
colorScale: config.colorScale,
|
|
5349
6081
|
valueRange: config.valueRange,
|
|
6082
|
+
colorMidpoint: config.colorMidpoint,
|
|
5350
6083
|
radius: config.radius,
|
|
5351
6084
|
format: config.format
|
|
5352
6085
|
}],
|
|
@@ -5366,7 +6099,7 @@ var heatmapChartOptions = (config, base = {}) => {
|
|
|
5366
6099
|
grid: false,
|
|
5367
6100
|
...base.yAxis
|
|
5368
6101
|
},
|
|
5369
|
-
legend: base.legend ??
|
|
6102
|
+
legend: base.legend ?? true,
|
|
5370
6103
|
interaction: base.interaction ?? { zoom: false },
|
|
5371
6104
|
tooltip: base.tooltip ?? { mode: "nearest" }
|
|
5372
6105
|
};
|
|
@@ -5811,7 +6544,8 @@ var waterfallSeries = (steps, options = {}) => {
|
|
|
5811
6544
|
color: total,
|
|
5812
6545
|
data,
|
|
5813
6546
|
showLabels: options.labels ?? false,
|
|
5814
|
-
format: options.format
|
|
6547
|
+
format: options.format,
|
|
6548
|
+
connector: options.connector ?? true
|
|
5815
6549
|
};
|
|
5816
6550
|
};
|
|
5817
6551
|
/**
|
|
@@ -5920,7 +6654,10 @@ var time = (v) => v instanceof Date ? v.getTime() : v === void 0 ? NaN : v;
|
|
|
5920
6654
|
var ganttSeries = (tasks, options = {}) => {
|
|
5921
6655
|
const locale = resolveLocale(options.locale);
|
|
5922
6656
|
const names = presetLabels(locale);
|
|
6657
|
+
const rows = chartLabels(locale);
|
|
5923
6658
|
const taskName = options.taskName ?? names.tasks;
|
|
6659
|
+
const progressName = options.progressName ?? names.progress;
|
|
6660
|
+
const separator = /^(zh|ja)\b/i.test(locale) ? "、" : ", ";
|
|
5924
6661
|
const groups = [];
|
|
5925
6662
|
for (const t of tasks) {
|
|
5926
6663
|
const g = t.group ?? taskName;
|
|
@@ -5943,19 +6680,32 @@ var ganttSeries = (tasks, options = {}) => {
|
|
|
5943
6680
|
opacity: .3,
|
|
5944
6681
|
barWidth: .62,
|
|
5945
6682
|
radius: 4,
|
|
5946
|
-
data: tasks.filter((t) => !t.milestone && (t.group ?? taskName) === g).map((t) =>
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
6683
|
+
data: tasks.filter((t) => !t.milestone && (t.group ?? taskName) === g).map((t) => {
|
|
6684
|
+
const details = [];
|
|
6685
|
+
if (t.progress !== void 0) details.push({
|
|
6686
|
+
name: progressName,
|
|
6687
|
+
value: formatProgress(Math.min(1, Math.max(0, t.progress)))
|
|
6688
|
+
});
|
|
6689
|
+
if (t.dependencies?.length) details.push({
|
|
6690
|
+
name: options.dependenciesName ?? rows.dependencies,
|
|
6691
|
+
value: t.dependencies.join(separator)
|
|
6692
|
+
});
|
|
6693
|
+
return {
|
|
6694
|
+
x: t.name,
|
|
6695
|
+
y0: time(t.start),
|
|
6696
|
+
y: time(t.end ?? t.start),
|
|
6697
|
+
...t.color ? { color: t.color } : {},
|
|
6698
|
+
...details.length ? { details } : {}
|
|
6699
|
+
};
|
|
6700
|
+
})
|
|
5952
6701
|
}));
|
|
5953
6702
|
const progress = tasks.filter((t) => !t.milestone && t.progress !== void 0 && t.progress > 0);
|
|
5954
6703
|
if (progress.length) series.push({
|
|
5955
6704
|
id: "gantt:progress",
|
|
5956
|
-
name:
|
|
6705
|
+
name: progressName,
|
|
5957
6706
|
type: "bar",
|
|
5958
6707
|
stack: "gantt",
|
|
6708
|
+
tooltip: false,
|
|
5959
6709
|
color: "var(--text-secondary-color, #6b7280)",
|
|
5960
6710
|
radius: 4,
|
|
5961
6711
|
data: progress.map((t) => {
|
|
@@ -6055,6 +6805,65 @@ var ellipsize = (text, max, font, measure) => {
|
|
|
6055
6805
|
}
|
|
6056
6806
|
return lo ? text.slice(0, lo).trimEnd() + "…" : "";
|
|
6057
6807
|
};
|
|
6808
|
+
/** Characters that must not start a line (closing brackets and punctuation) */
|
|
6809
|
+
var NO_LINE_START = /^[)\]}、。,.:;!?)」』】》〉,.:;!?%…]/;
|
|
6810
|
+
/** Greedy line breaking at `max` pixels, without a line limit */
|
|
6811
|
+
var breakLines = (text, max, font, measure) => {
|
|
6812
|
+
const lines = [];
|
|
6813
|
+
let rest = text.trim();
|
|
6814
|
+
while (rest) {
|
|
6815
|
+
if (measure(rest, font) <= max) {
|
|
6816
|
+
lines.push(rest);
|
|
6817
|
+
break;
|
|
6818
|
+
}
|
|
6819
|
+
let lo = 0;
|
|
6820
|
+
let hi = rest.length;
|
|
6821
|
+
while (lo < hi) {
|
|
6822
|
+
const mid = lo + hi + 1 >> 1;
|
|
6823
|
+
if (measure(rest.slice(0, mid), font) <= max) lo = mid;
|
|
6824
|
+
else hi = mid - 1;
|
|
6825
|
+
}
|
|
6826
|
+
if (!lo) return null;
|
|
6827
|
+
let cut = lo;
|
|
6828
|
+
if (rest[lo] !== " ") {
|
|
6829
|
+
const space = rest.lastIndexOf(" ", lo);
|
|
6830
|
+
if (space > lo * .4) cut = space;
|
|
6831
|
+
else while (cut > 1 && NO_LINE_START.test(rest.slice(cut))) cut--;
|
|
6832
|
+
}
|
|
6833
|
+
lines.push(rest.slice(0, cut).trimEnd());
|
|
6834
|
+
rest = rest.slice(cut).trimStart();
|
|
6835
|
+
}
|
|
6836
|
+
return lines;
|
|
6837
|
+
};
|
|
6838
|
+
/**
|
|
6839
|
+
* Breaks a text into at most `maxLines` lines of `max` pixels, at spaces when
|
|
6840
|
+
* possible (anywhere otherwise, e.g. CJK, never before closing punctuation);
|
|
6841
|
+
* a text that fits is balanced across its lines, one that does not ends the
|
|
6842
|
+
* last line with an ellipsis
|
|
6843
|
+
*/
|
|
6844
|
+
var wrapText = (text, max, font, measure, maxLines = 2) => {
|
|
6845
|
+
const whole = text.trim();
|
|
6846
|
+
if (!whole || maxLines < 1) return [];
|
|
6847
|
+
const lines = breakLines(whole, max, font, measure);
|
|
6848
|
+
if (!lines) {
|
|
6849
|
+
const last = ellipsize(whole, max, font, measure);
|
|
6850
|
+
return last ? [last] : [];
|
|
6851
|
+
}
|
|
6852
|
+
if (lines.length > maxLines) {
|
|
6853
|
+
const head = lines.slice(0, maxLines - 1);
|
|
6854
|
+
let rest = whole;
|
|
6855
|
+
for (const line of head) rest = rest.slice(line.length).trimStart();
|
|
6856
|
+
const tail = ellipsize(rest, max, font, measure);
|
|
6857
|
+
return tail ? [...head, tail] : head;
|
|
6858
|
+
}
|
|
6859
|
+
if (lines.length < 2) return lines;
|
|
6860
|
+
const lo = measure(whole, font) / lines.length;
|
|
6861
|
+
for (let k = 0; k <= 8; k++) {
|
|
6862
|
+
const balanced = breakLines(whole, lo + (max - lo) * k / 8, font, measure);
|
|
6863
|
+
if (balanced && balanced.length <= lines.length) return balanced;
|
|
6864
|
+
}
|
|
6865
|
+
return lines;
|
|
6866
|
+
};
|
|
6058
6867
|
/** Stable keys of named values: the name, `name#2` for duplicates */
|
|
6059
6868
|
var uniqueKeys = (names) => {
|
|
6060
6869
|
const seen = /* @__PURE__ */ new Map();
|
|
@@ -6342,6 +7151,56 @@ var linkStyle = (ctx, node) => {
|
|
|
6342
7151
|
gradient.addColorStop(1, node.color1);
|
|
6343
7152
|
return gradient;
|
|
6344
7153
|
};
|
|
7154
|
+
/** Whether a chord ribbon joins an arc to itself (a self flow) */
|
|
7155
|
+
var ribbonIsLoop = (node) => Math.abs(node.s0 - node.t0) < 1e-9 && Math.abs(node.s1 - node.t1) < 1e-9;
|
|
7156
|
+
/** Control point of the inward bulge of a self-flow ribbon */
|
|
7157
|
+
var loopControl = (node) => {
|
|
7158
|
+
const m = (node.s0 + node.s1) / 2;
|
|
7159
|
+
return [node.cx + node.r * .4 * Math.cos(m), node.cy + node.r * .4 * Math.sin(m)];
|
|
7160
|
+
};
|
|
7161
|
+
/** Outline of a chord ribbon: source arc, curve, target arc or arrowhead, curve */
|
|
7162
|
+
var ribbonPath = (ctx, node) => {
|
|
7163
|
+
const { cx, cy, r } = node;
|
|
7164
|
+
const at = (a, radius = r) => [cx + radius * Math.cos(a), cy + radius * Math.sin(a)];
|
|
7165
|
+
ctx.beginPath();
|
|
7166
|
+
const s = at(node.s0);
|
|
7167
|
+
ctx.moveTo(s[0], s[1]);
|
|
7168
|
+
if (node.s1 > node.s0) ctx.arc(cx, cy, r, node.s0, node.s1);
|
|
7169
|
+
if (ribbonIsLoop(node)) {
|
|
7170
|
+
const [qx, qy] = loopControl(node);
|
|
7171
|
+
ctx.quadraticCurveTo(qx, qy, s[0], s[1]);
|
|
7172
|
+
ctx.closePath();
|
|
7173
|
+
return;
|
|
7174
|
+
}
|
|
7175
|
+
if (node.head > 0) {
|
|
7176
|
+
const p0 = at(node.t0, r - node.head);
|
|
7177
|
+
const tip = at((node.t0 + node.t1) / 2);
|
|
7178
|
+
const p1 = at(node.t1, r - node.head);
|
|
7179
|
+
ctx.quadraticCurveTo(cx, cy, p0[0], p0[1]);
|
|
7180
|
+
ctx.lineTo(tip[0], tip[1]);
|
|
7181
|
+
ctx.lineTo(p1[0], p1[1]);
|
|
7182
|
+
} else {
|
|
7183
|
+
const t = at(node.t0);
|
|
7184
|
+
ctx.quadraticCurveTo(cx, cy, t[0], t[1]);
|
|
7185
|
+
if (node.t1 > node.t0) ctx.arc(cx, cy, r, node.t0, node.t1);
|
|
7186
|
+
}
|
|
7187
|
+
ctx.quadraticCurveTo(cx, cy, s[0], s[1]);
|
|
7188
|
+
ctx.closePath();
|
|
7189
|
+
};
|
|
7190
|
+
var ribbonStyle = (ctx, node) => {
|
|
7191
|
+
if (node.color0 === node.color1 || typeof ctx.createLinearGradient !== "function") return node.color0;
|
|
7192
|
+
const ms = (node.s0 + node.s1) / 2;
|
|
7193
|
+
const mt = (node.t0 + node.t1) / 2;
|
|
7194
|
+
const x0 = node.cx + node.r * Math.cos(ms);
|
|
7195
|
+
const y0 = node.cy + node.r * Math.sin(ms);
|
|
7196
|
+
const x1 = node.cx + node.r * Math.cos(mt);
|
|
7197
|
+
const y1 = node.cy + node.r * Math.sin(mt);
|
|
7198
|
+
if (Math.hypot(x1 - x0, y1 - y0) < 1) return node.color0;
|
|
7199
|
+
const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
|
|
7200
|
+
gradient.addColorStop(0, node.color0);
|
|
7201
|
+
gradient.addColorStop(1, node.color1);
|
|
7202
|
+
return gradient;
|
|
7203
|
+
};
|
|
6345
7204
|
/**
|
|
6346
7205
|
* Draws a scene in CSS pixels (the caller sets the pixel-ratio transform and
|
|
6347
7206
|
* clears the canvas). `hover` emphasizes an item and dims the others.
|
|
@@ -6494,6 +7353,17 @@ var drawShapeScene = (ctx, scene, hover) => {
|
|
|
6494
7353
|
ctx.stroke();
|
|
6495
7354
|
ctx.lineCap = "round";
|
|
6496
7355
|
break;
|
|
7356
|
+
case "ribbon":
|
|
7357
|
+
if (active && node.activeAlpha !== void 0) ctx.globalAlpha = base * node.activeAlpha;
|
|
7358
|
+
ribbonPath(ctx, node);
|
|
7359
|
+
ctx.fillStyle = ribbonStyle(ctx, node);
|
|
7360
|
+
ctx.fill();
|
|
7361
|
+
if (focused) {
|
|
7362
|
+
ctx.strokeStyle = node.color0;
|
|
7363
|
+
ctx.lineWidth = 1;
|
|
7364
|
+
ctx.stroke();
|
|
7365
|
+
}
|
|
7366
|
+
break;
|
|
6497
7367
|
case "guide": {
|
|
6498
7368
|
const k = hover?.indicator;
|
|
6499
7369
|
if (k === void 0 || !node.ends[k]) break;
|
|
@@ -6571,8 +7441,10 @@ var drawShapeTooltip = (ctx, theme, box) => {
|
|
|
6571
7441
|
ctx.font = font(theme, 12, 600);
|
|
6572
7442
|
ctx.fillStyle = toCss(theme.text);
|
|
6573
7443
|
ctx.textAlign = "left";
|
|
6574
|
-
|
|
6575
|
-
|
|
7444
|
+
for (const line of box.titleLines ?? [content.title]) {
|
|
7445
|
+
ctx.fillText(line, x, y);
|
|
7446
|
+
y += lineHeight;
|
|
7447
|
+
}
|
|
6576
7448
|
for (const row of content.rows) {
|
|
6577
7449
|
x = left;
|
|
6578
7450
|
if (row.color) {
|
|
@@ -6656,6 +7528,7 @@ var nodeContains = (node, x, y) => {
|
|
|
6656
7528
|
return wrapFrom(Math.atan2(y - node.cy, x - node.cx), node.a0) <= node.a1;
|
|
6657
7529
|
}
|
|
6658
7530
|
case "link": return pointNearLink(x, y, node);
|
|
7531
|
+
case "ribbon": return Math.hypot(x - node.cx, y - node.cy) <= node.r + 1 && pointInPolygon(x, y, ribbonOutline(node));
|
|
6659
7532
|
default: return false;
|
|
6660
7533
|
}
|
|
6661
7534
|
};
|
|
@@ -6691,6 +7564,46 @@ var pointNearLink = (x, y, node) => {
|
|
|
6691
7564
|
return false;
|
|
6692
7565
|
};
|
|
6693
7566
|
var clampUnit = (v) => v < 0 ? 0 : v > 1 ? 1 : v;
|
|
7567
|
+
/** Polygon (flat x, y list) approximating a chord ribbon, as drawn */
|
|
7568
|
+
var ribbonOutline = (node) => {
|
|
7569
|
+
const { cx, cy, r } = node;
|
|
7570
|
+
const pts = [];
|
|
7571
|
+
const arc = (a0, a1, radius = r) => {
|
|
7572
|
+
const steps = Math.max(1, Math.ceil((a1 - a0) / .06));
|
|
7573
|
+
for (let k = 0; k <= steps; k++) {
|
|
7574
|
+
const a = a0 + (a1 - a0) * k / steps;
|
|
7575
|
+
pts.push(cx + radius * Math.cos(a), cy + radius * Math.sin(a));
|
|
7576
|
+
}
|
|
7577
|
+
};
|
|
7578
|
+
const quad = (qx, qy, x, y) => {
|
|
7579
|
+
const x0 = pts[pts.length - 2];
|
|
7580
|
+
const y0 = pts[pts.length - 1];
|
|
7581
|
+
for (let k = 1; k <= 16; k++) {
|
|
7582
|
+
const t = k / 16;
|
|
7583
|
+
const u = 1 - t;
|
|
7584
|
+
pts.push(u * u * x0 + 2 * u * t * qx + t * t * x, u * u * y0 + 2 * u * t * qy + t * t * y);
|
|
7585
|
+
}
|
|
7586
|
+
};
|
|
7587
|
+
const at = (a, radius = r) => [cx + radius * Math.cos(a), cy + radius * Math.sin(a)];
|
|
7588
|
+
arc(node.s0, Math.max(node.s0, node.s1));
|
|
7589
|
+
const s = at(node.s0);
|
|
7590
|
+
if (ribbonIsLoop(node)) {
|
|
7591
|
+
const [qx, qy] = loopControl(node);
|
|
7592
|
+
quad(qx, qy, s[0], s[1]);
|
|
7593
|
+
return pts;
|
|
7594
|
+
}
|
|
7595
|
+
if (node.head > 0) {
|
|
7596
|
+
const p0 = at(node.t0, r - node.head);
|
|
7597
|
+
quad(cx, cy, p0[0], p0[1]);
|
|
7598
|
+
pts.push(...at((node.t0 + node.t1) / 2), ...at(node.t1, r - node.head));
|
|
7599
|
+
} else {
|
|
7600
|
+
const t = at(node.t0);
|
|
7601
|
+
quad(cx, cy, t[0], t[1]);
|
|
7602
|
+
arc(node.t0, Math.max(node.t0, node.t1));
|
|
7603
|
+
}
|
|
7604
|
+
quad(cx, cy, s[0], s[1]);
|
|
7605
|
+
return pts;
|
|
7606
|
+
};
|
|
6694
7607
|
/** Radar: the vertex under the pointer, else the smallest polygon containing it */
|
|
6695
7608
|
var hitRadar = (scene, x, y) => {
|
|
6696
7609
|
const radar = scene.radar;
|
|
@@ -6811,6 +7724,8 @@ var rangeFills = (o, c, count) => {
|
|
|
6811
7724
|
return own ? resolveWith(theme, own, gray) : gray;
|
|
6812
7725
|
});
|
|
6813
7726
|
};
|
|
7727
|
+
/** Line height of the wrapped names */
|
|
7728
|
+
var NAME_LINE = 15;
|
|
6814
7729
|
var layoutBullet = (o, c) => {
|
|
6815
7730
|
const { theme, area, measure, hidden } = c;
|
|
6816
7731
|
const keys = keysOf$3(o);
|
|
@@ -6834,9 +7749,14 @@ var layoutBullet = (o, c) => {
|
|
|
6834
7749
|
const items = [];
|
|
6835
7750
|
const hasSubtitle = o.data.some((d, i) => !!d.subtitle && weights[i] > 0);
|
|
6836
7751
|
const valueText = o.data.map((d) => c.format(finite(d.value)));
|
|
6837
|
-
const
|
|
7752
|
+
const nameW = o.data.map((d) => measure(d.name, nameFont));
|
|
7753
|
+
const labelCap = area.width * (area.width < 420 ? .34 : .4);
|
|
7754
|
+
const lineW = o.data.map((d, i) => nameW[i] <= labelCap - 14 ? nameW[i] : Math.max(0, ...wrapText(d.name, labelCap - 14, nameFont, measure, 2).map((l) => measure(l, nameFont))));
|
|
7755
|
+
const labelW = vertical ? 0 : Math.min(labelCap, Math.max(0, ...o.data.map((d, i) => Math.max(lineW[i], d.subtitle ? measure(d.subtitle, subFont) : 0))) + 14);
|
|
6838
7756
|
const valueW = vertical ? 0 : Math.min(area.width * .2, Math.max(0, ...valueText.map((t) => measure(t, valueFont))) + 12);
|
|
6839
|
-
const
|
|
7757
|
+
const columnW = area.width / total;
|
|
7758
|
+
const wraps = vertical && o.data.some((_, i) => weights[i] > 0 && nameW[i] > columnW - 8);
|
|
7759
|
+
const labelH = vertical ? 22 + (wraps ? NAME_LINE : 0) + (hasSubtitle ? 14 : 0) : 0;
|
|
6840
7760
|
const valueH = vertical ? 20 : 0;
|
|
6841
7761
|
const unit = (vertical ? area.width : area.height) / total;
|
|
6842
7762
|
let offset = 0;
|
|
@@ -6970,25 +7890,25 @@ var layoutBullet = (o, c) => {
|
|
|
6970
7890
|
}
|
|
6971
7891
|
if (vertical) {
|
|
6972
7892
|
const room = Math.max(0, slot - 8);
|
|
6973
|
-
const
|
|
7893
|
+
const lines = wrapText(d.name, room, nameFont, measure, wraps ? 2 : 1);
|
|
6974
7894
|
const bottom = area.y + area.height;
|
|
6975
|
-
|
|
7895
|
+
lines.forEach((line, k) => nodes.push({
|
|
6976
7896
|
kind: "text",
|
|
6977
7897
|
x: mid,
|
|
6978
|
-
y: bottom - labelH + 16,
|
|
6979
|
-
text:
|
|
7898
|
+
y: bottom - labelH + 16 + k * NAME_LINE,
|
|
7899
|
+
text: line,
|
|
6980
7900
|
font: nameFont,
|
|
6981
7901
|
color: text,
|
|
6982
7902
|
align: "center",
|
|
6983
7903
|
baseline: "middle",
|
|
6984
7904
|
hit: i,
|
|
6985
7905
|
alpha
|
|
6986
|
-
});
|
|
7906
|
+
}));
|
|
6987
7907
|
const sub = d.subtitle ? ellipsize(d.subtitle, room, subFont, measure) : "";
|
|
6988
7908
|
if (sub) nodes.push({
|
|
6989
7909
|
kind: "text",
|
|
6990
7910
|
x: mid,
|
|
6991
|
-
y: bottom - labelH + 31,
|
|
7911
|
+
y: bottom - labelH + 31 + (wraps ? NAME_LINE : 0),
|
|
6992
7912
|
text: sub,
|
|
6993
7913
|
font: subFont,
|
|
6994
7914
|
color: muted,
|
|
@@ -7012,25 +7932,28 @@ var layoutBullet = (o, c) => {
|
|
|
7012
7932
|
});
|
|
7013
7933
|
} else {
|
|
7014
7934
|
const room = Math.max(0, labelW - 14);
|
|
7015
|
-
const
|
|
7016
|
-
const sub = d.subtitle &&
|
|
7935
|
+
const avail = slot - 4;
|
|
7936
|
+
const sub = d.subtitle && avail >= 29 ? ellipsize(d.subtitle, room, subFont, measure) : "";
|
|
7937
|
+
const subH = sub ? 13 : 0;
|
|
7938
|
+
const lines = wrapText(d.name, room, nameFont, measure, avail >= 30 + subH ? 2 : 1);
|
|
7939
|
+
const top = mid - (lines.length * NAME_LINE + subH) / 2;
|
|
7017
7940
|
const x = area.x + labelW - 14;
|
|
7018
|
-
|
|
7941
|
+
lines.forEach((line, k) => nodes.push({
|
|
7019
7942
|
kind: "text",
|
|
7020
7943
|
x,
|
|
7021
|
-
y:
|
|
7022
|
-
text:
|
|
7944
|
+
y: top + NAME_LINE / 2 + k * NAME_LINE,
|
|
7945
|
+
text: line,
|
|
7023
7946
|
font: nameFont,
|
|
7024
7947
|
color: text,
|
|
7025
7948
|
align: "right",
|
|
7026
7949
|
baseline: "middle",
|
|
7027
7950
|
hit: i,
|
|
7028
7951
|
alpha
|
|
7029
|
-
});
|
|
7952
|
+
}));
|
|
7030
7953
|
if (sub) nodes.push({
|
|
7031
7954
|
kind: "text",
|
|
7032
7955
|
x,
|
|
7033
|
-
y:
|
|
7956
|
+
y: top + lines.length * NAME_LINE + subH / 2,
|
|
7034
7957
|
text: sub,
|
|
7035
7958
|
font: subFont,
|
|
7036
7959
|
color: muted,
|
|
@@ -7112,6 +8035,7 @@ var SHAPE_LABELS = {
|
|
|
7112
8035
|
target: "Target",
|
|
7113
8036
|
ofTarget: "Of target",
|
|
7114
8037
|
range: "Range",
|
|
8038
|
+
reverse: "Reverse",
|
|
7115
8039
|
series: "Series {index}",
|
|
7116
8040
|
pieChart: "Pie chart",
|
|
7117
8041
|
donutChart: "Donut chart",
|
|
@@ -7125,7 +8049,8 @@ var SHAPE_LABELS = {
|
|
|
7125
8049
|
sunburstChart: "Sunburst chart",
|
|
7126
8050
|
radialBarChart: "Radial bar chart",
|
|
7127
8051
|
calendarHeatmap: "Calendar heatmap",
|
|
7128
|
-
bulletChart: "Bullet chart"
|
|
8052
|
+
bulletChart: "Bullet chart",
|
|
8053
|
+
chordChart: "Chord diagram"
|
|
7129
8054
|
},
|
|
7130
8055
|
zh: {
|
|
7131
8056
|
noData: "暂无数据",
|
|
@@ -7142,6 +8067,7 @@ var SHAPE_LABELS = {
|
|
|
7142
8067
|
target: "目标",
|
|
7143
8068
|
ofTarget: "目标达成",
|
|
7144
8069
|
range: "区间",
|
|
8070
|
+
reverse: "反向",
|
|
7145
8071
|
series: "系列 {index}",
|
|
7146
8072
|
pieChart: "饼图",
|
|
7147
8073
|
donutChart: "环形图",
|
|
@@ -7155,7 +8081,8 @@ var SHAPE_LABELS = {
|
|
|
7155
8081
|
sunburstChart: "旭日图",
|
|
7156
8082
|
radialBarChart: "径向条形图",
|
|
7157
8083
|
calendarHeatmap: "日历热力图",
|
|
7158
|
-
bulletChart: "子弹图"
|
|
8084
|
+
bulletChart: "子弹图",
|
|
8085
|
+
chordChart: "弦图"
|
|
7159
8086
|
},
|
|
7160
8087
|
ja: {
|
|
7161
8088
|
noData: "データなし",
|
|
@@ -7172,6 +8099,7 @@ var SHAPE_LABELS = {
|
|
|
7172
8099
|
target: "目標",
|
|
7173
8100
|
ofTarget: "目標達成率",
|
|
7174
8101
|
range: "範囲",
|
|
8102
|
+
reverse: "逆方向",
|
|
7175
8103
|
series: "系列 {index}",
|
|
7176
8104
|
pieChart: "円グラフ",
|
|
7177
8105
|
donutChart: "ドーナツグラフ",
|
|
@@ -7185,7 +8113,8 @@ var SHAPE_LABELS = {
|
|
|
7185
8113
|
sunburstChart: "サンバースト図",
|
|
7186
8114
|
radialBarChart: "円形棒グラフ",
|
|
7187
8115
|
calendarHeatmap: "カレンダーヒートマップ",
|
|
7188
|
-
bulletChart: "ブレットグラフ"
|
|
8116
|
+
bulletChart: "ブレットグラフ",
|
|
8117
|
+
chordChart: "コードダイアグラム"
|
|
7189
8118
|
},
|
|
7190
8119
|
fr: {
|
|
7191
8120
|
noData: "Aucune donnée",
|
|
@@ -7202,6 +8131,7 @@ var SHAPE_LABELS = {
|
|
|
7202
8131
|
target: "Objectif",
|
|
7203
8132
|
ofTarget: "Atteinte de l’objectif",
|
|
7204
8133
|
range: "Plage",
|
|
8134
|
+
reverse: "Sens inverse",
|
|
7205
8135
|
series: "Série {index}",
|
|
7206
8136
|
pieChart: "Graphique circulaire",
|
|
7207
8137
|
donutChart: "Graphique en anneau",
|
|
@@ -7215,7 +8145,8 @@ var SHAPE_LABELS = {
|
|
|
7215
8145
|
sunburstChart: "Diagramme en rayons de soleil",
|
|
7216
8146
|
radialBarChart: "Graphique à barres radiales",
|
|
7217
8147
|
calendarHeatmap: "Calendrier thermique",
|
|
7218
|
-
bulletChart: "Graphique à puces"
|
|
8148
|
+
bulletChart: "Graphique à puces",
|
|
8149
|
+
chordChart: "Diagramme d’accords"
|
|
7219
8150
|
}
|
|
7220
8151
|
};
|
|
7221
8152
|
/** Texts of a chart: its `locale` (the page language by default) and `texts` overrides */
|
|
@@ -7787,6 +8718,581 @@ var layoutCalendar = (o, c) => {
|
|
|
7787
8718
|
};
|
|
7788
8719
|
};
|
|
7789
8720
|
//#endregion
|
|
8721
|
+
//#region ../charts/src/engine/shapes/chord.ts
|
|
8722
|
+
/**
|
|
8723
|
+
* Resolves the groups (declared, then the ones only named by links) and
|
|
8724
|
+
* the square flow matrix (from `links`, else `matrix`)
|
|
8725
|
+
*/
|
|
8726
|
+
var resolveChord = (o) => {
|
|
8727
|
+
const names = [];
|
|
8728
|
+
const colors = [];
|
|
8729
|
+
const byName = /* @__PURE__ */ new Map();
|
|
8730
|
+
for (const g of o.groups ?? []) {
|
|
8731
|
+
const group = typeof g === "string" ? { name: g } : g;
|
|
8732
|
+
if (!group || typeof group.name !== "string") continue;
|
|
8733
|
+
if (!byName.has(group.name)) byName.set(group.name, names.length);
|
|
8734
|
+
names.push(group.name);
|
|
8735
|
+
colors.push(group.color);
|
|
8736
|
+
}
|
|
8737
|
+
const cellColors = /* @__PURE__ */ new Map();
|
|
8738
|
+
if (o.links) {
|
|
8739
|
+
const declared = names.length;
|
|
8740
|
+
const resolve = (end) => {
|
|
8741
|
+
if (typeof end === "number") return Number.isInteger(end) && end >= 0 && end < declared ? end : -1;
|
|
8742
|
+
if (typeof end !== "string") return -1;
|
|
8743
|
+
const known = byName.get(end);
|
|
8744
|
+
if (known !== void 0) return known;
|
|
8745
|
+
byName.set(end, names.length);
|
|
8746
|
+
names.push(end);
|
|
8747
|
+
colors.push(void 0);
|
|
8748
|
+
return names.length - 1;
|
|
8749
|
+
};
|
|
8750
|
+
const flows = [];
|
|
8751
|
+
for (const l of o.links) {
|
|
8752
|
+
if (!l) continue;
|
|
8753
|
+
const s = resolve(l.source);
|
|
8754
|
+
const t = resolve(l.target);
|
|
8755
|
+
if (s < 0 || t < 0) continue;
|
|
8756
|
+
flows.push([
|
|
8757
|
+
s,
|
|
8758
|
+
t,
|
|
8759
|
+
positive(l.value),
|
|
8760
|
+
l.color
|
|
8761
|
+
]);
|
|
8762
|
+
}
|
|
8763
|
+
const n = names.length;
|
|
8764
|
+
const matrix = names.map(() => new Array(n).fill(0));
|
|
8765
|
+
for (const [s, t, v, color] of flows) {
|
|
8766
|
+
matrix[s][t] += v;
|
|
8767
|
+
if (color) cellColors.set(s * n + t, color);
|
|
8768
|
+
}
|
|
8769
|
+
return {
|
|
8770
|
+
names,
|
|
8771
|
+
colors,
|
|
8772
|
+
matrix,
|
|
8773
|
+
cellColors
|
|
8774
|
+
};
|
|
8775
|
+
}
|
|
8776
|
+
const rows = o.matrix ?? [];
|
|
8777
|
+
const n = Math.max(names.length, rows.length);
|
|
8778
|
+
for (let i = names.length; i < n; i++) {
|
|
8779
|
+
names.push(String(i + 1));
|
|
8780
|
+
colors.push(void 0);
|
|
8781
|
+
}
|
|
8782
|
+
return {
|
|
8783
|
+
names,
|
|
8784
|
+
colors,
|
|
8785
|
+
matrix: names.map((_, i) => names.map((__, j) => positive(rows[i]?.[j]))),
|
|
8786
|
+
cellColors
|
|
8787
|
+
};
|
|
8788
|
+
};
|
|
8789
|
+
/** Keys of the animated quantities: `~group` (shown 0-1) and `group→group` */
|
|
8790
|
+
var chordKeys = (m) => {
|
|
8791
|
+
const keys = uniqueKeys(m.names);
|
|
8792
|
+
return {
|
|
8793
|
+
group: (i) => `~${keys[i]}`,
|
|
8794
|
+
cell: (i, j) => `${keys[i]}\u2192${keys[j]}`
|
|
8795
|
+
};
|
|
8796
|
+
};
|
|
8797
|
+
/** Whether a cell is a flow of the diagram (directed: self flows are ignored) */
|
|
8798
|
+
var isFlow = (m, directed, i, j) => m.matrix[i][j] > 0 && !(directed && i === j);
|
|
8799
|
+
var chordValues = (o, hidden, out) => {
|
|
8800
|
+
const m = resolveChord(o);
|
|
8801
|
+
const k = chordKeys(m);
|
|
8802
|
+
const directed = !!o.directed;
|
|
8803
|
+
m.names.forEach((_, i) => {
|
|
8804
|
+
out.set(k.group(i), hidden.has(i) ? 0 : 1);
|
|
8805
|
+
m.names.forEach((__, j) => {
|
|
8806
|
+
if (isFlow(m, directed, i, j)) out.set(k.cell(i, j), hidden.has(i) || hidden.has(j) ? 0 : m.matrix[i][j]);
|
|
8807
|
+
});
|
|
8808
|
+
});
|
|
8809
|
+
};
|
|
8810
|
+
/** Totals of a matrix: outgoing, incoming and arc value of every group */
|
|
8811
|
+
var totals = (matrix, directed) => {
|
|
8812
|
+
const n = matrix.length;
|
|
8813
|
+
const out = new Array(n).fill(0);
|
|
8814
|
+
const inc = new Array(n).fill(0);
|
|
8815
|
+
for (let i = 0; i < n; i++) for (let j = 0; j < n; j++) {
|
|
8816
|
+
if (directed && i === j) continue;
|
|
8817
|
+
out[i] += matrix[i][j];
|
|
8818
|
+
inc[j] += matrix[i][j];
|
|
8819
|
+
}
|
|
8820
|
+
return {
|
|
8821
|
+
out,
|
|
8822
|
+
inc,
|
|
8823
|
+
value: out.map((v, i) => directed ? v + inc[i] : v)
|
|
8824
|
+
};
|
|
8825
|
+
};
|
|
8826
|
+
/** Smallest of 1, 2, 5 × 10^k not below `raw` */
|
|
8827
|
+
var niceCeil = (raw) => {
|
|
8828
|
+
if (!(raw > 0) || !Number.isFinite(raw)) return 0;
|
|
8829
|
+
const base = Math.pow(10, Math.floor(Math.log10(raw)));
|
|
8830
|
+
for (const f of [
|
|
8831
|
+
1,
|
|
8832
|
+
2,
|
|
8833
|
+
5,
|
|
8834
|
+
10
|
|
8835
|
+
]) if (f * base >= raw * (1 - 1e-9)) return f * base;
|
|
8836
|
+
return 10 * base;
|
|
8837
|
+
};
|
|
8838
|
+
var LABEL_FONT_SIZE = 12;
|
|
8839
|
+
var TICK_BAND = 22;
|
|
8840
|
+
var layoutChord = (o, c) => {
|
|
8841
|
+
const { theme, area, measure, hidden } = c;
|
|
8842
|
+
const model = resolveChord(o);
|
|
8843
|
+
const { names, matrix: raw } = model;
|
|
8844
|
+
const n = names.length;
|
|
8845
|
+
if (!n) return emptyLayout(c);
|
|
8846
|
+
const directed = !!o.directed;
|
|
8847
|
+
const keys = chordKeys(model);
|
|
8848
|
+
const flow = (i, j) => isFlow(model, directed, i, j);
|
|
8849
|
+
const shown = raw.map((row, i) => row.map((v, j) => flow(i, j) ? Math.max(0, c.value(keys.cell(i, j), hidden.has(i) || hidden.has(j) ? 0 : v)) : 0));
|
|
8850
|
+
const target = raw.map((row, i) => row.map((v, j) => flow(i, j) && !hidden.has(i) && !hidden.has(j) ? v : 0));
|
|
8851
|
+
const now = totals(shown, directed);
|
|
8852
|
+
const goal = totals(target, directed);
|
|
8853
|
+
const whole = goal.value.reduce((a, b) => a + b, 0);
|
|
8854
|
+
const visibleWeight = names.map((_, i) => goal.value[i] > 0 || now.value[i] > 1e-9 ? clamp(c.value(keys.group(i), hidden.has(i) ? 0 : 1), 0, 1) : 0);
|
|
8855
|
+
const sumNow = now.value.reduce((a, b) => a + b, 0);
|
|
8856
|
+
if (sumNow <= 1e-12) return emptyLayout(c);
|
|
8857
|
+
const allGoal = totals(raw.map((row, i) => row.map((v, j) => flow(i, j) ? v : 0)), directed).value;
|
|
8858
|
+
const order = names.map((_, i) => i);
|
|
8859
|
+
if (o.sortGroups === "ascending" || o.sortGroups === "descending") {
|
|
8860
|
+
const sign = o.sortGroups === "ascending" ? 1 : -1;
|
|
8861
|
+
order.sort((a, b) => sign * (allGoal[a] - allGoal[b]) || a - b);
|
|
8862
|
+
}
|
|
8863
|
+
const pos = new Array(n);
|
|
8864
|
+
order.forEach((g, p) => pos[g] = p);
|
|
8865
|
+
const cx = area.x + area.width / 2;
|
|
8866
|
+
const cy = area.y + area.height / 2;
|
|
8867
|
+
const half = Math.min(area.width, area.height) / 2;
|
|
8868
|
+
const labelMode = o.labels ?? "auto";
|
|
8869
|
+
const nameFont = font(theme, LABEL_FONT_SIZE, 500);
|
|
8870
|
+
const tickFont = font(theme, 10);
|
|
8871
|
+
const tickOption = o.ticks;
|
|
8872
|
+
const showTicks = tickOption === false ? false : typeof tickOption === "number" ? tickOption > 0 : half >= 150;
|
|
8873
|
+
const tickBand = showTicks ? TICK_BAND : 0;
|
|
8874
|
+
const pad = clamp(finite(o.padAngle, 2), 0, 45) * (Math.PI / 180);
|
|
8875
|
+
const padTotal = pad * visibleWeight.reduce((a, b) => a + b, 0);
|
|
8876
|
+
const padScale = padTotal > TAU * .5 ? TAU * .5 / padTotal : 1;
|
|
8877
|
+
const k = (TAU - padTotal * padScale) / sumNow;
|
|
8878
|
+
const start = -Math.PI / 2 + finite(o.startAngle) * Math.PI / 180;
|
|
8879
|
+
const arcs = new Array(n);
|
|
8880
|
+
{
|
|
8881
|
+
let a = start + pad * padScale * (visibleWeight[order[0]] ?? 0) / 2;
|
|
8882
|
+
for (const g of order) {
|
|
8883
|
+
const a0 = a;
|
|
8884
|
+
const a1 = a0 + now.value[g] * k;
|
|
8885
|
+
arcs[g] = {
|
|
8886
|
+
a0,
|
|
8887
|
+
a1
|
|
8888
|
+
};
|
|
8889
|
+
a = a1 + pad * padScale * visibleWeight[g];
|
|
8890
|
+
}
|
|
8891
|
+
}
|
|
8892
|
+
const drawnGroup = (g) => arcs[g].a1 - arcs[g].a0 > 1e-6;
|
|
8893
|
+
const nameW = names.map((name) => measure(name, nameFont));
|
|
8894
|
+
const fitsTangential = (r) => order.every((g) => !drawnGroup(g) || nameW[g] + 6 <= (arcs[g].a1 - arcs[g].a0 + pad * padScale * .8) * r);
|
|
8895
|
+
let mode = labelMode === "none" ? "none" : labelMode === "radial" ? "radial" : "tangential";
|
|
8896
|
+
const tangentialRoom = 22;
|
|
8897
|
+
if (labelMode === "auto" && !fitsTangential(Math.max(1, half - 12))) mode = "radial";
|
|
8898
|
+
const reach = (a) => {
|
|
8899
|
+
const cos = Math.abs(Math.cos(a));
|
|
8900
|
+
const sin = Math.abs(Math.sin(a));
|
|
8901
|
+
return Math.min(cos > 1e-6 ? (area.width / 2 - 2) / cos : Infinity, sin > 1e-6 ? (area.height / 2 - LABEL_FONT_SIZE / 2 - 1) / sin : Infinity);
|
|
8902
|
+
};
|
|
8903
|
+
const midOf = (g) => (arcs[g].a0 + arcs[g].a1) / 2;
|
|
8904
|
+
const horizontal = (a) => Math.abs(Math.sin(a)) > .92;
|
|
8905
|
+
let outer;
|
|
8906
|
+
if (mode === "radial") {
|
|
8907
|
+
outer = half - tickBand - 8;
|
|
8908
|
+
for (const g of order) if (drawnGroup(g) && visibleWeight[g] > .5) {
|
|
8909
|
+
const a = midOf(g);
|
|
8910
|
+
const need = horizontal(a) ? 14 : nameW[g];
|
|
8911
|
+
outer = Math.min(outer, reach(a) - need - tickBand - 10);
|
|
8912
|
+
}
|
|
8913
|
+
outer = Math.max(half * .5, outer);
|
|
8914
|
+
} else outer = half - tickBand - (mode === "none" ? 0 : tangentialRoom) - 2;
|
|
8915
|
+
outer = Math.max(16, outer);
|
|
8916
|
+
const arcWidth = clamp(finite(o.arcWidth, clamp(outer * .06, 8, 18)), 2, outer * .5);
|
|
8917
|
+
const inner = outer - arcWidth;
|
|
8918
|
+
const ribbonR = Math.max(4, inner - 2);
|
|
8919
|
+
const segments = names.map(() => []);
|
|
8920
|
+
for (let i = 0; i < n; i++) for (let j = 0; j < n; j++) if (directed) {
|
|
8921
|
+
if (flow(i, j)) {
|
|
8922
|
+
segments[i].push({
|
|
8923
|
+
j,
|
|
8924
|
+
dir: "out",
|
|
8925
|
+
raw: raw[i][j],
|
|
8926
|
+
a0: 0,
|
|
8927
|
+
a1: 0
|
|
8928
|
+
});
|
|
8929
|
+
segments[j].push({
|
|
8930
|
+
j: i,
|
|
8931
|
+
dir: "in",
|
|
8932
|
+
raw: raw[i][j],
|
|
8933
|
+
a0: 0,
|
|
8934
|
+
a1: 0
|
|
8935
|
+
});
|
|
8936
|
+
}
|
|
8937
|
+
} else if (flow(i, j) || flow(j, i)) segments[i].push({
|
|
8938
|
+
j,
|
|
8939
|
+
dir: "out",
|
|
8940
|
+
raw: raw[i][j],
|
|
8941
|
+
a0: 0,
|
|
8942
|
+
a1: 0
|
|
8943
|
+
});
|
|
8944
|
+
const sortSub = o.sortSubgroups ?? "auto";
|
|
8945
|
+
segments.forEach((list, i) => {
|
|
8946
|
+
const offset = (j) => {
|
|
8947
|
+
const d = (pos[j] - pos[i] + n) % n;
|
|
8948
|
+
return d === 0 ? n / 2 : d;
|
|
8949
|
+
};
|
|
8950
|
+
list.sort((a, b) => {
|
|
8951
|
+
const dir = Number(a.dir === "in") - Number(b.dir === "in");
|
|
8952
|
+
if (sortSub === "ascending" || sortSub === "descending") return (sortSub === "ascending" ? 1 : -1) * (a.raw - b.raw) || pos[a.j] - pos[b.j] || dir;
|
|
8953
|
+
if (sortSub === "none") return pos[a.j] - pos[b.j] || dir;
|
|
8954
|
+
return offset(b.j) - offset(a.j) || dir;
|
|
8955
|
+
});
|
|
8956
|
+
let a = arcs[i].a0;
|
|
8957
|
+
for (const s of list) {
|
|
8958
|
+
const v = s.dir === "out" ? shown[i][s.j] : shown[s.j][i];
|
|
8959
|
+
s.a0 = a;
|
|
8960
|
+
s.a1 = a + v * k;
|
|
8961
|
+
a = s.a1;
|
|
8962
|
+
}
|
|
8963
|
+
});
|
|
8964
|
+
const segment = (g, j, dir) => segments[g].find((s) => s.j === j && s.dir === dir);
|
|
8965
|
+
const css = names.map((_, i) => c.color(model.colors[i], i)).map((col) => toCss(col));
|
|
8966
|
+
const neutral = toCss(mix(theme.grid, theme.textMuted, .45));
|
|
8967
|
+
const colorMode = o.ribbonColor ?? "gradient";
|
|
8968
|
+
const opacity = clamp(finite(o.ribbonOpacity, .65), .02, 1);
|
|
8969
|
+
const activeAlpha = Math.min(1, opacity + .25);
|
|
8970
|
+
const head = o.arrows ?? directed ? clamp(ribbonR * .07, 5, 12) : 0;
|
|
8971
|
+
const ribbons = [];
|
|
8972
|
+
const ribbonIndex = (s, t) => n + s * n + t;
|
|
8973
|
+
for (let i = 0; i < n; i++) for (let j = directed ? 0 : i; j < n; j++) if (directed) {
|
|
8974
|
+
if (!flow(i, j)) continue;
|
|
8975
|
+
const src = segment(i, j, "out");
|
|
8976
|
+
const tgt = segment(j, i, "in");
|
|
8977
|
+
if (src && tgt) ribbons.push({
|
|
8978
|
+
index: ribbonIndex(i, j),
|
|
8979
|
+
s: i,
|
|
8980
|
+
t: j,
|
|
8981
|
+
src,
|
|
8982
|
+
tgt
|
|
8983
|
+
});
|
|
8984
|
+
} else {
|
|
8985
|
+
if (!flow(i, j) && !flow(j, i)) continue;
|
|
8986
|
+
const [s, t] = raw[j][i] > raw[i][j] ? [j, i] : [i, j];
|
|
8987
|
+
const src = segment(s, t, "out");
|
|
8988
|
+
const tgt = segment(t, s, "out");
|
|
8989
|
+
if (src && tgt) ribbons.push({
|
|
8990
|
+
index: ribbonIndex(s, t),
|
|
8991
|
+
s,
|
|
8992
|
+
t,
|
|
8993
|
+
src,
|
|
8994
|
+
tgt
|
|
8995
|
+
});
|
|
8996
|
+
}
|
|
8997
|
+
const ribbonsOf = names.map(() => []);
|
|
8998
|
+
for (const r of ribbons) {
|
|
8999
|
+
ribbonsOf[r.s].push(r.index);
|
|
9000
|
+
if (r.t !== r.s) ribbonsOf[r.t].push(r.index);
|
|
9001
|
+
}
|
|
9002
|
+
const nodes = [];
|
|
9003
|
+
const width = (r) => r.src.a1 - r.src.a0 + (r.tgt.a1 - r.tgt.a0);
|
|
9004
|
+
for (const r of ribbons.slice().sort((a, b) => width(b) - width(a))) {
|
|
9005
|
+
if (width(r) <= 1e-6) continue;
|
|
9006
|
+
const own = model.cellColors.get(r.s * n + r.t) ?? (directed ? void 0 : model.cellColors.get(r.t * n + r.s));
|
|
9007
|
+
let c0;
|
|
9008
|
+
let c1;
|
|
9009
|
+
if (own) c0 = c1 = toCss(c.color(own, r.s));
|
|
9010
|
+
else if (colorMode === "source") c0 = c1 = css[r.s];
|
|
9011
|
+
else if (colorMode === "target") c0 = c1 = css[r.t];
|
|
9012
|
+
else if (colorMode === "neutral") c0 = c1 = neutral;
|
|
9013
|
+
else {
|
|
9014
|
+
c0 = css[r.s];
|
|
9015
|
+
c1 = css[r.t];
|
|
9016
|
+
}
|
|
9017
|
+
nodes.push({
|
|
9018
|
+
kind: "ribbon",
|
|
9019
|
+
cx,
|
|
9020
|
+
cy,
|
|
9021
|
+
r: ribbonR,
|
|
9022
|
+
s0: r.src.a0,
|
|
9023
|
+
s1: r.src.a1,
|
|
9024
|
+
t0: r.tgt.a0,
|
|
9025
|
+
t1: r.tgt.a1,
|
|
9026
|
+
head: r.s === r.t ? 0 : head,
|
|
9027
|
+
color0: c0,
|
|
9028
|
+
color1: c1,
|
|
9029
|
+
alpha: opacity,
|
|
9030
|
+
activeAlpha,
|
|
9031
|
+
hit: r.index,
|
|
9032
|
+
also: r.s === r.t ? [r.s] : [r.s, r.t]
|
|
9033
|
+
});
|
|
9034
|
+
}
|
|
9035
|
+
for (const g of order) {
|
|
9036
|
+
if (!drawnGroup(g)) continue;
|
|
9037
|
+
nodes.push({
|
|
9038
|
+
kind: "sector",
|
|
9039
|
+
cx,
|
|
9040
|
+
cy,
|
|
9041
|
+
r0: inner,
|
|
9042
|
+
r1: outer,
|
|
9043
|
+
a0: arcs[g].a0,
|
|
9044
|
+
a1: arcs[g].a1,
|
|
9045
|
+
pad: 0,
|
|
9046
|
+
corner: Math.min(2, arcWidth / 4),
|
|
9047
|
+
fill: css[g],
|
|
9048
|
+
hit: g,
|
|
9049
|
+
also: ribbonsOf[g],
|
|
9050
|
+
alpha: visibleWeight[g]
|
|
9051
|
+
});
|
|
9052
|
+
}
|
|
9053
|
+
const muted = toCss(theme.textMuted);
|
|
9054
|
+
const tickColor = toCss(theme.textMuted, .7);
|
|
9055
|
+
if (showTicks) {
|
|
9056
|
+
const unitPx = k * outer;
|
|
9057
|
+
const tickFormat = o.tickFormat ?? localeFormat(c.locale);
|
|
9058
|
+
const labelPx = measure(tickFormat(Math.max(...allGoal)), tickFont) + 14;
|
|
9059
|
+
let major = typeof tickOption === "number" ? tickOption : niceCeil(labelPx / Math.max(unitPx, 1e-12));
|
|
9060
|
+
const count = sumNow / Math.max(major, 1e-12);
|
|
9061
|
+
if (!(major > 0) || count > 240) major = niceCeil(sumNow / 240);
|
|
9062
|
+
const minor = major / 5 * unitPx >= 5 ? major / 5 : major / 2 * unitPx >= 5 ? major / 2 : major;
|
|
9063
|
+
const perMajor = Math.round(major / minor);
|
|
9064
|
+
const tickR = outer + 2;
|
|
9065
|
+
const labelR = outer + 15;
|
|
9066
|
+
let lastEnd = -Infinity;
|
|
9067
|
+
let firstStart = null;
|
|
9068
|
+
for (const g of order) {
|
|
9069
|
+
if (!drawnGroup(g)) continue;
|
|
9070
|
+
const { a0, a1 } = arcs[g];
|
|
9071
|
+
const also = ribbonsOf[g];
|
|
9072
|
+
for (let m = 0;; m++) {
|
|
9073
|
+
const a = a0 + m * minor * k;
|
|
9074
|
+
if (a > a1 + 1e-9) break;
|
|
9075
|
+
const isMajor = m % perMajor === 0;
|
|
9076
|
+
const len = isMajor ? 5 : 3;
|
|
9077
|
+
if (unitPx * minor >= 3 || isMajor) nodes.push({
|
|
9078
|
+
kind: "line",
|
|
9079
|
+
points: [
|
|
9080
|
+
cx + tickR * Math.cos(a),
|
|
9081
|
+
cy + tickR * Math.sin(a),
|
|
9082
|
+
cx + (tickR + len) * Math.cos(a),
|
|
9083
|
+
cy + (tickR + len) * Math.sin(a)
|
|
9084
|
+
],
|
|
9085
|
+
color: tickColor,
|
|
9086
|
+
width: 1,
|
|
9087
|
+
hit: g,
|
|
9088
|
+
also
|
|
9089
|
+
});
|
|
9090
|
+
if (!isMajor) continue;
|
|
9091
|
+
const text = tickFormat(m * minor);
|
|
9092
|
+
const halfAngle = (measure(text, tickFont) / 2 + 3) / labelR;
|
|
9093
|
+
if (a - halfAngle < lastEnd) continue;
|
|
9094
|
+
if (firstStart !== null && a + halfAngle > firstStart + TAU) continue;
|
|
9095
|
+
if (firstStart === null) firstStart = a - halfAngle;
|
|
9096
|
+
lastEnd = a + halfAngle;
|
|
9097
|
+
nodes.push({
|
|
9098
|
+
kind: "text",
|
|
9099
|
+
x: cx + labelR * Math.cos(a),
|
|
9100
|
+
y: cy + labelR * Math.sin(a),
|
|
9101
|
+
text,
|
|
9102
|
+
font: tickFont,
|
|
9103
|
+
color: muted,
|
|
9104
|
+
align: "center",
|
|
9105
|
+
baseline: "middle",
|
|
9106
|
+
rotate: upright(a + Math.PI / 2),
|
|
9107
|
+
hit: g,
|
|
9108
|
+
also
|
|
9109
|
+
});
|
|
9110
|
+
}
|
|
9111
|
+
}
|
|
9112
|
+
}
|
|
9113
|
+
if (mode !== "none") {
|
|
9114
|
+
const nameR = outer + tickBand + 6;
|
|
9115
|
+
const color = toCss(theme.text);
|
|
9116
|
+
const placed = [];
|
|
9117
|
+
const lineGap = 15;
|
|
9118
|
+
const samples = (x, y, dx, dy, length) => {
|
|
9119
|
+
const pts = [];
|
|
9120
|
+
const steps = Math.max(1, Math.ceil(length / 6));
|
|
9121
|
+
for (let s = 0; s <= steps; s++) pts.push([x + dx * length * s / steps, y + dy * length * s / steps]);
|
|
9122
|
+
return pts;
|
|
9123
|
+
};
|
|
9124
|
+
const collides = (pts) => placed.some((other) => other.some(([x, y]) => pts.some(([u, v]) => Math.hypot(x - u, y - v) < lineGap)));
|
|
9125
|
+
const byValue = order.filter((g) => drawnGroup(g) && visibleWeight[g] > .5).sort((a, b) => now.value[b] - now.value[a]);
|
|
9126
|
+
for (const g of byValue) {
|
|
9127
|
+
const { a0, a1 } = arcs[g];
|
|
9128
|
+
const mid = (a0 + a1) / 2;
|
|
9129
|
+
if (mode === "tangential") {
|
|
9130
|
+
const room = (a1 - a0 + pad * padScale * .8) * (nameR + 6) - 6;
|
|
9131
|
+
const text = ellipsize(names[g], room, nameFont, measure);
|
|
9132
|
+
if (!text) continue;
|
|
9133
|
+
nodes.push({
|
|
9134
|
+
kind: "text",
|
|
9135
|
+
x: cx + (nameR + 6) * Math.cos(mid),
|
|
9136
|
+
y: cy + (nameR + 6) * Math.sin(mid),
|
|
9137
|
+
text,
|
|
9138
|
+
font: nameFont,
|
|
9139
|
+
color,
|
|
9140
|
+
align: "center",
|
|
9141
|
+
baseline: "middle",
|
|
9142
|
+
rotate: upright(mid + Math.PI / 2),
|
|
9143
|
+
hit: g,
|
|
9144
|
+
also: ribbonsOf[g]
|
|
9145
|
+
});
|
|
9146
|
+
continue;
|
|
9147
|
+
}
|
|
9148
|
+
const ax = cx + nameR * Math.cos(mid);
|
|
9149
|
+
const ay = cy + nameR * Math.sin(mid);
|
|
9150
|
+
if (horizontal(mid)) {
|
|
9151
|
+
const y = ay + Math.sign(Math.sin(mid)) * 7;
|
|
9152
|
+
const outward = Math.cos(mid) >= 0 ? "left" : "right";
|
|
9153
|
+
const aligns = [
|
|
9154
|
+
"center",
|
|
9155
|
+
outward,
|
|
9156
|
+
outward === "left" ? "right" : "left"
|
|
9157
|
+
];
|
|
9158
|
+
const clear = (pts) => pts.every(([x, py]) => Math.hypot(x - cx, py - cy) >= nameR + 2);
|
|
9159
|
+
for (const align of aligns) {
|
|
9160
|
+
const room = align === "center" ? 2 * Math.min(ax - area.x, area.x + area.width - ax) - 4 : align === "left" ? area.x + area.width - ax - 2 : ax - area.x - 2;
|
|
9161
|
+
const text = ellipsize(names[g], room, nameFont, measure);
|
|
9162
|
+
if (!text) continue;
|
|
9163
|
+
const w = measure(text, nameFont);
|
|
9164
|
+
const pts = samples(align === "left" ? ax : align === "right" ? ax - w : ax - w / 2, y, 1, 0, w);
|
|
9165
|
+
if (!clear(pts) || collides(pts)) continue;
|
|
9166
|
+
placed.push(pts);
|
|
9167
|
+
nodes.push({
|
|
9168
|
+
kind: "text",
|
|
9169
|
+
x: ax,
|
|
9170
|
+
y,
|
|
9171
|
+
text,
|
|
9172
|
+
font: nameFont,
|
|
9173
|
+
color,
|
|
9174
|
+
align,
|
|
9175
|
+
baseline: "middle",
|
|
9176
|
+
hit: g,
|
|
9177
|
+
also: ribbonsOf[g]
|
|
9178
|
+
});
|
|
9179
|
+
break;
|
|
9180
|
+
}
|
|
9181
|
+
continue;
|
|
9182
|
+
}
|
|
9183
|
+
const text = ellipsize(names[g], reach(mid) - nameR - 2, nameFont, measure);
|
|
9184
|
+
if (!text) continue;
|
|
9185
|
+
const pts = samples(ax, ay, Math.cos(mid), Math.sin(mid), measure(text, nameFont));
|
|
9186
|
+
if (collides(pts)) continue;
|
|
9187
|
+
placed.push(pts);
|
|
9188
|
+
const right = Math.cos(mid) >= 0;
|
|
9189
|
+
nodes.push({
|
|
9190
|
+
kind: "text",
|
|
9191
|
+
x: ax,
|
|
9192
|
+
y: ay,
|
|
9193
|
+
text,
|
|
9194
|
+
font: nameFont,
|
|
9195
|
+
color,
|
|
9196
|
+
align: right ? "left" : "right",
|
|
9197
|
+
baseline: "middle",
|
|
9198
|
+
rotate: right ? mid : mid + Math.PI,
|
|
9199
|
+
hit: g,
|
|
9200
|
+
also: ribbonsOf[g]
|
|
9201
|
+
});
|
|
9202
|
+
}
|
|
9203
|
+
}
|
|
9204
|
+
const items = [];
|
|
9205
|
+
const asymmetric = directed || raw.some((row, i) => row.some((v, j) => Math.abs(v - raw[j][i]) > 1e-12));
|
|
9206
|
+
for (const g of order) {
|
|
9207
|
+
const value = goal.value[g];
|
|
9208
|
+
if (!(value > 0) || hidden.has(g)) continue;
|
|
9209
|
+
const percent = whole > 0 ? value / whole : 0;
|
|
9210
|
+
const mid = (arcs[g].a0 + arcs[g].a1) / 2;
|
|
9211
|
+
items.push({
|
|
9212
|
+
index: g,
|
|
9213
|
+
name: names[g],
|
|
9214
|
+
value,
|
|
9215
|
+
percent,
|
|
9216
|
+
share: c.percent(percent),
|
|
9217
|
+
color: css[g],
|
|
9218
|
+
x: cx + outer * Math.cos(mid),
|
|
9219
|
+
y: cy + outer * Math.sin(mid),
|
|
9220
|
+
rows: [
|
|
9221
|
+
...directed || !asymmetric ? [{
|
|
9222
|
+
name: c.labels.value,
|
|
9223
|
+
value: c.format(value)
|
|
9224
|
+
}] : [],
|
|
9225
|
+
...asymmetric ? [{
|
|
9226
|
+
name: c.labels.outgoing,
|
|
9227
|
+
value: c.format(goal.out[g])
|
|
9228
|
+
}, {
|
|
9229
|
+
name: c.labels.incoming,
|
|
9230
|
+
value: c.format(goal.inc[g])
|
|
9231
|
+
}] : [],
|
|
9232
|
+
{
|
|
9233
|
+
name: c.labels.share,
|
|
9234
|
+
value: c.percent(percent)
|
|
9235
|
+
}
|
|
9236
|
+
]
|
|
9237
|
+
});
|
|
9238
|
+
}
|
|
9239
|
+
const flowTotal = target.reduce((s, row) => s + row.reduce((a, b) => a + b, 0), 0);
|
|
9240
|
+
const ribbonItems = ribbons.filter((r) => target[r.s][r.t] > 0 || target[r.t][r.s] > 0).sort((a, b) => pos[a.s] - pos[b.s] || a.src.a0 - b.src.a0 || pos[a.t] - pos[b.t]);
|
|
9241
|
+
for (const r of ribbonItems) {
|
|
9242
|
+
const value = target[r.s][r.t];
|
|
9243
|
+
const reverse = r.s !== r.t && target[r.s][r.t] + target[r.t][r.s] > 0 ? raw[r.t][r.s] : 0;
|
|
9244
|
+
const percent = flowTotal > 0 ? value / flowTotal : 0;
|
|
9245
|
+
const source = names[r.s];
|
|
9246
|
+
const tgt = names[r.t];
|
|
9247
|
+
const ms = (r.src.a0 + r.src.a1) / 2;
|
|
9248
|
+
const mt = (r.tgt.a0 + r.tgt.a1) / 2;
|
|
9249
|
+
const x = r.s === r.t ? cx + ribbonR * .7 * Math.cos(ms) : .25 * (cx + ribbonR * Math.cos(ms)) + .5 * cx + .25 * (cx + ribbonR * Math.cos(mt));
|
|
9250
|
+
const y = r.s === r.t ? cy + ribbonR * .7 * Math.sin(ms) : .25 * (cy + ribbonR * Math.sin(ms)) + .5 * cy + .25 * (cy + ribbonR * Math.sin(mt));
|
|
9251
|
+
items.push({
|
|
9252
|
+
index: r.index,
|
|
9253
|
+
name: r.s === r.t ? source : `${source} \u2192 ${tgt}`,
|
|
9254
|
+
value,
|
|
9255
|
+
percent,
|
|
9256
|
+
share: c.percent(percent),
|
|
9257
|
+
color: css[r.s],
|
|
9258
|
+
x,
|
|
9259
|
+
y,
|
|
9260
|
+
rows: [
|
|
9261
|
+
{
|
|
9262
|
+
name: c.labels.value,
|
|
9263
|
+
value: c.format(value)
|
|
9264
|
+
},
|
|
9265
|
+
...r.s !== r.t && (!directed || reverse > 0) ? [{
|
|
9266
|
+
name: c.labels.reverse,
|
|
9267
|
+
value: c.format(reverse)
|
|
9268
|
+
}] : [],
|
|
9269
|
+
{
|
|
9270
|
+
name: c.labels.share,
|
|
9271
|
+
value: c.percent(percent)
|
|
9272
|
+
}
|
|
9273
|
+
],
|
|
9274
|
+
event: {
|
|
9275
|
+
source,
|
|
9276
|
+
target: tgt,
|
|
9277
|
+
reverseValue: reverse
|
|
9278
|
+
}
|
|
9279
|
+
});
|
|
9280
|
+
}
|
|
9281
|
+
const enter = clamp(c.enter, 0, 1);
|
|
9282
|
+
return {
|
|
9283
|
+
nodes,
|
|
9284
|
+
items,
|
|
9285
|
+
dim: .25,
|
|
9286
|
+
empty: false,
|
|
9287
|
+
...enter < 1 ? { enter: {
|
|
9288
|
+
alpha: enter,
|
|
9289
|
+
scale: .94 + .06 * enter,
|
|
9290
|
+
cx,
|
|
9291
|
+
cy
|
|
9292
|
+
} } : {}
|
|
9293
|
+
};
|
|
9294
|
+
};
|
|
9295
|
+
//#endregion
|
|
7790
9296
|
//#region ../charts/src/engine/shapes/funnel.ts
|
|
7791
9297
|
var keysOf$2 = (o) => uniqueKeys(o.data.map((d) => d.name));
|
|
7792
9298
|
var funnelValues = (o, hidden, out) => {
|
|
@@ -10430,6 +11936,9 @@ var layoutShapeScene = (input) => {
|
|
|
10430
11936
|
case "bullet":
|
|
10431
11937
|
result = layoutBullet(o, c);
|
|
10432
11938
|
break;
|
|
11939
|
+
case "chord":
|
|
11940
|
+
result = layoutChord(o, c);
|
|
11941
|
+
break;
|
|
10433
11942
|
default: result = layoutTreemap(o, c);
|
|
10434
11943
|
}
|
|
10435
11944
|
return {
|
|
@@ -10472,6 +11981,9 @@ var shapeValues = (o, hidden = NO_HIDDEN, focus = NO_FOCUS) => {
|
|
|
10472
11981
|
case "bullet":
|
|
10473
11982
|
bulletValues(o, hidden, out);
|
|
10474
11983
|
break;
|
|
11984
|
+
case "chord":
|
|
11985
|
+
chordValues(o, hidden, out);
|
|
11986
|
+
break;
|
|
10475
11987
|
default: treemapValues(o, hidden, out);
|
|
10476
11988
|
}
|
|
10477
11989
|
return out;
|
|
@@ -10575,12 +12087,24 @@ var shapeLegend = (o, theme, hidden = NO_HIDDEN) => {
|
|
|
10575
12087
|
case "calendarHeatmap":
|
|
10576
12088
|
shown = true;
|
|
10577
12089
|
entries = calendarLegend(o, theme, hidden);
|
|
12090
|
+
break;
|
|
12091
|
+
case "chord": {
|
|
12092
|
+
shown = true;
|
|
12093
|
+
const m = resolveChord(o);
|
|
12094
|
+
entries = m.names.map((name, i) => ({
|
|
12095
|
+
index: i,
|
|
12096
|
+
name,
|
|
12097
|
+
color: color(m.colors[i], i),
|
|
12098
|
+
hidden: hidden.has(i)
|
|
12099
|
+
}));
|
|
12100
|
+
break;
|
|
12101
|
+
}
|
|
10578
12102
|
}
|
|
10579
12103
|
return shown && entries.length ? entries : null;
|
|
10580
12104
|
};
|
|
10581
12105
|
/**
|
|
10582
12106
|
* Number of toggleable entries (slices, stages, series, top-level nodes,
|
|
10583
|
-
* sankey nodes, bars, rows, calendar levels)
|
|
12107
|
+
* sankey nodes, bars, rows, calendar levels, chord groups)
|
|
10584
12108
|
*/
|
|
10585
12109
|
var toggleCount = (o) => {
|
|
10586
12110
|
switch (o.type) {
|
|
@@ -10588,6 +12112,7 @@ var toggleCount = (o) => {
|
|
|
10588
12112
|
case "gauge": return 0;
|
|
10589
12113
|
case "sankey": return resolveSankey(o).names.length;
|
|
10590
12114
|
case "calendarHeatmap": return calendarModel(o)?.count ?? 0;
|
|
12115
|
+
case "chord": return resolveChord(o).names.length;
|
|
10591
12116
|
default: return o.data.length;
|
|
10592
12117
|
}
|
|
10593
12118
|
};
|
|
@@ -10758,6 +12283,7 @@ var layoutShapeTooltip = (value, anchorX, anchorY, width, height, theme, measure
|
|
|
10758
12283
|
let lines;
|
|
10759
12284
|
let content;
|
|
10760
12285
|
let text;
|
|
12286
|
+
let titleLines;
|
|
10761
12287
|
if (typeof value === "string") {
|
|
10762
12288
|
text = value.split("\n");
|
|
10763
12289
|
const f = font(theme, 12);
|
|
@@ -10765,9 +12291,14 @@ var layoutShapeTooltip = (value, anchorX, anchorY, width, height, theme, measure
|
|
|
10765
12291
|
lines = text.length;
|
|
10766
12292
|
} else {
|
|
10767
12293
|
content = value;
|
|
10768
|
-
|
|
12294
|
+
const titleFont = font(theme, 12, 600);
|
|
12295
|
+
const dot = value.color ? 14 : 0;
|
|
12296
|
+
const maxTitle = Math.max(60, Math.min(260, width - 16 - 18) - dot);
|
|
12297
|
+
titleLines = wrapText(value.title, maxTitle, titleFont, measure, 3);
|
|
12298
|
+
if (!titleLines.length) titleLines = [value.title];
|
|
12299
|
+
for (const line of titleLines) w = Math.max(w, dot + measure(line, titleFont));
|
|
10769
12300
|
for (const row of value.rows) w = Math.max(w, (row.color ? 14 : 0) + measure(row.name, font(theme, 12)) + 16 + measure(row.value, font(theme, 12, 600)));
|
|
10770
|
-
lines =
|
|
12301
|
+
lines = titleLines.length + value.rows.length;
|
|
10771
12302
|
}
|
|
10772
12303
|
const bw = Math.max(96, Math.ceil(w + 18 + 4));
|
|
10773
12304
|
const bh = lines * lineHeight + 18;
|
|
@@ -10782,7 +12313,10 @@ var layoutShapeTooltip = (value, anchorX, anchorY, width, height, theme, measure
|
|
|
10782
12313
|
height: bh,
|
|
10783
12314
|
padding,
|
|
10784
12315
|
lineHeight,
|
|
10785
|
-
...content ? {
|
|
12316
|
+
...content ? {
|
|
12317
|
+
content,
|
|
12318
|
+
titleLines
|
|
12319
|
+
} : {},
|
|
10786
12320
|
...text ? { text } : {}
|
|
10787
12321
|
};
|
|
10788
12322
|
};
|
|
@@ -11308,6 +12842,12 @@ Object.defineProperty(exports, "formatCompact", {
|
|
|
11308
12842
|
return formatCompact;
|
|
11309
12843
|
}
|
|
11310
12844
|
});
|
|
12845
|
+
Object.defineProperty(exports, "formatDuration", {
|
|
12846
|
+
enumerable: true,
|
|
12847
|
+
get: function() {
|
|
12848
|
+
return formatDuration;
|
|
12849
|
+
}
|
|
12850
|
+
});
|
|
11311
12851
|
Object.defineProperty(exports, "formatValue", {
|
|
11312
12852
|
enumerable: true,
|
|
11313
12853
|
get: function() {
|