@forgecharts/sdk 1.1.27 → 1.1.28
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/__tests__/backwardCompatibility.test.d.ts +14 -0
- package/dist/__tests__/backwardCompatibility.test.d.ts.map +1 -0
- package/dist/__tests__/backwardCompatibility.test.js +159 -0
- package/dist/__tests__/backwardCompatibility.test.js.map +1 -0
- package/dist/__tests__/candleInvariant.test.d.ts +20 -0
- package/dist/__tests__/candleInvariant.test.d.ts.map +1 -0
- package/dist/__tests__/candleInvariant.test.js +415 -0
- package/dist/__tests__/candleInvariant.test.js.map +1 -0
- package/dist/__tests__/public-api-surface.d.ts +13 -0
- package/dist/__tests__/public-api-surface.d.ts.map +1 -0
- package/{src/__tests__/public-api-surface.ts → dist/__tests__/public-api-surface.js} +4 -42
- package/dist/__tests__/public-api-surface.js.map +1 -0
- package/dist/__tests__/timeframeBoundary.test.d.ts +17 -0
- package/dist/__tests__/timeframeBoundary.test.d.ts.map +1 -0
- package/dist/__tests__/timeframeBoundary.test.js +452 -0
- package/dist/__tests__/timeframeBoundary.test.js.map +1 -0
- package/dist/api/DrawingManager.d.ts +20 -0
- package/dist/api/DrawingManager.d.ts.map +1 -0
- package/dist/api/DrawingManager.js +190 -0
- package/dist/api/DrawingManager.js.map +1 -0
- package/dist/api/EventBus.d.ts +19 -0
- package/dist/api/EventBus.d.ts.map +1 -0
- package/dist/api/EventBus.js +44 -0
- package/dist/api/EventBus.js.map +1 -0
- package/dist/api/IndicatorDAG.d.ts +85 -0
- package/dist/api/IndicatorDAG.d.ts.map +1 -0
- package/dist/api/IndicatorDAG.js +316 -0
- package/dist/api/IndicatorDAG.js.map +1 -0
- package/dist/api/IndicatorRegistry.d.ts +22 -0
- package/dist/api/IndicatorRegistry.d.ts.map +1 -0
- package/dist/api/IndicatorRegistry.js +39 -0
- package/dist/api/IndicatorRegistry.js.map +1 -0
- package/dist/api/LayoutManager.d.ts +30 -0
- package/dist/api/LayoutManager.d.ts.map +1 -0
- package/dist/api/LayoutManager.js +51 -0
- package/dist/api/LayoutManager.js.map +1 -0
- package/dist/api/PaneManager.d.ts +42 -0
- package/dist/api/PaneManager.d.ts.map +1 -0
- package/dist/api/PaneManager.js +119 -0
- package/dist/api/PaneManager.js.map +1 -0
- package/dist/api/ReferenceAPI.d.ts +78 -0
- package/dist/api/ReferenceAPI.d.ts.map +1 -0
- package/dist/api/ReferenceAPI.js +153 -0
- package/dist/api/ReferenceAPI.js.map +1 -0
- package/dist/api/TChart.d.ts +345 -0
- package/dist/api/TChart.d.ts.map +1 -0
- package/dist/api/TChart.js +765 -0
- package/dist/api/TChart.js.map +1 -0
- package/{src/api/createChart.ts → dist/api/createChart.d.ts} +2 -7
- package/dist/api/createChart.d.ts.map +1 -0
- package/dist/api/createChart.js +42 -0
- package/dist/api/createChart.js.map +1 -0
- package/dist/api/drawing tools/fib gann menu/fibRetracement.d.ts +4 -0
- package/dist/api/drawing tools/fib gann menu/fibRetracement.d.ts.map +1 -0
- package/dist/api/drawing tools/fib gann menu/fibRetracement.js +22 -0
- package/dist/api/drawing tools/fib gann menu/fibRetracement.js.map +1 -0
- package/dist/api/drawing tools/lines menu/crossLine.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/crossLine.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/crossLine.js +16 -0
- package/dist/api/drawing tools/lines menu/crossLine.js.map +1 -0
- package/dist/api/drawing tools/lines menu/disjointChannel.d.ts +17 -0
- package/dist/api/drawing tools/lines menu/disjointChannel.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/disjointChannel.js +59 -0
- package/dist/api/drawing tools/lines menu/disjointChannel.js.map +1 -0
- package/dist/api/drawing tools/lines menu/extendedLine.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/extendedLine.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/extendedLine.js +17 -0
- package/dist/api/drawing tools/lines menu/extendedLine.js.map +1 -0
- package/dist/api/drawing tools/lines menu/flatTopBottom.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/flatTopBottom.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/flatTopBottom.js +41 -0
- package/dist/api/drawing tools/lines menu/flatTopBottom.js.map +1 -0
- package/dist/api/drawing tools/lines menu/horizontal.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/horizontal.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/horizontal.js +19 -0
- package/dist/api/drawing tools/lines menu/horizontal.js.map +1 -0
- package/dist/api/drawing tools/lines menu/horizontalRay.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/horizontalRay.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/horizontalRay.js +20 -0
- package/dist/api/drawing tools/lines menu/horizontalRay.js.map +1 -0
- package/dist/api/drawing tools/lines menu/infoLine.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/infoLine.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/infoLine.js +107 -0
- package/dist/api/drawing tools/lines menu/infoLine.js.map +1 -0
- package/dist/api/drawing tools/lines menu/insidePitchfork.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/insidePitchfork.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/insidePitchfork.js +31 -0
- package/dist/api/drawing tools/lines menu/insidePitchfork.js.map +1 -0
- package/dist/api/drawing tools/lines menu/modifiedSchiffPitchfork.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/modifiedSchiffPitchfork.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/modifiedSchiffPitchfork.js +15 -0
- package/dist/api/drawing tools/lines menu/modifiedSchiffPitchfork.js.map +1 -0
- package/dist/api/drawing tools/lines menu/parallelChannel.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/parallelChannel.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/parallelChannel.js +43 -0
- package/dist/api/drawing tools/lines menu/parallelChannel.js.map +1 -0
- package/dist/api/drawing tools/lines menu/pitchfork.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/pitchfork.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/pitchfork.js +12 -0
- package/dist/api/drawing tools/lines menu/pitchfork.js.map +1 -0
- package/dist/api/drawing tools/lines menu/ray.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/ray.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/ray.js +23 -0
- package/dist/api/drawing tools/lines menu/ray.js.map +1 -0
- package/dist/api/drawing tools/lines menu/regressionTrend.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/regressionTrend.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/regressionTrend.js +127 -0
- package/dist/api/drawing tools/lines menu/regressionTrend.js.map +1 -0
- package/dist/api/drawing tools/lines menu/schiffPitchfork.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/schiffPitchfork.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/schiffPitchfork.js +15 -0
- package/dist/api/drawing tools/lines menu/schiffPitchfork.js.map +1 -0
- package/dist/api/drawing tools/lines menu/trendAngle.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/trendAngle.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/trendAngle.js +51 -0
- package/dist/api/drawing tools/lines menu/trendAngle.js.map +1 -0
- package/dist/api/drawing tools/lines menu/trendline.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/trendline.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/trendline.js +11 -0
- package/dist/api/drawing tools/lines menu/trendline.js.map +1 -0
- package/dist/api/drawing tools/lines menu/vertical.d.ts +4 -0
- package/dist/api/drawing tools/lines menu/vertical.d.ts.map +1 -0
- package/dist/api/drawing tools/lines menu/vertical.js +11 -0
- package/dist/api/drawing tools/lines menu/vertical.js.map +1 -0
- package/dist/api/drawing tools/pointers menu/crosshair.d.ts +16 -0
- package/dist/api/drawing tools/pointers menu/crosshair.d.ts.map +1 -0
- package/{src/api/drawing tools/pointers menu/crosshair.ts → dist/api/drawing tools/pointers menu/crosshair.js } +6 -7
- package/dist/api/drawing tools/pointers menu/crosshair.js.map +1 -0
- package/dist/api/drawing tools/pointers menu/cursor.d.ts +15 -0
- package/dist/api/drawing tools/pointers menu/cursor.d.ts.map +1 -0
- package/{src/api/drawing tools/pointers menu/cursor.ts → dist/api/drawing tools/pointers menu/cursor.js } +7 -8
- package/dist/api/drawing tools/pointers menu/cursor.js.map +1 -0
- package/dist/api/drawing tools/pointers menu/demonstration.d.ts +30 -0
- package/dist/api/drawing tools/pointers menu/demonstration.d.ts.map +1 -0
- package/{src/api/drawing tools/pointers menu/demonstration.ts → dist/api/drawing tools/pointers menu/demonstration.js } +9 -14
- package/dist/api/drawing tools/pointers menu/demonstration.js.map +1 -0
- package/dist/api/drawing tools/pointers menu/dot.d.ts +23 -0
- package/dist/api/drawing tools/pointers menu/dot.d.ts.map +1 -0
- package/{src/api/drawing tools/pointers menu/dot.ts → dist/api/drawing tools/pointers menu/dot.js } +8 -11
- package/dist/api/drawing tools/pointers menu/dot.js.map +1 -0
- package/dist/api/drawing tools/shapes menu/rectangle.d.ts +4 -0
- package/dist/api/drawing tools/shapes menu/rectangle.d.ts.map +1 -0
- package/dist/api/drawing tools/shapes menu/rectangle.js +19 -0
- package/dist/api/drawing tools/shapes menu/rectangle.js.map +1 -0
- package/dist/api/drawing tools/shapes menu/text.d.ts +4 -0
- package/dist/api/drawing tools/shapes menu/text.d.ts.map +1 -0
- package/dist/api/drawing tools/shapes menu/text.js +25 -0
- package/dist/api/drawing tools/shapes menu/text.js.map +1 -0
- package/dist/api/drawingUtils.d.ts +22 -0
- package/dist/api/drawingUtils.d.ts.map +1 -0
- package/dist/api/drawingUtils.js +83 -0
- package/dist/api/drawingUtils.js.map +1 -0
- package/dist/core/CanvasLayer.d.ts +26 -0
- package/dist/core/CanvasLayer.d.ts.map +1 -0
- package/dist/core/CanvasLayer.js +56 -0
- package/dist/core/CanvasLayer.js.map +1 -0
- package/dist/core/Chart.d.ts +164 -0
- package/dist/core/Chart.d.ts.map +1 -0
- package/dist/core/Chart.js +839 -0
- package/dist/core/Chart.js.map +1 -0
- package/dist/core/CoordTransform.d.ts +168 -0
- package/dist/core/CoordTransform.d.ts.map +1 -0
- package/dist/core/CoordTransform.js +224 -0
- package/dist/core/CoordTransform.js.map +1 -0
- package/dist/core/Crosshair.d.ts +30 -0
- package/dist/core/Crosshair.d.ts.map +1 -0
- package/dist/core/Crosshair.js +186 -0
- package/dist/core/Crosshair.js.map +1 -0
- package/dist/core/IndicatorEngine.d.ts +51 -0
- package/dist/core/IndicatorEngine.d.ts.map +1 -0
- package/dist/core/IndicatorEngine.js +181 -0
- package/dist/core/IndicatorEngine.js.map +1 -0
- package/dist/core/InteractionManager.d.ts +197 -0
- package/dist/core/InteractionManager.d.ts.map +1 -0
- package/dist/core/InteractionManager.js +698 -0
- package/dist/core/InteractionManager.js.map +1 -0
- package/dist/core/PriceScale.d.ts +27 -0
- package/dist/core/PriceScale.d.ts.map +1 -0
- package/dist/core/PriceScale.js +113 -0
- package/dist/core/PriceScale.js.map +1 -0
- package/dist/core/Series.d.ts +40 -0
- package/dist/core/Series.d.ts.map +1 -0
- package/dist/core/Series.js +114 -0
- package/dist/core/Series.js.map +1 -0
- package/dist/core/TimeScale.d.ts +43 -0
- package/dist/core/TimeScale.d.ts.map +1 -0
- package/dist/core/TimeScale.js +150 -0
- package/dist/core/TimeScale.js.map +1 -0
- package/dist/datafeed/DatafeedConnector.d.ts +89 -0
- package/dist/datafeed/DatafeedConnector.d.ts.map +1 -0
- package/dist/datafeed/DatafeedConnector.js +268 -0
- package/dist/datafeed/DatafeedConnector.js.map +1 -0
- package/dist/engine/CandleEngine.d.ts +207 -0
- package/dist/engine/CandleEngine.d.ts.map +1 -0
- package/dist/engine/CandleEngine.js +318 -0
- package/dist/engine/CandleEngine.js.map +1 -0
- package/dist/engine/__tests__/CandleEngine.test.d.ts +2 -0
- package/dist/engine/__tests__/CandleEngine.test.d.ts.map +1 -0
- package/dist/engine/__tests__/CandleEngine.test.js +300 -0
- package/dist/engine/__tests__/CandleEngine.test.js.map +1 -0
- package/dist/engine/candleInvariants.d.ts +66 -0
- package/dist/engine/candleInvariants.d.ts.map +1 -0
- package/dist/engine/candleInvariants.js +134 -0
- package/dist/engine/candleInvariants.js.map +1 -0
- package/{src/engine/mergeUtils.ts → dist/engine/mergeUtils.d.ts} +15 -52
- package/dist/engine/mergeUtils.d.ts.map +1 -0
- package/dist/engine/mergeUtils.js +64 -0
- package/dist/engine/mergeUtils.js.map +1 -0
- package/dist/engine/timeframeUtils.d.ts +80 -0
- package/dist/engine/timeframeUtils.d.ts.map +1 -0
- package/{src/engine/timeframeUtils.ts → dist/engine/timeframeUtils.js} +30 -48
- package/dist/engine/timeframeUtils.js.map +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +29 -0
- package/dist/internal.d.ts.map +1 -0
- package/{src/internal.ts → dist/internal.js} +1 -10
- package/dist/internal.js.map +1 -0
- package/dist/licensing/ChartRuntimeResolver.d.ts +233 -0
- package/dist/licensing/ChartRuntimeResolver.d.ts.map +1 -0
- package/dist/licensing/ChartRuntimeResolver.js +310 -0
- package/dist/licensing/ChartRuntimeResolver.js.map +1 -0
- package/dist/licensing/LicenseManager.d.ts +55 -0
- package/dist/licensing/LicenseManager.d.ts.map +1 -0
- package/dist/licensing/LicenseManager.js +114 -0
- package/dist/licensing/LicenseManager.js.map +1 -0
- package/dist/licensing/__tests__/ChartRuntimeResolver.test.d.ts +13 -0
- package/dist/licensing/__tests__/ChartRuntimeResolver.test.d.ts.map +1 -0
- package/dist/licensing/__tests__/ChartRuntimeResolver.test.js +177 -0
- package/dist/licensing/__tests__/ChartRuntimeResolver.test.js.map +1 -0
- package/dist/licensing/__tests__/LicenseManager.test.d.ts +12 -0
- package/dist/licensing/__tests__/LicenseManager.test.d.ts.map +1 -0
- package/dist/licensing/__tests__/LicenseManager.test.js +153 -0
- package/dist/licensing/__tests__/LicenseManager.test.js.map +1 -0
- package/dist/licensing/licenseTypes.d.ts +18 -0
- package/dist/licensing/licenseTypes.d.ts.map +1 -0
- package/dist/licensing/licenseTypes.js +2 -0
- package/dist/licensing/licenseTypes.js.map +1 -0
- package/dist/pine/PineCompiler.d.ts +35 -0
- package/dist/pine/PineCompiler.d.ts.map +1 -0
- package/dist/pine/PineCompiler.js +44 -0
- package/dist/pine/PineCompiler.js.map +1 -0
- package/dist/pine/diagnostics.d.ts +20 -0
- package/dist/pine/diagnostics.d.ts.map +1 -0
- package/dist/pine/diagnostics.js +11 -0
- package/dist/pine/diagnostics.js.map +1 -0
- package/{src/pine/index.ts → dist/pine/index.d.ts} +4 -3
- package/dist/pine/index.d.ts.map +1 -0
- package/dist/pine/index.js +5 -0
- package/dist/pine/index.js.map +1 -0
- package/dist/pine/pine-ast.d.ts +142 -0
- package/dist/pine/pine-ast.d.ts.map +1 -0
- package/dist/pine/pine-ast.js +19 -0
- package/dist/pine/pine-ast.js.map +1 -0
- package/dist/pine/pine-lexer.d.ts +41 -0
- package/dist/pine/pine-lexer.d.ts.map +1 -0
- package/dist/pine/pine-lexer.js +249 -0
- package/dist/pine/pine-lexer.js.map +1 -0
- package/dist/pine/pine-parser.d.ts +51 -0
- package/dist/pine/pine-parser.d.ts.map +1 -0
- package/dist/pine/pine-parser.js +416 -0
- package/dist/pine/pine-parser.js.map +1 -0
- package/dist/pine/pine-transpiler.d.ts +33 -0
- package/dist/pine/pine-transpiler.d.ts.map +1 -0
- package/dist/pine/pine-transpiler.js +260 -0
- package/dist/pine/pine-transpiler.js.map +1 -0
- package/dist/pixi/LayerName.d.ts +18 -0
- package/dist/pixi/LayerName.d.ts.map +1 -0
- package/dist/pixi/LayerName.js +35 -0
- package/dist/pixi/LayerName.js.map +1 -0
- package/dist/pixi/PixiCandlestickRenderer.d.ts +23 -0
- package/dist/pixi/PixiCandlestickRenderer.d.ts.map +1 -0
- package/dist/pixi/PixiCandlestickRenderer.js +107 -0
- package/dist/pixi/PixiCandlestickRenderer.js.map +1 -0
- package/dist/pixi/PixiChart.d.ts +72 -0
- package/dist/pixi/PixiChart.d.ts.map +1 -0
- package/dist/pixi/PixiChart.js +367 -0
- package/dist/pixi/PixiChart.js.map +1 -0
- package/dist/pixi/PixiCrosshairRenderer.d.ts +29 -0
- package/dist/pixi/PixiCrosshairRenderer.d.ts.map +1 -0
- package/dist/pixi/PixiCrosshairRenderer.js +110 -0
- package/dist/pixi/PixiCrosshairRenderer.js.map +1 -0
- package/dist/pixi/PixiDrawingRenderer.d.ts +17 -0
- package/dist/pixi/PixiDrawingRenderer.d.ts.map +1 -0
- package/dist/pixi/PixiDrawingRenderer.js +111 -0
- package/dist/pixi/PixiDrawingRenderer.js.map +1 -0
- package/dist/pixi/PixiGridRenderer.d.ts +22 -0
- package/dist/pixi/PixiGridRenderer.d.ts.map +1 -0
- package/dist/pixi/PixiGridRenderer.js +114 -0
- package/dist/pixi/PixiGridRenderer.js.map +1 -0
- package/dist/pixi/PixiLayerManager.d.ts +56 -0
- package/dist/pixi/PixiLayerManager.d.ts.map +1 -0
- package/dist/pixi/PixiLayerManager.js +92 -0
- package/dist/pixi/PixiLayerManager.js.map +1 -0
- package/dist/react/canvas/ChartCanvas.d.ts +85 -0
- package/dist/react/canvas/ChartCanvas.d.ts.map +1 -0
- package/dist/react/canvas/ChartCanvas.js +604 -0
- package/dist/react/canvas/ChartCanvas.js.map +1 -0
- package/dist/react/canvas/ChartContextMenu.d.ts +18 -0
- package/dist/react/canvas/ChartContextMenu.d.ts.map +1 -0
- package/dist/react/canvas/ChartContextMenu.js +5 -0
- package/dist/react/canvas/ChartContextMenu.js.map +1 -0
- package/dist/react/canvas/ChartSettingsDialog.d.ts +25 -0
- package/dist/react/canvas/ChartSettingsDialog.d.ts.map +1 -0
- package/dist/react/canvas/ChartSettingsDialog.js +28 -0
- package/dist/react/canvas/ChartSettingsDialog.js.map +1 -0
- package/dist/react/canvas/IndicatorLabel.d.ts +21 -0
- package/dist/react/canvas/IndicatorLabel.d.ts.map +1 -0
- package/dist/react/canvas/IndicatorLabel.js +196 -0
- package/dist/react/canvas/IndicatorLabel.js.map +1 -0
- package/dist/react/canvas/IndicatorPane.d.ts +32 -0
- package/dist/react/canvas/IndicatorPane.d.ts.map +1 -0
- package/dist/react/canvas/IndicatorPane.js +395 -0
- package/dist/react/canvas/IndicatorPane.js.map +1 -0
- package/dist/react/canvas/PointerOverlay.d.ts +23 -0
- package/dist/react/canvas/PointerOverlay.d.ts.map +1 -0
- package/dist/react/canvas/PointerOverlay.js +61 -0
- package/dist/react/canvas/PointerOverlay.js.map +1 -0
- package/dist/react/canvas/toolbars/LeftToolbar.d.ts +19 -0
- package/dist/react/canvas/toolbars/LeftToolbar.d.ts.map +1 -0
- package/dist/react/canvas/toolbars/LeftToolbar.js +407 -0
- package/dist/react/canvas/toolbars/LeftToolbar.js.map +1 -0
- package/dist/react/hooks/useChartCapabilities.d.ts +21 -0
- package/dist/react/hooks/useChartCapabilities.d.ts.map +1 -0
- package/dist/react/hooks/useChartCapabilities.js +66 -0
- package/dist/react/hooks/useChartCapabilities.js.map +1 -0
- package/dist/react/index.d.ts +30 -0
- package/dist/react/index.d.ts.map +1 -0
- package/{src/react/index.ts → dist/react/index.js} +1 -24
- package/dist/react/index.js.map +1 -0
- package/dist/react/internal.d.ts +38 -0
- package/dist/react/internal.d.ts.map +1 -0
- package/{src/react/internal.ts → dist/react/internal.js} +1 -19
- package/dist/react/internal.js.map +1 -0
- package/dist/react/shell/ManagedAppShell.d.ts +91 -0
- package/dist/react/shell/ManagedAppShell.d.ts.map +1 -0
- package/dist/react/shell/ManagedAppShell.js +440 -0
- package/dist/react/shell/ManagedAppShell.js.map +1 -0
- package/dist/react/trading/TradingBridge.d.ts +86 -0
- package/dist/react/trading/TradingBridge.d.ts.map +1 -0
- package/dist/react/trading/TradingBridge.js +73 -0
- package/dist/react/trading/TradingBridge.js.map +1 -0
- package/dist/react/workspace/ChartWorkspace.d.ts +73 -0
- package/dist/react/workspace/ChartWorkspace.d.ts.map +1 -0
- package/dist/react/workspace/ChartWorkspace.js +42 -0
- package/dist/react/workspace/ChartWorkspace.js.map +1 -0
- package/dist/react/workspace/FloatingPanel.d.ts +18 -0
- package/dist/react/workspace/FloatingPanel.d.ts.map +1 -0
- package/dist/react/workspace/FloatingPanel.js +82 -0
- package/dist/react/workspace/FloatingPanel.js.map +1 -0
- package/dist/react/workspace/IndicatorsDialog.d.ts +8 -0
- package/dist/react/workspace/IndicatorsDialog.d.ts.map +1 -0
- package/dist/react/workspace/IndicatorsDialog.js +121 -0
- package/dist/react/workspace/IndicatorsDialog.js.map +1 -0
- package/dist/react/workspace/LayoutMenu.d.ts +33 -0
- package/dist/react/workspace/LayoutMenu.d.ts.map +1 -0
- package/dist/react/workspace/LayoutMenu.js +113 -0
- package/dist/react/workspace/LayoutMenu.js.map +1 -0
- package/dist/react/workspace/SymbolSearchDialog.d.ts +10 -0
- package/dist/react/workspace/SymbolSearchDialog.d.ts.map +1 -0
- package/dist/react/workspace/SymbolSearchDialog.js +245 -0
- package/dist/react/workspace/SymbolSearchDialog.js.map +1 -0
- package/dist/react/workspace/TabBar.d.ts +17 -0
- package/dist/react/workspace/TabBar.d.ts.map +1 -0
- package/dist/react/workspace/TabBar.js +29 -0
- package/dist/react/workspace/TabBar.js.map +1 -0
- package/dist/react/workspace/toolbars/BottomToolbar.d.ts +19 -0
- package/dist/react/workspace/toolbars/BottomToolbar.d.ts.map +1 -0
- package/dist/react/workspace/toolbars/BottomToolbar.js +236 -0
- package/dist/react/workspace/toolbars/BottomToolbar.js.map +1 -0
- package/dist/react/workspace/toolbars/RightToolbar.d.ts +8 -0
- package/dist/react/workspace/toolbars/RightToolbar.d.ts.map +1 -0
- package/dist/react/workspace/toolbars/RightToolbar.js +18 -0
- package/dist/react/workspace/toolbars/RightToolbar.js.map +1 -0
- package/dist/react/workspace/toolbars/TopToolbar.d.ts +41 -0
- package/dist/react/workspace/toolbars/TopToolbar.d.ts.map +1 -0
- package/dist/react/workspace/toolbars/TopToolbar.js +82 -0
- package/dist/react/workspace/toolbars/TopToolbar.js.map +1 -0
- package/dist/renderers/CandlestickRenderer.d.ts +13 -0
- package/dist/renderers/CandlestickRenderer.d.ts.map +1 -0
- package/dist/renderers/CandlestickRenderer.js +98 -0
- package/dist/renderers/CandlestickRenderer.js.map +1 -0
- package/dist/renderers/HistogramRenderer.d.ts +11 -0
- package/dist/renderers/HistogramRenderer.d.ts.map +1 -0
- package/dist/renderers/HistogramRenderer.js +50 -0
- package/dist/renderers/HistogramRenderer.js.map +1 -0
- package/dist/renderers/LineRenderer.d.ts +12 -0
- package/dist/renderers/LineRenderer.d.ts.map +1 -0
- package/dist/renderers/LineRenderer.js +64 -0
- package/dist/renderers/LineRenderer.js.map +1 -0
- package/dist/theme/colors.d.ts +4 -0
- package/dist/theme/colors.d.ts.map +1 -0
- package/dist/theme/colors.js +19 -0
- package/dist/theme/colors.js.map +1 -0
- package/dist/tools/barDivergenceCheck.d.ts +120 -0
- package/dist/tools/barDivergenceCheck.d.ts.map +1 -0
- package/dist/tools/barDivergenceCheck.js +200 -0
- package/dist/tools/barDivergenceCheck.js.map +1 -0
- package/dist/trading/TradingOverlayStore.d.ts +86 -0
- package/dist/trading/TradingOverlayStore.d.ts.map +1 -0
- package/dist/trading/TradingOverlayStore.js +139 -0
- package/dist/trading/TradingOverlayStore.js.map +1 -0
- package/dist/trading/UnmanagedIngestion.d.ts +91 -0
- package/dist/trading/UnmanagedIngestion.d.ts.map +1 -0
- package/dist/trading/UnmanagedIngestion.js +114 -0
- package/dist/trading/UnmanagedIngestion.js.map +1 -0
- package/dist/trading/__tests__/ManagedTradingController.test.d.ts +18 -0
- package/dist/trading/__tests__/ManagedTradingController.test.d.ts.map +1 -0
- package/dist/trading/__tests__/ManagedTradingController.test.js +271 -0
- package/dist/trading/__tests__/ManagedTradingController.test.js.map +1 -0
- package/dist/trading/__tests__/TradingOverlayStore.test.d.ts +16 -0
- package/dist/trading/__tests__/TradingOverlayStore.test.d.ts.map +1 -0
- package/dist/trading/__tests__/TradingOverlayStore.test.js +267 -0
- package/dist/trading/__tests__/TradingOverlayStore.test.js.map +1 -0
- package/dist/trading/__tests__/UnmanagedIngestion.test.d.ts +16 -0
- package/dist/trading/__tests__/UnmanagedIngestion.test.d.ts.map +1 -0
- package/dist/trading/__tests__/UnmanagedIngestion.test.js +170 -0
- package/dist/trading/__tests__/UnmanagedIngestion.test.js.map +1 -0
- package/dist/trading/managed/ManagedTradingController.d.ts +110 -0
- package/dist/trading/managed/ManagedTradingController.d.ts.map +1 -0
- package/dist/trading/managed/ManagedTradingController.js +247 -0
- package/dist/trading/managed/ManagedTradingController.js.map +1 -0
- package/dist/trading/managed/managedCapabilities.d.ts +45 -0
- package/dist/trading/managed/managedCapabilities.d.ts.map +1 -0
- package/dist/trading/managed/managedCapabilities.js +79 -0
- package/dist/trading/managed/managedCapabilities.js.map +1 -0
- package/dist/trading/managed/managedTypes.d.ts +122 -0
- package/dist/trading/managed/managedTypes.d.ts.map +1 -0
- package/dist/trading/managed/managedTypes.js +13 -0
- package/dist/trading/managed/managedTypes.js.map +1 -0
- package/dist/trading/tradingTypes.d.ts +89 -0
- package/dist/trading/tradingTypes.d.ts.map +1 -0
- package/dist/trading/tradingTypes.js +8 -0
- package/dist/trading/tradingTypes.js.map +1 -0
- package/dist/tscript/TScriptIndicator.d.ts +41 -0
- package/dist/tscript/TScriptIndicator.d.ts.map +1 -0
- package/dist/tscript/TScriptIndicator.js +47 -0
- package/dist/tscript/TScriptIndicator.js.map +1 -0
- package/dist/tscript/ast.d.ts +89 -0
- package/dist/tscript/ast.d.ts.map +1 -0
- package/dist/tscript/ast.js +22 -0
- package/dist/tscript/ast.js.map +1 -0
- package/dist/tscript/lexer.d.ts +36 -0
- package/dist/tscript/lexer.d.ts.map +1 -0
- package/dist/tscript/lexer.js +187 -0
- package/dist/tscript/lexer.js.map +1 -0
- package/dist/tscript/parser.d.ts +50 -0
- package/dist/tscript/parser.d.ts.map +1 -0
- package/dist/tscript/parser.js +318 -0
- package/dist/tscript/parser.js.map +1 -0
- package/dist/tscript/runtime.d.ts +123 -0
- package/dist/tscript/runtime.d.ts.map +1 -0
- package/dist/tscript/runtime.js +475 -0
- package/dist/tscript/runtime.js.map +1 -0
- package/dist/tscript/series.d.ts +49 -0
- package/dist/tscript/series.d.ts.map +1 -0
- package/dist/tscript/series.js +79 -0
- package/dist/tscript/series.js.map +1 -0
- package/dist/types/IChart.d.ts +48 -0
- package/dist/types/IChart.d.ts.map +1 -0
- package/dist/types/IChart.js +2 -0
- package/dist/types/IChart.js.map +1 -0
- package/{src/types/IRenderer.ts → dist/types/IRenderer.d.ts} +2 -8
- package/dist/types/IRenderer.d.ts.map +1 -0
- package/dist/types/IRenderer.js +2 -0
- package/dist/types/IRenderer.js.map +1 -0
- package/dist/types/ISeries.d.ts +26 -0
- package/dist/types/ISeries.d.ts.map +1 -0
- package/dist/types/ISeries.js +2 -0
- package/dist/types/ISeries.js.map +1 -0
- package/package.json +5 -1
- package/src/__tests__/backwardCompatibility.test.ts +0 -191
- package/src/__tests__/candleInvariant.test.ts +0 -500
- package/src/__tests__/timeframeBoundary.test.ts +0 -583
- package/src/api/DrawingManager.ts +0 -188
- package/src/api/EventBus.ts +0 -53
- package/src/api/IndicatorDAG.ts +0 -389
- package/src/api/IndicatorRegistry.ts +0 -47
- package/src/api/LayoutManager.ts +0 -72
- package/src/api/PaneManager.ts +0 -129
- package/src/api/ReferenceAPI.ts +0 -195
- package/src/api/TChart.ts +0 -881
- package/src/api/drawing tools/fib gann menu/fibRetracement.ts +0 -27
- package/src/api/drawing tools/lines menu/crossLine.ts +0 -21
- package/src/api/drawing tools/lines menu/disjointChannel.ts +0 -74
- package/src/api/drawing tools/lines menu/extendedLine.ts +0 -22
- package/src/api/drawing tools/lines menu/flatTopBottom.ts +0 -45
- package/src/api/drawing tools/lines menu/horizontal.ts +0 -24
- package/src/api/drawing tools/lines menu/horizontalRay.ts +0 -25
- package/src/api/drawing tools/lines menu/infoLine.ts +0 -127
- package/src/api/drawing tools/lines menu/insidePitchfork.ts +0 -21
- package/src/api/drawing tools/lines menu/modifiedSchiffPitchfork.ts +0 -18
- package/src/api/drawing tools/lines menu/parallelChannel.ts +0 -47
- package/src/api/drawing tools/lines menu/pitchfork.ts +0 -15
- package/src/api/drawing tools/lines menu/ray.ts +0 -28
- package/src/api/drawing tools/lines menu/regressionTrend.ts +0 -157
- package/src/api/drawing tools/lines menu/schiffPitchfork.ts +0 -18
- package/src/api/drawing tools/lines menu/trendAngle.ts +0 -64
- package/src/api/drawing tools/lines menu/trendline.ts +0 -16
- package/src/api/drawing tools/lines menu/vertical.ts +0 -16
- package/src/api/drawing tools/shapes menu/rectangle.ts +0 -24
- package/src/api/drawing tools/shapes menu/text.ts +0 -30
- package/src/api/drawingUtils.ts +0 -82
- package/src/core/CanvasLayer.ts +0 -77
- package/src/core/Chart.ts +0 -917
- package/src/core/CoordTransform.ts +0 -282
- package/src/core/Crosshair.ts +0 -207
- package/src/core/IndicatorEngine.ts +0 -216
- package/src/core/InteractionManager.ts +0 -899
- package/src/core/PriceScale.ts +0 -133
- package/src/core/Series.ts +0 -132
- package/src/core/TimeScale.ts +0 -175
- package/src/datafeed/DatafeedConnector.ts +0 -300
- package/src/engine/CandleEngine.ts +0 -458
- package/src/engine/__tests__/CandleEngine.test.ts +0 -402
- package/src/engine/candleInvariants.ts +0 -172
- package/src/index.ts +0 -190
- package/src/licensing/ChartRuntimeResolver.ts +0 -380
- package/src/licensing/LicenseManager.ts +0 -131
- package/src/licensing/__tests__/ChartRuntimeResolver.test.ts +0 -207
- package/src/licensing/__tests__/LicenseManager.test.ts +0 -180
- package/src/licensing/licenseTypes.ts +0 -19
- package/src/pine/PineCompiler.ts +0 -68
- package/src/pine/diagnostics.ts +0 -30
- package/src/pine/pine-ast.ts +0 -163
- package/src/pine/pine-lexer.ts +0 -265
- package/src/pine/pine-parser.ts +0 -439
- package/src/pine/pine-transpiler.ts +0 -301
- package/src/pixi/LayerName.ts +0 -35
- package/src/pixi/PixiCandlestickRenderer.ts +0 -125
- package/src/pixi/PixiChart.ts +0 -425
- package/src/pixi/PixiCrosshairRenderer.ts +0 -134
- package/src/pixi/PixiDrawingRenderer.ts +0 -121
- package/src/pixi/PixiGridRenderer.ts +0 -136
- package/src/pixi/PixiLayerManager.ts +0 -102
- package/src/react/canvas/ChartCanvas.tsx +0 -984
- package/src/react/canvas/ChartContextMenu.tsx +0 -60
- package/src/react/canvas/ChartSettingsDialog.tsx +0 -133
- package/src/react/canvas/IndicatorLabel.tsx +0 -347
- package/src/react/canvas/IndicatorPane.tsx +0 -503
- package/src/react/canvas/PointerOverlay.tsx +0 -126
- package/src/react/canvas/toolbars/LeftToolbar.tsx +0 -1096
- package/src/react/hooks/useChartCapabilities.ts +0 -76
- package/src/react/shell/ManagedAppShell.tsx +0 -699
- package/src/react/trading/TradingBridge.ts +0 -156
- package/src/react/workspace/ChartWorkspace.tsx +0 -228
- package/src/react/workspace/FloatingPanel.tsx +0 -131
- package/src/react/workspace/IndicatorsDialog.tsx +0 -246
- package/src/react/workspace/LayoutMenu.tsx +0 -345
- package/src/react/workspace/SymbolSearchDialog.tsx +0 -377
- package/src/react/workspace/TabBar.tsx +0 -87
- package/src/react/workspace/toolbars/BottomToolbar.tsx +0 -372
- package/src/react/workspace/toolbars/RightToolbar.tsx +0 -46
- package/src/react/workspace/toolbars/TopToolbar.tsx +0 -431
- package/src/renderers/CandlestickRenderer.ts +0 -130
- package/src/renderers/HistogramRenderer.ts +0 -63
- package/src/renderers/LineRenderer.ts +0 -77
- package/src/theme/colors.ts +0 -21
- package/src/tools/barDivergenceCheck.ts +0 -305
- package/src/trading/TradingOverlayStore.ts +0 -161
- package/src/trading/UnmanagedIngestion.ts +0 -156
- package/src/trading/__tests__/ManagedTradingController.test.ts +0 -338
- package/src/trading/__tests__/TradingOverlayStore.test.ts +0 -323
- package/src/trading/__tests__/UnmanagedIngestion.test.ts +0 -205
- package/src/trading/managed/ManagedTradingController.ts +0 -292
- package/src/trading/managed/managedCapabilities.ts +0 -98
- package/src/trading/managed/managedTypes.ts +0 -151
- package/src/trading/tradingTypes.ts +0 -135
- package/src/tscript/TScriptIndicator.ts +0 -54
- package/src/tscript/ast.ts +0 -105
- package/src/tscript/lexer.ts +0 -190
- package/src/tscript/parser.ts +0 -334
- package/src/tscript/runtime.ts +0 -525
- package/src/tscript/series.ts +0 -84
- package/src/types/IChart.ts +0 -56
- package/src/types/ISeries.ts +0 -30
- package/tsconfig.json +0 -23
- package/tsup.config.ts +0 -16
- package/vitest.config.ts +0 -25
|
@@ -1,431 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect, useRef } from 'react';
|
|
2
|
-
import type { ChartTheme, IndicatorConfig } from '@forgecharts/types';
|
|
3
|
-
import { LayoutMenu } from '../LayoutMenu';
|
|
4
|
-
import { SymbolSearchDialog } from '../SymbolSearchDialog';
|
|
5
|
-
import type { ISymbolResolver } from '@forgecharts/types';
|
|
6
|
-
import { IndicatorsDialog } from '../IndicatorsDialog';
|
|
7
|
-
|
|
8
|
-
// ─── Timeframe data ───────────────────────────────────────────────────────────
|
|
9
|
-
|
|
10
|
-
export const DEFAULT_FAVORITES: string[] = ['1m', '5m', '15m', '30m', '1h', '4h', '1d', '1w'];
|
|
11
|
-
|
|
12
|
-
const TF_LABELS: Record<string, string> = {
|
|
13
|
-
'1m': '1 minute', '2m': '2 minutes', '3m': '3 minutes', '4m': '4 minutes',
|
|
14
|
-
'5m': '5 minutes', '10m': '10 minutes', '15m': '15 minutes', '20m': '20 minutes',
|
|
15
|
-
'30m': '30 minutes', '45m': '45 minutes',
|
|
16
|
-
'1h': '1 hour', '2h': '2 hours', '3h': '3 hours', '4h': '4 hours',
|
|
17
|
-
'6h': '6 hours', '8h': '8 hours', '12h': '12 hours',
|
|
18
|
-
'1d': '1 day', '2d': '2 days', '3d': '3 days', '1w': '1 week',
|
|
19
|
-
'2w': '2 weeks', '1M': '1 month', '3M': '3 months', '6M': '6 months', '12M': '12 months',
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const TF_GROUPS_ALL: { label: string; items: string[] }[] = [
|
|
23
|
-
{ label: 'Minutes', items: ['1m', '2m', '3m', '4m', '5m', '10m', '15m', '20m', '30m', '45m'] },
|
|
24
|
-
{ label: 'Hours', items: ['1h', '2h', '3h', '4h', '6h', '8h', '12h'] },
|
|
25
|
-
{ label: 'Days', items: ['1d', '2d', '3d', '1w', '2w', '1M', '3M', '6M', '12M'] },
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
// ─── Timeframe dropdown ───────────────────────────────────────────────────────
|
|
29
|
-
|
|
30
|
-
function TimeframeDropdown({
|
|
31
|
-
timeframe,
|
|
32
|
-
customTimeframes,
|
|
33
|
-
favorites,
|
|
34
|
-
onSelect,
|
|
35
|
-
onToggleFavorite,
|
|
36
|
-
onAddCustom,
|
|
37
|
-
onClose,
|
|
38
|
-
}: {
|
|
39
|
-
timeframe: string;
|
|
40
|
-
customTimeframes: string[];
|
|
41
|
-
favorites: string[];
|
|
42
|
-
onSelect: (tf: string) => void;
|
|
43
|
-
onToggleFavorite: (tf: string) => void;
|
|
44
|
-
onAddCustom: (tf: string) => void;
|
|
45
|
-
onClose: () => void;
|
|
46
|
-
}) {
|
|
47
|
-
const [collapsed, setCollapsed] = useState<Record<string, boolean>>({});
|
|
48
|
-
const [addingCustom, setAddingCustom] = useState(false);
|
|
49
|
-
const [input, setInput] = useState('');
|
|
50
|
-
const ref = useRef<HTMLDivElement>(null);
|
|
51
|
-
|
|
52
|
-
useEffect(() => {
|
|
53
|
-
const handler = (e: MouseEvent) => {
|
|
54
|
-
if (ref.current && !ref.current.contains(e.target as Node)) onClose();
|
|
55
|
-
};
|
|
56
|
-
document.addEventListener('mousedown', handler);
|
|
57
|
-
return () => document.removeEventListener('mousedown', handler);
|
|
58
|
-
}, [onClose]);
|
|
59
|
-
|
|
60
|
-
const commit = () => {
|
|
61
|
-
const val = input.trim();
|
|
62
|
-
if (!val) return;
|
|
63
|
-
onAddCustom(val);
|
|
64
|
-
onSelect(val);
|
|
65
|
-
setInput('');
|
|
66
|
-
onClose();
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const toggleGroup = (label: string) =>
|
|
70
|
-
setCollapsed((prev) => ({ ...prev, [label]: !prev[label] }));
|
|
71
|
-
|
|
72
|
-
return (
|
|
73
|
-
<div ref={ref} className="tf-dropdown">
|
|
74
|
-
<button
|
|
75
|
-
className="tf-dropdown-add-custom"
|
|
76
|
-
onClick={() => setAddingCustom((a) => !a)}
|
|
77
|
-
>
|
|
78
|
-
+ Add custom interval...
|
|
79
|
-
</button>
|
|
80
|
-
|
|
81
|
-
{addingCustom && (
|
|
82
|
-
<div className="tf-dropdown-add-row">
|
|
83
|
-
<input
|
|
84
|
-
className="tf-dropdown-input"
|
|
85
|
-
type="text"
|
|
86
|
-
value={input}
|
|
87
|
-
placeholder="e.g. 2h, 45m"
|
|
88
|
-
onChange={(e) => setInput(e.target.value)}
|
|
89
|
-
onKeyDown={(e) => { if (e.key === 'Enter') commit(); }}
|
|
90
|
-
autoFocus
|
|
91
|
-
/>
|
|
92
|
-
<button
|
|
93
|
-
className="tf-dropdown-add-btn"
|
|
94
|
-
disabled={!input.trim()}
|
|
95
|
-
onClick={commit}
|
|
96
|
-
>
|
|
97
|
-
Add
|
|
98
|
-
</button>
|
|
99
|
-
</div>
|
|
100
|
-
)}
|
|
101
|
-
|
|
102
|
-
{TF_GROUPS_ALL.map((group) => (
|
|
103
|
-
<div key={group.label}>
|
|
104
|
-
<button
|
|
105
|
-
className="tf-dropdown-group-hdr"
|
|
106
|
-
onClick={() => toggleGroup(group.label)}
|
|
107
|
-
>
|
|
108
|
-
<span>{group.label}</span>
|
|
109
|
-
<span className={`tf-dropdown-chevron${collapsed[group.label] ? ' collapsed' : ''}`}>∧</span>
|
|
110
|
-
</button>
|
|
111
|
-
{!collapsed[group.label] && group.items.map((tf) => (
|
|
112
|
-
<button
|
|
113
|
-
key={tf}
|
|
114
|
-
className="tf-dropdown-row"
|
|
115
|
-
onClick={() => { onSelect(tf); onClose(); }}
|
|
116
|
-
>
|
|
117
|
-
<span>{TF_LABELS[tf] ?? tf}</span>
|
|
118
|
-
<button
|
|
119
|
-
className="tf-star-btn"
|
|
120
|
-
title={favorites.includes(tf) ? 'Remove from toolbar' : 'Add to toolbar'}
|
|
121
|
-
onClick={(e) => { e.stopPropagation(); onToggleFavorite(tf); }}
|
|
122
|
-
>
|
|
123
|
-
<span className={`tf-star${favorites.includes(tf) ? ' favorited' : ''}`}>★</span>
|
|
124
|
-
</button>
|
|
125
|
-
</button>
|
|
126
|
-
))}
|
|
127
|
-
</div>
|
|
128
|
-
))}
|
|
129
|
-
|
|
130
|
-
{customTimeframes.length > 0 && (
|
|
131
|
-
<div>
|
|
132
|
-
<button
|
|
133
|
-
className="tf-dropdown-group-hdr"
|
|
134
|
-
onClick={() => toggleGroup('Custom')}
|
|
135
|
-
>
|
|
136
|
-
<span>Custom</span>
|
|
137
|
-
<span className={`tf-dropdown-chevron${collapsed['Custom'] ? ' collapsed' : ''}`}>∧</span>
|
|
138
|
-
</button>
|
|
139
|
-
{!collapsed['Custom'] && customTimeframes.map((tf) => (
|
|
140
|
-
<button
|
|
141
|
-
key={tf}
|
|
142
|
-
className="tf-dropdown-row"
|
|
143
|
-
onClick={() => { onSelect(tf); onClose(); }}
|
|
144
|
-
>
|
|
145
|
-
<span>{tf}</span>
|
|
146
|
-
</button>
|
|
147
|
-
))}
|
|
148
|
-
</div>
|
|
149
|
-
)}
|
|
150
|
-
</div>
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// ─── TopToolbar ─────────────────────────────────────────────────────────────
|
|
155
|
-
|
|
156
|
-
type Props = {
|
|
157
|
-
symbol: string;
|
|
158
|
-
timeframe: string;
|
|
159
|
-
theme: ChartTheme;
|
|
160
|
-
customTimeframes: string[];
|
|
161
|
-
favorites: string[];
|
|
162
|
-
onSymbolChange: (s: string) => void;
|
|
163
|
-
onTimeframeChange: (tf: string) => void;
|
|
164
|
-
onAddCustomTimeframe: (tf: string) => void;
|
|
165
|
-
onFavoritesChange: (favs: string[]) => void;
|
|
166
|
-
onAddIndicator: (config: IndicatorConfig) => void;
|
|
167
|
-
onToggleTheme: () => void;
|
|
168
|
-
onCopyScreenshot: () => void;
|
|
169
|
-
onDownloadScreenshot: () => void;
|
|
170
|
-
onFullscreen: () => void;
|
|
171
|
-
isFullscreen: boolean;
|
|
172
|
-
currentLayoutName?: string | undefined;
|
|
173
|
-
currentLayoutId?: string | undefined;
|
|
174
|
-
autoSave: boolean;
|
|
175
|
-
onSaveLayout: (name: string) => Promise<void>;
|
|
176
|
-
onLoadLayout: (layoutId: string) => Promise<void>;
|
|
177
|
-
onRenameLayout: (newName: string) => Promise<void>;
|
|
178
|
-
onCopyLayout: (newName: string) => Promise<void>;
|
|
179
|
-
onToggleAutoSave: (enabled: boolean) => void;
|
|
180
|
-
onDeleteLayout: (id: string) => Promise<void>;
|
|
181
|
-
onOpenLayoutInNewTab: (id: string) => Promise<void>;
|
|
182
|
-
/** Called to fetch current saved layouts. Passed through to LayoutMenu. */
|
|
183
|
-
onFetchLayouts: () => Promise<import('../LayoutMenu').LayoutRecord[]>;
|
|
184
|
-
/** Resolver used by the symbol search dialog. */
|
|
185
|
-
symbolResolver: ISymbolResolver;
|
|
186
|
-
/** Only rendered when a managed license is active */
|
|
187
|
-
showTradeButton?: boolean;
|
|
188
|
-
tradeDrawerOpen?: boolean;
|
|
189
|
-
onToggleTradeDrawer?: () => void;
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
export function TopToolbar({
|
|
193
|
-
symbol, timeframe, theme, customTimeframes, favorites,
|
|
194
|
-
onSymbolChange, onTimeframeChange, onAddCustomTimeframe, onFavoritesChange,
|
|
195
|
-
onAddIndicator,
|
|
196
|
-
onToggleTheme,
|
|
197
|
-
onCopyScreenshot, onDownloadScreenshot, onFullscreen, isFullscreen,
|
|
198
|
-
currentLayoutName, currentLayoutId, autoSave,
|
|
199
|
-
onSaveLayout, onLoadLayout, onRenameLayout, onCopyLayout, onToggleAutoSave,
|
|
200
|
-
onDeleteLayout, onOpenLayoutInNewTab, onFetchLayouts, symbolResolver,
|
|
201
|
-
showTradeButton, tradeDrawerOpen, onToggleTradeDrawer,
|
|
202
|
-
}: Props) {
|
|
203
|
-
const [tfOpen, setTfOpen] = useState(false);
|
|
204
|
-
const [symOpen, setSymOpen] = useState(false);
|
|
205
|
-
const [indOpen, setIndOpen] = useState(false);
|
|
206
|
-
const [ssOpen, setSsOpen] = useState(false);
|
|
207
|
-
const ssRef = useRef<HTMLDivElement>(null);
|
|
208
|
-
const tfRef = useRef<HTMLDivElement>(null);
|
|
209
|
-
|
|
210
|
-
useEffect(() => {
|
|
211
|
-
if (!ssOpen) return;
|
|
212
|
-
const handler = (e: MouseEvent) => {
|
|
213
|
-
if (ssRef.current && !ssRef.current.contains(e.target as Node)) setSsOpen(false);
|
|
214
|
-
};
|
|
215
|
-
document.addEventListener('mousedown', handler);
|
|
216
|
-
return () => document.removeEventListener('mousedown', handler);
|
|
217
|
-
}, [ssOpen]);
|
|
218
|
-
|
|
219
|
-
// Close dropdown on outside click is handled inside TimeframeDropdown itself.
|
|
220
|
-
|
|
221
|
-
return (
|
|
222
|
-
<div
|
|
223
|
-
style={{
|
|
224
|
-
display: 'flex',
|
|
225
|
-
alignItems: 'center',
|
|
226
|
-
gap: 8,
|
|
227
|
-
padding: '6px 12px',
|
|
228
|
-
background: 'var(--toolbar-bg)',
|
|
229
|
-
borderRadius: 8,
|
|
230
|
-
flexShrink: 0,
|
|
231
|
-
}}
|
|
232
|
-
>
|
|
233
|
-
{/* Logo */}
|
|
234
|
-
<span style={{ fontWeight: 700, letterSpacing: '-0.5px', color: 'var(--accent)' }}>
|
|
235
|
-
ForgeCharts
|
|
236
|
-
</span>
|
|
237
|
-
|
|
238
|
-
<div className="toolbar-sep" />
|
|
239
|
-
|
|
240
|
-
{/* Symbol picker */}
|
|
241
|
-
<button
|
|
242
|
-
className="sym-trigger"
|
|
243
|
-
onClick={() => setSymOpen(true)}
|
|
244
|
-
title="Search symbols"
|
|
245
|
-
>
|
|
246
|
-
<svg viewBox="0 0 14 14" width="12" height="12" stroke="currentColor"
|
|
247
|
-
fill="none" strokeWidth="1.8" strokeLinecap="round">
|
|
248
|
-
<circle cx="5.5" cy="5.5" r="4" />
|
|
249
|
-
<line x1="9" y1="9" x2="13" y2="13" />
|
|
250
|
-
</svg>
|
|
251
|
-
<span>{symbol}</span>
|
|
252
|
-
<svg viewBox="0 0 10 6" width="8" height="6" fill="currentColor">
|
|
253
|
-
<path d="M0 0l5 6 5-6z" />
|
|
254
|
-
</svg>
|
|
255
|
-
</button>
|
|
256
|
-
|
|
257
|
-
{symOpen && (
|
|
258
|
-
<SymbolSearchDialog
|
|
259
|
-
current={symbol}
|
|
260
|
-
onSelect={onSymbolChange}
|
|
261
|
-
onClose={() => setSymOpen(false)}
|
|
262
|
-
symbolResolver={symbolResolver}
|
|
263
|
-
/>
|
|
264
|
-
)}
|
|
265
|
-
|
|
266
|
-
<div className="toolbar-sep" />
|
|
267
|
-
|
|
268
|
-
{/* Timeframe buttons + dropdown */}
|
|
269
|
-
<div ref={tfRef} style={{ display: 'flex', gap: 2, position: 'relative' }}>
|
|
270
|
-
{favorites.map((tf) => (
|
|
271
|
-
<button
|
|
272
|
-
key={tf}
|
|
273
|
-
className={tf === timeframe ? 'active' : undefined}
|
|
274
|
-
onClick={() => onTimeframeChange(tf)}
|
|
275
|
-
>
|
|
276
|
-
{tf}
|
|
277
|
-
</button>
|
|
278
|
-
))}
|
|
279
|
-
|
|
280
|
-
{/* Extra button for active non-favorited timeframe */}
|
|
281
|
-
{!favorites.includes(timeframe) && timeframe && (
|
|
282
|
-
<button className="active" style={{ fontStyle: 'italic' }}>
|
|
283
|
-
{timeframe}
|
|
284
|
-
</button>
|
|
285
|
-
)}
|
|
286
|
-
|
|
287
|
-
{/* More timeframes trigger */}
|
|
288
|
-
<button
|
|
289
|
-
className={tfOpen ? 'active' : undefined}
|
|
290
|
-
onClick={() => setTfOpen((o) => !o)}
|
|
291
|
-
title="More timeframes"
|
|
292
|
-
style={{ fontSize: 11, padding: '4px 7px' }}
|
|
293
|
-
>
|
|
294
|
-
▾
|
|
295
|
-
</button>
|
|
296
|
-
|
|
297
|
-
{tfOpen && (
|
|
298
|
-
<TimeframeDropdown
|
|
299
|
-
timeframe={timeframe}
|
|
300
|
-
customTimeframes={customTimeframes}
|
|
301
|
-
favorites={favorites}
|
|
302
|
-
onSelect={onTimeframeChange}
|
|
303
|
-
onToggleFavorite={(tf) => {
|
|
304
|
-
const next = favorites.includes(tf)
|
|
305
|
-
? favorites.filter((f) => f !== tf)
|
|
306
|
-
: [...favorites, tf];
|
|
307
|
-
onFavoritesChange(next);
|
|
308
|
-
}}
|
|
309
|
-
onAddCustom={onAddCustomTimeframe}
|
|
310
|
-
onClose={() => setTfOpen(false)}
|
|
311
|
-
/>
|
|
312
|
-
)}
|
|
313
|
-
</div>
|
|
314
|
-
|
|
315
|
-
<div className="toolbar-sep" />
|
|
316
|
-
|
|
317
|
-
{/* Indicators button */}
|
|
318
|
-
<button
|
|
319
|
-
className={`ind-trigger${indOpen ? ' active' : ''}`}
|
|
320
|
-
onClick={() => setIndOpen((o) => !o)}
|
|
321
|
-
title="Indicators"
|
|
322
|
-
>
|
|
323
|
-
<svg viewBox="0 0 16 16" width="13" height="13" stroke="currentColor" fill="none" strokeWidth="1.6" strokeLinecap="round">
|
|
324
|
-
<polyline points="2,12 6,7 9,10 14,4" />
|
|
325
|
-
<line x1="11" y1="2" x2="14" y2="2" />
|
|
326
|
-
<line x1="14" y1="2" x2="14" y2="5" />
|
|
327
|
-
</svg>
|
|
328
|
-
Indicators
|
|
329
|
-
</button>
|
|
330
|
-
|
|
331
|
-
{indOpen && (
|
|
332
|
-
<IndicatorsDialog
|
|
333
|
-
onAdd={(config: IndicatorConfig) => { onAddIndicator(config); }}
|
|
334
|
-
onClose={() => setIndOpen(false)}
|
|
335
|
-
/>
|
|
336
|
-
)}
|
|
337
|
-
|
|
338
|
-
{/* Layout + theme toggle — pinned to right edge */}
|
|
339
|
-
<div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 4 }}>
|
|
340
|
-
{showTradeButton && (
|
|
341
|
-
<>
|
|
342
|
-
<button
|
|
343
|
-
className={`top-trade-btn${tradeDrawerOpen ? ' active' : ''}`}
|
|
344
|
-
onClick={onToggleTradeDrawer}
|
|
345
|
-
title="Trade — Connect your broker"
|
|
346
|
-
style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '4px 8px', fontSize: 12 }}
|
|
347
|
-
>
|
|
348
|
-
<svg viewBox="0 0 16 16" width="11" height="11" fill="none" stroke="currentColor" strokeWidth="1.6">
|
|
349
|
-
<rect x="1.5" y="3" width="13" height="10" rx="1.5" />
|
|
350
|
-
<line x1="5" y1="8" x2="11" y2="8" />
|
|
351
|
-
<line x1="8" y1="5" x2="8" y2="11" />
|
|
352
|
-
</svg>
|
|
353
|
-
Trade
|
|
354
|
-
</button>
|
|
355
|
-
<div className="toolbar-sep" />
|
|
356
|
-
</>
|
|
357
|
-
)}
|
|
358
|
-
<LayoutMenu
|
|
359
|
-
currentName={currentLayoutName}
|
|
360
|
-
currentLayoutId={currentLayoutId}
|
|
361
|
-
autoSave={autoSave}
|
|
362
|
-
onFetchLayouts={onFetchLayouts}
|
|
363
|
-
onSave={onSaveLayout}
|
|
364
|
-
onLoad={onLoadLayout}
|
|
365
|
-
onRename={onRenameLayout}
|
|
366
|
-
onCopy={onCopyLayout}
|
|
367
|
-
onToggleAutoSave={onToggleAutoSave}
|
|
368
|
-
onDelete={onDeleteLayout}
|
|
369
|
-
onOpenInNewTab={onOpenLayoutInNewTab}
|
|
370
|
-
/>
|
|
371
|
-
<button
|
|
372
|
-
onClick={onToggleTheme}
|
|
373
|
-
title={`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}
|
|
374
|
-
style={{ fontSize: 14, padding: '4px 8px' }}
|
|
375
|
-
>
|
|
376
|
-
{theme === 'dark' ? '☀' : '☾'}
|
|
377
|
-
</button>
|
|
378
|
-
{/* Screenshot */}
|
|
379
|
-
<div ref={ssRef} style={{ position: 'relative' }}>
|
|
380
|
-
<button
|
|
381
|
-
className={ssOpen ? 'active' : undefined}
|
|
382
|
-
onClick={() => setSsOpen((o) => !o)}
|
|
383
|
-
title="Screenshot"
|
|
384
|
-
style={{ display: 'inline-flex', alignItems: 'center', padding: '4px 7px' }}
|
|
385
|
-
>
|
|
386
|
-
<svg viewBox="0 0 16 16" width="14" height="14" stroke="currentColor" fill="none" strokeWidth="1.5">
|
|
387
|
-
<rect x="2" y="4" width="12" height="9" rx="1" />
|
|
388
|
-
<circle cx="8" cy="8.5" r="2.5" />
|
|
389
|
-
<path d="M6 4l1-2h2l1 2" />
|
|
390
|
-
</svg>
|
|
391
|
-
</button>
|
|
392
|
-
{ssOpen && (
|
|
393
|
-
<div className="ss-dropdown">
|
|
394
|
-
<button className="ss-dropdown-item" onClick={() => { setSsOpen(false); onCopyScreenshot(); }}>
|
|
395
|
-
<svg viewBox="0 0 16 16" width="13" height="13" stroke="currentColor" fill="none" strokeWidth="1.5">
|
|
396
|
-
<rect x="5" y="5" width="9" height="9" rx="1" />
|
|
397
|
-
<path d="M3 11H2a1 1 0 01-1-1V2a1 1 0 011-1h8a1 1 0 011 1v1" />
|
|
398
|
-
</svg>
|
|
399
|
-
Copy to Clipboard
|
|
400
|
-
</button>
|
|
401
|
-
<button className="ss-dropdown-item" onClick={() => { setSsOpen(false); onDownloadScreenshot(); }}>
|
|
402
|
-
<svg viewBox="0 0 16 16" width="13" height="13" stroke="currentColor" fill="none" strokeWidth="1.5" strokeLinecap="round">
|
|
403
|
-
<line x1="8" y1="2" x2="8" y2="11" />
|
|
404
|
-
<polyline points="4,7 8,11 12,7" />
|
|
405
|
-
<line x1="2" y1="14" x2="14" y2="14" />
|
|
406
|
-
</svg>
|
|
407
|
-
Download PNG
|
|
408
|
-
</button>
|
|
409
|
-
</div>
|
|
410
|
-
)}
|
|
411
|
-
</div>
|
|
412
|
-
{/* Fullscreen */}
|
|
413
|
-
<button
|
|
414
|
-
onClick={onFullscreen}
|
|
415
|
-
title={isFullscreen ? 'Exit Fullscreen' : 'Fullscreen'}
|
|
416
|
-
style={{ display: 'inline-flex', alignItems: 'center', padding: '4px 7px' }}
|
|
417
|
-
>
|
|
418
|
-
{isFullscreen ? (
|
|
419
|
-
<svg viewBox="0 0 16 16" width="14" height="14" stroke="currentColor" fill="none" strokeWidth="1.5">
|
|
420
|
-
<path d="M6 2v4H2M10 2v4h4M10 14v-4h4M6 14v-4H2" />
|
|
421
|
-
</svg>
|
|
422
|
-
) : (
|
|
423
|
-
<svg viewBox="0 0 16 16" width="14" height="14" stroke="currentColor" fill="none" strokeWidth="1.5">
|
|
424
|
-
<path d="M2 6V2h4M10 2h4v4M14 10v4h-4M6 14H2v-4" />
|
|
425
|
-
</svg>
|
|
426
|
-
)}
|
|
427
|
-
</button>
|
|
428
|
-
</div>
|
|
429
|
-
</div>
|
|
430
|
-
);
|
|
431
|
-
}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import type { OHLCV, SeriesOptions, Viewport, Rect, ChartColors } from '@forgecharts/types';
|
|
2
|
-
import type { IRenderer } from '../types/IRenderer';
|
|
3
|
-
import { mapRange } from '@forgecharts/utils';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* CandlestickRenderer — draws OHLCV data as Japanese candlesticks.
|
|
7
|
-
* All rendering is pure Canvas 2D; no third-party dependencies.
|
|
8
|
-
*/
|
|
9
|
-
export class CandlestickRenderer implements IRenderer {
|
|
10
|
-
private readonly _colors: ChartColors;
|
|
11
|
-
|
|
12
|
-
constructor(colors: ChartColors) {
|
|
13
|
-
this._colors = colors;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
draw(
|
|
17
|
-
ctx: CanvasRenderingContext2D,
|
|
18
|
-
bars: readonly OHLCV[],
|
|
19
|
-
viewport: Viewport,
|
|
20
|
-
rect: Rect,
|
|
21
|
-
options: SeriesOptions,
|
|
22
|
-
): void {
|
|
23
|
-
if (options.type !== 'candlestick' && options.type !== 'heikinashi' && options.type !== 'bar') {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const plotData = options.type === 'heikinashi' ? this._toHeikinAshi(bars) : bars;
|
|
27
|
-
|
|
28
|
-
const upColor = 'upColor' in options ? (options.upColor ?? '#26a641') : '#26a641';
|
|
29
|
-
const downColor = 'downColor' in options ? (options.downColor ?? '#f85149') : '#f85149';
|
|
30
|
-
const wickUpColor = 'wickUpColor' in options ? (options.wickUpColor ?? upColor) : upColor;
|
|
31
|
-
const wickDownColor =
|
|
32
|
-
'wickDownColor' in options ? (options.wickDownColor ?? downColor) : downColor;
|
|
33
|
-
const borderVisible = 'borderVisible' in options ? (options.borderVisible ?? false) : false;
|
|
34
|
-
|
|
35
|
-
const plotW = rect.width - 70; // price axis reserved
|
|
36
|
-
const plotH = rect.height - 30; // time axis reserved
|
|
37
|
-
|
|
38
|
-
// ── Bar pitch: pixels per candle ─────────────────────────────────────────
|
|
39
|
-
// IMPORTANT: must be derived from the visible time range + candle interval,
|
|
40
|
-
// NOT from total bar count. Using bar count means pitch shrinks as you pan
|
|
41
|
-
// into history (more bars → narrower candles) and widens as you pan forward
|
|
42
|
-
// (fewer bars visible → wider candles with gaps), which is wrong.
|
|
43
|
-
|
|
44
|
-
// Infer candle interval from the median gap between consecutive bars.
|
|
45
|
-
let candleInterval = 0;
|
|
46
|
-
if (plotData.length >= 2) {
|
|
47
|
-
const deltas: number[] = [];
|
|
48
|
-
for (let i = 1; i < Math.min(plotData.length, 20); i++) {
|
|
49
|
-
const d = plotData[i]!.time - plotData[i - 1]!.time;
|
|
50
|
-
if (d > 0) deltas.push(d);
|
|
51
|
-
}
|
|
52
|
-
if (deltas.length > 0) {
|
|
53
|
-
deltas.sort((a, b) => a - b);
|
|
54
|
-
candleInterval = deltas[Math.floor(deltas.length / 2)]!;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const visibleSpan = viewport.timeRange.to - viewport.timeRange.from;
|
|
59
|
-
const pixelsPerSecond = visibleSpan > 0 ? plotW / visibleSpan : 1;
|
|
60
|
-
const barPitch = candleInterval > 0
|
|
61
|
-
? candleInterval * pixelsPerSecond // correct: interval-based
|
|
62
|
-
: plotW / Math.max(1, plotData.length); // fallback for edge cases
|
|
63
|
-
|
|
64
|
-
const minBarWidth = 1;
|
|
65
|
-
const maxBarWidth = 20;
|
|
66
|
-
const gap = Math.max(1, Math.round(barPitch * 0.15));
|
|
67
|
-
const barWidth = Math.min(
|
|
68
|
-
maxBarWidth,
|
|
69
|
-
Math.max(minBarWidth, Math.floor(barPitch) - gap),
|
|
70
|
-
);
|
|
71
|
-
const halfBar = Math.max(0.5, barWidth / 2);
|
|
72
|
-
|
|
73
|
-
for (const bar of plotData) {
|
|
74
|
-
const x = mapRange(
|
|
75
|
-
bar.time,
|
|
76
|
-
viewport.timeRange.from,
|
|
77
|
-
viewport.timeRange.to,
|
|
78
|
-
0,
|
|
79
|
-
plotW,
|
|
80
|
-
);
|
|
81
|
-
|
|
82
|
-
if (x < -barWidth || x > plotW + barWidth) continue;
|
|
83
|
-
|
|
84
|
-
const yOpen = mapRange(bar.open, viewport.priceRange.max, viewport.priceRange.min, 0, plotH);
|
|
85
|
-
const yClose = mapRange(bar.close, viewport.priceRange.max, viewport.priceRange.min, 0, plotH);
|
|
86
|
-
const yHigh = mapRange(bar.high, viewport.priceRange.max, viewport.priceRange.min, 0, plotH);
|
|
87
|
-
const yLow = mapRange(bar.low, viewport.priceRange.max, viewport.priceRange.min, 0, plotH);
|
|
88
|
-
|
|
89
|
-
const bullish = bar.close >= bar.open;
|
|
90
|
-
const bodyColor = bullish ? upColor : downColor;
|
|
91
|
-
const bodyTop = Math.min(yOpen, yClose);
|
|
92
|
-
const bodyBottom = Math.max(yOpen, yClose);
|
|
93
|
-
const bodyH = Math.max(1, bodyBottom - bodyTop);
|
|
94
|
-
|
|
95
|
-
// Wick
|
|
96
|
-
ctx.beginPath();
|
|
97
|
-
ctx.strokeStyle = bullish ? wickUpColor : wickDownColor;
|
|
98
|
-
ctx.lineWidth = 1;
|
|
99
|
-
ctx.moveTo(x, yHigh);
|
|
100
|
-
ctx.lineTo(x, bodyTop);
|
|
101
|
-
ctx.moveTo(x, bodyBottom);
|
|
102
|
-
ctx.lineTo(x, yLow);
|
|
103
|
-
ctx.stroke();
|
|
104
|
-
|
|
105
|
-
// Body
|
|
106
|
-
ctx.fillStyle = bodyColor;
|
|
107
|
-
ctx.fillRect(x - halfBar, bodyTop, barWidth, bodyH);
|
|
108
|
-
|
|
109
|
-
if (borderVisible) {
|
|
110
|
-
ctx.strokeStyle = bodyColor;
|
|
111
|
-
ctx.lineWidth = 1;
|
|
112
|
-
ctx.strokeRect(x - halfBar, bodyTop, barWidth, bodyH);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
private _toHeikinAshi(bars: readonly OHLCV[]): OHLCV[] {
|
|
118
|
-
const result: OHLCV[] = [];
|
|
119
|
-
for (let i = 0; i < bars.length; i++) {
|
|
120
|
-
const bar = bars[i]!;
|
|
121
|
-
const prev = result[i - 1] ?? bar;
|
|
122
|
-
const haClose = (bar.open + bar.high + bar.low + bar.close) / 4;
|
|
123
|
-
const haOpen = (prev.open + prev.close) / 2;
|
|
124
|
-
const haHigh = Math.max(bar.high, haOpen, haClose);
|
|
125
|
-
const haLow = Math.min(bar.low, haOpen, haClose);
|
|
126
|
-
result.push({ time: bar.time, open: haOpen, high: haHigh, low: haLow, close: haClose, volume: bar.volume });
|
|
127
|
-
}
|
|
128
|
-
return result;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type { OHLCV, SeriesOptions, Viewport, Rect, ChartColors } from '@forgecharts/types';
|
|
2
|
-
import type { IRenderer } from '../types/IRenderer';
|
|
3
|
-
import { mapRange } from '@forgecharts/utils';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* HistogramRenderer — draws volume or indicator values as vertical bars.
|
|
7
|
-
*/
|
|
8
|
-
export class HistogramRenderer implements IRenderer {
|
|
9
|
-
private readonly _colors: ChartColors;
|
|
10
|
-
|
|
11
|
-
constructor(colors: ChartColors) {
|
|
12
|
-
this._colors = colors;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
draw(
|
|
16
|
-
ctx: CanvasRenderingContext2D,
|
|
17
|
-
bars: readonly OHLCV[],
|
|
18
|
-
viewport: Viewport,
|
|
19
|
-
rect: Rect,
|
|
20
|
-
options: SeriesOptions,
|
|
21
|
-
): void {
|
|
22
|
-
if (options.type !== 'histogram') return;
|
|
23
|
-
|
|
24
|
-
const color = options.color ?? '#8b949e';
|
|
25
|
-
const plotW = rect.width - 70;
|
|
26
|
-
const plotH = rect.height - 30;
|
|
27
|
-
|
|
28
|
-
// Derive pitch from candle interval × pixels-per-second (same fix as CandlestickRenderer)
|
|
29
|
-
let candleInterval = 0;
|
|
30
|
-
if (bars.length >= 2) {
|
|
31
|
-
const deltas: number[] = [];
|
|
32
|
-
for (let i = 1; i < Math.min(bars.length, 20); i++) {
|
|
33
|
-
const d = bars[i]!.time - bars[i - 1]!.time;
|
|
34
|
-
if (d > 0) deltas.push(d);
|
|
35
|
-
}
|
|
36
|
-
if (deltas.length > 0) {
|
|
37
|
-
deltas.sort((a, b) => a - b);
|
|
38
|
-
candleInterval = deltas[Math.floor(deltas.length / 2)]!;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
const visibleSpan = viewport.timeRange.to - viewport.timeRange.from;
|
|
42
|
-
const pixelsPerSecond = visibleSpan > 0 ? plotW / visibleSpan : 1;
|
|
43
|
-
const barPitch = candleInterval > 0
|
|
44
|
-
? candleInterval * pixelsPerSecond
|
|
45
|
-
: plotW / Math.max(1, bars.length);
|
|
46
|
-
const barWidth = Math.max(1, Math.floor(barPitch) - 1);
|
|
47
|
-
const halfBar = barWidth / 2;
|
|
48
|
-
const baseline = plotH; // draws from bottom up
|
|
49
|
-
|
|
50
|
-
for (const bar of bars) {
|
|
51
|
-
const x = mapRange(bar.time, viewport.timeRange.from, viewport.timeRange.to, 0, plotW);
|
|
52
|
-
if (x < -barWidth || x > plotW + barWidth) continue;
|
|
53
|
-
|
|
54
|
-
const y = mapRange(bar.volume, viewport.priceRange.max, viewport.priceRange.min, 0, plotH);
|
|
55
|
-
const barH = Math.max(1, baseline - y);
|
|
56
|
-
|
|
57
|
-
ctx.fillStyle = bar.close >= bar.open ? '#26a641' : '#f85149';
|
|
58
|
-
ctx.fillRect(x - halfBar, y, barWidth, barH);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
void color; // unused when per-bar coloring is active
|
|
62
|
-
}
|
|
63
|
-
}
|