velo-plot 3.1.0 → 4.0.0-alpha.1
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-AnR_3Xkb.js → ChartCore-KYG2HTcK.js} +1349 -1213
- package/dist/ChartCore-KYG2HTcK.js.map +1 -0
- package/dist/{PluginRegistry-CzMHebYP.js → PluginRegistry-CDf_jcnp.js} +2 -2
- package/dist/{PluginRegistry-CzMHebYP.js.map → PluginRegistry-CDf_jcnp.js.map} +1 -1
- package/dist/SVGDocumentBuilder-C-uLkcFW.js +83 -0
- package/dist/SVGDocumentBuilder-C-uLkcFW.js.map +1 -0
- package/dist/angular-hooks.js +1 -1
- package/dist/angular.js +4 -4
- package/dist/{chartSyncBridge-D_rCtbFq.js → chartSyncBridge-C1uRy0ZS.js} +3 -3
- package/dist/{chartSyncBridge-D_rCtbFq.js.map → chartSyncBridge-C1uRy0ZS.js.map} +1 -1
- package/dist/core/chart/ChartCore.d.ts +7 -3
- package/dist/core/chart/ChartRenderLoop.d.ts +5 -0
- package/dist/core/chart/ChartRenderer.d.ts +9 -0
- package/dist/core/chart/ChartSetup.d.ts +1 -0
- package/dist/core/chart/exporter/SVGExporter.d.ts +9 -7
- package/dist/core/chart/exporter/svg/SVGDocumentBuilder.d.ts +27 -0
- package/dist/core/chart/exporter/svg/SVGExportContext.d.ts +147 -0
- package/dist/core/chart/exporter/svg/SVGOrchestrator.d.ts +3 -0
- package/dist/core/chart/exporter/svg/SVGThemeAdapter.d.ts +22 -0
- package/dist/core/chart/exporter/svg/__tests__/testFixtures.d.ts +46 -0
- package/dist/core/chart/exporter/svg/__tests__/visualTestUtils.d.ts +12 -0
- package/dist/core/chart/exporter/svg/overlay/axes.d.ts +4 -0
- package/dist/core/chart/exporter/svg/overlay/border.d.ts +4 -0
- package/dist/core/chart/exporter/svg/overlay/errorBars.d.ts +7 -0
- package/dist/core/chart/exporter/svg/overlay/grid.d.ts +4 -0
- package/dist/core/chart/exporter/svg/overlay/index.d.ts +12 -0
- package/dist/core/chart/exporter/svg/overlay/legend.d.ts +4 -0
- package/dist/core/chart/exporter/svg/overlay/pluginCharts.d.ts +6 -0
- package/dist/core/chart/exporter/svg/overlay/polarGrid.d.ts +4 -0
- package/dist/core/chart/exporter/svg/overlay/specialChart.d.ts +15 -0
- package/dist/core/chart/exporter/svg/overlay/title.d.ts +4 -0
- package/dist/core/chart/exporter/svg/plugins/annotations.d.ts +5 -0
- package/dist/core/chart/exporter/svg/plugins/brokenAxis.d.ts +20 -0
- package/dist/core/chart/exporter/svg/plugins/latex.d.ts +9 -0
- package/dist/core/chart/exporter/svg/plugins/register.d.ts +8 -0
- package/dist/core/chart/exporter/svg/plugins/regression.d.ts +33 -0
- package/dist/core/chart/exporter/svg/plugins/roi.d.ts +12 -0
- package/dist/core/chart/exporter/svg/plugins/tradeMarkers.d.ts +3 -0
- package/dist/core/chart/exporter/svg/plugins/types.d.ts +28 -0
- package/dist/core/chart/exporter/svg/plugins/watermark.d.ts +13 -0
- package/dist/core/chart/exporter/svg/series/band.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/bar.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/boxplot.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/candlestick.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/finitePoints.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/gauge.d.ts +5 -0
- package/dist/core/chart/exporter/svg/series/heatmap.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/indicator.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/line.d.ts +12 -0
- package/dist/core/chart/exporter/svg/series/polar.d.ts +6 -0
- package/dist/core/chart/exporter/svg/series/radar.d.ts +5 -0
- package/dist/core/chart/exporter/svg/series/registry.d.ts +10 -0
- package/dist/core/chart/exporter/svg/series/sankey.d.ts +5 -0
- package/dist/core/chart/exporter/svg/series/scatter.d.ts +1 -0
- package/dist/core/chart/exporter/svg/series/ternary.d.ts +7 -0
- package/dist/core/chart/exporter/svg/series/waterfall.d.ts +6 -0
- package/dist/core/chart/exporter/svg/seriesAtTimestamp.d.ts +4 -0
- package/dist/core/chart/exporter/svg/seriesUtils.d.ts +3 -0
- package/dist/core/chart/exporter/svg/symbols.d.ts +5 -0
- package/dist/core/chart/exporter/svg/tickUtils.d.ts +9 -0
- package/dist/core/chart/mountSVGString.d.ts +5 -0
- package/dist/core/chart/types.d.ts +2 -2
- package/dist/core/stacked/StackSVGComposer.d.ts +14 -0
- package/dist/core/stacked/index.d.ts +3 -2
- package/dist/core/stacked/types.d.ts +12 -4
- package/dist/createStackedChart-DjA3aJAu.js +2761 -0
- package/dist/createStackedChart-DjA3aJAu.js.map +1 -0
- package/dist/{hooks-DH-3bewj.js → hooks-4wQH27r9.js} +3 -3
- package/dist/{hooks-DH-3bewj.js.map → hooks-4wQH27r9.js.map} +1 -1
- package/dist/index-Bj-xyXY6.js +582 -0
- package/dist/index-Bj-xyXY6.js.map +1 -0
- package/dist/plugins/PluginManager.d.ts +5 -0
- package/dist/plugins/annotations.js +8 -7
- package/dist/plugins/annotations.js.map +1 -1
- package/dist/plugins/broken-axis.js +198 -152
- package/dist/plugins/broken-axis.js.map +1 -1
- package/dist/plugins/forecasting.js +273 -258
- package/dist/plugins/forecasting.js.map +1 -1
- package/dist/plugins/ml-integration.js +107 -93
- package/dist/plugins/ml-integration.js.map +1 -1
- package/dist/plugins/radar/types.d.ts +11 -0
- package/dist/plugins/radar.js +64 -53
- package/dist/plugins/radar.js.map +1 -1
- package/dist/plugins/roi/index.d.ts +2 -0
- package/dist/plugins/roi.js +184 -145
- package/dist/plugins/roi.js.map +1 -1
- package/dist/plugins/snapshot.js +20 -15
- package/dist/plugins/snapshot.js.map +1 -1
- package/dist/plugins/types.d.ts +4 -0
- package/dist/react.js +2 -2
- package/dist/regression-HNdyk1Dm.js +28 -0
- package/dist/regression-HNdyk1Dm.js.map +1 -0
- package/dist/renderer/ChartSeriesRenderer.d.ts +3 -2
- package/dist/renderer/SVGChartRenderer.d.ts +15 -0
- package/dist/renderer/SankeyRenderer.d.ts +1 -0
- package/dist/renderer/registerSVG.d.ts +5 -0
- package/dist/renderer/sankeyLayout.d.ts +29 -0
- package/dist/scientific.js +2 -2
- package/dist/solid.js +2 -2
- package/dist/svelte.js +2 -2
- package/dist/tickUtils-B_X-ha13.js +41 -0
- package/dist/tickUtils-B_X-ha13.js.map +1 -0
- package/dist/trading.js +3 -3
- package/dist/types.d.ts +2 -1
- package/dist/velo-plot.full.js +1107 -1292
- package/dist/velo-plot.full.js.map +1 -1
- package/dist/velo-plot.js +2 -2
- package/dist/vue/VeloPlot.vue.d.ts +1 -1
- package/dist/vue/index.d.ts +33 -33
- package/dist/vue.js +2 -2
- package/package.json +6 -1
- package/dist/ChartCore-AnR_3Xkb.js.map +0 -1
- package/dist/createStackedChart-DqcLCFGS.js +0 -1338
- package/dist/createStackedChart-DqcLCFGS.js.map +0 -1
- package/dist/index-Cv6ZDLWf.js +0 -521
- package/dist/index-Cv6ZDLWf.js.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var c = Object.defineProperty;
|
|
2
2
|
var g = (i, e, r) => e in i ? c(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-
|
|
4
|
+
import { N as f } from "./ChartCore-KYG2HTcK.js";
|
|
5
5
|
function m(i) {
|
|
6
6
|
return new f(i);
|
|
7
7
|
}
|
|
@@ -151,4 +151,4 @@ export {
|
|
|
151
151
|
p as r,
|
|
152
152
|
$ as v
|
|
153
153
|
};
|
|
154
|
-
//# sourceMappingURL=PluginRegistry-
|
|
154
|
+
//# sourceMappingURL=PluginRegistry-CDf_jcnp.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginRegistry-CzMHebYP.js","sources":["../src/renderer/RendererInterface.ts","../src/plugins/PluginRegistry.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 * Velo 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 `[VeloPlot 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(`[VeloPlot] 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"],"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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PluginRegistry-CDf_jcnp.js","sources":["../src/renderer/RendererInterface.ts","../src/plugins/PluginRegistry.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 * Velo 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 `[VeloPlot 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(`[VeloPlot] 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"],"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"],"mappings":";;;;AA6FO,SAASA,EAAeC,GAA2C;AACxE,SAAO,IAAIC,EAAoBD,CAAM;AACvC;AC1EA,MAAME,EAA6C;AAAA,EAAnD;AACY,IAAAC,EAAA,qCAAc,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKtB,SAASC,GAAkC;AACvC,UAAMC,IAAOD,EAAM,SAAS;AAE5B,IAAI,KAAK,QAAQ,IAAIC,CAAI,KACrB,QAAQ;AAAA,MACJ,+BAA+BA,CAAI;AAAA,IAAA,GAI3C,KAAK,QAAQ,IAAIA,GAAMD,CAAK;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,WAAWC,GAAuB;AAC9B,UAAMC,IAAU,KAAK,QAAQ,IAAID,CAAI;AACrC,gBAAK,QAAQ,OAAOA,CAAI,GACjBC;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,IAAID,GAAyC;;AACzC,YAAOE,IAAA,KAAK,QAAQ,IAAIF,CAAI,MAArB,gBAAAE,EAAwB;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,OAAyB;AACrB,WAAO,MAAM,KAAK,KAAK,QAAQ,QAAQ,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAiBC,GAAgD;AAC7D,UAAMC,IAA4B,CAAA;AAElC,gBAAK,QAAQ,QAAQ,CAACL,MAAU;;AAC5B,OAAIG,IAAAH,EAAM,SAAS,aAAf,QAAAG,EAAyB,SAASC,MAClCC,EAAQ,KAAKL,EAAM,QAAQ;AAAA,IAEnC,CAAC,GAEMK;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,UAAUC,GAA+B;AACrC,UAAMD,IAA4B,CAAA,GAC5BE,IAAWD,EAAI,YAAA;AAErB,gBAAK,QAAQ,QAAQ,CAACN,MAAU;;AAC5B,OAAIG,IAAAH,EAAM,SAAS,SAAf,QAAAG,EAAqB,KAAK,CAACK,MAAMA,EAAE,YAAA,EAAc,SAASD,CAAQ,MAClEF,EAAQ,KAAKL,EAAM,QAAQ;AAAA,IAEnC,CAAC,GAEMK;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,IAAIJ,GAAuB;AACvB,WAAO,KAAK,QAAQ,IAAIA,CAAI;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe;AACf,WAAO,KAAK,QAAQ;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACV,SAAK,QAAQ,MAAA;AAAA,EACjB;AACJ;AAMA,IAAIQ,IAA8C;AAK3C,SAASC,IAAoC;AAChD,SAAKD,MACDA,IAAmB,IAAIX,EAAA,IAEpBW;AACX;AAMO,SAASE,EAAeX,GAAkC;AAC7D,EAAAU,EAAA,EAAoB,SAASV,CAAK;AACtC;AAKO,SAASY,EACZC,GACAC,GACsB;AACtB,SAAO,CAACC,OAEG;AAAA,IACH,GAFWD,EAAQC,CAAM;AAAA,IAGzB,UAAAF;AAAA,EAAA;AAGZ;AAKO,SAASG,EACZH,GACAC,GACsB;AACtB,QAAMG,IAAgBL,EAAaC,GAAUC,CAAO;AACpD,SAAAH,EAAe,EAAE,UAAAE,GAAU,SAASI,EAAA,CAAgC,GAC7DA;AACX;AASA,eAAsBC,EAClBjB,GACAc,GAC2D;AAC3D,QAAMD,IAAUJ,IAAoB,IAAIT,CAAI;AAC5C,MAAI,CAACa,GAAS;AACV,YAAQ,KAAK,sBAAsBb,CAAI,yBAAyB;AAChE;AAAA,EACJ;AACA,SAAOa,EAAQC,CAAM;AACzB;AAKO,SAASI,IAAoE;AAChF,QAAMC,IAAWV,EAAA,GACXW,IAAiC;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,GAGEC,IAA2C,CAAA;AACjD,SAAAD,EAAW,QAAQ,CAACE,MAAQ;AACxB,IAAAD,EAAOC,CAAG,IAAIH,EAAS,iBAAiBG,CAAG;AAAA,EAC/C,CAAC,GAEMD;AACX;AASO,SAASE,EAAiBX,GAAoC;AACjE,QAAMY,IAAmB,CAAA;AAEzB,SAAKZ,EAAS,OAEF,yCAAyC,KAAKA,EAAS,IAAI,KACnEY,EAAO;AAAA,IACH;AAAA,EAAA,IAHJA,EAAO,KAAK,8BAA8B,GAOzCZ,EAAS,UAEF,kBAAkB,KAAKA,EAAS,OAAO,KAC/CY,EAAO,KAAK,+DAA+D,IAF3EA,EAAO,KAAK,iCAAiC,GAK7CZ,EAAS,iBACJ,MAAM,QAAQA,EAAS,YAAY,KACpCY,EAAO,KAAK,+BAA+B,IAI/CZ,EAAS,aACJ,MAAM,QAAQA,EAAS,QAAQ,KAChCY,EAAO,KAAK,2BAA2B,IAIxCA;AACX;AAKO,SAASC,EACZb,GACAc,GAC2C;AAC3C,QAAMC,IAAqB,CAAA;AAE3B,MAAIf,EAAS,eAAe;AACxB,UAAM,CAACgB,CAAQ,IAAIhB,EAAS,cAAc,MAAM,GAAG,EAAE,IAAI,MAAM,GACzD,CAACiB,CAAQ,IAAIH,EAAc,MAAM,GAAG,EAAE,IAAI,MAAM;AAEtD,QAAIE,IAAWC;AACX,aAAO;AAAA,QACH,YAAY;AAAA,QACZ,UAAU;AAAA,UACN,2BAA2BjB,EAAS,aAAa,iBAAiBc,CAAa;AAAA,QAAA;AAAA,MACnF;AAIR,IAAIE,IAAWC,KACXF,EAAS;AAAA,MACL,gCAAgCf,EAAS,aAAa;AAAA,IAAA;AAAA,EAGlE;AAEA,SAAO,EAAE,YAAY,IAAM,UAAAe,EAAA;AAC/B;"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
var u = Object.defineProperty;
|
|
2
|
+
var f = (i, t, e) => t in i ? u(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
|
|
3
|
+
var p = (i, t, e) => f(i, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
let l = 0;
|
|
5
|
+
function n(i) {
|
|
6
|
+
return i.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
7
|
+
}
|
|
8
|
+
function $(i, t = 1) {
|
|
9
|
+
return i.toFixed(t);
|
|
10
|
+
}
|
|
11
|
+
class c {
|
|
12
|
+
constructor(t, e, r) {
|
|
13
|
+
p(this, "defs", []);
|
|
14
|
+
p(this, "layers", /* @__PURE__ */ new Map());
|
|
15
|
+
this.width = t, this.height = e, this.fontFamily = r;
|
|
16
|
+
}
|
|
17
|
+
resetGradientCounter() {
|
|
18
|
+
l = 0;
|
|
19
|
+
}
|
|
20
|
+
addDef(t) {
|
|
21
|
+
const e = `vp-def-${++l}`;
|
|
22
|
+
return this.defs.push(`<${t.includes("id=") ? t : `linearGradient id="${e}" ${t}`}>`), e;
|
|
23
|
+
}
|
|
24
|
+
registerLinearGradient(t, e, r, s, h) {
|
|
25
|
+
const o = `vp-grad-${++l}`, a = h.map(
|
|
26
|
+
(d) => `<stop offset="${d.offset}" stop-color="${d.color}"${d.opacity !== void 0 ? ` stop-opacity="${d.opacity}"` : ""}/>`
|
|
27
|
+
).join("");
|
|
28
|
+
return this.defs.push(
|
|
29
|
+
`<linearGradient id="${o}" x1="${t}" y1="${e}" x2="${r}" y2="${s}">${a}</linearGradient>`
|
|
30
|
+
), o;
|
|
31
|
+
}
|
|
32
|
+
registerClipPath(t, e) {
|
|
33
|
+
this.defs.push(`<clipPath id="${t}">${e}</clipPath>`);
|
|
34
|
+
}
|
|
35
|
+
registerArrowMarker(t, e) {
|
|
36
|
+
this.defs.push(
|
|
37
|
+
`<marker id="${t}" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L8,3 L0,6 Z" fill="${n(e)}"/></marker>`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
push(t, e) {
|
|
41
|
+
this.layers.has(t) || this.layers.set(t, []), this.layers.get(t).push(e);
|
|
42
|
+
}
|
|
43
|
+
pushRaw(t) {
|
|
44
|
+
this.push("default", t);
|
|
45
|
+
}
|
|
46
|
+
openGroup(t, e, r) {
|
|
47
|
+
const s = r ? " " + Object.entries(r).map(([o, a]) => `${o}="${n(a)}"`).join(" ") : "", h = `<g${e ? ` transform="${e}"` : ""}${s}>`;
|
|
48
|
+
return this.push(t, h), t;
|
|
49
|
+
}
|
|
50
|
+
closeGroup(t) {
|
|
51
|
+
this.push(t, "</g>");
|
|
52
|
+
}
|
|
53
|
+
build(t, e) {
|
|
54
|
+
const r = [
|
|
55
|
+
"background",
|
|
56
|
+
"grid",
|
|
57
|
+
"series",
|
|
58
|
+
"errorBars",
|
|
59
|
+
"plugins",
|
|
60
|
+
"axes",
|
|
61
|
+
"border",
|
|
62
|
+
"title",
|
|
63
|
+
"legend",
|
|
64
|
+
"cursor"
|
|
65
|
+
], s = [
|
|
66
|
+
`<svg width="${this.width}" height="${this.height}" viewBox="0 0 ${this.width} ${this.height}" xmlns="http://www.w3.org/2000/svg" font-family="${n(this.fontFamily)}"${e ? ` role="img" aria-label="${n(e)}"` : ""}>`
|
|
67
|
+
];
|
|
68
|
+
e && s.push(`<title>${n(e)}</title>`), s.push(`<rect width="100%" height="100%" fill="${t}" />`), this.defs.length > 0 && s.push(`<defs>${this.defs.join("")}</defs>`), s.push("<g>");
|
|
69
|
+
for (const o of r) {
|
|
70
|
+
const a = this.layers.get(o);
|
|
71
|
+
a && s.push(...a);
|
|
72
|
+
}
|
|
73
|
+
const h = this.layers.get("default");
|
|
74
|
+
return h && s.push(...h), s.push("</g>"), s.push("</svg>"), s.join(`
|
|
75
|
+
`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
c as S,
|
|
80
|
+
n as e,
|
|
81
|
+
$ as f
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=SVGDocumentBuilder-C-uLkcFW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SVGDocumentBuilder-C-uLkcFW.js","sources":["../src/core/chart/exporter/svg/SVGDocumentBuilder.ts"],"sourcesContent":["/**\n * SVG document construction utilities — XML escape, defs, gradients, clipPaths.\n */\n\nlet gradientIdCounter = 0;\n\nexport function escapeXml(text: string): string {\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\");\n}\n\nexport function fmt(n: number, decimals = 1): string {\n return n.toFixed(decimals);\n}\n\nexport class SVGDocumentBuilder {\n private defs: string[] = [];\n private layers: Map<string, string[]> = new Map();\n\n constructor(\n private width: number,\n private height: number,\n private fontFamily: string,\n ) {}\n\n resetGradientCounter(): void {\n gradientIdCounter = 0;\n }\n\n addDef(content: string): string {\n const id = `vp-def-${++gradientIdCounter}`;\n this.defs.push(`<${content.includes(\"id=\") ? content : `linearGradient id=\"${id}\" ${content}`}>`);\n return id;\n }\n\n registerLinearGradient(\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n stops: Array<{ offset: string; color: string; opacity?: number }>,\n ): string {\n const id = `vp-grad-${++gradientIdCounter}`;\n const stopEls = stops\n .map(\n (s) =>\n `<stop offset=\"${s.offset}\" stop-color=\"${s.color}\"${s.opacity !== undefined ? ` stop-opacity=\"${s.opacity}\"` : \"\"}/>`,\n )\n .join(\"\");\n this.defs.push(\n `<linearGradient id=\"${id}\" x1=\"${x1}\" y1=\"${y1}\" x2=\"${x2}\" y2=\"${y2}\">${stopEls}</linearGradient>`,\n );\n return id;\n }\n\n registerClipPath(id: string, content: string): void {\n this.defs.push(`<clipPath id=\"${id}\">${content}</clipPath>`);\n }\n\n registerArrowMarker(id: string, color: string): void {\n this.defs.push(\n `<marker id=\"${id}\" markerWidth=\"8\" markerHeight=\"8\" refX=\"6\" refY=\"3\" orient=\"auto\" markerUnits=\"strokeWidth\">` +\n `<path d=\"M0,0 L8,3 L0,6 Z\" fill=\"${escapeXml(color)}\"/></marker>`,\n );\n }\n\n push(layer: string, element: string): void {\n if (!this.layers.has(layer)) this.layers.set(layer, []);\n this.layers.get(layer)!.push(element);\n }\n\n pushRaw(element: string): void {\n this.push(\"default\", element);\n }\n\n openGroup(layer: string, transform?: string, attrs?: Record<string, string>): string {\n const attrStr = attrs\n ? \" \" + Object.entries(attrs).map(([k, v]) => `${k}=\"${escapeXml(v)}\"`).join(\" \")\n : \"\";\n const el = `<g${transform ? ` transform=\"${transform}\"` : \"\"}${attrStr}>`;\n this.push(layer, el);\n return layer;\n }\n\n closeGroup(layer: string): void {\n this.push(layer, \"</g>\");\n }\n\n build(backgroundColor: string, ariaLabel?: string): string {\n const layerOrder = [\n \"background\",\n \"grid\",\n \"series\",\n \"errorBars\",\n \"plugins\",\n \"axes\",\n \"border\",\n \"title\",\n \"legend\",\n \"cursor\",\n ];\n\n const svg: string[] = [\n `<svg width=\"${this.width}\" height=\"${this.height}\" viewBox=\"0 0 ${this.width} ${this.height}\" xmlns=\"http://www.w3.org/2000/svg\" font-family=\"${escapeXml(this.fontFamily)}\"${ariaLabel ? ` role=\"img\" aria-label=\"${escapeXml(ariaLabel)}\"` : \"\"}>`,\n ];\n\n if (ariaLabel) {\n svg.push(`<title>${escapeXml(ariaLabel)}</title>`);\n }\n\n svg.push(`<rect width=\"100%\" height=\"100%\" fill=\"${backgroundColor}\" />`);\n\n if (this.defs.length > 0) {\n svg.push(`<defs>${this.defs.join(\"\")}</defs>`);\n }\n\n svg.push(\"<g>\");\n for (const layer of layerOrder) {\n const items = this.layers.get(layer);\n if (items) svg.push(...items);\n }\n const defaultLayer = this.layers.get(\"default\");\n if (defaultLayer) svg.push(...defaultLayer);\n svg.push(\"</g>\");\n svg.push(\"</svg>\");\n\n return svg.join(\"\\n\");\n }\n}\n"],"names":["gradientIdCounter","escapeXml","text","fmt","n","decimals","SVGDocumentBuilder","width","height","fontFamily","__publicField","content","id","x1","y1","x2","y2","stops","stopEls","s","color","layer","element","transform","attrs","attrStr","k","v","el","backgroundColor","ariaLabel","layerOrder","svg","items","defaultLayer"],"mappings":"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"}
|
package/dist/angular-hooks.js
CHANGED
package/dist/angular.js
CHANGED
|
@@ -22,11 +22,11 @@ var b = (e) => [, , , Q((e == null ? void 0 : e[$("metadata")]) ?? null)], q = [
|
|
|
22
22
|
}, n = (e, t, s) => j(e, typeof t != "symbol" ? t + "" : t, s), D = (e, t, s) => t.has(e) || f("Cannot " + s), X = (e, t) => Object(t) !== t ? f('Cannot use the "in" operator on this value') : e.has(t), M = (e, t, s) => (D(e, t, "read from private field"), s ? s.call(e) : t.get(e));
|
|
23
23
|
var P = (e, t, s, c) => (D(e, t, "write to private field"), c ? c.call(e, s) : t.set(e, s), s), Y = (e, t, s) => (D(e, t, "access private method"), s);
|
|
24
24
|
import { input as d, output as _, viewChild as J, effect as tt, Component as K } from "@angular/core";
|
|
25
|
-
import { c as et } from "./createStackedChart-
|
|
25
|
+
import { c as et } from "./createStackedChart-DjA3aJAu.js";
|
|
26
26
|
import { p as I, o as st, s as it, d as rt } from "./optionsSync-QUiN4Inw.js";
|
|
27
|
-
import { c as nt } from "./chartSyncBridge-
|
|
28
|
-
import { u as ht } from "./hooks-
|
|
29
|
-
import { V as gt, c as mt, b as vt, a as kt } from "./hooks-
|
|
27
|
+
import { c as nt } from "./chartSyncBridge-C1uRy0ZS.js";
|
|
28
|
+
import { u as ht } from "./hooks-4wQH27r9.js";
|
|
29
|
+
import { V as gt, c as mt, b as vt, a as kt } from "./hooks-4wQH27r9.js";
|
|
30
30
|
function m(e) {
|
|
31
31
|
return typeof e == "number" ? `${e}px` : e;
|
|
32
32
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as s } from "./ChartCore-
|
|
2
|
-
import { a as d } from "./createStackedChart-
|
|
1
|
+
import { c as s } from "./ChartCore-KYG2HTcK.js";
|
|
2
|
+
import { a as d } from "./createStackedChart-DjA3aJAu.js";
|
|
3
3
|
import { c as u } from "./index-CaXWSOTk.js";
|
|
4
4
|
function c(e) {
|
|
5
5
|
const r = e.responsive ?? { reducedMotion: "auto" };
|
|
@@ -55,4 +55,4 @@ export {
|
|
|
55
55
|
f as i,
|
|
56
56
|
p as r
|
|
57
57
|
};
|
|
58
|
-
//# sourceMappingURL=chartSyncBridge-
|
|
58
|
+
//# sourceMappingURL=chartSyncBridge-C1uRy0ZS.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chartSyncBridge-
|
|
1
|
+
{"version":3,"file":"chartSyncBridge-C1uRy0ZS.js","sources":["../src/bindings/shared/chartLifecycle.ts","../src/bindings/shared/indicatorBridge.ts","../src/bindings/shared/chartSyncBridge.ts"],"sourcesContent":["/**\n * Framework-agnostic chart lifecycle helpers.\n */\n\nimport { createChart, type Chart } from \"../../core/Chart\";\nimport type { ChartOptions, Bounds } from \"../../types\";\nimport type { BindingChartOptions } from \"./types\";\n\nexport type ChartBindingOptions = Omit<ChartOptions, \"container\"> &\n BindingChartOptions;\n\nexport interface ChartLifecycleHandle {\n chart: Chart;\n destroy: () => void;\n getBounds: () => Bounds | null;\n}\n\nexport interface ChartLifecycleCallbacks {\n onBoundsChange?: (bounds: Bounds) => void;\n onError?: (error: Error) => void;\n}\n\nfunction defaultResponsive(\n options: ChartBindingOptions,\n): ChartBindingOptions {\n const responsive = options.responsive ?? { reducedMotion: \"auto\" as const };\n return { ...options, responsive };\n}\n\nexport function createChartLifecycle(\n container: HTMLDivElement,\n options: ChartBindingOptions,\n callbacks: ChartLifecycleCallbacks = {},\n): ChartLifecycleHandle {\n const chart = createChart({\n ...defaultResponsive(options),\n container,\n });\n\n const onZoom = () => {\n callbacks.onBoundsChange?.(chart.getViewBounds());\n };\n chart.on(\"zoom\", onZoom);\n\n let resizeObserver: ResizeObserver | undefined;\n if (options.autoResize !== false) {\n resizeObserver = new ResizeObserver(() => {\n chart.resize();\n });\n resizeObserver.observe(container);\n }\n\n return {\n chart,\n getBounds: () => chart.getViewBounds(),\n destroy: () => {\n resizeObserver?.disconnect();\n chart.off(\"zoom\", onZoom);\n chart.destroy();\n },\n };\n}\n\nexport function attachZoomListener(\n chart: Chart,\n onBoundsChange: (bounds: Bounds) => void,\n): () => void {\n const handler = () => onBoundsChange(chart.getViewBounds());\n chart.on(\"zoom\", handler);\n return () => chart.off(\"zoom\", handler);\n}\n","/**\n * Indicator bridge for framework bindings.\n */\n\nimport type { Chart } from \"../../core/chart/types\";\nimport type { StackedChart } from \"../../core/stacked/types\";\nimport {\n addIndicatorToChart,\n type AddIndicatorOptions,\n type AddIndicatorResult,\n} from \"../../core/indicator/addIndicator\";\nimport type { IndicatorPresetName } from \"../../core/indicator/indicatorPresets\";\n\nexport type IndicatorHost = Chart | StackedChart | null;\n\nexport function isStackedChart(host: IndicatorHost): host is StackedChart {\n return (\n host != null &&\n \"getPanes\" in host &&\n typeof (host as StackedChart).getPanes === \"function\"\n );\n}\n\nexport async function addIndicatorToHost(\n host: IndicatorHost,\n preset: IndicatorPresetName,\n options: AddIndicatorOptions = {},\n): Promise<AddIndicatorResult & { paneId?: string }> {\n if (!host) {\n throw new Error(\n \"[useIndicator] Chart is not ready. Wait for isReady before adding indicators.\",\n );\n }\n\n if (isStackedChart(host)) {\n const result = await host.addIndicator(preset, options);\n return result;\n }\n\n return addIndicatorToChart(host, preset, options);\n}\n\nexport function removeIndicatorFromChart(\n chart: Chart,\n rootId: string,\n): void {\n for (const s of [...chart.getAllSeries()]) {\n const sid = s.getId();\n if (sid === rootId || sid.startsWith(`${rootId}-`)) {\n chart.removeSeries(sid);\n }\n }\n}\n","/**\n * Chart sync bridge for framework bindings.\n */\n\nimport {\n ChartGroup,\n createChartGroup,\n type ChartLike,\n type SyncOptions,\n} from \"../../core/sync\";\n\nexport interface ChartSyncHandle {\n group: ChartGroup;\n destroy: () => void;\n}\n\nexport function createChartSync(\n charts: ChartLike[],\n options?: SyncOptions,\n): ChartSyncHandle {\n const group = createChartGroup(charts, options);\n return {\n group,\n destroy: () => group.destroy(),\n };\n}\n\nexport function updateChartSync(\n handle: ChartSyncHandle | null,\n charts: ChartLike[],\n options?: SyncOptions,\n): ChartSyncHandle {\n handle?.destroy();\n if (charts.length < 2) {\n return { group: new ChartGroup(options), destroy: () => {} };\n }\n return createChartSync(charts, options);\n}\n"],"names":["defaultResponsive","options","responsive","createChartLifecycle","container","callbacks","chart","createChart","onZoom","_a","resizeObserver","isStackedChart","host","addIndicatorToHost","preset","addIndicatorToChart","removeIndicatorFromChart","rootId","s","sid","createChartSync","charts","group","createChartGroup"],"mappings":";;;AAsBA,SAASA,EACPC,GACqB;AACrB,QAAMC,IAAaD,EAAQ,cAAc,EAAE,eAAe,OAAA;AAC1D,SAAO,EAAE,GAAGA,GAAS,YAAAC,EAAA;AACvB;AAEO,SAASC,EACdC,GACAH,GACAI,IAAqC,CAAA,GACf;AACtB,QAAMC,IAAQC,EAAY;AAAA,IACxB,GAAGP,EAAkBC,CAAO;AAAA,IAC5B,WAAAG;AAAA,EAAA,CACD,GAEKI,IAAS,MAAM;;AACnB,KAAAC,IAAAJ,EAAU,mBAAV,QAAAI,EAAA,KAAAJ,GAA2BC,EAAM;EACnC;AACA,EAAAA,EAAM,GAAG,QAAQE,CAAM;AAEvB,MAAIE;AACJ,SAAIT,EAAQ,eAAe,OACzBS,IAAiB,IAAI,eAAe,MAAM;AACxC,IAAAJ,EAAM,OAAA;AAAA,EACR,CAAC,GACDI,EAAe,QAAQN,CAAS,IAG3B;AAAA,IACL,OAAAE;AAAA,IACA,WAAW,MAAMA,EAAM,cAAA;AAAA,IACvB,SAAS,MAAM;AACb,MAAAI,KAAA,QAAAA,EAAgB,cAChBJ,EAAM,IAAI,QAAQE,CAAM,GACxBF,EAAM,QAAA;AAAA,IACR;AAAA,EAAA;AAEJ;AC9CO,SAASK,EAAeC,GAA2C;AACxE,SACEA,KAAQ,QACR,cAAcA,KACd,OAAQA,EAAsB,YAAa;AAE/C;AAEA,eAAsBC,EACpBD,GACAE,GACAb,IAA+B,CAAA,GACoB;AACnD,MAAI,CAACW;AACH,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAIJ,SAAID,EAAeC,CAAI,IACN,MAAMA,EAAK,aAAaE,GAAQb,CAAO,IAIjDc,EAAoBH,GAAME,GAAQb,CAAO;AAClD;AAEO,SAASe,EACdV,GACAW,GACM;AACN,aAAWC,KAAK,CAAC,GAAGZ,EAAM,aAAA,CAAc,GAAG;AACzC,UAAMa,IAAMD,EAAE,MAAA;AACd,KAAIC,MAAQF,KAAUE,EAAI,WAAW,GAAGF,CAAM,GAAG,MAC/CX,EAAM,aAAaa,CAAG;AAAA,EAE1B;AACF;ACpCO,SAASC,EACdC,GACApB,GACiB;AACjB,QAAMqB,IAAQC,EAAiBF,GAAQpB,CAAO;AAC9C,SAAO;AAAA,IACL,OAAAqB;AAAA,IACA,SAAS,MAAMA,EAAM,QAAA;AAAA,EAAQ;AAEjC;"}
|
|
@@ -17,6 +17,7 @@ export declare class ChartImpl implements Chart {
|
|
|
17
17
|
private container;
|
|
18
18
|
private webglCanvas;
|
|
19
19
|
private overlayCanvas;
|
|
20
|
+
private svgRoot;
|
|
20
21
|
private overlayCtx;
|
|
21
22
|
series: Map<string, Series>;
|
|
22
23
|
events: EventEmitter<ChartEventMap>;
|
|
@@ -141,7 +142,7 @@ export declare class ChartImpl implements Chart {
|
|
|
141
142
|
private getInteractedBounds;
|
|
142
143
|
exportImage(type?: "png" | "jpeg"): string;
|
|
143
144
|
setFeatureHooks(hooks: ChartFeatureHooks | null): void;
|
|
144
|
-
exportSVG(): string;
|
|
145
|
+
exportSVG(_options?: import('./exporter/SVGExporter').SVGExportOptions): string;
|
|
145
146
|
private getSeriesContext;
|
|
146
147
|
addSeries(options: SeriesOptions | HeatmapOptions): void;
|
|
147
148
|
addBar(options: Omit<SeriesOptions, "type">): void;
|
|
@@ -235,8 +236,11 @@ export declare class ChartImpl implements Chart {
|
|
|
235
236
|
* Get current device pixel ratio
|
|
236
237
|
*/
|
|
237
238
|
getDPR(): number;
|
|
238
|
-
|
|
239
|
-
|
|
239
|
+
getActiveRenderer(): "webgl" | "webgpu" | "svg";
|
|
240
|
+
/** Series id hovered from the legend — affects draw order in canvas and live SVG. */
|
|
241
|
+
getHoveredSeriesId(): string | null;
|
|
242
|
+
/** @internal Vector frame for `renderer: 'svg'` — patched on extended bundles. */
|
|
243
|
+
buildSVGFrame(): string;
|
|
240
244
|
/**
|
|
241
245
|
* Set device pixel ratio and re-render
|
|
242
246
|
*/
|
|
@@ -50,6 +50,11 @@ export interface RenderLoopContext {
|
|
|
50
50
|
direction?: string;
|
|
51
51
|
}>;
|
|
52
52
|
get yScale(): Scale;
|
|
53
|
+
/** Live SVG renderer root (when `renderer: 'svg'`). */
|
|
54
|
+
svgRoot?: SVGSVGElement | null;
|
|
55
|
+
/** Produce full SVG document string for vector renderer mode. */
|
|
56
|
+
buildSVGFrame?: () => string;
|
|
57
|
+
getActiveRenderer?: () => "webgl" | "webgpu" | "svg";
|
|
53
58
|
}
|
|
54
59
|
export declare class ChartRenderLoop {
|
|
55
60
|
private ctx;
|
|
@@ -7,6 +7,10 @@ import { OverlayRenderer } from '../OverlayRenderer';
|
|
|
7
7
|
import { EventEmitter } from '../EventEmitter';
|
|
8
8
|
import { SelectionManager } from '../selection';
|
|
9
9
|
|
|
10
|
+
/** Match series/render ids related to a hovered legend entry (incl. candlestick splits). */
|
|
11
|
+
export declare function matchesHoveredSeriesId(id: string, hoveredSeriesId: string): boolean;
|
|
12
|
+
/** Move hovered series (and related ids) to the end so they paint on top. */
|
|
13
|
+
export declare function reorderForHoveredSeries<T>(items: T[], hoveredSeriesId: string | null, getId: (item: T) => string): T[];
|
|
10
14
|
export interface RenderContext {
|
|
11
15
|
webglCanvas: HTMLCanvasElement;
|
|
12
16
|
overlayCanvas: HTMLCanvasElement;
|
|
@@ -47,7 +51,12 @@ export interface RenderContext {
|
|
|
47
51
|
price: number;
|
|
48
52
|
direction?: string;
|
|
49
53
|
}>;
|
|
54
|
+
getActiveRenderer?: () => "webgl" | "webgpu" | "svg";
|
|
55
|
+
/** When true, overlay draws only interactive UI (cursor, tooltips, plugins). */
|
|
56
|
+
vectorOverlayOnly?: boolean;
|
|
50
57
|
}
|
|
58
|
+
/** Map view bounds to pixel ranges — required before SVG export / vector frame build. */
|
|
59
|
+
export declare function syncScalesForRender(plotArea: PlotArea, viewBounds: Bounds, xScale: Scale, yScales: Map<string, Scale>, yAxisOptionsMap: Map<string, AxisOptions>, xAxisOptions: AxisOptions, primaryYAxisId: string, layout: import('../layout').LayoutOptions): void;
|
|
51
60
|
/**
|
|
52
61
|
* Prepare series data for WebGL rendering
|
|
53
62
|
*/
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Series } from '../../Series';
|
|
2
|
-
import {
|
|
2
|
+
import { Bounds, PlotArea } from '../../../types';
|
|
3
3
|
import { Scale } from '../../../scales';
|
|
4
4
|
import { ChartTheme } from '../../../theme';
|
|
5
|
+
import { SVGExportOptions, SVGExportInput, captureLayoutSnapshot } from './svg/SVGExportContext';
|
|
5
6
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export declare function
|
|
7
|
+
export type { SVGExportOptions } from './svg/SVGExportContext';
|
|
8
|
+
export { captureLayoutSnapshot, buildSVGExportContext } from './svg/SVGExportContext';
|
|
9
|
+
export { renderSVG } from './svg/SVGOrchestrator';
|
|
10
|
+
/** @deprecated Use buildSVGExportContext + renderSVG */
|
|
11
|
+
export declare function exportToSVG(series: Series[], viewBounds: Bounds, plotArea: PlotArea, xAxis: Scale, yAxes: Map<string, Scale>, theme: ChartTheme, width: number, height: number, axisOptions?: SVGExportOptions): string;
|
|
12
|
+
export declare function exportChartToSVG(input: SVGExportInput): string;
|
|
13
|
+
export declare function exportChartSnapshot(chart: Parameters<typeof captureLayoutSnapshot>[0], options?: SVGExportOptions): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG document construction utilities — XML escape, defs, gradients, clipPaths.
|
|
3
|
+
*/
|
|
4
|
+
export declare function escapeXml(text: string): string;
|
|
5
|
+
export declare function fmt(n: number, decimals?: number): string;
|
|
6
|
+
export declare class SVGDocumentBuilder {
|
|
7
|
+
private width;
|
|
8
|
+
private height;
|
|
9
|
+
private fontFamily;
|
|
10
|
+
private defs;
|
|
11
|
+
private layers;
|
|
12
|
+
constructor(width: number, height: number, fontFamily: string);
|
|
13
|
+
resetGradientCounter(): void;
|
|
14
|
+
addDef(content: string): string;
|
|
15
|
+
registerLinearGradient(x1: number, y1: number, x2: number, y2: number, stops: Array<{
|
|
16
|
+
offset: string;
|
|
17
|
+
color: string;
|
|
18
|
+
opacity?: number;
|
|
19
|
+
}>): string;
|
|
20
|
+
registerClipPath(id: string, content: string): void;
|
|
21
|
+
registerArrowMarker(id: string, color: string): void;
|
|
22
|
+
push(layer: string, element: string): void;
|
|
23
|
+
pushRaw(element: string): void;
|
|
24
|
+
openGroup(layer: string, transform?: string, attrs?: Record<string, string>): string;
|
|
25
|
+
closeGroup(layer: string): void;
|
|
26
|
+
build(backgroundColor: string, ariaLabel?: string): string;
|
|
27
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Series } from '../../../Series';
|
|
2
|
+
import { Scale } from '../../../../scales';
|
|
3
|
+
import { ChartTheme } from '../../../../theme';
|
|
4
|
+
import { AxisOptions, Bounds, PlotArea } from '../../../../types';
|
|
5
|
+
import { ChartTitleOptions } from '../../../layout/types';
|
|
6
|
+
import { LayoutOptions } from '../../../layout';
|
|
7
|
+
import { BusinessDayMapping } from '../../../time/TimeScale';
|
|
8
|
+
import { SVGExportPluginContext } from './plugins/types';
|
|
9
|
+
|
|
10
|
+
export interface SVGExportOptions {
|
|
11
|
+
xAxis?: AxisOptions;
|
|
12
|
+
yAxis?: AxisOptions;
|
|
13
|
+
primaryYAxisId?: string;
|
|
14
|
+
/** Include plugin overlays (annotations, regression, etc.) */
|
|
15
|
+
includeOverlays?: boolean;
|
|
16
|
+
/** Include legend in SVG */
|
|
17
|
+
includeLegend?: boolean;
|
|
18
|
+
/** Include annotation plugin content */
|
|
19
|
+
includeAnnotations?: boolean;
|
|
20
|
+
/** Include crosshair at capture position */
|
|
21
|
+
includeCursor?: boolean;
|
|
22
|
+
/** Include selection rectangle */
|
|
23
|
+
includeSelection?: boolean;
|
|
24
|
+
/** Export state at specific timestamp (replay) */
|
|
25
|
+
at?: number;
|
|
26
|
+
/** Optional watermark text (snapshot / export) */
|
|
27
|
+
watermarkText?: string;
|
|
28
|
+
/** Embed web fonts in defs (P2) */
|
|
29
|
+
embedFonts?: boolean;
|
|
30
|
+
/** Accessible label for root SVG */
|
|
31
|
+
ariaLabel?: string;
|
|
32
|
+
/** 3D export mode — deferred */
|
|
33
|
+
svgExport3DMode?: "raster" | "project";
|
|
34
|
+
/** Legacy raster fallback during development */
|
|
35
|
+
svgExportMode?: "vector" | "legacy-raster";
|
|
36
|
+
}
|
|
37
|
+
export interface YAxisLayoutEntry {
|
|
38
|
+
id: string;
|
|
39
|
+
scale: Scale;
|
|
40
|
+
options?: AxisOptions;
|
|
41
|
+
position: "left" | "right";
|
|
42
|
+
offset: number;
|
|
43
|
+
}
|
|
44
|
+
export interface CursorSnapshot {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
}
|
|
48
|
+
export interface SelectionSnapshot {
|
|
49
|
+
x: number;
|
|
50
|
+
y: number;
|
|
51
|
+
width: number;
|
|
52
|
+
height: number;
|
|
53
|
+
}
|
|
54
|
+
export interface PriceAlertSnapshot {
|
|
55
|
+
price: number;
|
|
56
|
+
direction?: string;
|
|
57
|
+
}
|
|
58
|
+
export interface SVGExportContext {
|
|
59
|
+
series: Series[];
|
|
60
|
+
viewBounds: Bounds;
|
|
61
|
+
plotArea: PlotArea;
|
|
62
|
+
xScale: Scale;
|
|
63
|
+
yAxes: Map<string, Scale>;
|
|
64
|
+
yAxisLayouts: YAxisLayoutEntry[];
|
|
65
|
+
theme: ChartTheme;
|
|
66
|
+
width: number;
|
|
67
|
+
height: number;
|
|
68
|
+
xAxisOptions?: AxisOptions;
|
|
69
|
+
yAxisOptionsMap: Map<string, AxisOptions>;
|
|
70
|
+
primaryYAxisId?: string;
|
|
71
|
+
titleOptions?: ChartTitleOptions;
|
|
72
|
+
layout: LayoutOptions;
|
|
73
|
+
businessDayMapping?: BusinessDayMapping | null;
|
|
74
|
+
showLegend: boolean;
|
|
75
|
+
legendSeries: Series[];
|
|
76
|
+
cursor?: CursorSnapshot | null;
|
|
77
|
+
selection?: SelectionSnapshot | null;
|
|
78
|
+
alerts?: PriceAlertSnapshot[];
|
|
79
|
+
options: SVGExportOptions;
|
|
80
|
+
pluginContexts: SVGExportPluginContext[];
|
|
81
|
+
pluginManager?: {
|
|
82
|
+
get: (name: string) => import('../../../../plugins/types').ChartPlugin | undefined;
|
|
83
|
+
notifyExportSVG?: (ctx: SVGExportPluginContext) => void;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export interface SVGExportInput {
|
|
87
|
+
series: Series[];
|
|
88
|
+
viewBounds: Bounds;
|
|
89
|
+
plotArea: PlotArea;
|
|
90
|
+
xScale: Scale;
|
|
91
|
+
yAxes: Map<string, Scale>;
|
|
92
|
+
theme: ChartTheme;
|
|
93
|
+
width: number;
|
|
94
|
+
height: number;
|
|
95
|
+
options?: SVGExportOptions;
|
|
96
|
+
xAxisOptions?: AxisOptions;
|
|
97
|
+
yAxisOptionsMap?: Map<string, AxisOptions>;
|
|
98
|
+
primaryYAxisId?: string;
|
|
99
|
+
titleOptions?: ChartTitleOptions;
|
|
100
|
+
layout?: LayoutOptions;
|
|
101
|
+
businessDayMapping?: BusinessDayMapping | null;
|
|
102
|
+
showLegend?: boolean;
|
|
103
|
+
cursor?: CursorSnapshot | null;
|
|
104
|
+
selection?: SelectionSnapshot | null;
|
|
105
|
+
alerts?: PriceAlertSnapshot[];
|
|
106
|
+
pluginContexts?: SVGExportPluginContext[];
|
|
107
|
+
pluginManager?: SVGExportContext["pluginManager"];
|
|
108
|
+
}
|
|
109
|
+
/** Build Y-axis layout entries with left/right offsets matching OverlayRenderer. */
|
|
110
|
+
export declare function buildYAxisLayouts(_plotArea: PlotArea, yAxes: Map<string, Scale>, yAxisOptionsMap: Map<string, AxisOptions>, primaryYAxisId?: string): YAxisLayoutEntry[];
|
|
111
|
+
export declare function buildSVGExportContext(input: SVGExportInput): SVGExportContext;
|
|
112
|
+
/** Capture layout snapshot from a live ChartImpl instance. */
|
|
113
|
+
export declare function captureLayoutSnapshot(chart: {
|
|
114
|
+
getAllSeries: () => Series[];
|
|
115
|
+
viewBounds: Bounds;
|
|
116
|
+
getPlotArea: () => PlotArea;
|
|
117
|
+
xScale: Scale;
|
|
118
|
+
yScales: Map<string, Scale>;
|
|
119
|
+
theme: ChartTheme;
|
|
120
|
+
container: HTMLElement;
|
|
121
|
+
xAxisOptions: AxisOptions;
|
|
122
|
+
yAxisOptionsMap: Map<string, AxisOptions>;
|
|
123
|
+
primaryYAxisId: string;
|
|
124
|
+
getLayout?: () => LayoutOptions;
|
|
125
|
+
getBusinessDayMapping?: () => BusinessDayMapping | null;
|
|
126
|
+
showLegend?: boolean;
|
|
127
|
+
getCursorPosition?: () => {
|
|
128
|
+
x: number;
|
|
129
|
+
y: number;
|
|
130
|
+
} | null;
|
|
131
|
+
selectionRect?: {
|
|
132
|
+
x: number;
|
|
133
|
+
y: number;
|
|
134
|
+
width: number;
|
|
135
|
+
height: number;
|
|
136
|
+
} | null;
|
|
137
|
+
getAlerts?: () => Array<{
|
|
138
|
+
price: number;
|
|
139
|
+
direction?: string;
|
|
140
|
+
}>;
|
|
141
|
+
getHoveredSeriesId?: () => string | null;
|
|
142
|
+
pluginManager?: {
|
|
143
|
+
get: (name: string) => unknown;
|
|
144
|
+
notifyExportSVG?: (ctx: SVGExportPluginContext) => void;
|
|
145
|
+
};
|
|
146
|
+
titleOptions?: ChartTitleOptions;
|
|
147
|
+
}, exportOptions?: SVGExportOptions): SVGExportContext;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ChartTheme } from '../../../../theme';
|
|
2
|
+
|
|
3
|
+
export declare function dashArrayToSvg(dash: number[] | undefined): string | undefined;
|
|
4
|
+
export interface SvgStrokeStyle {
|
|
5
|
+
stroke: string;
|
|
6
|
+
strokeWidth: number;
|
|
7
|
+
strokeOpacity?: number;
|
|
8
|
+
strokeDasharray?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SvgTextStyle {
|
|
11
|
+
fill: string;
|
|
12
|
+
fontSize: number;
|
|
13
|
+
fontFamily: string;
|
|
14
|
+
fontWeight?: string | number;
|
|
15
|
+
}
|
|
16
|
+
export declare function gridMajorStyle(theme: ChartTheme): SvgStrokeStyle;
|
|
17
|
+
export declare function gridMinorStyle(theme: ChartTheme): SvgStrokeStyle;
|
|
18
|
+
export declare function axisLineStyle(theme: ChartTheme, orientation: "x" | "y"): SvgStrokeStyle;
|
|
19
|
+
export declare function axisTickStyle(theme: ChartTheme, orientation: "x" | "y"): SvgStrokeStyle;
|
|
20
|
+
export declare function axisLabelStyle(theme: ChartTheme, orientation: "x" | "y"): SvgTextStyle;
|
|
21
|
+
export declare function strokeAttrs(style: SvgStrokeStyle): string;
|
|
22
|
+
export declare function textAttrs(style: SvgTextStyle, anchor?: string, baseline?: string): string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { LinearScale } from '../../../../../scales';
|
|
2
|
+
import { Series } from '../../../../Series';
|
|
3
|
+
import { ChartTheme } from '../../../../../theme';
|
|
4
|
+
import { Annotation } from '../../../../annotations/types';
|
|
5
|
+
import { SVGExportInput } from '../SVGExportContext';
|
|
6
|
+
|
|
7
|
+
export declare const testTheme: ChartTheme;
|
|
8
|
+
export declare function testScales(): {
|
|
9
|
+
xScale: LinearScale;
|
|
10
|
+
yScale: LinearScale;
|
|
11
|
+
};
|
|
12
|
+
export declare function mockSeries(type: string, overrides?: Partial<{
|
|
13
|
+
id: string;
|
|
14
|
+
data: Record<string, Float32Array | Float32Array[]>;
|
|
15
|
+
style: Record<string, unknown>;
|
|
16
|
+
visible: boolean;
|
|
17
|
+
yAxisId: string;
|
|
18
|
+
heatmapData: {
|
|
19
|
+
xValues: Float32Array;
|
|
20
|
+
yValues: Float32Array;
|
|
21
|
+
zValues: Float32Array;
|
|
22
|
+
};
|
|
23
|
+
polarData: {
|
|
24
|
+
r: Float32Array;
|
|
25
|
+
theta: Float32Array;
|
|
26
|
+
};
|
|
27
|
+
gaugeData: {
|
|
28
|
+
value: number;
|
|
29
|
+
min: number;
|
|
30
|
+
max: number;
|
|
31
|
+
};
|
|
32
|
+
sankeyData: {
|
|
33
|
+
nodes: string[];
|
|
34
|
+
links: Array<{
|
|
35
|
+
source: string;
|
|
36
|
+
target: string;
|
|
37
|
+
value: number;
|
|
38
|
+
}>;
|
|
39
|
+
};
|
|
40
|
+
indicatorOptions: Record<string, unknown>;
|
|
41
|
+
hasError: boolean;
|
|
42
|
+
markers: unknown[];
|
|
43
|
+
}>): Series;
|
|
44
|
+
export declare function seriesFixtures(): Record<string, Series>;
|
|
45
|
+
export declare function buildTestContext(series: Series[], extra?: Partial<SVGExportInput>): import('../SVGExportContext').SVGExportContext;
|
|
46
|
+
export declare const sampleAnnotations: Annotation[];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function fixturesPath(name: string): string;
|
|
2
|
+
/** Normalize volatile SVG ids for golden string comparison. */
|
|
3
|
+
export declare function normalizeSvg(svg: string): string;
|
|
4
|
+
export declare function rasterizeSvg(svg: string, width?: number): Buffer;
|
|
5
|
+
export declare function readGoldenText(name: string): string;
|
|
6
|
+
export declare function readGoldenPng(name: string): Buffer;
|
|
7
|
+
export declare function writeGolden(name: string, data: string | Buffer): void;
|
|
8
|
+
export declare function updateGoldenEnabled(): boolean;
|
|
9
|
+
export declare function assertGoldenText(name: string, actual: string): void;
|
|
10
|
+
export declare function assertGoldenPng(name: string, actual: Buffer, maxDiffRatio?: number): void;
|
|
11
|
+
export declare function comparePngBuffers(actual: Buffer, expected: Buffer, maxDiffRatio?: number): number;
|
|
12
|
+
export declare function decodeDataUrlPng(dataUrl: string): Buffer;
|