velo-plot 1.19.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ChartCore-DQ691eXH.js → ChartCore-BhQ4j7f5.js} +1299 -1102
- package/dist/ChartCore-BhQ4j7f5.js.map +1 -0
- package/dist/SciPlot-GJvw7GJo.js +463 -0
- package/dist/SciPlot-GJvw7GJo.js.map +1 -0
- package/dist/axisFormat-SPX-CD5s.js +200 -0
- package/dist/axisFormat-SPX-CD5s.js.map +1 -0
- package/dist/core/InteractionManager.d.ts +1 -0
- package/dist/core/OverlayRenderer.d.ts +11 -0
- package/dist/core/chart/ChartCore.d.ts +5 -0
- package/dist/core/chart/ChartRenderLoop.d.ts +5 -0
- package/dist/core/chart/ChartRenderer.d.ts +5 -0
- package/dist/core/chart/positionLines.d.ts +12 -0
- package/dist/core/chart/types.d.ts +2 -0
- package/dist/core/format/axisFormat.d.ts +2 -1
- package/dist/core/indicator/addIndicator.d.ts +1 -1
- package/dist/core/indicator/indicatorPresets.d.ts +10 -2
- package/dist/core/time/TimeScale.d.ts +2 -2
- package/dist/core/time/applyTimeScale.d.ts +10 -0
- package/dist/createStackedChart-DJSmqerD.js +706 -0
- package/dist/createStackedChart-DJSmqerD.js.map +1 -0
- package/dist/{index-DjeWClO9.js → index-CWipqOLP.js} +2 -2
- package/dist/{index-DjeWClO9.js.map → index-CWipqOLP.js.map} +1 -1
- package/dist/{index.core-BtGFYMOu.js → index.core-fpZ1dYN0.js} +3 -3
- package/dist/{index.core-BtGFYMOu.js.map → index.core-fpZ1dYN0.js.map} +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/mockDatafeed-Cdg5hKEo.js +511 -0
- package/dist/mockDatafeed-Cdg5hKEo.js.map +1 -0
- package/dist/plugins/drawing-tools/index.d.ts +14 -1
- package/dist/plugins/drawing-tools/measure.d.ts +21 -0
- package/dist/plugins/drawing-tools/snapToCandle.d.ts +21 -0
- package/dist/plugins/tools.js +1 -1
- package/dist/react.js +5 -5
- package/dist/trading/datafeed.d.ts +48 -0
- package/dist/trading/index.d.ts +29 -0
- package/dist/trading/mockDatafeed.d.ts +9 -0
- package/dist/trading/ohlcvGenerator.d.ts +25 -0
- package/dist/trading.d.ts +1 -0
- package/dist/trading.js +95 -0
- package/dist/trading.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/velo-plot.full.js +833 -1054
- package/dist/velo-plot.full.js.map +1 -1
- package/dist/velo-plot.js +13 -13
- package/package.json +13 -1
- package/dist/ChartCore-DQ691eXH.js.map +0 -1
- package/dist/axisFormat-B7o_uIEA.js +0 -127
- package/dist/axisFormat-B7o_uIEA.js.map +0 -1
- package/dist/createStackedChart-BPooTQ9z.js +0 -1164
- package/dist/createStackedChart-BPooTQ9z.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
var l = Object.defineProperty;
|
|
2
2
|
var g = (i, e, r) => e in i ? l(i, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : i[e] = r;
|
|
3
3
|
var u = (i, e, r) => g(i, typeof e != "symbol" ? e + "" : e, r);
|
|
4
|
-
import { N as f } from "./ChartCore-
|
|
5
|
-
import "./axisFormat-
|
|
4
|
+
import { N as f } from "./ChartCore-BhQ4j7f5.js";
|
|
5
|
+
import "./axisFormat-SPX-CD5s.js";
|
|
6
6
|
import "./index-x4stH3jD.js";
|
|
7
7
|
function b(i) {
|
|
8
8
|
return new f(i);
|
|
@@ -164,4 +164,4 @@ export {
|
|
|
164
164
|
p as r,
|
|
165
165
|
z as v
|
|
166
166
|
};
|
|
167
|
-
//# sourceMappingURL=index.core-
|
|
167
|
+
//# sourceMappingURL=index.core-fpZ1dYN0.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.core-BtGFYMOu.js","sources":["../src/renderer/RendererInterface.ts","../src/plugins/PluginRegistry.ts","../src/plugins/index.ts"],"sourcesContent":["/**\n * WebGL Renderer Interface & Factory\n *\n * This module provides a common interface for WebGL rendering.\n * Currently optimized for NativeWebGLRenderer (zero dependencies).\n */\n\nimport type { Bounds } from '../types';\nimport { NativeWebGLRenderer } from './NativeWebGLRenderer';\n\n// ============================================\n// Common Types\n// ============================================\n\nexport interface SeriesRenderData {\n id: string;\n buffer: WebGLBuffer;\n count: number;\n style: any;\n visible: boolean;\n type: string;\n zBounds?: { min: number; max: number };\n colormapTexture?: WebGLTexture;\n}\n\nexport interface RenderOptions {\n bounds: Bounds;\n backgroundColor?: [number, number, number, number];\n}\n\n// ============================================\n// Renderer Interface\n// ============================================\n\n/**\n * Common interface for all WebGL renderer implementations\n */\nexport interface IWebGLRenderer {\n /** Check if WebGL is available and initialized */\n readonly available: boolean;\n\n /**\n * Create or update a GPU buffer with interleaved X,Y data\n * @param id - Unique buffer identifier\n * @param data - Interleaved Float32Array [x0, y0, x1, y1, ...]\n */\n createBuffer(id: string, data: Float32Array): void;\n\n /**\n * Get a buffer by ID\n */\n getBuffer(id: string): WebGLBuffer | undefined;\n\n /**\n * Delete a buffer and free GPU memory\n */\n deleteBuffer(id: string): void;\n \n /** \n * Create a 1D texture for heatmaps \n */\n createColormapTexture(id: string, data: Uint8Array): WebGLTexture;\n\n /**\n * Render a frame with all visible series\n */\n render(series: SeriesRenderData[], options: RenderOptions): void;\n\n /**\n * Handle canvas resize\n */\n resize(): void;\n\n /**\n * Get WebGL capabilities/limits\n */\n getLimits(): Record<string, unknown>;\n\n /**\n * Cleanup and destroy all GPU resources\n */\n destroy(): void;\n}\n\n// ============================================\n// Factory Functions\n// ============================================\n\n/**\n * Create a WebGL renderer (Native WebGL)\n *\n * @param canvas - Target canvas element\n */\nexport function createRenderer(canvas: HTMLCanvasElement): IWebGLRenderer {\n return new NativeWebGLRenderer(canvas);\n}\n\n/**\n * Create a renderer synchronously (native only)\n */\nexport { NativeWebGLRenderer as createNativeRenderer } from './NativeWebGLRenderer';\n","/**\n * Sci Plot - Global Plugin Registry\n * \n * Provides a global registry for third-party plugins that can be\n * discovered and loaded by name without explicit imports.\n * \n * @module plugins/PluginRegistry\n */\n\nimport type {\n PluginFactory,\n PluginManifest,\n PluginCapability,\n PluginRegistry,\n PluginRegistryEntry,\n} from \"./types\";\n\n// ============================================\n// Global Registry Implementation\n// ============================================\n\nclass PluginRegistryImpl implements PluginRegistry {\n private entries = new Map<string, PluginRegistryEntry>();\n\n /**\n * Register a plugin globally\n */\n register(entry: PluginRegistryEntry): void {\n const name = entry.manifest.name;\n\n if (this.entries.has(name)) {\n console.warn(\n `[SciPlot Registry] Plugin \"${name}\" is already registered, overwriting`\n );\n }\n\n this.entries.set(name, entry);\n }\n\n /**\n * Unregister a plugin\n */\n unregister(name: string): boolean {\n const existed = this.entries.has(name);\n this.entries.delete(name);\n return existed;\n }\n\n /**\n * Get a registered plugin factory by name\n */\n get(name: string): PluginFactory | undefined {\n return this.entries.get(name)?.factory;\n }\n\n /**\n * List all registered plugins\n */\n list(): PluginManifest[] {\n return Array.from(this.entries.values()).map((e) => e.manifest);\n }\n\n /**\n * Search plugins by capability\n */\n findByCapability(capability: PluginCapability): PluginManifest[] {\n const results: PluginManifest[] = [];\n\n this.entries.forEach((entry) => {\n if (entry.manifest.provides?.includes(capability)) {\n results.push(entry.manifest);\n }\n });\n\n return results;\n }\n\n /**\n * Search plugins by tag\n */\n findByTag(tag: string): PluginManifest[] {\n const results: PluginManifest[] = [];\n const lowerTag = tag.toLowerCase();\n\n this.entries.forEach((entry) => {\n if (entry.manifest.tags?.some((t) => t.toLowerCase().includes(lowerTag))) {\n results.push(entry.manifest);\n }\n });\n\n return results;\n }\n\n /**\n * Check if a plugin is registered\n */\n has(name: string): boolean {\n return this.entries.has(name);\n }\n\n /**\n * Get plugin count\n */\n get size(): number {\n return this.entries.size;\n }\n\n /**\n * Clear all registrations\n */\n clear(): void {\n this.entries.clear();\n }\n}\n\n// ============================================\n// Singleton Instance\n// ============================================\n\nlet registryInstance: PluginRegistryImpl | null = null;\n\n/**\n * Get the global plugin registry singleton\n */\nexport function getPluginRegistry(): PluginRegistry {\n if (!registryInstance) {\n registryInstance = new PluginRegistryImpl();\n }\n return registryInstance;\n}\n\n/**\n * Register a plugin in the global registry\n * Shorthand for getPluginRegistry().register()\n */\nexport function registerPlugin(entry: PluginRegistryEntry): void {\n getPluginRegistry().register(entry);\n}\n\n/**\n * Create a plugin factory with manifest validation\n */\nexport function definePlugin<TConfig = unknown>(\n manifest: PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): PluginFactory<TConfig> {\n return (config?: TConfig) => {\n const plugin = factory(config);\n return {\n ...plugin,\n manifest,\n };\n };\n}\n\n/**\n * Register a plugin from definition\n */\nexport function defineAndRegister<TConfig = unknown>(\n manifest: PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): PluginFactory<TConfig> {\n const pluginFactory = definePlugin(manifest, factory);\n registerPlugin({ manifest, factory: pluginFactory as PluginFactory });\n return pluginFactory;\n}\n\n// ============================================\n// Plugin Discovery Helpers\n// ============================================\n\n/**\n * Load a plugin from the registry by name\n */\nexport async function loadPlugin<TConfig = unknown>(\n name: string,\n config?: TConfig\n): Promise<import(\"./types\").ChartPlugin<TConfig> | undefined> {\n const factory = getPluginRegistry().get(name);\n if (!factory) {\n console.warn(`[SciPlot] Plugin \"${name}\" not found in registry`);\n return undefined;\n }\n return factory(config) as import(\"./types\").ChartPlugin<TConfig>;\n}\n\n/**\n * List available plugins by category\n */\nexport function listPluginsByCategory(): Record<PluginCapability, PluginManifest[]> {\n const registry = getPluginRegistry();\n const categories: PluginCapability[] = [\n \"analysis\",\n \"visualization\",\n \"interaction\",\n \"data-source\",\n \"export\",\n \"ui\",\n \"annotation\",\n \"theme\",\n ];\n\n const result: Record<string, PluginManifest[]> = {};\n categories.forEach((cat) => {\n result[cat] = registry.findByCapability(cat);\n });\n\n return result as Record<PluginCapability, PluginManifest[]>;\n}\n\n// ============================================\n// Plugin Validation\n// ============================================\n\n/**\n * Validate a plugin manifest\n */\nexport function validateManifest(manifest: PluginManifest): string[] {\n const errors: string[] = [];\n\n if (!manifest.name) {\n errors.push(\"Missing required field: name\");\n } else if (!/^[@a-z0-9-]+\\/[a-z0-9-]+$|^[a-z0-9-]+$/.test(manifest.name)) {\n errors.push(\n 'Invalid name format. Use lowercase with hyphens, optionally scoped (e.g., \"@org/name\")'\n );\n }\n\n if (!manifest.version) {\n errors.push(\"Missing required field: version\");\n } else if (!/^\\d+\\.\\d+\\.\\d+$/.test(manifest.version)) {\n errors.push(\"Invalid version format. Use semantic versioning (e.g., 1.0.0)\");\n }\n\n if (manifest.dependencies) {\n if (!Array.isArray(manifest.dependencies)) {\n errors.push(\"dependencies must be an array\");\n }\n }\n\n if (manifest.provides) {\n if (!Array.isArray(manifest.provides)) {\n errors.push(\"provides must be an array\");\n }\n }\n\n return errors;\n}\n\n/**\n * Validate a plugin for compatibility\n */\nexport function checkPluginCompatibility(\n manifest: PluginManifest,\n engineVersion: string\n): { compatible: boolean; warnings: string[] } {\n const warnings: string[] = [];\n\n if (manifest.engineVersion) {\n const [reqMajor] = manifest.engineVersion.split(\".\").map(Number);\n const [curMajor] = engineVersion.split(\".\").map(Number);\n\n if (reqMajor > curMajor) {\n return {\n compatible: false,\n warnings: [\n `Plugin requires engine v${manifest.engineVersion}, current is v${engineVersion}`,\n ],\n };\n }\n\n if (reqMajor < curMajor) {\n warnings.push(\n `Plugin was built for engine v${manifest.engineVersion}, may have compatibility issues`\n );\n }\n }\n\n return { compatible: true, warnings };\n}\n","/**\n * Sci Plot - Plugin System\n * \n * Comprehensive plugin architecture for extending chart functionality.\n * \n * Features:\n * - Complete lifecycle hooks (init, render, data, view, interaction, destroy)\n * - Rich plugin context with access to all chart internals\n * - Plugin storage for persistent state\n * - Dependency management between plugins\n * - Global registry for third-party plugins\n * - Built-in plugins for common use cases\n * \n * @packageDocumentation\n * @module plugins\n */\n\n// ============================================\n// Core Types\n// ============================================\nexport type {\n // Manifest & Metadata\n PluginVersion,\n PluginCapability,\n PluginManifest,\n\n // Context Types\n PluginContext,\n RenderContext,\n CoordinateContext,\n DataContext,\n UIContext,\n EventContext,\n PluginStorage,\n PluginLogger,\n OverlayOptions,\n NotificationOptions,\n PickResult,\n\n // Hook Event Types\n BeforeRenderEvent,\n AfterRenderEvent,\n InteractionEvent,\n ViewChangeEvent,\n SeriesChangeEvent,\n DataUpdateEvent,\n\n // Plugin Types\n ChartPlugin,\n PluginFactory,\n TypedPlugin,\n\n // Manager Types\n PluginManager,\n PluginRegistry,\n PluginRegistryEntry,\n} from \"./types\";\n\n// ============================================\n// Core Implementation\n// ============================================\nexport { createPluginContext } from \"./PluginContext\";\nexport type { ContextDependencies } from \"./PluginContext\";\n\nexport { PluginManagerImpl } from \"./PluginManager\";\n\n// ============================================\n// Registry\n// ============================================\nexport {\n getPluginRegistry,\n registerPlugin,\n definePlugin,\n defineAndRegister,\n loadPlugin,\n listPluginsByCategory,\n validateManifest,\n checkPluginCompatibility,\n} from \"./PluginRegistry\";\n\n// ============================================\n// Built-in Plugins\n// ============================================\nexport {\n // Individual plugins\n CrosshairPlugin,\n StatsPlugin,\n WatermarkPlugin,\n GridHighlightPlugin,\n DataLoggerPlugin,\n DirectionIndicatorPlugin,\n\n // Plugin collection\n BuiltinPlugins,\n\n // Plugin configs\n type CrosshairPluginConfig,\n type StatsPluginConfig,\n type WatermarkPluginConfig,\n type GridHighlightConfig,\n type DataLoggerConfig,\n type DirectionIndicatorConfig,\n} from \"./builtins\";\n\n// ============================================\n// Modular Plugins\n// ============================================\nexport { Plugin3D, type Plugin3DConfig } from \"./3d\";\nexport { PluginGpu, type PluginGpuConfig } from \"./gpu\";\nexport { PluginAnalysis, type PluginAnalysisConfig } from \"./analysis\";\nexport { PluginTools, type PluginToolsConfig } from \"./tools\";\nexport { PluginAnnotations, type PluginAnnotationsConfig } from \"./annotations\";\nexport { PluginStreaming, type PluginStreamingConfig } from \"./streaming\";\nexport { PluginThemeEditor, type PluginThemeEditorConfig } from \"./theme-editor\";\nexport { PluginI18n, type PluginI18nConfig } from \"./i18n\";\nexport { PluginKeyboard, type PluginKeyboardConfig } from \"./keyboard\";\nexport { PluginClipboard, type PluginClipboardConfig } from \"./clipboard\";\nexport { PluginSync, type PluginSyncConfig } from \"./sync\";\nexport { PluginDebug, type PluginDebugConfig } from \"./debug\";\nexport { PluginLoading, type PluginLoadingConfig } from \"./loading\";\nexport { PluginDataExport, type PluginDataExportConfig } from \"./data-export\";\nexport { PluginContextMenu, type PluginContextMenuConfig } from \"./context-menu\";\nexport { PluginAnomalyDetection, type PluginAnomalyDetectionConfig, type AnomalyDetectionResult, type AnomalyPoint, type AnomalyMethod } from \"./anomaly-detection\";\nexport { PluginMLIntegration, type PluginMLIntegrationConfig, type MLIntegrationAPI, type MLModelAPI, type PredictionResult, type VisualizationConfig } from \"./ml-integration\";\nexport { PluginPatternRecognition, type PluginPatternRecognitionConfig, type PatternRecognitionAPI, type PatternMatch, type PatternDetectionResult } from \"./pattern-recognition\";\nexport { PluginRegression, type PluginRegressionConfig, type RegressionAPI, type RegressionResult, type RegressionData } from \"./regression\";\nexport { PluginRadar, type PluginRadarConfig, type RadarAPI, type RadarSeriesData, type RadarPoint } from \"./radar\";\nexport { PluginSnapshot, type PluginSnapshotConfig, type SnapshotExportAPI, type SnapshotExportOptions, type SnapshotResolution, type SnapshotFormat } from \"./snapshot\";\nexport { PluginDataTransform, type PluginDataTransformConfig, type DataTransformAPI, type TransformOp, type TransformType } from \"./data-transform\";\nexport { PluginLaTeX, type PluginLaTeXConfig, type LaTeXPluginAPI, type LaTeXDimensions } from \"./latex\";\nexport * from \"./forecasting\";\n\n// Drag & Drop Editing\nexport { PluginDragEdit, type PluginDragEditConfig, type DragEditAPI, type DragEditEvent } from \"./drag-edit\";\n\n// Caching\nexport { PluginCaching, type PluginCachingConfig, type CachingAPI, type CacheStats } from \"./caching\";\n\n// Lazy Loading\nexport { PluginLazyLoad, type PluginLazyLoadConfig, type LazyLoadAPI, type DataProvider } from \"./lazy-load\";\n\n// Broken Axis\nexport { PluginBrokenAxis, type PluginBrokenAxisConfig, type BrokenAxisAPI, type AxisBreak } from \"./broken-axis\";\n\n// Video Recorder\nexport { PluginVideoRecorder, type PluginVideoRecorderConfig, type VideoRecorderAPI, type VideoRecorderOptions } from \"./video-recorder\";\n\n// Offscreen Rendering\nexport { PluginOffscreen, type PluginOffscreenConfig, type OffscreenAPI, type OffscreenStats, type OffscreenMode, type OffscreenTransferMode, type OffscreenFallbackMode } from \"./offscreen\";\n\n// Virtualization\nexport { PluginVirtualization, type PluginVirtualizationConfig, type VirtualizationAPI, type VirtualizationStats, type VirtualizationMode, type VirtualizationStrategy } from \"./virtualization\";\n\n// Stage 2 — Trading\nexport { PluginDrawingTools, type PluginDrawingToolsConfig, type DrawingToolsAPI, type DrawingMode } from \"./drawing-tools\";\nexport { PluginReplay, type PluginReplayConfig, type ReplayAPI } from \"./replay\";\n\n// ROI\nexport { PluginROI, type PluginROIConfig, type RoiAPI, type RoiRegion, type RoiPoint, type RoiMaskResult, type RoiTool, type RoiEvent, type RoiSelectedEvent } from \"./roi\";\n\n// ============================================\n// Helper for creating typed plugins\n// ============================================\n\n/**\n * Helper function to create a plugin with proper typing\n * \n * @example\n * ```typescript\n * const MyPlugin = createPlugin({\n * manifest: {\n * name: 'my-plugin',\n * version: '1.0.0',\n * provides: ['analysis'],\n * },\n * onInit(ctx) {\n * ctx.log.info('Plugin initialized!');\n * },\n * onAfterRender(ctx, event) {\n * // Custom rendering\n * },\n * api: {\n * doSomething() { return 'done'; }\n * }\n * });\n * \n * chart.use(MyPlugin);\n * ```\n */\nexport function createPlugin<TConfig = void, TApi extends Record<string, unknown> = {}>(\n definition: import(\"./types\").ChartPlugin<TConfig> & { api?: TApi }\n): import(\"./types\").ChartPlugin<TConfig> & { api: TApi } {\n return definition as import(\"./types\").ChartPlugin<TConfig> & { api: TApi };\n}\n\n/**\n * Helper function to create a configurable plugin factory\n * \n * @example\n * ```typescript\n * interface MyConfig {\n * color: string;\n * enabled: boolean;\n * }\n * \n * const MyPlugin = createConfigurablePlugin<MyConfig>(\n * {\n * name: 'my-plugin',\n * version: '1.0.0',\n * },\n * (config) => ({\n * onInit(ctx) {\n * ctx.log.info(`Color: ${config?.color}`);\n * }\n * })\n * );\n * \n * chart.use(MyPlugin({ color: 'red', enabled: true }));\n * ```\n */\nexport function createConfigurablePlugin<TConfig = void>(\n manifest: import(\"./types\").PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): import(\"./types\").PluginFactory<TConfig> {\n return (config?: TConfig) => ({\n ...factory(config),\n manifest,\n });\n}\n"],"names":["createRenderer","canvas","NativeWebGLRenderer","PluginRegistryImpl","__publicField","entry","name","existed","_a","capability","results","tag","lowerTag","t","registryInstance","getPluginRegistry","registerPlugin","definePlugin","manifest","factory","config","defineAndRegister","pluginFactory","loadPlugin","listPluginsByCategory","registry","categories","result","cat","validateManifest","errors","checkPluginCompatibility","engineVersion","warnings","reqMajor","curMajor","createPlugin","definition","createConfigurablePlugin"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.core-fpZ1dYN0.js","sources":["../src/renderer/RendererInterface.ts","../src/plugins/PluginRegistry.ts","../src/plugins/index.ts"],"sourcesContent":["/**\n * WebGL Renderer Interface & Factory\n *\n * This module provides a common interface for WebGL rendering.\n * Currently optimized for NativeWebGLRenderer (zero dependencies).\n */\n\nimport type { Bounds } from '../types';\nimport { NativeWebGLRenderer } from './NativeWebGLRenderer';\n\n// ============================================\n// Common Types\n// ============================================\n\nexport interface SeriesRenderData {\n id: string;\n buffer: WebGLBuffer;\n count: number;\n style: any;\n visible: boolean;\n type: string;\n zBounds?: { min: number; max: number };\n colormapTexture?: WebGLTexture;\n}\n\nexport interface RenderOptions {\n bounds: Bounds;\n backgroundColor?: [number, number, number, number];\n}\n\n// ============================================\n// Renderer Interface\n// ============================================\n\n/**\n * Common interface for all WebGL renderer implementations\n */\nexport interface IWebGLRenderer {\n /** Check if WebGL is available and initialized */\n readonly available: boolean;\n\n /**\n * Create or update a GPU buffer with interleaved X,Y data\n * @param id - Unique buffer identifier\n * @param data - Interleaved Float32Array [x0, y0, x1, y1, ...]\n */\n createBuffer(id: string, data: Float32Array): void;\n\n /**\n * Get a buffer by ID\n */\n getBuffer(id: string): WebGLBuffer | undefined;\n\n /**\n * Delete a buffer and free GPU memory\n */\n deleteBuffer(id: string): void;\n \n /** \n * Create a 1D texture for heatmaps \n */\n createColormapTexture(id: string, data: Uint8Array): WebGLTexture;\n\n /**\n * Render a frame with all visible series\n */\n render(series: SeriesRenderData[], options: RenderOptions): void;\n\n /**\n * Handle canvas resize\n */\n resize(): void;\n\n /**\n * Get WebGL capabilities/limits\n */\n getLimits(): Record<string, unknown>;\n\n /**\n * Cleanup and destroy all GPU resources\n */\n destroy(): void;\n}\n\n// ============================================\n// Factory Functions\n// ============================================\n\n/**\n * Create a WebGL renderer (Native WebGL)\n *\n * @param canvas - Target canvas element\n */\nexport function createRenderer(canvas: HTMLCanvasElement): IWebGLRenderer {\n return new NativeWebGLRenderer(canvas);\n}\n\n/**\n * Create a renderer synchronously (native only)\n */\nexport { NativeWebGLRenderer as createNativeRenderer } from './NativeWebGLRenderer';\n","/**\n * Sci Plot - Global Plugin Registry\n * \n * Provides a global registry for third-party plugins that can be\n * discovered and loaded by name without explicit imports.\n * \n * @module plugins/PluginRegistry\n */\n\nimport type {\n PluginFactory,\n PluginManifest,\n PluginCapability,\n PluginRegistry,\n PluginRegistryEntry,\n} from \"./types\";\n\n// ============================================\n// Global Registry Implementation\n// ============================================\n\nclass PluginRegistryImpl implements PluginRegistry {\n private entries = new Map<string, PluginRegistryEntry>();\n\n /**\n * Register a plugin globally\n */\n register(entry: PluginRegistryEntry): void {\n const name = entry.manifest.name;\n\n if (this.entries.has(name)) {\n console.warn(\n `[SciPlot Registry] Plugin \"${name}\" is already registered, overwriting`\n );\n }\n\n this.entries.set(name, entry);\n }\n\n /**\n * Unregister a plugin\n */\n unregister(name: string): boolean {\n const existed = this.entries.has(name);\n this.entries.delete(name);\n return existed;\n }\n\n /**\n * Get a registered plugin factory by name\n */\n get(name: string): PluginFactory | undefined {\n return this.entries.get(name)?.factory;\n }\n\n /**\n * List all registered plugins\n */\n list(): PluginManifest[] {\n return Array.from(this.entries.values()).map((e) => e.manifest);\n }\n\n /**\n * Search plugins by capability\n */\n findByCapability(capability: PluginCapability): PluginManifest[] {\n const results: PluginManifest[] = [];\n\n this.entries.forEach((entry) => {\n if (entry.manifest.provides?.includes(capability)) {\n results.push(entry.manifest);\n }\n });\n\n return results;\n }\n\n /**\n * Search plugins by tag\n */\n findByTag(tag: string): PluginManifest[] {\n const results: PluginManifest[] = [];\n const lowerTag = tag.toLowerCase();\n\n this.entries.forEach((entry) => {\n if (entry.manifest.tags?.some((t) => t.toLowerCase().includes(lowerTag))) {\n results.push(entry.manifest);\n }\n });\n\n return results;\n }\n\n /**\n * Check if a plugin is registered\n */\n has(name: string): boolean {\n return this.entries.has(name);\n }\n\n /**\n * Get plugin count\n */\n get size(): number {\n return this.entries.size;\n }\n\n /**\n * Clear all registrations\n */\n clear(): void {\n this.entries.clear();\n }\n}\n\n// ============================================\n// Singleton Instance\n// ============================================\n\nlet registryInstance: PluginRegistryImpl | null = null;\n\n/**\n * Get the global plugin registry singleton\n */\nexport function getPluginRegistry(): PluginRegistry {\n if (!registryInstance) {\n registryInstance = new PluginRegistryImpl();\n }\n return registryInstance;\n}\n\n/**\n * Register a plugin in the global registry\n * Shorthand for getPluginRegistry().register()\n */\nexport function registerPlugin(entry: PluginRegistryEntry): void {\n getPluginRegistry().register(entry);\n}\n\n/**\n * Create a plugin factory with manifest validation\n */\nexport function definePlugin<TConfig = unknown>(\n manifest: PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): PluginFactory<TConfig> {\n return (config?: TConfig) => {\n const plugin = factory(config);\n return {\n ...plugin,\n manifest,\n };\n };\n}\n\n/**\n * Register a plugin from definition\n */\nexport function defineAndRegister<TConfig = unknown>(\n manifest: PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): PluginFactory<TConfig> {\n const pluginFactory = definePlugin(manifest, factory);\n registerPlugin({ manifest, factory: pluginFactory as PluginFactory });\n return pluginFactory;\n}\n\n// ============================================\n// Plugin Discovery Helpers\n// ============================================\n\n/**\n * Load a plugin from the registry by name\n */\nexport async function loadPlugin<TConfig = unknown>(\n name: string,\n config?: TConfig\n): Promise<import(\"./types\").ChartPlugin<TConfig> | undefined> {\n const factory = getPluginRegistry().get(name);\n if (!factory) {\n console.warn(`[SciPlot] Plugin \"${name}\" not found in registry`);\n return undefined;\n }\n return factory(config) as import(\"./types\").ChartPlugin<TConfig>;\n}\n\n/**\n * List available plugins by category\n */\nexport function listPluginsByCategory(): Record<PluginCapability, PluginManifest[]> {\n const registry = getPluginRegistry();\n const categories: PluginCapability[] = [\n \"analysis\",\n \"visualization\",\n \"interaction\",\n \"data-source\",\n \"export\",\n \"ui\",\n \"annotation\",\n \"theme\",\n ];\n\n const result: Record<string, PluginManifest[]> = {};\n categories.forEach((cat) => {\n result[cat] = registry.findByCapability(cat);\n });\n\n return result as Record<PluginCapability, PluginManifest[]>;\n}\n\n// ============================================\n// Plugin Validation\n// ============================================\n\n/**\n * Validate a plugin manifest\n */\nexport function validateManifest(manifest: PluginManifest): string[] {\n const errors: string[] = [];\n\n if (!manifest.name) {\n errors.push(\"Missing required field: name\");\n } else if (!/^[@a-z0-9-]+\\/[a-z0-9-]+$|^[a-z0-9-]+$/.test(manifest.name)) {\n errors.push(\n 'Invalid name format. Use lowercase with hyphens, optionally scoped (e.g., \"@org/name\")'\n );\n }\n\n if (!manifest.version) {\n errors.push(\"Missing required field: version\");\n } else if (!/^\\d+\\.\\d+\\.\\d+$/.test(manifest.version)) {\n errors.push(\"Invalid version format. Use semantic versioning (e.g., 1.0.0)\");\n }\n\n if (manifest.dependencies) {\n if (!Array.isArray(manifest.dependencies)) {\n errors.push(\"dependencies must be an array\");\n }\n }\n\n if (manifest.provides) {\n if (!Array.isArray(manifest.provides)) {\n errors.push(\"provides must be an array\");\n }\n }\n\n return errors;\n}\n\n/**\n * Validate a plugin for compatibility\n */\nexport function checkPluginCompatibility(\n manifest: PluginManifest,\n engineVersion: string\n): { compatible: boolean; warnings: string[] } {\n const warnings: string[] = [];\n\n if (manifest.engineVersion) {\n const [reqMajor] = manifest.engineVersion.split(\".\").map(Number);\n const [curMajor] = engineVersion.split(\".\").map(Number);\n\n if (reqMajor > curMajor) {\n return {\n compatible: false,\n warnings: [\n `Plugin requires engine v${manifest.engineVersion}, current is v${engineVersion}`,\n ],\n };\n }\n\n if (reqMajor < curMajor) {\n warnings.push(\n `Plugin was built for engine v${manifest.engineVersion}, may have compatibility issues`\n );\n }\n }\n\n return { compatible: true, warnings };\n}\n","/**\n * Sci Plot - Plugin System\n * \n * Comprehensive plugin architecture for extending chart functionality.\n * \n * Features:\n * - Complete lifecycle hooks (init, render, data, view, interaction, destroy)\n * - Rich plugin context with access to all chart internals\n * - Plugin storage for persistent state\n * - Dependency management between plugins\n * - Global registry for third-party plugins\n * - Built-in plugins for common use cases\n * \n * @packageDocumentation\n * @module plugins\n */\n\n// ============================================\n// Core Types\n// ============================================\nexport type {\n // Manifest & Metadata\n PluginVersion,\n PluginCapability,\n PluginManifest,\n\n // Context Types\n PluginContext,\n RenderContext,\n CoordinateContext,\n DataContext,\n UIContext,\n EventContext,\n PluginStorage,\n PluginLogger,\n OverlayOptions,\n NotificationOptions,\n PickResult,\n\n // Hook Event Types\n BeforeRenderEvent,\n AfterRenderEvent,\n InteractionEvent,\n ViewChangeEvent,\n SeriesChangeEvent,\n DataUpdateEvent,\n\n // Plugin Types\n ChartPlugin,\n PluginFactory,\n TypedPlugin,\n\n // Manager Types\n PluginManager,\n PluginRegistry,\n PluginRegistryEntry,\n} from \"./types\";\n\n// ============================================\n// Core Implementation\n// ============================================\nexport { createPluginContext } from \"./PluginContext\";\nexport type { ContextDependencies } from \"./PluginContext\";\n\nexport { PluginManagerImpl } from \"./PluginManager\";\n\n// ============================================\n// Registry\n// ============================================\nexport {\n getPluginRegistry,\n registerPlugin,\n definePlugin,\n defineAndRegister,\n loadPlugin,\n listPluginsByCategory,\n validateManifest,\n checkPluginCompatibility,\n} from \"./PluginRegistry\";\n\n// ============================================\n// Built-in Plugins\n// ============================================\nexport {\n // Individual plugins\n CrosshairPlugin,\n StatsPlugin,\n WatermarkPlugin,\n GridHighlightPlugin,\n DataLoggerPlugin,\n DirectionIndicatorPlugin,\n\n // Plugin collection\n BuiltinPlugins,\n\n // Plugin configs\n type CrosshairPluginConfig,\n type StatsPluginConfig,\n type WatermarkPluginConfig,\n type GridHighlightConfig,\n type DataLoggerConfig,\n type DirectionIndicatorConfig,\n} from \"./builtins\";\n\n// ============================================\n// Modular Plugins\n// ============================================\nexport { Plugin3D, type Plugin3DConfig } from \"./3d\";\nexport { PluginGpu, type PluginGpuConfig } from \"./gpu\";\nexport { PluginAnalysis, type PluginAnalysisConfig } from \"./analysis\";\nexport { PluginTools, type PluginToolsConfig } from \"./tools\";\nexport { PluginAnnotations, type PluginAnnotationsConfig } from \"./annotations\";\nexport { PluginStreaming, type PluginStreamingConfig } from \"./streaming\";\nexport { PluginThemeEditor, type PluginThemeEditorConfig } from \"./theme-editor\";\nexport { PluginI18n, type PluginI18nConfig } from \"./i18n\";\nexport { PluginKeyboard, type PluginKeyboardConfig } from \"./keyboard\";\nexport { PluginClipboard, type PluginClipboardConfig } from \"./clipboard\";\nexport { PluginSync, type PluginSyncConfig } from \"./sync\";\nexport { PluginDebug, type PluginDebugConfig } from \"./debug\";\nexport { PluginLoading, type PluginLoadingConfig } from \"./loading\";\nexport { PluginDataExport, type PluginDataExportConfig } from \"./data-export\";\nexport { PluginContextMenu, type PluginContextMenuConfig } from \"./context-menu\";\nexport { PluginAnomalyDetection, type PluginAnomalyDetectionConfig, type AnomalyDetectionResult, type AnomalyPoint, type AnomalyMethod } from \"./anomaly-detection\";\nexport { PluginMLIntegration, type PluginMLIntegrationConfig, type MLIntegrationAPI, type MLModelAPI, type PredictionResult, type VisualizationConfig } from \"./ml-integration\";\nexport { PluginPatternRecognition, type PluginPatternRecognitionConfig, type PatternRecognitionAPI, type PatternMatch, type PatternDetectionResult } from \"./pattern-recognition\";\nexport { PluginRegression, type PluginRegressionConfig, type RegressionAPI, type RegressionResult, type RegressionData } from \"./regression\";\nexport { PluginRadar, type PluginRadarConfig, type RadarAPI, type RadarSeriesData, type RadarPoint } from \"./radar\";\nexport { PluginSnapshot, type PluginSnapshotConfig, type SnapshotExportAPI, type SnapshotExportOptions, type SnapshotResolution, type SnapshotFormat } from \"./snapshot\";\nexport { PluginDataTransform, type PluginDataTransformConfig, type DataTransformAPI, type TransformOp, type TransformType } from \"./data-transform\";\nexport { PluginLaTeX, type PluginLaTeXConfig, type LaTeXPluginAPI, type LaTeXDimensions } from \"./latex\";\nexport * from \"./forecasting\";\n\n// Drag & Drop Editing\nexport { PluginDragEdit, type PluginDragEditConfig, type DragEditAPI, type DragEditEvent } from \"./drag-edit\";\n\n// Caching\nexport { PluginCaching, type PluginCachingConfig, type CachingAPI, type CacheStats } from \"./caching\";\n\n// Lazy Loading\nexport { PluginLazyLoad, type PluginLazyLoadConfig, type LazyLoadAPI, type DataProvider } from \"./lazy-load\";\n\n// Broken Axis\nexport { PluginBrokenAxis, type PluginBrokenAxisConfig, type BrokenAxisAPI, type AxisBreak } from \"./broken-axis\";\n\n// Video Recorder\nexport { PluginVideoRecorder, type PluginVideoRecorderConfig, type VideoRecorderAPI, type VideoRecorderOptions } from \"./video-recorder\";\n\n// Offscreen Rendering\nexport { PluginOffscreen, type PluginOffscreenConfig, type OffscreenAPI, type OffscreenStats, type OffscreenMode, type OffscreenTransferMode, type OffscreenFallbackMode } from \"./offscreen\";\n\n// Virtualization\nexport { PluginVirtualization, type PluginVirtualizationConfig, type VirtualizationAPI, type VirtualizationStats, type VirtualizationMode, type VirtualizationStrategy } from \"./virtualization\";\n\n// Stage 2 — Trading\nexport { PluginDrawingTools, type PluginDrawingToolsConfig, type DrawingToolsAPI, type DrawingMode } from \"./drawing-tools\";\nexport { PluginReplay, type PluginReplayConfig, type ReplayAPI } from \"./replay\";\n\n// ROI\nexport { PluginROI, type PluginROIConfig, type RoiAPI, type RoiRegion, type RoiPoint, type RoiMaskResult, type RoiTool, type RoiEvent, type RoiSelectedEvent } from \"./roi\";\n\n// ============================================\n// Helper for creating typed plugins\n// ============================================\n\n/**\n * Helper function to create a plugin with proper typing\n * \n * @example\n * ```typescript\n * const MyPlugin = createPlugin({\n * manifest: {\n * name: 'my-plugin',\n * version: '1.0.0',\n * provides: ['analysis'],\n * },\n * onInit(ctx) {\n * ctx.log.info('Plugin initialized!');\n * },\n * onAfterRender(ctx, event) {\n * // Custom rendering\n * },\n * api: {\n * doSomething() { return 'done'; }\n * }\n * });\n * \n * chart.use(MyPlugin);\n * ```\n */\nexport function createPlugin<TConfig = void, TApi extends Record<string, unknown> = {}>(\n definition: import(\"./types\").ChartPlugin<TConfig> & { api?: TApi }\n): import(\"./types\").ChartPlugin<TConfig> & { api: TApi } {\n return definition as import(\"./types\").ChartPlugin<TConfig> & { api: TApi };\n}\n\n/**\n * Helper function to create a configurable plugin factory\n * \n * @example\n * ```typescript\n * interface MyConfig {\n * color: string;\n * enabled: boolean;\n * }\n * \n * const MyPlugin = createConfigurablePlugin<MyConfig>(\n * {\n * name: 'my-plugin',\n * version: '1.0.0',\n * },\n * (config) => ({\n * onInit(ctx) {\n * ctx.log.info(`Color: ${config?.color}`);\n * }\n * })\n * );\n * \n * chart.use(MyPlugin({ color: 'red', enabled: true }));\n * ```\n */\nexport function createConfigurablePlugin<TConfig = void>(\n manifest: import(\"./types\").PluginManifest,\n factory: (config?: TConfig) => Omit<import(\"./types\").ChartPlugin<TConfig>, \"manifest\">\n): import(\"./types\").PluginFactory<TConfig> {\n return (config?: TConfig) => ({\n ...factory(config),\n manifest,\n });\n}\n"],"names":["createRenderer","canvas","NativeWebGLRenderer","PluginRegistryImpl","__publicField","entry","name","existed","_a","capability","results","tag","lowerTag","t","registryInstance","getPluginRegistry","registerPlugin","definePlugin","manifest","factory","config","defineAndRegister","pluginFactory","loadPlugin","listPluginsByCategory","registry","categories","result","cat","validateManifest","errors","checkPluginCompatibility","engineVersion","warnings","reqMajor","curMajor","createPlugin","definition","createConfigurablePlugin"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -51,7 +51,12 @@ export { ChartGroup, createChartGroup, linkCharts, createMasterSlave, type SyncA
|
|
|
51
51
|
export { createStackedChart, STACKED_MAX_PANES, STACKED_DEFAULT_MIN_PANE_RATIO, type StackedChart, type StackedChartOptions, type StackedPaneConfig, type StackedSyncOptions, } from './core/stacked';
|
|
52
52
|
export { buildIndicatorSeries, createIndicatorSeries, buildIndicatorPane, buildIndicatorPaneFromPreset, addIndicatorToChart, computeIndicatorFromSeries, computeIndicatorPreset, detectIndicatorMarkers, type IndicatorData, type IndicatorSeriesOptions, type IndicatorStyle, type IndicatorLineLayer, type IndicatorLineColorZones, type BuildIndicatorPaneOptions, type AddIndicatorOptions, type AddIndicatorResult, type IndicatorPresetName, } from './core/indicator';
|
|
53
53
|
export { mapToBusinessDayScale, isBusinessDay, businessDaySpanMs, type TimeScaleOptions, type BusinessDayMapping, } from './core/time/TimeScale';
|
|
54
|
+
export { isBusinessDayScaleActive, applyBusinessDayX, formatBusinessDayTick, } from './core/time/applyTimeScale';
|
|
54
55
|
export { computeHeikinAshi } from './core/chart/heikinAshi';
|
|
56
|
+
export { buildPositionLineAnnotation, type PositionLineOptions } from './core/chart/positionLines';
|
|
57
|
+
export type { DatafeedAdapter, Bar, SymbolInfo } from './trading/datafeed';
|
|
58
|
+
export { barsToOhlc } from './trading/datafeed';
|
|
59
|
+
export { createMockDatafeed } from './trading/mockDatafeed';
|
|
55
60
|
export type { CandlestickMarker, CandlestickMarkerPosition, CandlestickMarkerShape, } from './core/chart/candlestickMarkers';
|
|
56
61
|
export type { PriceAlertOptions } from './core/chart/ChartAlerts';
|
|
57
62
|
export { ThemeEditor, createThemeEditor, getPresetTheme, getPresetNames, THEME_PRESETS, type EditorTheme, type ThemeEditorOptions, type ThemePreset, type ColorGroup, type ColorProperty, } from './core/theme-editor';
|
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
function j(r, e) {
|
|
2
|
+
if (r.length === 0) return -1;
|
|
3
|
+
let s = 0, n = Math.abs(r[0] - e);
|
|
4
|
+
for (let i = 1; i < r.length; i++) {
|
|
5
|
+
const f = Math.abs(r[i] - e);
|
|
6
|
+
f < n && (n = f, s = i);
|
|
7
|
+
}
|
|
8
|
+
return s;
|
|
9
|
+
}
|
|
10
|
+
function J(r) {
|
|
11
|
+
if (r.barX.length === 0)
|
|
12
|
+
return { x: r.x, y: r.y };
|
|
13
|
+
const e = j(r.barX, r.x);
|
|
14
|
+
if (e < 0) return { x: r.x, y: r.y };
|
|
15
|
+
const s = r.barX[e], n = [
|
|
16
|
+
r.open[e],
|
|
17
|
+
r.high[e],
|
|
18
|
+
r.low[e],
|
|
19
|
+
r.close[e]
|
|
20
|
+
], i = r.dataToPixelY(r.y), f = r.pixelThreshold ?? 12;
|
|
21
|
+
let m = r.y, d = 1 / 0;
|
|
22
|
+
for (const c of n) {
|
|
23
|
+
const h = r.dataToPixelY(c), x = Math.abs(h - i);
|
|
24
|
+
x < d && x <= f && (d = x, m = c);
|
|
25
|
+
}
|
|
26
|
+
return { x: s, y: m };
|
|
27
|
+
}
|
|
28
|
+
function $(r, e) {
|
|
29
|
+
const s = e.y - r.y, n = Math.abs(r.y), i = n > 0 ? s / n * 100 : 0, f = Math.round(Math.abs(e.x - r.x));
|
|
30
|
+
return { change: s, percent: i, bars: f, up: s >= 0 };
|
|
31
|
+
}
|
|
32
|
+
function L(r) {
|
|
33
|
+
const e = r.change >= 0 ? "+" : "";
|
|
34
|
+
return `${e}${r.change.toFixed(2)} (${e}${r.percent.toFixed(2)}%) · ${r.bars} bars`;
|
|
35
|
+
}
|
|
36
|
+
function U(r) {
|
|
37
|
+
const e = Math.abs(r), s = e >= 1e3 ? 0 : e >= 1 ? 2 : 4;
|
|
38
|
+
return r.toLocaleString("en-US", {
|
|
39
|
+
minimumFractionDigits: s,
|
|
40
|
+
maximumFractionDigits: s
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const Y = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1], K = 4, Q = "#26a69a", Z = "#ef5350";
|
|
44
|
+
function E(r, e) {
|
|
45
|
+
return r.startsWith("#") && r.length === 7 ? r + e : r;
|
|
46
|
+
}
|
|
47
|
+
const C = {
|
|
48
|
+
name: "velo-plot-drawing-tools",
|
|
49
|
+
version: "1.0.0",
|
|
50
|
+
description: "Interactive trendline, horizontal, vertical, rectangle, and fibonacci drawing",
|
|
51
|
+
provides: ["drawing"],
|
|
52
|
+
tags: ["drawing", "annotations", "trading"]
|
|
53
|
+
};
|
|
54
|
+
function B(r) {
|
|
55
|
+
return r !== "none" && r !== "pan";
|
|
56
|
+
}
|
|
57
|
+
function tt(r) {
|
|
58
|
+
for (const e of r.data.getAllSeries())
|
|
59
|
+
if (e.getType() === "candlestick") return e;
|
|
60
|
+
}
|
|
61
|
+
function it(r = {}) {
|
|
62
|
+
let e = null;
|
|
63
|
+
const s = r.autoDeselect !== !1;
|
|
64
|
+
let n = {
|
|
65
|
+
mode: "none",
|
|
66
|
+
pending: null,
|
|
67
|
+
start: null,
|
|
68
|
+
dragging: !1,
|
|
69
|
+
dragMoved: !1,
|
|
70
|
+
dragStartPixel: null,
|
|
71
|
+
cursor: null,
|
|
72
|
+
magnet: r.magnet ?? !1,
|
|
73
|
+
undoStack: [],
|
|
74
|
+
redoStack: []
|
|
75
|
+
};
|
|
76
|
+
const i = r.color ?? "#38bdf8", f = r.measureUpColor ?? Q, m = r.measureDownColor ?? Z;
|
|
77
|
+
function d() {
|
|
78
|
+
var t, o;
|
|
79
|
+
return ((o = e == null ? void 0 : (t = e.chart).getAnnotations) == null ? void 0 : o.call(t)) ?? [];
|
|
80
|
+
}
|
|
81
|
+
function c() {
|
|
82
|
+
n.undoStack.push(d()), n.redoStack = [];
|
|
83
|
+
}
|
|
84
|
+
function h() {
|
|
85
|
+
n.pending = null, n.start = null, n.dragging = !1, n.dragMoved = !1, n.dragStartPixel = null;
|
|
86
|
+
}
|
|
87
|
+
function x(t) {
|
|
88
|
+
var o, a;
|
|
89
|
+
n.mode = t, h(), (o = r.onModeChange) == null || o.call(r, t), (a = e == null ? void 0 : e.requestRender) == null || a.call(e);
|
|
90
|
+
}
|
|
91
|
+
function u() {
|
|
92
|
+
var t;
|
|
93
|
+
h(), s ? x("none") : (t = e == null ? void 0 : e.requestRender) == null || t.call(e);
|
|
94
|
+
}
|
|
95
|
+
function T(t, o) {
|
|
96
|
+
if (!e || !n.magnet) return { x: t, y: o };
|
|
97
|
+
const a = tt(e);
|
|
98
|
+
if (!a) return { x: t, y: o };
|
|
99
|
+
const l = a.getData();
|
|
100
|
+
return !l.open || !l.high || !l.low || !l.close ? { x: t, y: o } : J({
|
|
101
|
+
x: t,
|
|
102
|
+
y: o,
|
|
103
|
+
barX: l.x,
|
|
104
|
+
open: l.open,
|
|
105
|
+
high: l.high,
|
|
106
|
+
low: l.low,
|
|
107
|
+
close: l.close,
|
|
108
|
+
dataToPixelX: (y) => e.coords.dataToPixelX(y),
|
|
109
|
+
dataToPixelY: (y) => e.coords.dataToPixelY(y),
|
|
110
|
+
enabled: !0
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
function k(t, o) {
|
|
114
|
+
return T(
|
|
115
|
+
t.coords.pixelToDataX(o.pixelX),
|
|
116
|
+
t.coords.pixelToDataY(o.pixelY)
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
function W(t) {
|
|
120
|
+
e && (c(), e.chart.addAnnotation({
|
|
121
|
+
type: "horizontal-line",
|
|
122
|
+
y: t,
|
|
123
|
+
color: i,
|
|
124
|
+
interactive: !0
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
127
|
+
function z(t) {
|
|
128
|
+
e && (c(), e.chart.addAnnotation({
|
|
129
|
+
type: "vertical-line",
|
|
130
|
+
x: t,
|
|
131
|
+
color: i,
|
|
132
|
+
interactive: !0
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
function _(t, o) {
|
|
136
|
+
if (!e) return;
|
|
137
|
+
c();
|
|
138
|
+
const a = $(t, o), l = a.up ? f : m, y = (t.x + o.x) / 2;
|
|
139
|
+
e.chart.addAnnotation({
|
|
140
|
+
type: "rectangle",
|
|
141
|
+
xMin: Math.min(t.x, o.x),
|
|
142
|
+
xMax: Math.max(t.x, o.x),
|
|
143
|
+
yMin: Math.min(t.y, o.y),
|
|
144
|
+
yMax: Math.max(t.y, o.y),
|
|
145
|
+
strokeColor: l,
|
|
146
|
+
fillColor: E(l, "33"),
|
|
147
|
+
interactive: !0
|
|
148
|
+
}), e.chart.addAnnotation({
|
|
149
|
+
type: "arrow",
|
|
150
|
+
x1: y,
|
|
151
|
+
y1: t.y,
|
|
152
|
+
x2: y,
|
|
153
|
+
y2: o.y,
|
|
154
|
+
color: l,
|
|
155
|
+
headStyle: "filled",
|
|
156
|
+
interactive: !0
|
|
157
|
+
}), e.chart.addAnnotation({
|
|
158
|
+
type: "text",
|
|
159
|
+
x: y,
|
|
160
|
+
y: o.y,
|
|
161
|
+
text: L(a),
|
|
162
|
+
color: "#ffffff",
|
|
163
|
+
backgroundColor: l,
|
|
164
|
+
padding: 4,
|
|
165
|
+
fontWeight: "bold",
|
|
166
|
+
anchor: a.up ? "bottom-center" : "top-center",
|
|
167
|
+
interactive: !0
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
function F(t, o) {
|
|
171
|
+
if (e) {
|
|
172
|
+
if (n.mode === "measure") {
|
|
173
|
+
_(t, o);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (c(), n.mode === "trendline")
|
|
177
|
+
e.chart.addAnnotation({
|
|
178
|
+
type: "arrow",
|
|
179
|
+
x1: t.x,
|
|
180
|
+
y1: t.y,
|
|
181
|
+
x2: o.x,
|
|
182
|
+
y2: o.y,
|
|
183
|
+
color: i,
|
|
184
|
+
interactive: !0
|
|
185
|
+
});
|
|
186
|
+
else if (n.mode === "rectangle")
|
|
187
|
+
e.chart.addAnnotation({
|
|
188
|
+
type: "rectangle",
|
|
189
|
+
xMin: Math.min(t.x, o.x),
|
|
190
|
+
xMax: Math.max(t.x, o.x),
|
|
191
|
+
yMin: Math.min(t.y, o.y),
|
|
192
|
+
yMax: Math.max(t.y, o.y),
|
|
193
|
+
strokeColor: i,
|
|
194
|
+
fillColor: i + "22",
|
|
195
|
+
interactive: !0
|
|
196
|
+
});
|
|
197
|
+
else if (n.mode === "fibonacci") {
|
|
198
|
+
const a = Math.min(t.y, o.y), l = Math.max(t.y, o.y);
|
|
199
|
+
for (const y of Y) {
|
|
200
|
+
const M = l - (l - a) * y;
|
|
201
|
+
e.chart.addAnnotation({
|
|
202
|
+
type: "horizontal-line",
|
|
203
|
+
y: M,
|
|
204
|
+
color: i,
|
|
205
|
+
lineDash: y === 0 || y === 1 ? void 0 : [4, 4],
|
|
206
|
+
label: `${(y * 100).toFixed(1)}% ${U(M)}`,
|
|
207
|
+
labelPosition: "right",
|
|
208
|
+
interactive: !0
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
function H(t, o, a) {
|
|
215
|
+
const l = n.mode;
|
|
216
|
+
if (!B(l) || !n.cursor) return;
|
|
217
|
+
const y = n.cursor, M = n.pending ?? n.start;
|
|
218
|
+
t.save(), t.strokeStyle = i, t.lineWidth = 1.5, t.setLineDash([6, 4]), t.globalAlpha = 0.85;
|
|
219
|
+
const b = (g, v) => ({
|
|
220
|
+
px: a.dataToPixelX(g),
|
|
221
|
+
py: a.dataToPixelY(v)
|
|
222
|
+
});
|
|
223
|
+
if (l === "horizontal") {
|
|
224
|
+
const { py: g } = b(0, y.y);
|
|
225
|
+
t.beginPath(), t.moveTo(o.x, g), t.lineTo(o.x + o.width, g), t.stroke();
|
|
226
|
+
} else if (l === "vertical") {
|
|
227
|
+
const { px: g } = b(y.x, 0);
|
|
228
|
+
t.beginPath(), t.moveTo(g, o.y), t.lineTo(g, o.y + o.height), t.stroke();
|
|
229
|
+
} else if (M) {
|
|
230
|
+
const g = b(M.x, M.y), v = b(y.x, y.y);
|
|
231
|
+
if (l === "trendline")
|
|
232
|
+
t.beginPath(), t.moveTo(g.px, g.py), t.lineTo(v.px, v.py), t.stroke();
|
|
233
|
+
else if (l === "rectangle") {
|
|
234
|
+
const S = Math.min(g.px, v.px), w = Math.min(g.py, v.py), p = Math.abs(v.px - g.px), P = Math.abs(v.py - g.py);
|
|
235
|
+
t.strokeRect(S, w, p, P), t.fillStyle = i + "22", t.fillRect(S, w, p, P);
|
|
236
|
+
} else if (l === "fibonacci") {
|
|
237
|
+
const S = Math.min(M.y, y.y), w = Math.max(M.y, y.y);
|
|
238
|
+
t.font = "11px sans-serif", t.textAlign = "left", t.textBaseline = "bottom";
|
|
239
|
+
for (const p of Y) {
|
|
240
|
+
const P = w - (w - S) * p, { py: A } = b(0, P);
|
|
241
|
+
t.beginPath(), t.moveTo(o.x, A), t.lineTo(o.x + o.width, A), t.stroke(), t.save(), t.setLineDash([]), t.globalAlpha = 1, t.fillStyle = i, t.fillText(
|
|
242
|
+
`${(p * 100).toFixed(1)}% ${U(P)}`,
|
|
243
|
+
o.x + 4,
|
|
244
|
+
A - 2
|
|
245
|
+
), t.restore();
|
|
246
|
+
}
|
|
247
|
+
} else l === "measure" && O(t, g, v, M, y);
|
|
248
|
+
}
|
|
249
|
+
t.restore();
|
|
250
|
+
}
|
|
251
|
+
function O(t, o, a, l, y) {
|
|
252
|
+
const M = $(l, y), b = M.up ? f : m, g = Math.min(o.px, a.px), v = Math.min(o.py, a.py), S = Math.abs(a.px - o.px), w = Math.abs(a.py - o.py);
|
|
253
|
+
t.setLineDash([]), t.globalAlpha = 0.9, t.fillStyle = E(b, "33"), t.fillRect(g, v, S, w), t.strokeStyle = b, t.lineWidth = 1.5, t.strokeRect(g, v, S, w);
|
|
254
|
+
const p = (o.px + a.px) / 2;
|
|
255
|
+
t.beginPath(), t.moveTo(p, o.py), t.lineTo(p, a.py), t.stroke();
|
|
256
|
+
const P = 7, A = a.py >= o.py ? 1 : -1;
|
|
257
|
+
t.beginPath(), t.moveTo(p, a.py), t.lineTo(p - 4, a.py - A * P), t.lineTo(p + 4, a.py - A * P), t.closePath(), t.fillStyle = b, t.fill();
|
|
258
|
+
const I = L(M);
|
|
259
|
+
t.font = "12px sans-serif";
|
|
260
|
+
const R = t.measureText(I).width + 6 * 2, D = 20, G = p - R / 2, X = M.up ? a.py - D - 8 : a.py + 8;
|
|
261
|
+
t.globalAlpha = 1, t.fillStyle = b, t.fillRect(G, X, R, D), t.fillStyle = "#ffffff", t.textAlign = "center", t.textBaseline = "middle", t.fillText(I, p, X + D / 2);
|
|
262
|
+
}
|
|
263
|
+
function N(t, o) {
|
|
264
|
+
var l;
|
|
265
|
+
if (!o.inPlotArea) return;
|
|
266
|
+
o.preventDefault();
|
|
267
|
+
const a = k(t, o);
|
|
268
|
+
if (n.mode === "horizontal") {
|
|
269
|
+
W(a.y), u();
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (n.mode === "vertical") {
|
|
273
|
+
z(a.x), u();
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
if (n.pending) {
|
|
277
|
+
F(n.pending, a), u();
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
n.start = a, n.dragging = !0, n.dragMoved = !1, n.dragStartPixel = { x: o.pixelX, y: o.pixelY }, n.cursor = a, (l = t.requestRender) == null || l.call(t);
|
|
281
|
+
}
|
|
282
|
+
function V(t, o) {
|
|
283
|
+
var l;
|
|
284
|
+
const a = k(t, o);
|
|
285
|
+
if (n.cursor = a, n.dragging && n.dragStartPixel) {
|
|
286
|
+
const y = o.pixelX - n.dragStartPixel.x, M = o.pixelY - n.dragStartPixel.y;
|
|
287
|
+
Math.hypot(y, M) >= K && (n.dragMoved = !0);
|
|
288
|
+
}
|
|
289
|
+
o.preventDefault(), (l = t.requestRender) == null || l.call(t);
|
|
290
|
+
}
|
|
291
|
+
function q(t, o) {
|
|
292
|
+
var y;
|
|
293
|
+
if (!n.dragging || !n.start) return;
|
|
294
|
+
const a = k(t, o), l = n.start;
|
|
295
|
+
if (n.dragging = !1, n.dragStartPixel = null, n.dragMoved) {
|
|
296
|
+
F(l, a), u();
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
n.pending = l, n.start = null, n.cursor = a, (y = t.requestRender) == null || y.call(t);
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
manifest: C,
|
|
303
|
+
api: {
|
|
304
|
+
setMode(t) {
|
|
305
|
+
x(t);
|
|
306
|
+
},
|
|
307
|
+
getMode() {
|
|
308
|
+
return n.mode;
|
|
309
|
+
},
|
|
310
|
+
setMagnet(t) {
|
|
311
|
+
n.magnet = t;
|
|
312
|
+
},
|
|
313
|
+
isMagnet() {
|
|
314
|
+
return n.magnet;
|
|
315
|
+
},
|
|
316
|
+
undo() {
|
|
317
|
+
if (!e || n.undoStack.length === 0) return !1;
|
|
318
|
+
n.redoStack.push(d());
|
|
319
|
+
const t = n.undoStack.pop(), o = d();
|
|
320
|
+
for (const a of o) e.chart.removeAnnotation(a.id);
|
|
321
|
+
for (const a of t) e.chart.addAnnotation(a);
|
|
322
|
+
return !0;
|
|
323
|
+
},
|
|
324
|
+
redo() {
|
|
325
|
+
if (!e || n.redoStack.length === 0) return !1;
|
|
326
|
+
n.undoStack.push(d());
|
|
327
|
+
const t = n.redoStack.pop(), o = d();
|
|
328
|
+
for (const a of o) e.chart.removeAnnotation(a.id);
|
|
329
|
+
for (const a of t) e.chart.addAnnotation(a);
|
|
330
|
+
return !0;
|
|
331
|
+
},
|
|
332
|
+
clear() {
|
|
333
|
+
if (e) {
|
|
334
|
+
c();
|
|
335
|
+
for (const t of d()) e.chart.removeAnnotation(t.id);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
},
|
|
339
|
+
onInit(t) {
|
|
340
|
+
e = t;
|
|
341
|
+
},
|
|
342
|
+
onDestroy() {
|
|
343
|
+
e = null;
|
|
344
|
+
},
|
|
345
|
+
onInteraction(t, o) {
|
|
346
|
+
if (B(n.mode)) {
|
|
347
|
+
if (o.type === "mousedown") {
|
|
348
|
+
N(t, o);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (o.type === "mousemove") {
|
|
352
|
+
V(t, o);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
o.type === "mouseup" && q(t, o);
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
onRenderOverlay(t) {
|
|
359
|
+
const o = t.render.ctx2d;
|
|
360
|
+
o && H(o, t.render.plotArea, t.coords);
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
const et = {
|
|
365
|
+
name: "velo-plot-replay",
|
|
366
|
+
version: "1.0.0",
|
|
367
|
+
description: "Bar-by-bar chart replay with speed control",
|
|
368
|
+
provides: ["replay"],
|
|
369
|
+
tags: ["replay", "trading"]
|
|
370
|
+
};
|
|
371
|
+
function lt(r) {
|
|
372
|
+
let e = null, s = null, n = 0, i = null, f = 1;
|
|
373
|
+
const m = r.frameMs ?? 250;
|
|
374
|
+
function d(h) {
|
|
375
|
+
if (!e || !s) return;
|
|
376
|
+
const x = Math.min(h + 1, s.x.length), u = (T) => T ? T.subarray(0, x) : void 0;
|
|
377
|
+
e.chart.updateSeries(r.seriesId, {
|
|
378
|
+
x: u(s.x),
|
|
379
|
+
y: u(s.y),
|
|
380
|
+
open: u(s.open),
|
|
381
|
+
high: u(s.high),
|
|
382
|
+
low: u(s.low),
|
|
383
|
+
close: u(s.close)
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
const c = {
|
|
387
|
+
play(h = 1) {
|
|
388
|
+
s && (f = Math.max(0.1, h), i && clearInterval(i), i = setInterval(() => {
|
|
389
|
+
if (n >= s.x.length - 1) {
|
|
390
|
+
c.pause();
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
n++, d(n);
|
|
394
|
+
}, m / f));
|
|
395
|
+
},
|
|
396
|
+
pause() {
|
|
397
|
+
i && (clearInterval(i), i = null);
|
|
398
|
+
},
|
|
399
|
+
step(h = 1) {
|
|
400
|
+
s && (n = Math.min(s.x.length - 1, n + h), d(n));
|
|
401
|
+
},
|
|
402
|
+
seek(h) {
|
|
403
|
+
s && (n = Math.max(0, Math.min(s.x.length - 1, h)), d(n));
|
|
404
|
+
},
|
|
405
|
+
getIndex() {
|
|
406
|
+
return n;
|
|
407
|
+
},
|
|
408
|
+
getLength() {
|
|
409
|
+
return (s == null ? void 0 : s.x.length) ?? 0;
|
|
410
|
+
},
|
|
411
|
+
isPlaying() {
|
|
412
|
+
return i != null;
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
return {
|
|
416
|
+
manifest: et,
|
|
417
|
+
api: c,
|
|
418
|
+
onInit(h) {
|
|
419
|
+
e = h;
|
|
420
|
+
const x = e.chart.getSeries(r.seriesId);
|
|
421
|
+
if (!x) {
|
|
422
|
+
console.warn(`[PluginReplay] Series "${r.seriesId}" not found`);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
const u = x.getData();
|
|
426
|
+
s = {
|
|
427
|
+
x: Float32Array.from(u.x),
|
|
428
|
+
y: u.y ? Float32Array.from(u.y) : void 0,
|
|
429
|
+
open: u.open ? Float32Array.from(u.open) : void 0,
|
|
430
|
+
high: u.high ? Float32Array.from(u.high) : void 0,
|
|
431
|
+
low: u.low ? Float32Array.from(u.low) : void 0,
|
|
432
|
+
close: u.close ? Float32Array.from(u.close) : void 0
|
|
433
|
+
}, n = Math.max(0, s.x.length - 1);
|
|
434
|
+
},
|
|
435
|
+
onDestroy() {
|
|
436
|
+
c.pause(), e = null, s = null;
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
function ct(r) {
|
|
441
|
+
const e = r.length, s = new Float64Array(e), n = new Float32Array(e), i = new Float32Array(e), f = new Float32Array(e), m = new Float32Array(e), d = new Float32Array(e);
|
|
442
|
+
for (let c = 0; c < e; c++) {
|
|
443
|
+
const h = r[c];
|
|
444
|
+
s[c] = h.time, n[c] = h.open, i[c] = h.high, f[c] = h.low, m[c] = h.close, d[c] = h.volume ?? 0;
|
|
445
|
+
}
|
|
446
|
+
return { x: s, open: n, high: i, low: f, close: m, volume: d };
|
|
447
|
+
}
|
|
448
|
+
function nt(r) {
|
|
449
|
+
let e = r;
|
|
450
|
+
return () => (e = e * 16807 % 2147483647, (e - 1) / 2147483646);
|
|
451
|
+
}
|
|
452
|
+
function ot(r, e, s, n, i) {
|
|
453
|
+
const f = [];
|
|
454
|
+
let m = n;
|
|
455
|
+
for (let d = r; d <= e; d += s) {
|
|
456
|
+
const c = m, h = (i() - 0.48) * 2, x = Math.max(1, c + h), u = Math.max(c, x) + i() * 1.5, T = Math.min(c, x) - i() * 1.5;
|
|
457
|
+
f.push({
|
|
458
|
+
time: d,
|
|
459
|
+
open: c,
|
|
460
|
+
high: u,
|
|
461
|
+
low: T,
|
|
462
|
+
close: x,
|
|
463
|
+
volume: 1e3 + i() * 5e3
|
|
464
|
+
}), m = x;
|
|
465
|
+
}
|
|
466
|
+
return f;
|
|
467
|
+
}
|
|
468
|
+
function ft(r = {}) {
|
|
469
|
+
const e = r.barMs ?? 6e4, s = r.basePrice ?? 100, n = nt(r.seed ?? 42), i = /* @__PURE__ */ new Map();
|
|
470
|
+
return {
|
|
471
|
+
async resolveSymbol(f) {
|
|
472
|
+
return {
|
|
473
|
+
symbol: f,
|
|
474
|
+
name: f,
|
|
475
|
+
description: `Mock symbol ${f}`,
|
|
476
|
+
timezone: "UTC",
|
|
477
|
+
session: "24x7",
|
|
478
|
+
pricescale: 100
|
|
479
|
+
};
|
|
480
|
+
},
|
|
481
|
+
async getBars(f) {
|
|
482
|
+
const m = `${f.symbol}:${f.from}:${f.to}`;
|
|
483
|
+
return i.has(m) || i.set(
|
|
484
|
+
m,
|
|
485
|
+
ot(f.from, f.to, e, s, n)
|
|
486
|
+
), i.get(m);
|
|
487
|
+
},
|
|
488
|
+
subscribeBars(f) {
|
|
489
|
+
let m = s + n() * 5;
|
|
490
|
+
const d = setInterval(() => {
|
|
491
|
+
const c = m, h = Math.max(1, c + (n() - 0.5) * 2), x = Math.max(c, h) + n(), u = Math.min(c, h) - n();
|
|
492
|
+
f.onBar({
|
|
493
|
+
time: Date.now(),
|
|
494
|
+
open: c,
|
|
495
|
+
high: x,
|
|
496
|
+
low: u,
|
|
497
|
+
close: h,
|
|
498
|
+
volume: 1e3 + n() * 3e3
|
|
499
|
+
}), m = h;
|
|
500
|
+
}, e);
|
|
501
|
+
return () => clearInterval(d);
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
export {
|
|
506
|
+
it as P,
|
|
507
|
+
lt as a,
|
|
508
|
+
ct as b,
|
|
509
|
+
ft as c
|
|
510
|
+
};
|
|
511
|
+
//# sourceMappingURL=mockDatafeed-Cdg5hKEo.js.map
|