@363045841yyt/klinechart-core 0.9.0-alpha.0 → 0.9.0-alpha.2
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/dist/controllers/createChartController.d.ts.map +1 -1
- package/dist/controllers/createChartController.js +31 -13
- package/dist/controllers/createChartController.js.map +1 -1
- package/dist/controllers/index.d.ts +1 -0
- package/dist/controllers/index.d.ts.map +1 -1
- package/dist/controllers/index.js.map +1 -1
- package/dist/controllers/types.d.ts +12 -0
- package/dist/controllers/types.d.ts.map +1 -1
- package/dist/engine/chart.d.ts +29 -11
- package/dist/engine/chart.d.ts.map +1 -1
- package/dist/engine/chart.js +147 -25
- package/dist/engine/chart.js.map +1 -1
- package/dist/engine/controller/interaction.d.ts +29 -4
- package/dist/engine/controller/interaction.d.ts.map +1 -1
- package/dist/engine/controller/interaction.js +78 -31
- package/dist/engine/controller/interaction.js.map +1 -1
- package/dist/engine/data/incrementalLoadHint.d.ts.map +1 -1
- package/dist/engine/data/incrementalLoadHint.js +5 -1
- package/dist/engine/data/incrementalLoadHint.js.map +1 -1
- package/dist/engine/drawing/DrawingState.d.ts +19 -34
- package/dist/engine/drawing/DrawingState.d.ts.map +1 -1
- package/dist/engine/drawing/DrawingState.js +110 -92
- package/dist/engine/drawing/DrawingState.js.map +1 -1
- package/dist/engine/drawing/index.d.ts +4 -1
- package/dist/engine/drawing/index.d.ts.map +1 -1
- package/dist/engine/drawing/index.js +9 -4
- package/dist/engine/drawing/index.js.map +1 -1
- package/dist/engine/drawing/interaction.d.ts +9 -29
- package/dist/engine/drawing/interaction.d.ts.map +1 -1
- package/dist/engine/drawing/interaction.js +23 -40
- package/dist/engine/drawing/interaction.js.map +1 -1
- package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -1
- package/dist/engine/indicators/chartIndicatorManager.js +4 -12
- package/dist/engine/indicators/chartIndicatorManager.js.map +1 -1
- package/dist/engine/layout/chartPaneLayout.d.ts +0 -2
- package/dist/engine/layout/chartPaneLayout.d.ts.map +1 -1
- package/dist/engine/layout/chartPaneLayout.js +5 -9
- package/dist/engine/layout/chartPaneLayout.js.map +1 -1
- package/dist/engine/layout/pane.d.ts +0 -39
- package/dist/engine/layout/pane.d.ts.map +1 -1
- package/dist/engine/layout/pane.js +0 -9
- package/dist/engine/layout/pane.js.map +1 -1
- package/dist/engine/paneRenderer.d.ts +1 -10
- package/dist/engine/paneRenderer.d.ts.map +1 -1
- package/dist/engine/paneRenderer.js +2 -19
- package/dist/engine/paneRenderer.js.map +1 -1
- package/dist/engine/render/chartRenderer.d.ts +49 -8
- package/dist/engine/render/chartRenderer.d.ts.map +1 -1
- package/dist/engine/render/chartRenderer.js +143 -72
- package/dist/engine/render/chartRenderer.js.map +1 -1
- package/dist/engine/renderers/Indicator/atr.js +3 -13
- package/dist/engine/renderers/Indicator/atr.js.map +1 -1
- package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/boll.js +12 -24
- package/dist/engine/renderers/Indicator/boll.js.map +1 -1
- package/dist/engine/renderers/Indicator/cci.js +6 -13
- package/dist/engine/renderers/Indicator/cci.js.map +1 -1
- package/dist/engine/renderers/Indicator/chaikinVol.js +3 -11
- package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -1
- package/dist/engine/renderers/Indicator/cmf.js +3 -11
- package/dist/engine/renderers/Indicator/cmf.js.map +1 -1
- package/dist/engine/renderers/Indicator/dema.js +3 -11
- package/dist/engine/renderers/Indicator/dema.js.map +1 -1
- package/dist/engine/renderers/Indicator/donchian.js +3 -11
- package/dist/engine/renderers/Indicator/donchian.js.map +1 -1
- package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/ene.js +12 -24
- package/dist/engine/renderers/Indicator/ene.js.map +1 -1
- package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/expma.js +5 -11
- package/dist/engine/renderers/Indicator/expma.js.map +1 -1
- package/dist/engine/renderers/Indicator/fastk.js +6 -13
- package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
- package/dist/engine/renderers/Indicator/fib.js +3 -11
- package/dist/engine/renderers/Indicator/fib.js.map +1 -1
- package/dist/engine/renderers/Indicator/hma.js +3 -11
- package/dist/engine/renderers/Indicator/hma.js.map +1 -1
- package/dist/engine/renderers/Indicator/hv.js +3 -11
- package/dist/engine/renderers/Indicator/hv.js.map +1 -1
- package/dist/engine/renderers/Indicator/ichimoku.js +24 -18
- package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -1
- package/dist/engine/renderers/Indicator/kama.js +3 -11
- package/dist/engine/renderers/Indicator/kama.js.map +1 -1
- package/dist/engine/renderers/Indicator/keltner.js +3 -11
- package/dist/engine/renderers/Indicator/keltner.js.map +1 -1
- package/dist/engine/renderers/Indicator/kst.js +9 -17
- package/dist/engine/renderers/Indicator/kst.js.map +1 -1
- package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/ma.js +10 -21
- package/dist/engine/renderers/Indicator/ma.js.map +1 -1
- package/dist/engine/renderers/Indicator/macd.js +14 -44
- package/dist/engine/renderers/Indicator/macd.js.map +1 -1
- package/dist/engine/renderers/Indicator/mfi.js +3 -11
- package/dist/engine/renderers/Indicator/mfi.js.map +1 -1
- package/dist/engine/renderers/Indicator/mom.js +6 -13
- package/dist/engine/renderers/Indicator/mom.js.map +1 -1
- package/dist/engine/renderers/Indicator/obv.js +3 -11
- package/dist/engine/renderers/Indicator/obv.js.map +1 -1
- package/dist/engine/renderers/Indicator/parkinson.js +3 -11
- package/dist/engine/renderers/Indicator/parkinson.js.map +1 -1
- package/dist/engine/renderers/Indicator/pvt.js +3 -11
- package/dist/engine/renderers/Indicator/pvt.js.map +1 -1
- package/dist/engine/renderers/Indicator/roc.js +3 -11
- package/dist/engine/renderers/Indicator/roc.js.map +1 -1
- package/dist/engine/renderers/Indicator/rsi.js +12 -20
- package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
- package/dist/engine/renderers/Indicator/shared/webglBand.d.ts +0 -2
- package/dist/engine/renderers/Indicator/shared/webglBand.d.ts.map +1 -1
- package/dist/engine/renderers/Indicator/shared/webglBand.js +0 -6
- package/dist/engine/renderers/Indicator/shared/webglBand.js.map +1 -1
- package/dist/engine/renderers/Indicator/stoch.js +9 -17
- package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
- package/dist/engine/renderers/Indicator/tema.js +3 -11
- package/dist/engine/renderers/Indicator/tema.js.map +1 -1
- package/dist/engine/renderers/Indicator/trix.js +3 -11
- package/dist/engine/renderers/Indicator/trix.js.map +1 -1
- package/dist/engine/renderers/Indicator/vma.js +3 -11
- package/dist/engine/renderers/Indicator/vma.js.map +1 -1
- package/dist/engine/renderers/Indicator/vwap.js +3 -11
- package/dist/engine/renderers/Indicator/vwap.js.map +1 -1
- package/dist/engine/renderers/Indicator/wma.js +3 -11
- package/dist/engine/renderers/Indicator/wma.js.map +1 -1
- package/dist/engine/renderers/Indicator/wmsr.js +6 -13
- package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
- package/dist/engine/renderers/candle.d.ts.map +1 -1
- package/dist/engine/renderers/candle.js +21 -28
- package/dist/engine/renderers/candle.js.map +1 -1
- package/dist/engine/renderers/candleViaRenderer.d.ts +19 -0
- package/dist/engine/renderers/candleViaRenderer.d.ts.map +1 -0
- package/dist/engine/renderers/candleViaRenderer.js +15 -0
- package/dist/engine/renderers/candleViaRenderer.js.map +1 -0
- package/dist/engine/renderers/linesViaRenderer.d.ts +55 -0
- package/dist/engine/renderers/linesViaRenderer.d.ts.map +1 -0
- package/dist/engine/renderers/linesViaRenderer.js +169 -0
- package/dist/engine/renderers/linesViaRenderer.js.map +1 -0
- package/dist/engine/renderers/rectsViaRenderer.d.ts +18 -0
- package/dist/engine/renderers/rectsViaRenderer.d.ts.map +1 -0
- package/dist/engine/renderers/rectsViaRenderer.js +63 -0
- package/dist/engine/renderers/rectsViaRenderer.js.map +1 -0
- package/dist/engine/renderers/subVolume.js +7 -26
- package/dist/engine/renderers/subVolume.js.map +1 -1
- package/dist/engine/renderers/timeAxis.js +1 -1
- package/dist/engine/renderers/timeAxis.js.map +1 -1
- package/dist/engine/state/chartStateKernel.d.ts +11 -2
- package/dist/engine/state/chartStateKernel.d.ts.map +1 -1
- package/dist/engine/state/chartStateKernel.js +28 -12
- package/dist/engine/state/chartStateKernel.js.map +1 -1
- package/dist/engine/state/index.d.ts +1 -1
- package/dist/engine/state/index.d.ts.map +1 -1
- package/dist/engine/state/index.js +1 -1
- package/dist/engine/state/index.js.map +1 -1
- package/dist/engine/state/interactionState.d.ts +15 -7
- package/dist/engine/state/interactionState.d.ts.map +1 -1
- package/dist/engine/state/interactionState.js +55 -60
- package/dist/engine/state/interactionState.js.map +1 -1
- package/dist/engine/state/rendererState.d.ts +14 -0
- package/dist/engine/state/rendererState.d.ts.map +1 -0
- package/dist/engine/state/rendererState.js +25 -0
- package/dist/engine/state/rendererState.js.map +1 -0
- package/dist/engine/state/themeState.d.ts +11 -4
- package/dist/engine/state/themeState.d.ts.map +1 -1
- package/dist/engine/state/themeState.js +13 -5
- package/dist/engine/state/themeState.js.map +1 -1
- package/dist/engine/state/viewportState.d.ts.map +1 -1
- package/dist/engine/state/viewportState.js +7 -3
- package/dist/engine/state/viewportState.js.map +1 -1
- package/dist/engine/subPaneManager.d.ts.map +1 -1
- package/dist/engine/subPaneManager.js +2 -10
- package/dist/engine/subPaneManager.js.map +1 -1
- package/dist/foundation/config/chartSettings.d.ts +16 -4
- package/dist/foundation/config/chartSettings.d.ts.map +1 -1
- package/dist/foundation/config/chartSettings.js +21 -6
- package/dist/foundation/config/chartSettings.js.map +1 -1
- package/dist/foundation/plugin/index.d.ts +0 -1
- package/dist/foundation/plugin/index.d.ts.map +1 -1
- package/dist/foundation/plugin/rendererPluginManager.d.ts +1 -22
- package/dist/foundation/plugin/rendererPluginManager.d.ts.map +1 -1
- package/dist/foundation/plugin/rendererPluginManager.js +0 -84
- package/dist/foundation/plugin/rendererPluginManager.js.map +1 -1
- package/dist/foundation/plugin/types.d.ts +11 -17
- package/dist/foundation/plugin/types.d.ts.map +1 -1
- package/dist/foundation/plugin/types.js.map +1 -1
- package/dist/foundation/reactivity/frameTransaction.d.ts +71 -0
- package/dist/foundation/reactivity/frameTransaction.d.ts.map +1 -0
- package/dist/foundation/reactivity/frameTransaction.js +170 -0
- package/dist/foundation/reactivity/frameTransaction.js.map +1 -0
- package/dist/foundation/reactivity/index.d.ts +4 -2
- package/dist/foundation/reactivity/index.d.ts.map +1 -1
- package/dist/foundation/reactivity/index.js +2 -1
- package/dist/foundation/reactivity/index.js.map +1 -1
- package/dist/foundation/reactivity/signal.d.ts +20 -0
- package/dist/foundation/reactivity/signal.d.ts.map +1 -1
- package/dist/foundation/reactivity/signal.js +27 -0
- package/dist/foundation/reactivity/signal.js.map +1 -1
- package/dist/foundation/tokens/theme-dark.d.ts.map +1 -1
- package/dist/foundation/tokens/theme-dark.js +2 -1
- package/dist/foundation/tokens/theme-dark.js.map +1 -1
- package/dist/foundation/tokens/theme-light.d.ts.map +1 -1
- package/dist/foundation/tokens/theme-light.js +2 -1
- package/dist/foundation/tokens/theme-light.js.map +1 -1
- package/dist/rendering/render/Renderer.d.ts +29 -14
- package/dist/rendering/render/Renderer.d.ts.map +1 -1
- package/dist/rendering/render/Renderer.js +3 -10
- package/dist/rendering/render/Renderer.js.map +1 -1
- package/dist/rendering/render/SurfaceBackend.d.ts +5 -7
- package/dist/rendering/render/SurfaceBackend.d.ts.map +1 -1
- package/dist/rendering/render/SurfaceBackend.js +5 -7
- package/dist/rendering/render/SurfaceBackend.js.map +1 -1
- package/dist/rendering/render/createCanvas2DRenderer.d.ts +3 -0
- package/dist/rendering/render/createCanvas2DRenderer.d.ts.map +1 -0
- package/dist/rendering/render/createCanvas2DRenderer.js +74 -0
- package/dist/rendering/render/createCanvas2DRenderer.js.map +1 -0
- package/dist/rendering/render/createDefaultRendererHost.d.ts +4 -0
- package/dist/rendering/render/createDefaultRendererHost.d.ts.map +1 -0
- package/dist/rendering/render/createDefaultRendererHost.js +54 -0
- package/dist/rendering/render/createDefaultRendererHost.js.map +1 -0
- package/dist/rendering/render/createWebGLRenderer.d.ts.map +1 -1
- package/dist/rendering/render/createWebGLRenderer.js +42 -80
- package/dist/rendering/render/createWebGLRenderer.js.map +1 -1
- package/dist/rendering/render/createWebGPURenderer.d.ts +11 -0
- package/dist/rendering/render/createWebGPURenderer.d.ts.map +1 -0
- package/dist/rendering/render/createWebGPURenderer.js +619 -0
- package/dist/rendering/render/createWebGPURenderer.js.map +1 -0
- package/dist/rendering/render/createWebGPUSurfaceBackend.d.ts +15 -0
- package/dist/rendering/render/createWebGPUSurfaceBackend.d.ts.map +1 -0
- package/dist/rendering/render/createWebGPUSurfaceBackend.js +92 -0
- package/dist/rendering/render/createWebGPUSurfaceBackend.js.map +1 -0
- package/dist/rendering/render/frameMetrics.d.ts +19 -0
- package/dist/rendering/render/frameMetrics.d.ts.map +1 -0
- package/dist/rendering/render/frameMetrics.js +43 -0
- package/dist/rendering/render/frameMetrics.js.map +1 -0
- package/dist/rendering/render/index.d.ts +10 -0
- package/dist/rendering/render/index.d.ts.map +1 -1
- package/dist/rendering/render/index.js +6 -0
- package/dist/rendering/render/index.js.map +1 -1
- package/dist/rendering/render/rendererHost.d.ts +34 -0
- package/dist/rendering/render/rendererHost.d.ts.map +1 -0
- package/dist/rendering/render/rendererHost.js +144 -0
- package/dist/rendering/render/rendererHost.js.map +1 -0
- package/dist/rendering/render/webgpuResourceTable.d.ts +25 -0
- package/dist/rendering/render/webgpuResourceTable.d.ts.map +1 -0
- package/dist/rendering/render/webgpuResourceTable.js +54 -0
- package/dist/rendering/render/webgpuResourceTable.js.map +1 -0
- package/dist/rendering/scene/createLayerFromPlugin.d.ts.map +1 -1
- package/dist/rendering/scene/createLayerFromPlugin.js +10 -2
- package/dist/rendering/scene/createLayerFromPlugin.js.map +1 -1
- package/dist/rendering/scene/layerRegistry.d.ts +3 -5
- package/dist/rendering/scene/layerRegistry.d.ts.map +1 -1
- package/dist/rendering/scene/layerRegistry.js +1 -1
- package/dist/rendering/scene/layerRegistry.js.map +1 -1
- package/dist/rendering/scene/retainedScene.d.ts +60 -0
- package/dist/rendering/scene/retainedScene.d.ts.map +1 -0
- package/dist/rendering/scene/retainedScene.js +42 -0
- package/dist/rendering/scene/retainedScene.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
- package/src/__tests__/signal.test.ts +47 -1
- package/src/controllers/__tests__/createChartController.theme.test.ts +102 -0
- package/src/controllers/createChartController.ts +36 -12
- package/src/controllers/index.ts +5 -0
- package/src/controllers/types.ts +14 -0
- package/src/engine/__tests__/chart.dpr.test.ts +64 -0
- package/src/engine/__tests__/paneRenderer.resize.test.ts +0 -7
- package/src/engine/__tests__/renderSinglePath.test.ts +121 -0
- package/src/engine/chart.ts +172 -25
- package/src/engine/controller/__tests__/interaction.dpr.test.ts +45 -41
- package/src/engine/controller/interaction.ts +81 -30
- package/src/engine/data/__tests__/chartDataManager.incrementalLoad.test.ts +1 -0
- package/src/engine/data/incrementalLoadHint.ts +6 -1
- package/src/engine/drawing/DrawingState.ts +107 -89
- package/src/engine/drawing/__tests__/drawingState.workCopy.test.ts +95 -36
- package/src/engine/drawing/__tests__/drawingStore.projection.test.ts +22 -0
- package/src/engine/drawing/index.ts +12 -4
- package/src/engine/drawing/interaction.ts +25 -40
- package/src/engine/indicators/chartIndicatorManager.ts +6 -16
- package/src/engine/layout/chartPaneLayout.ts +6 -11
- package/src/engine/layout/pane.ts +0 -44
- package/src/engine/paneRenderer.ts +3 -34
- package/src/engine/render/chartRenderer.ts +181 -81
- package/src/engine/renderers/Indicator/atr.ts +5 -17
- package/src/engine/renderers/Indicator/boll.ts +15 -26
- package/src/engine/renderers/Indicator/cci.ts +7 -17
- package/src/engine/renderers/Indicator/chaikinVol.ts +3 -15
- package/src/engine/renderers/Indicator/cmf.ts +3 -15
- package/src/engine/renderers/Indicator/dema.ts +3 -15
- package/src/engine/renderers/Indicator/donchian.ts +3 -12
- package/src/engine/renderers/Indicator/ene.ts +15 -25
- package/src/engine/renderers/Indicator/expma.ts +4 -13
- package/src/engine/renderers/Indicator/fastk.ts +7 -17
- package/src/engine/renderers/Indicator/fib.ts +3 -12
- package/src/engine/renderers/Indicator/hma.ts +3 -15
- package/src/engine/renderers/Indicator/hv.ts +3 -15
- package/src/engine/renderers/Indicator/ichimoku.ts +21 -24
- package/src/engine/renderers/Indicator/kama.ts +3 -15
- package/src/engine/renderers/Indicator/keltner.ts +3 -12
- package/src/engine/renderers/Indicator/kst.ts +9 -20
- package/src/engine/renderers/Indicator/ma.ts +9 -21
- package/src/engine/renderers/Indicator/macd.ts +27 -102
- package/src/engine/renderers/Indicator/mfi.ts +3 -15
- package/src/engine/renderers/Indicator/mom.ts +7 -17
- package/src/engine/renderers/Indicator/obv.ts +3 -15
- package/src/engine/renderers/Indicator/parkinson.ts +3 -15
- package/src/engine/renderers/Indicator/pvt.ts +3 -15
- package/src/engine/renderers/Indicator/roc.ts +3 -15
- package/src/engine/renderers/Indicator/rsi.ts +12 -23
- package/src/engine/renderers/Indicator/shared/webglBand.ts +0 -13
- package/src/engine/renderers/Indicator/stoch.ts +9 -20
- package/src/engine/renderers/Indicator/tema.ts +3 -15
- package/src/engine/renderers/Indicator/trix.ts +3 -12
- package/src/engine/renderers/Indicator/vma.ts +3 -15
- package/src/engine/renderers/Indicator/vwap.ts +3 -15
- package/src/engine/renderers/Indicator/wma.ts +3 -15
- package/src/engine/renderers/Indicator/wmsr.ts +7 -17
- package/src/engine/renderers/__tests__/candle.sceneRenderer.test.ts +208 -0
- package/src/engine/renderers/__tests__/candleViaRenderer.test.ts +100 -0
- package/src/engine/renderers/__tests__/linesViaRenderer.test.ts +263 -0
- package/src/engine/renderers/__tests__/rectsViaRenderer.test.ts +87 -0
- package/src/engine/renderers/candle.ts +26 -69
- package/src/engine/renderers/candleViaRenderer.ts +38 -0
- package/src/engine/renderers/linesViaRenderer.ts +226 -0
- package/src/engine/renderers/rectsViaRenderer.ts +83 -0
- package/src/engine/renderers/subVolume.ts +9 -61
- package/src/engine/renderers/timeAxis.ts +1 -1
- package/src/engine/state/__tests__/effectiveTheme.test.ts +49 -0
- package/src/engine/state/__tests__/rendererState.test.ts +36 -0
- package/src/engine/state/__tests__/settingsState.test.ts +1 -1
- package/src/engine/state/chartStateKernel.ts +38 -17
- package/src/engine/state/index.ts +6 -1
- package/src/engine/state/interactionState.ts +73 -102
- package/src/engine/state/rendererState.ts +32 -0
- package/src/engine/state/themeState.ts +15 -8
- package/src/engine/state/viewportState.ts +6 -3
- package/src/engine/subPaneManager.ts +2 -16
- package/src/foundation/config/__tests__/chartSettings.test.ts +25 -0
- package/src/foundation/config/chartSettings.ts +24 -7
- package/src/foundation/plugin/index.ts +0 -1
- package/src/foundation/plugin/rendererPluginManager.ts +0 -99
- package/src/foundation/plugin/types.ts +11 -18
- package/src/foundation/reactivity/__tests__/frameTransaction.test.ts +306 -0
- package/src/foundation/reactivity/frameTransaction.ts +239 -0
- package/src/foundation/reactivity/index.ts +8 -0
- package/src/foundation/reactivity/signal.ts +39 -0
- package/src/foundation/tokens/__tests__/__snapshots__/baseline.test.ts.snap +2 -2
- package/src/foundation/tokens/theme-dark.ts +2 -1
- package/src/foundation/tokens/theme-light.ts +2 -1
- package/src/rendering/render/Renderer.ts +27 -14
- package/src/rendering/render/SurfaceBackend.ts +5 -7
- package/src/rendering/render/__tests__/canvas2DRenderer.test.ts +34 -0
- package/src/rendering/render/__tests__/contract.test.ts +2 -2
- package/src/rendering/render/__tests__/frameMetrics.test.ts +24 -0
- package/src/rendering/render/__tests__/rendererHost.test.ts +157 -0
- package/src/rendering/render/__tests__/webglRenderer.fallback.test.ts +14 -74
- package/src/rendering/render/__tests__/webglRenderer.test.ts +64 -6
- package/src/rendering/render/__tests__/webgpuRenderer.test.ts +370 -0
- package/src/rendering/render/__tests__/webgpuResourceTable.test.ts +62 -0
- package/src/rendering/render/__tests__/webgpuSurfaceBackend.test.ts +120 -0
- package/src/rendering/render/createCanvas2DRenderer.ts +83 -0
- package/src/rendering/render/createDefaultRendererHost.ts +74 -0
- package/src/rendering/render/createWebGLRenderer.ts +41 -87
- package/src/rendering/render/createWebGPURenderer.ts +677 -0
- package/src/rendering/render/createWebGPUSurfaceBackend.ts +106 -0
- package/src/rendering/render/frameMetrics.ts +54 -0
- package/src/rendering/render/index.ts +30 -0
- package/src/rendering/render/rendererHost.ts +210 -0
- package/src/rendering/render/webgpuResourceTable.ts +87 -0
- package/src/rendering/scene/__tests__/layerFromPlugin.test.ts +29 -2
- package/src/rendering/scene/__tests__/retainedScene.test.ts +59 -0
- package/src/rendering/scene/createLayerFromPlugin.ts +9 -2
- package/src/rendering/scene/layerRegistry.ts +4 -6
- package/src/rendering/scene/retainedScene.ts +101 -0
- package/src/version.ts +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retainedScene.d.ts","sourceRoot":"","sources":["../../../src/rendering/scene/retainedScene.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,CAAA;AAEjC,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,OAAO,CAAA;IACb,GAAG,EAAE,YAAY,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,YAAY,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,OAAO,CAAA;IACb,GAAG,EAAE,YAAY,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,aAAa,CAAC;QACpB,MAAM,EAAE,aAAa,CAAC;YAAE,CAAC,EAAE,MAAM,CAAC;YAAC,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;QAC/C,KAAK,EAAE,MAAM,CAAA;QACb,KAAK,CAAC,EAAE,MAAM,CAAA;KACf,CAAC,CAAA;IACF,UAAU,EAAE,MAAM,CAAA;IAClB,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,YAAY,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,aAAa,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9C,KAAK,EAAE,aAAa,CAAC;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9C,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,CAAC,EAAE,MAAM,CAAA;IACT,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;AAMxD,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IAC7B,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAAA;IAC5C,QAAQ,IAAI,IAAI,CAAA;IAChB,KAAK,IAAI,MAAM,EAAE,CAAA;IACjB,KAAK,IAAI,IAAI,CAAA;CACd,CAAA;AAED,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,oBAAyB,GAAG,aAAa,CAwCrF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export function createRetainedScene(options = {}) {
|
|
2
|
+
const staleFrames = options.staleFrames ?? 2;
|
|
3
|
+
const nodes = new Map();
|
|
4
|
+
let frameNumber = 0;
|
|
5
|
+
return {
|
|
6
|
+
beginFrame(nextFrameNumber) {
|
|
7
|
+
frameNumber = nextFrameNumber;
|
|
8
|
+
},
|
|
9
|
+
upsert(node) {
|
|
10
|
+
nodes.set(node.key, {
|
|
11
|
+
...node,
|
|
12
|
+
lastTouchedFrame: frameNumber,
|
|
13
|
+
});
|
|
14
|
+
},
|
|
15
|
+
collectVisible(paneId) {
|
|
16
|
+
const result = [];
|
|
17
|
+
for (const stored of nodes.values()) {
|
|
18
|
+
if (paneId !== undefined && stored.paneId !== paneId)
|
|
19
|
+
continue;
|
|
20
|
+
const { lastTouchedFrame: _lastTouchedFrame, ...node } = stored;
|
|
21
|
+
result.push(node);
|
|
22
|
+
}
|
|
23
|
+
result.sort((a, b) => a.z - b.z || a.key.localeCompare(b.key));
|
|
24
|
+
return result;
|
|
25
|
+
},
|
|
26
|
+
endFrame() { },
|
|
27
|
+
prune() {
|
|
28
|
+
const removed = [];
|
|
29
|
+
for (const [key, stored] of nodes) {
|
|
30
|
+
if (frameNumber - stored.lastTouchedFrame >= staleFrames) {
|
|
31
|
+
nodes.delete(key);
|
|
32
|
+
removed.push(key);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return removed;
|
|
36
|
+
},
|
|
37
|
+
clear() {
|
|
38
|
+
nodes.clear();
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=retainedScene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retainedScene.js","sourceRoot":"","sources":["../../../src/rendering/scene/retainedScene.ts"],"names":[],"mappings":"AA4DA,MAAM,UAAU,mBAAmB,CAAC,UAAgC,EAAE;IACpE,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC,CAAA;IAC5C,MAAM,KAAK,GAAG,IAAI,GAAG,EAA4B,CAAA;IACjD,IAAI,WAAW,GAAG,CAAC,CAAA;IAEnB,OAAO;QACL,UAAU,CAAC,eAAe;YACxB,WAAW,GAAG,eAAe,CAAA;QAC/B,CAAC;QACD,MAAM,CAAC,IAAI;YACT,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE;gBAClB,GAAG,IAAI;gBACP,gBAAgB,EAAE,WAAW;aAC9B,CAAC,CAAA;QACJ,CAAC;QACD,cAAc,CAAC,MAAM;YACnB,MAAM,MAAM,GAAgB,EAAE,CAAA;YAC9B,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBACpC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;oBAAE,SAAQ;gBAC9D,MAAM,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,GAAG,IAAI,EAAE,GAAG,MAAM,CAAA;gBAC/D,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACnB,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;YAC9D,OAAO,MAAM,CAAA;QACf,CAAC;QACD,QAAQ,KAAU,CAAC;QACnB,KAAK;YACH,MAAM,OAAO,GAAa,EAAE,CAAA;YAC5B,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;gBAClC,IAAI,WAAW,GAAG,MAAM,CAAC,gBAAgB,IAAI,WAAW,EAAE,CAAC;oBACzD,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;oBACjB,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACnB,CAAC;YACH,CAAC;YACD,OAAO,OAAO,CAAA;QAChB,CAAC;QACD,KAAK;YACH,KAAK,CAAC,KAAK,EAAE,CAAA;QACf,CAAC;KACF,CAAA;AACH,CAAC"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.9.0-alpha.
|
|
1
|
+
export declare const VERSION = "0.9.0-alpha.2";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '0.9.0-alpha.
|
|
1
|
+
export const VERSION = '0.9.0-alpha.2';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@363045841yyt/klinechart-core",
|
|
3
|
-
"version": "0.9.0-alpha.
|
|
3
|
+
"version": "0.9.0-alpha.2",
|
|
4
4
|
"description": "Headless K-line chart engine + reactive controllers. Zero framework dependencies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -126,6 +126,7 @@
|
|
|
126
126
|
"@arethetypeswrong/cli": "^0.18.3",
|
|
127
127
|
"@size-limit/preset-small-lib": "^12.1.0",
|
|
128
128
|
"@types/jsdom": "^28.0.0",
|
|
129
|
+
"@webgpu/types": "^0.1.71",
|
|
129
130
|
"publint": "^0.3.0",
|
|
130
131
|
"size-limit": "^12.1.0",
|
|
131
132
|
"typescript": "~6.0.3",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, vi } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import { createSignal, effect, computed } from '../foundation/reactivity/signal'
|
|
3
|
+
import { createSignal, effect, computed, selectSignal } from '../foundation/reactivity/signal'
|
|
4
4
|
|
|
5
5
|
describe('createSignal', () => {
|
|
6
6
|
it('reads initial value', () => {
|
|
@@ -123,3 +123,49 @@ describe('computed', () => {
|
|
|
123
123
|
expect(listener).toHaveBeenCalledTimes(1)
|
|
124
124
|
})
|
|
125
125
|
})
|
|
126
|
+
|
|
127
|
+
describe('selectSignal', () => {
|
|
128
|
+
it('notifies only when selected value changes', () => {
|
|
129
|
+
const source = createSignal({ a: 1, b: 2 })
|
|
130
|
+
const selected = selectSignal(source, (s) => s.a)
|
|
131
|
+
const listener = vi.fn()
|
|
132
|
+
selected.subscribe(listener)
|
|
133
|
+
|
|
134
|
+
source.set({ a: 1, b: 9 })
|
|
135
|
+
expect(listener).not.toHaveBeenCalled()
|
|
136
|
+
expect(selected.peek()).toBe(1)
|
|
137
|
+
|
|
138
|
+
source.set({ a: 3, b: 9 })
|
|
139
|
+
expect(listener).toHaveBeenCalledTimes(1)
|
|
140
|
+
expect(selected.peek()).toBe(3)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('supports custom equality for structural fields', () => {
|
|
144
|
+
const source = createSignal({ pos: { x: 1, y: 2 } as { x: number; y: number } | null })
|
|
145
|
+
const selected = selectSignal(
|
|
146
|
+
source,
|
|
147
|
+
(s) => s.pos,
|
|
148
|
+
(a, b) =>
|
|
149
|
+
a === b || (a !== null && b !== null && a.x === b.x && a.y === b.y) || (a === null && b === null),
|
|
150
|
+
)
|
|
151
|
+
const listener = vi.fn()
|
|
152
|
+
selected.subscribe(listener)
|
|
153
|
+
|
|
154
|
+
source.set({ pos: { x: 1, y: 2 } })
|
|
155
|
+
expect(listener).not.toHaveBeenCalled()
|
|
156
|
+
|
|
157
|
+
source.set({ pos: { x: 2, y: 2 } })
|
|
158
|
+
expect(listener).toHaveBeenCalledTimes(1)
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
it('dispose stops following source updates', () => {
|
|
162
|
+
const source = createSignal({ a: 1, b: 0 })
|
|
163
|
+
const selected = selectSignal(source, (s) => s.a)
|
|
164
|
+
const listener = vi.fn()
|
|
165
|
+
selected.subscribe(listener)
|
|
166
|
+
selected.dispose()
|
|
167
|
+
source.set({ a: 9, b: 0 })
|
|
168
|
+
expect(listener).not.toHaveBeenCalled()
|
|
169
|
+
expect(selected.peek()).toBe(1)
|
|
170
|
+
})
|
|
171
|
+
})
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// @vitest-environment jsdom
|
|
2
|
+
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
3
|
+
|
|
4
|
+
import { createChartController } from '../createChartController'
|
|
5
|
+
import { loadBuiltinIndicators } from '../../engine/indicators/registerBuiltins'
|
|
6
|
+
|
|
7
|
+
class ResizeObserverMock {
|
|
8
|
+
observe = vi.fn()
|
|
9
|
+
disconnect = vi.fn()
|
|
10
|
+
unobserve = vi.fn()
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function createCanvasContextStub() {
|
|
14
|
+
return {
|
|
15
|
+
setTransform: vi.fn(),
|
|
16
|
+
scale: vi.fn(),
|
|
17
|
+
clearRect: vi.fn(),
|
|
18
|
+
save: vi.fn(),
|
|
19
|
+
restore: vi.fn(),
|
|
20
|
+
beginPath: vi.fn(),
|
|
21
|
+
moveTo: vi.fn(),
|
|
22
|
+
lineTo: vi.fn(),
|
|
23
|
+
stroke: vi.fn(),
|
|
24
|
+
fillRect: vi.fn(),
|
|
25
|
+
strokeRect: vi.fn(),
|
|
26
|
+
fillText: vi.fn(),
|
|
27
|
+
measureText: vi.fn(() => ({ width: 40 })),
|
|
28
|
+
} as unknown as CanvasRenderingContext2D
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function createWebGLStub(): WebGL2RenderingContext {
|
|
32
|
+
const noop = () => {}
|
|
33
|
+
return new Proxy({} as unknown as WebGL2RenderingContext, {
|
|
34
|
+
get(_, prop) {
|
|
35
|
+
if (typeof prop !== 'string') return undefined
|
|
36
|
+
if (/^[A-Z][A-Z0-9_]*$/.test(prop)) return 0
|
|
37
|
+
if (prop === 'getShaderInfoLog' || prop === 'getProgramInfoLog') return () => ''
|
|
38
|
+
if (prop === 'getShaderParameter' || prop === 'getProgramParameter') return () => true
|
|
39
|
+
if (prop === 'getError') return () => 0
|
|
40
|
+
if (prop === 'getSupportedExtensions') return () => []
|
|
41
|
+
if (prop === 'getContextAttributes') return () => ({})
|
|
42
|
+
if (prop === 'getParameter') return () => 0
|
|
43
|
+
if (prop === 'getUniformLocation' || prop === 'getAttribLocation') return () => 0
|
|
44
|
+
if (prop.startsWith('create') || prop === 'getExtension') return () => ({ __webglStub: true })
|
|
45
|
+
if (prop === 'drawingBufferWidth' || prop === 'drawingBufferHeight') return 300
|
|
46
|
+
return noop
|
|
47
|
+
},
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
describe('createChartController mount theme', () => {
|
|
52
|
+
beforeAll(async () => {
|
|
53
|
+
await loadBuiltinIndicators()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
beforeEach(() => {
|
|
57
|
+
vi.stubGlobal('ResizeObserver', ResizeObserverMock)
|
|
58
|
+
HTMLCanvasElement.prototype.getContext = vi.fn((type: string) => {
|
|
59
|
+
if (type === '2d') return createCanvasContextStub()
|
|
60
|
+
if (type === 'webgl2' || type === 'webgl') return createWebGLStub()
|
|
61
|
+
return null
|
|
62
|
+
}) as never
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
afterEach(() => {
|
|
66
|
+
vi.unstubAllGlobals()
|
|
67
|
+
vi.restoreAllMocks()
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it('opts.theme light overrides settings default dark', async () => {
|
|
71
|
+
const container = document.createElement('div')
|
|
72
|
+
Object.defineProperty(container, 'clientWidth', { value: 800, configurable: true })
|
|
73
|
+
Object.defineProperty(container, 'clientHeight', { value: 600, configurable: true })
|
|
74
|
+
document.body.appendChild(container)
|
|
75
|
+
|
|
76
|
+
const ctrl = await createChartController({
|
|
77
|
+
container,
|
|
78
|
+
theme: 'light',
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
expect(ctrl.settings.peek().theme).toBe('light')
|
|
82
|
+
expect(ctrl.theme.peek()).toBe('light')
|
|
83
|
+
|
|
84
|
+
ctrl.dispose()
|
|
85
|
+
container.remove()
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it('without opts.theme keeps default dark preference', async () => {
|
|
89
|
+
const container = document.createElement('div')
|
|
90
|
+
Object.defineProperty(container, 'clientWidth', { value: 800, configurable: true })
|
|
91
|
+
Object.defineProperty(container, 'clientHeight', { value: 600, configurable: true })
|
|
92
|
+
document.body.appendChild(container)
|
|
93
|
+
|
|
94
|
+
const ctrl = await createChartController({ container })
|
|
95
|
+
|
|
96
|
+
expect(ctrl.settings.peek().theme).toBe('dark')
|
|
97
|
+
expect(ctrl.theme.peek()).toBe('dark')
|
|
98
|
+
|
|
99
|
+
ctrl.dispose()
|
|
100
|
+
container.remove()
|
|
101
|
+
})
|
|
102
|
+
})
|
|
@@ -28,6 +28,10 @@ import { zoomLevelToKWidth, kGapFromKWidth } from '../engine/utils/zoom'
|
|
|
28
28
|
import { KLineChartError } from '../errors'
|
|
29
29
|
import { ChartBridge } from '../features/mcp/chartBridge'
|
|
30
30
|
import { computed, type ReadonlySignal } from '../foundation/reactivity/index'
|
|
31
|
+
import {
|
|
32
|
+
createDefaultRendererHost,
|
|
33
|
+
type RendererBackend,
|
|
34
|
+
} from '../rendering/render/index'
|
|
31
35
|
|
|
32
36
|
import type {
|
|
33
37
|
ChartController,
|
|
@@ -334,6 +338,10 @@ export async function createChartController(opts: ChartMountOptions): Promise<Ch
|
|
|
334
338
|
initialZoomLevel,
|
|
335
339
|
}
|
|
336
340
|
|
|
341
|
+
const initialSettings = resolveSettings(opts.settings)
|
|
342
|
+
const rendererHost = await createDefaultRendererHost(
|
|
343
|
+
initialSettings.rendererBackend as RendererBackend,
|
|
344
|
+
)
|
|
337
345
|
const chart = new Chart(
|
|
338
346
|
{
|
|
339
347
|
container: mounted.container,
|
|
@@ -344,8 +352,13 @@ export async function createChartController(opts: ChartMountOptions): Promise<Ch
|
|
|
344
352
|
xAxisCanvas: mounted.xAxisCanvas,
|
|
345
353
|
},
|
|
346
354
|
chartOptions,
|
|
355
|
+
{ rendererHost, initialSettings },
|
|
347
356
|
)
|
|
348
357
|
|
|
358
|
+
if (import.meta.env?.MODE !== 'production' && typeof window !== 'undefined') {
|
|
359
|
+
;(window as any).__chart = chart
|
|
360
|
+
}
|
|
361
|
+
|
|
349
362
|
const currentDpr =
|
|
350
363
|
typeof window !== 'undefined' && window.devicePixelRatio > 0 ? window.devicePixelRatio : 1
|
|
351
364
|
const currentKWidth = zoomLevelToKWidth(initialZoomLevel, {
|
|
@@ -373,8 +386,9 @@ export async function createChartController(opts: ChartMountOptions): Promise<Ch
|
|
|
373
386
|
const comparisonLoading = chart.comparisonLoading
|
|
374
387
|
|
|
375
388
|
// Signals from ChartStateKernel — no wrapper needed
|
|
376
|
-
const themeSignal: ReadonlySignal<'light' | 'dark'> = chart.
|
|
389
|
+
const themeSignal: ReadonlySignal<'light' | 'dark'> = chart.theme
|
|
377
390
|
const settingsSignal = chart.kernel.settings.readonly.settings
|
|
391
|
+
const rendererRuntimeSignal = chart.kernel.renderer.readonly.runtime
|
|
378
392
|
const chartModeSignal = chart.kernel.mode.readonly.chartMode
|
|
379
393
|
const drawingTool = chart.kernel.drawing.readonly.drawingTool
|
|
380
394
|
// drawings need type mapping (plugin DrawingObject → controller DrawingObject)
|
|
@@ -414,8 +428,8 @@ export async function createChartController(opts: ChartMountOptions): Promise<Ch
|
|
|
414
428
|
chart.setSymbols(opts.symbols)
|
|
415
429
|
}
|
|
416
430
|
|
|
417
|
-
// Apply
|
|
418
|
-
if (opts.theme
|
|
431
|
+
// Apply mount theme preference (settings default may be dark — always honor explicit opts.theme)
|
|
432
|
+
if (opts.theme) {
|
|
419
433
|
try {
|
|
420
434
|
chart.setTheme(opts.theme)
|
|
421
435
|
} catch {
|
|
@@ -423,15 +437,6 @@ export async function createChartController(opts: ChartMountOptions): Promise<Ch
|
|
|
423
437
|
}
|
|
424
438
|
}
|
|
425
439
|
|
|
426
|
-
// Apply initial settings (partial, merged with defaults)
|
|
427
|
-
if (opts.settings) {
|
|
428
|
-
try {
|
|
429
|
-
chart.updateSettingsFacade(resolveSettings(opts.settings))
|
|
430
|
-
} catch {
|
|
431
|
-
/* tolerate first-paint racing */
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
440
|
// -------------------------------------------------------------------
|
|
436
441
|
// Apply initial render state + seed data
|
|
437
442
|
// -------------------------------------------------------------------
|
|
@@ -537,6 +542,11 @@ export async function createChartController(opts: ChartMountOptions): Promise<Ch
|
|
|
537
542
|
chart.setTheme(nextTheme)
|
|
538
543
|
}
|
|
539
544
|
|
|
545
|
+
function setSystemTheme(nextTheme: 'light' | 'dark'): void {
|
|
546
|
+
if (disposed) return
|
|
547
|
+
chart.setSystemTheme(nextTheme)
|
|
548
|
+
}
|
|
549
|
+
|
|
540
550
|
function zoomToLevel(level: number, anchorX?: number): void {
|
|
541
551
|
if (disposed) return
|
|
542
552
|
chart.zoomToLevel(level, anchorX)
|
|
@@ -714,11 +724,21 @@ export async function createChartController(opts: ChartMountOptions): Promise<Ch
|
|
|
714
724
|
return chart.drawings() as any[]
|
|
715
725
|
}
|
|
716
726
|
|
|
727
|
+
function requestDraw(): void {
|
|
728
|
+
if (disposed) return
|
|
729
|
+
chart.scheduleDraw()
|
|
730
|
+
}
|
|
731
|
+
|
|
717
732
|
function setSelectedDrawingId(id: string | null): void {
|
|
718
733
|
if (disposed) return
|
|
719
734
|
chart.setSelectedDrawingId(id)
|
|
720
735
|
}
|
|
721
736
|
|
|
737
|
+
function getSelectedDrawingId(): string | null {
|
|
738
|
+
if (disposed) return null
|
|
739
|
+
return chart.kernel.drawing.readonly.selectedDrawingId.peek()
|
|
740
|
+
}
|
|
741
|
+
|
|
722
742
|
function getViewport(): { scrollLeft: number; plotWidth: number; plotHeight: number } | null {
|
|
723
743
|
if (disposed) return null
|
|
724
744
|
const vp = chart.getViewport()
|
|
@@ -891,6 +911,7 @@ export async function createChartController(opts: ChartMountOptions): Promise<Ch
|
|
|
891
911
|
symbols,
|
|
892
912
|
theme: themeSignal,
|
|
893
913
|
settings: settingsSignal,
|
|
914
|
+
rendererRuntime: rendererRuntimeSignal,
|
|
894
915
|
chartMode: chartModeSignal,
|
|
895
916
|
indicators,
|
|
896
917
|
subPanes,
|
|
@@ -924,6 +945,7 @@ export async function createChartController(opts: ChartMountOptions): Promise<Ch
|
|
|
924
945
|
getData,
|
|
925
946
|
getZoomLevelCount,
|
|
926
947
|
setTheme,
|
|
948
|
+
setSystemTheme,
|
|
927
949
|
zoomToLevel,
|
|
928
950
|
zoomIn,
|
|
929
951
|
zoomOut,
|
|
@@ -949,7 +971,9 @@ export async function createChartController(opts: ChartMountOptions): Promise<Ch
|
|
|
949
971
|
removeDrawing,
|
|
950
972
|
setDrawings,
|
|
951
973
|
getFullDrawings,
|
|
974
|
+
requestDraw,
|
|
952
975
|
setSelectedDrawingId,
|
|
976
|
+
getSelectedDrawingId,
|
|
953
977
|
getViewport,
|
|
954
978
|
getKWidthKGap,
|
|
955
979
|
getCurrentDpr,
|
package/src/controllers/index.ts
CHANGED
|
@@ -31,6 +31,11 @@ export type {
|
|
|
31
31
|
DataFetcher,
|
|
32
32
|
CustomDataSource,
|
|
33
33
|
} from './types'
|
|
34
|
+
export type {
|
|
35
|
+
RendererBackend,
|
|
36
|
+
RendererBackendRuntime,
|
|
37
|
+
RendererBackendStatus,
|
|
38
|
+
} from '../rendering/render/rendererHost'
|
|
34
39
|
|
|
35
40
|
export { createChartController } from './createChartController'
|
|
36
41
|
export { createIndicatorSelectorController } from './createIndicatorSelectorController'
|
package/src/controllers/types.ts
CHANGED
|
@@ -202,10 +202,17 @@ export interface DrawingChartAdapter {
|
|
|
202
202
|
getFullDrawings(): any[]
|
|
203
203
|
/** highlight a drawing by ID */
|
|
204
204
|
setSelectedDrawingId(id: string | null): void
|
|
205
|
+
/** read selected drawing id from kernel */
|
|
206
|
+
getSelectedDrawingId(): string | null
|
|
205
207
|
/** write drawing tool id via Chart (kernel SSOT + session side effects) */
|
|
206
208
|
setDrawingToolId(toolId: import('../engine/drawing/toolConfig').DrawingToolId): void
|
|
207
209
|
/** read current drawing tool id from kernel */
|
|
208
210
|
getDrawingToolId(): import('../engine/drawing/toolConfig').DrawingToolId
|
|
211
|
+
/**
|
|
212
|
+
* 会话态变更后请求重绘(不写 kernel)。
|
|
213
|
+
* 预览 / 拖拽中间态只改会话层时调用。
|
|
214
|
+
*/
|
|
215
|
+
requestDraw?(): void
|
|
209
216
|
/** current viewport (nullable if chart not ready) */
|
|
210
217
|
getViewport(): DrawingChartViewport | null
|
|
211
218
|
/** resolved chart options (kWidth, kGap) */
|
|
@@ -291,6 +298,10 @@ export interface ChartController extends DrawingChartAdapter {
|
|
|
291
298
|
readonly settings: ReadonlySignal<
|
|
292
299
|
Readonly<import('../foundation/config/chartSettings').ChartSettings>
|
|
293
300
|
>
|
|
301
|
+
/** 当前有效 renderer、切换状态和最近错误。 */
|
|
302
|
+
readonly rendererRuntime: ReadonlySignal<
|
|
303
|
+
Readonly<import('../rendering/render/rendererHost').RendererBackendRuntime>
|
|
304
|
+
>
|
|
294
305
|
/** 图表模式 id:kline | timeshare */
|
|
295
306
|
readonly chartMode: ReadonlySignal<'kline' | 'timeshare'>
|
|
296
307
|
readonly indicators: ReadonlySignal<ReadonlyArray<IndicatorInstance>>
|
|
@@ -343,7 +354,10 @@ export interface ChartController extends DrawingChartAdapter {
|
|
|
343
354
|
ensureDataRange(startTs: number): void
|
|
344
355
|
|
|
345
356
|
// ---- Theme ----
|
|
357
|
+
/** 设置主题偏好 light|dark(写 settings) */
|
|
346
358
|
setTheme(theme: 'light' | 'dark'): void
|
|
359
|
+
/** 注入系统主题(settings.theme === auto 时驱动 effectiveTheme) */
|
|
360
|
+
setSystemTheme(theme: 'light' | 'dark'): void
|
|
347
361
|
|
|
348
362
|
// ---- Zoom ----
|
|
349
363
|
zoomToLevel(level: number, anchorX?: number): void
|
|
@@ -521,6 +521,70 @@ describe('Chart pane layout regressions', () => {
|
|
|
521
521
|
await chart.destroy()
|
|
522
522
|
})
|
|
523
523
|
|
|
524
|
+
it('removeDrawing drops id from kernel and clears selection', async () => {
|
|
525
|
+
const chart = new Chart(createDom(1000, 600), defaultOptions)
|
|
526
|
+
const d1 = {
|
|
527
|
+
id: 'd1',
|
|
528
|
+
kind: 'trend-line' as const,
|
|
529
|
+
paneId: 'main',
|
|
530
|
+
visible: true,
|
|
531
|
+
anchors: [],
|
|
532
|
+
params: {},
|
|
533
|
+
style: { stroke: '#f00' },
|
|
534
|
+
}
|
|
535
|
+
const d2 = { ...d1, id: 'd2' }
|
|
536
|
+
chart.setDrawings([d1, d2])
|
|
537
|
+
chart.setSelectedDrawingId('d1')
|
|
538
|
+
chart.removeDrawing('d1')
|
|
539
|
+
expect(chart.kernel.drawing.readonly.drawings.peek().map((d) => d.id)).toEqual(['d2'])
|
|
540
|
+
expect(chart.kernel.drawing.readonly.selectedDrawingId.peek()).toBeNull()
|
|
541
|
+
await chart.destroy()
|
|
542
|
+
})
|
|
543
|
+
|
|
544
|
+
it('removeDrawing with registered session updates kernel only', async () => {
|
|
545
|
+
const { DrawingInteractionController } = await import('../drawing/interaction')
|
|
546
|
+
const chart = new Chart(createDom(1000, 600), defaultOptions)
|
|
547
|
+
const d1 = {
|
|
548
|
+
id: 'd1',
|
|
549
|
+
kind: 'trend-line' as const,
|
|
550
|
+
paneId: 'main',
|
|
551
|
+
visible: true,
|
|
552
|
+
anchors: [],
|
|
553
|
+
params: {},
|
|
554
|
+
style: { stroke: '#f00' },
|
|
555
|
+
}
|
|
556
|
+
const d2 = { ...d1, id: 'd2' }
|
|
557
|
+
chart.setDrawings([d1, d2])
|
|
558
|
+
chart.setSelectedDrawingId('d1')
|
|
559
|
+
|
|
560
|
+
const adapter = {
|
|
561
|
+
setDrawings: (list: typeof d1[]) => chart.setDrawings(list),
|
|
562
|
+
getFullDrawings: () => [...chart.kernel.drawing.readonly.drawings.peek()],
|
|
563
|
+
setSelectedDrawingId: (id: string | null) => chart.setSelectedDrawingId(id),
|
|
564
|
+
getSelectedDrawingId: () => chart.kernel.drawing.readonly.selectedDrawingId.peek(),
|
|
565
|
+
setDrawingToolId: (id: import('../drawing/toolConfig').DrawingToolId) =>
|
|
566
|
+
chart.setDrawingTool(id),
|
|
567
|
+
getDrawingToolId: () => chart.kernel.drawing.readonly.drawingTool.peek(),
|
|
568
|
+
requestDraw: () => chart.scheduleDraw(),
|
|
569
|
+
getViewport: () => null,
|
|
570
|
+
getKWidthKGap: () => ({ kWidth: 6, kGap: 2 }),
|
|
571
|
+
getCurrentDpr: () => 1,
|
|
572
|
+
getData: () => [],
|
|
573
|
+
getLogicalIndexAtX: () => null,
|
|
574
|
+
getTimestampAtLogicalIndex: () => null,
|
|
575
|
+
priceToY: () => 0,
|
|
576
|
+
yToPrice: () => 0,
|
|
577
|
+
getPaneInfo: () => undefined,
|
|
578
|
+
}
|
|
579
|
+
const session = new DrawingInteractionController(adapter)
|
|
580
|
+
chart.registerDrawingSession(session)
|
|
581
|
+
chart.setSelectedDrawingId('d1')
|
|
582
|
+
chart.removeDrawing('d1')
|
|
583
|
+
expect(chart.kernel.drawing.readonly.drawings.peek().map((d) => d.id)).toEqual(['d2'])
|
|
584
|
+
expect(chart.kernel.drawing.readonly.selectedDrawingId.peek()).toBeNull()
|
|
585
|
+
chart.registerDrawingSession(null)
|
|
586
|
+
await chart.destroy()
|
|
587
|
+
})
|
|
524
588
|
it('setDrawingTool writes DrawingToolId to kernel', async () => {
|
|
525
589
|
const chart = new Chart(createDom(1000, 600), defaultOptions)
|
|
526
590
|
expect(chart.kernel.drawing.readonly.drawingTool.peek()).toBe('cursor')
|
|
@@ -3,7 +3,6 @@ import { describe, expect, it } from 'vitest'
|
|
|
3
3
|
|
|
4
4
|
import { Pane } from '@/core/layout/pane'
|
|
5
5
|
import { PaneRenderer } from '@/core/paneRenderer'
|
|
6
|
-
import { SharedWebGLSurface } from '@/core/renderers/webgl/sharedWebGLSurface'
|
|
7
6
|
|
|
8
7
|
describe('PaneRenderer resize DPR mapping', () => {
|
|
9
8
|
it('maps logical plot size to physical canvas size and keeps CSS size logical', () => {
|
|
@@ -11,7 +10,6 @@ describe('PaneRenderer resize DPR mapping', () => {
|
|
|
11
10
|
const overlayCanvas = document.createElement('canvas')
|
|
12
11
|
const yAxisCanvas = document.createElement('canvas')
|
|
13
12
|
const pane = new Pane('main')
|
|
14
|
-
const sharedWebGLSurface = new SharedWebGLSurface()
|
|
15
13
|
const renderer = new PaneRenderer(
|
|
16
14
|
{ mainCanvas, overlayCanvas, yAxisCanvas },
|
|
17
15
|
pane,
|
|
@@ -21,7 +19,6 @@ describe('PaneRenderer resize DPR mapping', () => {
|
|
|
21
19
|
yPaddingPx: 0,
|
|
22
20
|
priceLabelWidth: 60,
|
|
23
21
|
},
|
|
24
|
-
sharedWebGLSurface,
|
|
25
22
|
)
|
|
26
23
|
|
|
27
24
|
renderer.resize(500, 240, 2)
|
|
@@ -40,7 +37,6 @@ describe('PaneRenderer resize DPR mapping', () => {
|
|
|
40
37
|
const overlayCanvas = document.createElement('canvas')
|
|
41
38
|
const yAxisCanvas = document.createElement('canvas')
|
|
42
39
|
const pane = new Pane('main')
|
|
43
|
-
const sharedWebGLSurface = new SharedWebGLSurface()
|
|
44
40
|
const renderer = new PaneRenderer(
|
|
45
41
|
{ mainCanvas, overlayCanvas, yAxisCanvas },
|
|
46
42
|
pane,
|
|
@@ -50,7 +46,6 @@ describe('PaneRenderer resize DPR mapping', () => {
|
|
|
50
46
|
yPaddingPx: 0,
|
|
51
47
|
priceLabelWidth: 70,
|
|
52
48
|
},
|
|
53
|
-
sharedWebGLSurface,
|
|
54
49
|
)
|
|
55
50
|
|
|
56
51
|
renderer.resize(500, 200, 1.5)
|
|
@@ -74,7 +69,6 @@ describe('PaneRenderer resize DPR mapping', () => {
|
|
|
74
69
|
host.appendChild(yAxisCanvas)
|
|
75
70
|
|
|
76
71
|
const pane = new Pane('main')
|
|
77
|
-
const sharedWebGLSurface = new SharedWebGLSurface()
|
|
78
72
|
const renderer = new PaneRenderer(
|
|
79
73
|
{ mainCanvas, overlayCanvas, yAxisCanvas },
|
|
80
74
|
pane,
|
|
@@ -84,7 +78,6 @@ describe('PaneRenderer resize DPR mapping', () => {
|
|
|
84
78
|
yPaddingPx: 0,
|
|
85
79
|
priceLabelWidth: 70,
|
|
86
80
|
},
|
|
87
|
-
sharedWebGLSurface,
|
|
88
81
|
)
|
|
89
82
|
|
|
90
83
|
renderer.resize(500, 200, 1.5)
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
|
2
|
+
|
|
3
|
+
import { createScene } from '../../rendering/scene/createScene'
|
|
4
|
+
import { createLayerFromPlugin } from '../../rendering/scene/createLayerFromPlugin'
|
|
5
|
+
import { RendererPluginManager } from '../../foundation/plugin/rendererPluginManager'
|
|
6
|
+
import type { RendererPlugin, RenderContext } from '../../foundation/plugin/index'
|
|
7
|
+
import { RENDERER_PRIORITY } from '../../foundation/plugin/index'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Phase 0 契约:绘制只走 Scene;Manager 仅注册表;
|
|
11
|
+
* useRenderer 桥 = register + addLayer;setRendererEnabled 驱动 Layer 显隐。
|
|
12
|
+
*/
|
|
13
|
+
describe('render single-path (Phase 0)', () => {
|
|
14
|
+
let scene: ReturnType<typeof createScene>
|
|
15
|
+
let manager: RendererPluginManager
|
|
16
|
+
let consoleError: ReturnType<typeof vi.spyOn>
|
|
17
|
+
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
scene = createScene()
|
|
20
|
+
manager = new RendererPluginManager()
|
|
21
|
+
consoleError = vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
scene.dispose()
|
|
26
|
+
manager.clear()
|
|
27
|
+
consoleError.mockRestore()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
function makePlugin(name: string, draw = vi.fn()): RendererPlugin {
|
|
31
|
+
return {
|
|
32
|
+
name,
|
|
33
|
+
paneId: 'main',
|
|
34
|
+
priority: RENDERER_PRIORITY.MAIN,
|
|
35
|
+
enabled: true,
|
|
36
|
+
draw,
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function paintMain() {
|
|
41
|
+
scene.paintPane({
|
|
42
|
+
renderer: {} as never,
|
|
43
|
+
region: { x: 0, y: 0, width: 100, height: 100, dpr: 1 },
|
|
44
|
+
paneRole: 'main',
|
|
45
|
+
paneId: 'main',
|
|
46
|
+
frameNumber: 1,
|
|
47
|
+
deltaMs: 0,
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
it('bridge: register + createLayerFromPlugin paints via scene only', () => {
|
|
52
|
+
const draw = vi.fn()
|
|
53
|
+
const plugin = makePlugin('bridge-a', draw)
|
|
54
|
+
const ctx = { theme: 'dark' } as unknown as RenderContext
|
|
55
|
+
manager.register(plugin)
|
|
56
|
+
scene.addLayer(createLayerFromPlugin(plugin, () => ctx, 'main'))
|
|
57
|
+
|
|
58
|
+
paintMain()
|
|
59
|
+
expect(draw).toHaveBeenCalledOnce()
|
|
60
|
+
expect(draw).toHaveBeenCalledWith(ctx)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('setLayerVisibility false skips paint (timeshare candle path)', () => {
|
|
64
|
+
const draw = vi.fn()
|
|
65
|
+
const plugin = makePlugin('candle', draw)
|
|
66
|
+
scene.addLayer(createLayerFromPlugin(plugin, () => ({}) as RenderContext, 'main'))
|
|
67
|
+
|
|
68
|
+
expect(scene.setLayerVisibility('plugin:candle', false)).toBe(true)
|
|
69
|
+
paintMain()
|
|
70
|
+
expect(draw).not.toHaveBeenCalled()
|
|
71
|
+
|
|
72
|
+
scene.setLayerVisibility('plugin:candle', true)
|
|
73
|
+
paintMain()
|
|
74
|
+
expect(draw).toHaveBeenCalledOnce()
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
it('remove path: Manager.unregister owns onUninstall; removeLayer does not dispose-call it', () => {
|
|
78
|
+
const onUninstall = vi.fn()
|
|
79
|
+
const plugin = makePlugin('to-remove', vi.fn())
|
|
80
|
+
plugin.onUninstall = onUninstall
|
|
81
|
+
manager.register(plugin)
|
|
82
|
+
scene.addLayer(createLayerFromPlugin(plugin, () => null, 'main'))
|
|
83
|
+
|
|
84
|
+
manager.unregister('to-remove')
|
|
85
|
+
expect(onUninstall).toHaveBeenCalledOnce()
|
|
86
|
+
|
|
87
|
+
scene.removeLayer('plugin:to-remove')
|
|
88
|
+
// layer.dispose empty — no second onUninstall
|
|
89
|
+
expect(onUninstall).toHaveBeenCalledOnce()
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('one layer throw does not abort sibling layers', () => {
|
|
93
|
+
const ok = vi.fn()
|
|
94
|
+
const boom = vi.fn(() => {
|
|
95
|
+
throw new Error('boom')
|
|
96
|
+
})
|
|
97
|
+
scene.addLayer(
|
|
98
|
+
createLayerFromPlugin(makePlugin('boom', boom), () => ({}) as RenderContext, 'main'),
|
|
99
|
+
)
|
|
100
|
+
scene.addLayer(
|
|
101
|
+
createLayerFromPlugin(makePlugin('ok', ok), () => ({}) as RenderContext, 'main'),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
expect(() => paintMain()).not.toThrow()
|
|
105
|
+
expect(boom).toHaveBeenCalledOnce()
|
|
106
|
+
expect(ok).toHaveBeenCalledOnce()
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('Scene paints without Manager draw API (single path)', () => {
|
|
110
|
+
const draw = vi.fn()
|
|
111
|
+
const plugin = makePlugin('only-scene', draw)
|
|
112
|
+
manager.register(plugin)
|
|
113
|
+
manager.setEnabled(plugin.name, false)
|
|
114
|
+
scene.addLayer(createLayerFromPlugin(plugin, () => ({}) as RenderContext, 'main'))
|
|
115
|
+
|
|
116
|
+
// Manager 无 render 入口;Scene 仍画
|
|
117
|
+
expect(typeof (manager as { render?: unknown }).render).toBe('undefined')
|
|
118
|
+
paintMain()
|
|
119
|
+
expect(draw).toHaveBeenCalledOnce()
|
|
120
|
+
})
|
|
121
|
+
})
|