@qfo/qfchart 0.6.7 → 0.7.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/index.d.ts +4 -1
- package/dist/qfchart.min.browser.js +14 -14
- package/dist/qfchart.min.es.js +14 -14
- package/package.json +81 -81
- package/src/QFChart.ts +52 -0
- package/src/components/LayoutManager.ts +682 -679
- package/src/components/SeriesBuilder.ts +260 -250
- package/src/components/SeriesRendererFactory.ts +8 -0
- package/src/components/TableOverlayRenderer.ts +322 -0
- package/src/components/renderers/BoxRenderer.ts +258 -0
- package/src/components/renderers/DrawingLineRenderer.ts +194 -0
- package/src/components/renderers/FillRenderer.ts +99 -99
- package/src/components/renderers/LabelRenderer.ts +85 -41
- package/src/components/renderers/LinefillRenderer.ts +155 -0
- package/src/components/renderers/PolylineRenderer.ts +197 -0
- package/src/components/renderers/SeriesRenderer.ts +21 -20
- package/src/components/renderers/ShapeRenderer.ts +121 -121
- package/src/types.ts +2 -1
- package/src/utils/ShapeUtils.ts +156 -140
package/package.json
CHANGED
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@qfo/qfchart",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Professional financial charting library built on Apache ECharts with candlestick charts, technical indicators, and interactive drawing tools",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"chart",
|
|
7
|
-
"charting",
|
|
8
|
-
"candlestick",
|
|
9
|
-
"financial",
|
|
10
|
-
"trading",
|
|
11
|
-
"technical-analysis",
|
|
12
|
-
"indicators",
|
|
13
|
-
"echarts",
|
|
14
|
-
"ohlcv",
|
|
15
|
-
"stock-chart",
|
|
16
|
-
"crypto",
|
|
17
|
-
"forex",
|
|
18
|
-
"drawing-tools",
|
|
19
|
-
"fibonacci",
|
|
20
|
-
"typescript"
|
|
21
|
-
],
|
|
22
|
-
"homepage": "https://
|
|
23
|
-
"bugs": {
|
|
24
|
-
"url": "https://github.com/QuantForgeOrg/QFChart/issues"
|
|
25
|
-
},
|
|
26
|
-
"repository": {
|
|
27
|
-
"type": "git",
|
|
28
|
-
"url": "git+https://github.com/QuantForgeOrg/QFChart.git"
|
|
29
|
-
},
|
|
30
|
-
"license": "Apache-2.0",
|
|
31
|
-
"author": "Alaa-eddine KADDOURI",
|
|
32
|
-
"type": "module",
|
|
33
|
-
"main": "./dist/qfchart.min.browser.js",
|
|
34
|
-
"module": "./dist/qfchart.min.es.js",
|
|
35
|
-
"types": "./dist/index.d.ts",
|
|
36
|
-
"exports": {
|
|
37
|
-
".": {
|
|
38
|
-
"types": "./dist/index.d.ts",
|
|
39
|
-
"import": "./dist/qfchart.min.es.js",
|
|
40
|
-
"require": "./dist/qfchart.min.browser.js",
|
|
41
|
-
"default": "./dist/qfchart.min.browser.js"
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
"files": [
|
|
45
|
-
"dist",
|
|
46
|
-
"src",
|
|
47
|
-
"README.md",
|
|
48
|
-
"LICENSE"
|
|
49
|
-
],
|
|
50
|
-
"publishConfig": {
|
|
51
|
-
"access": "public"
|
|
52
|
-
},
|
|
53
|
-
"scripts": {
|
|
54
|
-
"clean": "node -e \"const fs = require('fs'); if (fs.existsSync('dist')) fs.rmSync('dist', { recursive: true, force: true })\"",
|
|
55
|
-
"build": "npm run clean && rollup -c",
|
|
56
|
-
"build:dev": "npm run clean && cross-env BUILD=dev rollup -c",
|
|
57
|
-
"build:prod": "npm run clean && cross-env BUILD=prod rollup -c",
|
|
58
|
-
"watch": "rollup -c -w",
|
|
59
|
-
"prepublishOnly": "npm run build:prod",
|
|
60
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
61
|
-
},
|
|
62
|
-
"devDependencies": {
|
|
63
|
-
"@rollup/plugin-commonjs": "^25.0.0",
|
|
64
|
-
"@rollup/plugin-json": "^6.0.0",
|
|
65
|
-
"@rollup/plugin-node-resolve": "^15.0.0",
|
|
66
|
-
"@rollup/plugin-replace": "^6.0.3",
|
|
67
|
-
"cross-env": "^7.0.3",
|
|
68
|
-
"echarts": "^6.0.0",
|
|
69
|
-
"esbuild": "^0.19.0",
|
|
70
|
-
"rollup": "^3.28.0",
|
|
71
|
-
"rollup-plugin-dts": "^6.3.0",
|
|
72
|
-
"rollup-plugin-esbuild": "^5.0.0",
|
|
73
|
-
"rollup-plugin-sourcemaps": "^0.6.3",
|
|
74
|
-
"rollup-plugin-typescript-paths": "^1.4.0",
|
|
75
|
-
"tslib": "^2.6.0",
|
|
76
|
-
"typescript": "^5.1.0"
|
|
77
|
-
},
|
|
78
|
-
"peerDependencies": {
|
|
79
|
-
"echarts": "^5.0.0 || ^6.0.0"
|
|
80
|
-
}
|
|
81
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@qfo/qfchart",
|
|
3
|
+
"version": "0.7.1",
|
|
4
|
+
"description": "Professional financial charting library built on Apache ECharts with candlestick charts, technical indicators, and interactive drawing tools",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"chart",
|
|
7
|
+
"charting",
|
|
8
|
+
"candlestick",
|
|
9
|
+
"financial",
|
|
10
|
+
"trading",
|
|
11
|
+
"technical-analysis",
|
|
12
|
+
"indicators",
|
|
13
|
+
"echarts",
|
|
14
|
+
"ohlcv",
|
|
15
|
+
"stock-chart",
|
|
16
|
+
"crypto",
|
|
17
|
+
"forex",
|
|
18
|
+
"drawing-tools",
|
|
19
|
+
"fibonacci",
|
|
20
|
+
"typescript"
|
|
21
|
+
],
|
|
22
|
+
"homepage": "https://quantforge.org/qfchart/",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/QuantForgeOrg/QFChart/issues"
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/QuantForgeOrg/QFChart.git"
|
|
29
|
+
},
|
|
30
|
+
"license": "Apache-2.0",
|
|
31
|
+
"author": "Alaa-eddine KADDOURI",
|
|
32
|
+
"type": "module",
|
|
33
|
+
"main": "./dist/qfchart.min.browser.js",
|
|
34
|
+
"module": "./dist/qfchart.min.es.js",
|
|
35
|
+
"types": "./dist/index.d.ts",
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"import": "./dist/qfchart.min.es.js",
|
|
40
|
+
"require": "./dist/qfchart.min.browser.js",
|
|
41
|
+
"default": "./dist/qfchart.min.browser.js"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"src",
|
|
47
|
+
"README.md",
|
|
48
|
+
"LICENSE"
|
|
49
|
+
],
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"clean": "node -e \"const fs = require('fs'); if (fs.existsSync('dist')) fs.rmSync('dist', { recursive: true, force: true })\"",
|
|
55
|
+
"build": "npm run clean && rollup -c",
|
|
56
|
+
"build:dev": "npm run clean && cross-env BUILD=dev rollup -c",
|
|
57
|
+
"build:prod": "npm run clean && cross-env BUILD=prod rollup -c",
|
|
58
|
+
"watch": "rollup -c -w",
|
|
59
|
+
"prepublishOnly": "npm run build:prod",
|
|
60
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@rollup/plugin-commonjs": "^25.0.0",
|
|
64
|
+
"@rollup/plugin-json": "^6.0.0",
|
|
65
|
+
"@rollup/plugin-node-resolve": "^15.0.0",
|
|
66
|
+
"@rollup/plugin-replace": "^6.0.3",
|
|
67
|
+
"cross-env": "^7.0.3",
|
|
68
|
+
"echarts": "^6.0.0",
|
|
69
|
+
"esbuild": "^0.19.0",
|
|
70
|
+
"rollup": "^3.28.0",
|
|
71
|
+
"rollup-plugin-dts": "^6.3.0",
|
|
72
|
+
"rollup-plugin-esbuild": "^5.0.0",
|
|
73
|
+
"rollup-plugin-sourcemaps": "^0.6.3",
|
|
74
|
+
"rollup-plugin-typescript-paths": "^1.4.0",
|
|
75
|
+
"tslib": "^2.6.0",
|
|
76
|
+
"typescript": "^5.1.0"
|
|
77
|
+
},
|
|
78
|
+
"peerDependencies": {
|
|
79
|
+
"echarts": "^5.0.0 || ^6.0.0"
|
|
80
|
+
}
|
|
81
|
+
}
|
package/src/QFChart.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { PluginManager } from './components/PluginManager';
|
|
|
9
9
|
import { DrawingEditor } from './components/DrawingEditor';
|
|
10
10
|
import { EventBus } from './utils/EventBus';
|
|
11
11
|
import { AxisUtils } from './utils/AxisUtils';
|
|
12
|
+
import { TableOverlayRenderer } from './components/TableOverlayRenderer';
|
|
12
13
|
|
|
13
14
|
export class QFChart implements ChartContext {
|
|
14
15
|
private chart: echarts.ECharts;
|
|
@@ -86,6 +87,8 @@ export class QFChart implements ChartContext {
|
|
|
86
87
|
private leftSidebar: HTMLElement;
|
|
87
88
|
private rightSidebar: HTMLElement;
|
|
88
89
|
private chartContainer: HTMLElement;
|
|
90
|
+
private overlayContainer: HTMLElement;
|
|
91
|
+
private _lastTables: any[] = [];
|
|
89
92
|
|
|
90
93
|
constructor(container: HTMLElement, options: QFChartOptions = {}) {
|
|
91
94
|
this.rootContainer = container;
|
|
@@ -176,6 +179,13 @@ export class QFChart implements ChartContext {
|
|
|
176
179
|
this.layoutContainer.appendChild(this.rightSidebar);
|
|
177
180
|
|
|
178
181
|
this.chart = echarts.init(this.chartContainer);
|
|
182
|
+
|
|
183
|
+
// Overlay container for table rendering (positioned above ECharts canvas)
|
|
184
|
+
this.chartContainer.style.position = 'relative';
|
|
185
|
+
this.overlayContainer = document.createElement('div');
|
|
186
|
+
this.overlayContainer.style.cssText = 'position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:100;overflow:hidden;';
|
|
187
|
+
this.chartContainer.appendChild(this.overlayContainer);
|
|
188
|
+
|
|
179
189
|
this.pluginManager = new PluginManager(this, this.toolbarContainer);
|
|
180
190
|
this.drawingEditor = new DrawingEditor(this);
|
|
181
191
|
|
|
@@ -727,6 +737,23 @@ export class QFChart implements ChartContext {
|
|
|
727
737
|
// Merge the update (don't replace entire config)
|
|
728
738
|
this.chart.setOption(updateOption, { notMerge: false });
|
|
729
739
|
|
|
740
|
+
// Re-render table overlays (indicators may have updated table data)
|
|
741
|
+
const allTables: any[] = [];
|
|
742
|
+
this.indicators.forEach((indicator) => {
|
|
743
|
+
Object.values(indicator.plots).forEach((plot: any) => {
|
|
744
|
+
if (plot.options?.style === 'table') {
|
|
745
|
+
plot.data?.forEach((entry: any) => {
|
|
746
|
+
const tables = Array.isArray(entry.value) ? entry.value : [entry.value];
|
|
747
|
+
tables.forEach((t: any) => {
|
|
748
|
+
if (t && !t._deleted) allTables.push(t);
|
|
749
|
+
});
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
});
|
|
754
|
+
this._lastTables = allTables;
|
|
755
|
+
this._renderTableOverlays();
|
|
756
|
+
|
|
730
757
|
// Update countdown if needed
|
|
731
758
|
this.startCountdown();
|
|
732
759
|
}
|
|
@@ -926,6 +953,12 @@ export class QFChart implements ChartContext {
|
|
|
926
953
|
|
|
927
954
|
public resize(): void {
|
|
928
955
|
this.chart.resize();
|
|
956
|
+
this._renderTableOverlays();
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
private _renderTableOverlays(): void {
|
|
960
|
+
const gridRect = (this.chart.getModel() as any).getComponent('grid', 0)?.coordinateSystem?.getRect();
|
|
961
|
+
TableOverlayRenderer.render(this.overlayContainer, this._lastTables, gridRect);
|
|
929
962
|
}
|
|
930
963
|
|
|
931
964
|
public destroy(): void {
|
|
@@ -1358,6 +1391,7 @@ export class QFChart implements ChartContext {
|
|
|
1358
1391
|
}
|
|
1359
1392
|
},
|
|
1360
1393
|
data: drawings.map((d) => [d.points[0].timeIndex, d.points[0].value, d.points[1].timeIndex, d.points[1].value]),
|
|
1394
|
+
encode: { x: [0, 2], y: [1, 3] },
|
|
1361
1395
|
z: 100,
|
|
1362
1396
|
silent: false,
|
|
1363
1397
|
});
|
|
@@ -1385,6 +1419,20 @@ export class QFChart implements ChartContext {
|
|
|
1385
1419
|
return `<div style="min-width: 200px;">${html}</div>`;
|
|
1386
1420
|
};
|
|
1387
1421
|
|
|
1422
|
+
// 6. Extract and render table overlays from indicator plots
|
|
1423
|
+
const allTables: any[] = [];
|
|
1424
|
+
this.indicators.forEach((indicator) => {
|
|
1425
|
+
Object.values(indicator.plots).forEach((plot: any) => {
|
|
1426
|
+
if (plot.options?.style === 'table') {
|
|
1427
|
+
plot.data?.forEach((entry: any) => {
|
|
1428
|
+
const tables = Array.isArray(entry.value) ? entry.value : [entry.value];
|
|
1429
|
+
tables.forEach((t: any) => {
|
|
1430
|
+
if (t && !t._deleted) allTables.push(t);
|
|
1431
|
+
});
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
});
|
|
1435
|
+
});
|
|
1388
1436
|
const option: any = {
|
|
1389
1437
|
backgroundColor: this.options.backgroundColor,
|
|
1390
1438
|
animation: false,
|
|
@@ -1430,5 +1478,9 @@ export class QFChart implements ChartContext {
|
|
|
1430
1478
|
};
|
|
1431
1479
|
|
|
1432
1480
|
this.chart.setOption(option, true); // true = not merge, replace.
|
|
1481
|
+
|
|
1482
|
+
// Render table overlays AFTER setOption so we can query the computed grid rect
|
|
1483
|
+
this._lastTables = allTables;
|
|
1484
|
+
this._renderTableOverlays();
|
|
1433
1485
|
}
|
|
1434
1486
|
}
|