@qfo/qfchart 0.8.0 → 0.8.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.
Files changed (50) hide show
  1. package/dist/index.d.ts +319 -12
  2. package/dist/qfchart.min.browser.js +32 -16
  3. package/dist/qfchart.min.es.js +32 -16
  4. package/package.json +1 -1
  5. package/src/QFChart.ts +98 -262
  6. package/src/components/AbstractPlugin.ts +234 -104
  7. package/src/components/DrawingEditor.ts +297 -248
  8. package/src/components/DrawingRendererRegistry.ts +13 -0
  9. package/src/components/GraphicBuilder.ts +2 -2
  10. package/src/components/LayoutManager.ts +41 -35
  11. package/src/components/SeriesBuilder.ts +10 -10
  12. package/src/components/TooltipFormatter.ts +1 -1
  13. package/src/index.ts +17 -6
  14. package/src/plugins/ABCDPatternTool/ABCDPatternDrawingRenderer.ts +112 -0
  15. package/src/plugins/ABCDPatternTool/ABCDPatternTool.ts +136 -0
  16. package/src/plugins/ABCDPatternTool/index.ts +2 -0
  17. package/src/plugins/CypherPatternTool/CypherPatternDrawingRenderer.ts +80 -0
  18. package/src/plugins/CypherPatternTool/CypherPatternTool.ts +84 -0
  19. package/src/plugins/CypherPatternTool/index.ts +2 -0
  20. package/src/plugins/FibSpeedResistanceFanTool/FibSpeedResistanceFanDrawingRenderer.ts +163 -0
  21. package/src/plugins/FibSpeedResistanceFanTool/FibSpeedResistanceFanTool.ts +210 -0
  22. package/src/plugins/FibSpeedResistanceFanTool/index.ts +2 -0
  23. package/src/plugins/FibTrendExtensionTool/FibTrendExtensionDrawingRenderer.ts +141 -0
  24. package/src/plugins/FibTrendExtensionTool/FibTrendExtensionTool.ts +188 -0
  25. package/src/plugins/FibTrendExtensionTool/index.ts +2 -0
  26. package/src/plugins/FibonacciChannelTool/FibonacciChannelDrawingRenderer.ts +128 -0
  27. package/src/plugins/FibonacciChannelTool/FibonacciChannelTool.ts +231 -0
  28. package/src/plugins/FibonacciChannelTool/index.ts +2 -0
  29. package/src/plugins/FibonacciTool/FibonacciDrawingRenderer.ts +107 -0
  30. package/src/plugins/{FibonacciTool.ts → FibonacciTool/FibonacciTool.ts} +195 -192
  31. package/src/plugins/FibonacciTool/index.ts +2 -0
  32. package/src/plugins/HeadAndShouldersTool/HeadAndShouldersDrawingRenderer.ts +95 -0
  33. package/src/plugins/HeadAndShouldersTool/HeadAndShouldersTool.ts +97 -0
  34. package/src/plugins/HeadAndShouldersTool/index.ts +2 -0
  35. package/src/plugins/LineTool/LineDrawingRenderer.ts +49 -0
  36. package/src/plugins/{LineTool.ts → LineTool/LineTool.ts} +161 -190
  37. package/src/plugins/LineTool/index.ts +2 -0
  38. package/src/plugins/{MeasureTool.ts → MeasureTool/MeasureTool.ts} +324 -344
  39. package/src/plugins/MeasureTool/index.ts +1 -0
  40. package/src/plugins/ThreeDrivesPatternTool/ThreeDrivesPatternDrawingRenderer.ts +106 -0
  41. package/src/plugins/ThreeDrivesPatternTool/ThreeDrivesPatternTool.ts +98 -0
  42. package/src/plugins/ThreeDrivesPatternTool/index.ts +2 -0
  43. package/src/plugins/ToolGroup.ts +211 -0
  44. package/src/plugins/TrianglePatternTool/TrianglePatternDrawingRenderer.ts +107 -0
  45. package/src/plugins/TrianglePatternTool/TrianglePatternTool.ts +98 -0
  46. package/src/plugins/TrianglePatternTool/index.ts +2 -0
  47. package/src/plugins/XABCDPatternTool/XABCDPatternDrawingRenderer.ts +178 -0
  48. package/src/plugins/XABCDPatternTool/XABCDPatternTool.ts +213 -0
  49. package/src/plugins/XABCDPatternTool/index.ts +2 -0
  50. package/src/types.ts +37 -11
@@ -1,190 +1,161 @@
1
- import { AbstractPlugin } from '../components/AbstractPlugin';
2
- import * as echarts from 'echarts';
3
-
4
- type PluginState = 'idle' | 'drawing' | 'finished';
5
-
6
- export class LineTool extends AbstractPlugin {
7
- private zr!: any;
8
- private state: PluginState = 'idle';
9
- private startPoint: number[] | null = null;
10
- private endPoint: number[] | null = null;
11
-
12
- // ZRender Elements
13
- private group: any = null;
14
- private line: any = null;
15
- private startCircle: any = null;
16
- private endCircle: any = null;
17
-
18
- constructor(options: { name?: string; icon?: string }) {
19
- super({
20
- id: 'trend-line',
21
- name: options?.name || 'Trend Line',
22
- icon:
23
- options?.icon ||
24
- `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="2" y1="22" x2="22" y2="2" /></svg>`,
25
- });
26
- }
27
-
28
- protected onInit(): void {
29
- this.zr = this.chart.getZr();
30
- }
31
-
32
- protected onActivate(): void {
33
- this.state = 'idle';
34
- this.chart.getZr().setCursorStyle('crosshair');
35
-
36
- this.zr.on('click', this.onClick);
37
- this.zr.on('mousemove', this.onMouseMove);
38
- }
39
-
40
- protected onDeactivate(): void {
41
- this.state = 'idle';
42
- this.chart.getZr().setCursorStyle('default');
43
-
44
- this.zr.off('click', this.onClick);
45
- this.zr.off('mousemove', this.onMouseMove);
46
-
47
- // Clean up clear listeners
48
- this.disableClearListeners();
49
-
50
- // @ts-ignore - state type comparison
51
- if (this.state === 'drawing') {
52
- this.removeGraphic();
53
- }
54
- }
55
-
56
- protected onDestroy(): void {
57
- this.removeGraphic();
58
- }
59
-
60
- // --- Interaction Handlers ---
61
-
62
- private onMouseDown = () => {
63
- // No longer needed
64
- };
65
-
66
- private onChartInteraction = () => {
67
- // No longer needed
68
- };
69
-
70
- private onClick = (params: any) => {
71
- if (this.state === 'idle') {
72
- this.state = 'drawing';
73
- this.startPoint = [params.offsetX, params.offsetY];
74
- this.endPoint = [params.offsetX, params.offsetY];
75
- this.initGraphic();
76
- this.updateGraphic();
77
- } else if (this.state === 'drawing') {
78
- this.state = 'finished';
79
- this.endPoint = [params.offsetX, params.offsetY];
80
- this.updateGraphic();
81
-
82
- // Convert to native chart drawing
83
- if (this.startPoint && this.endPoint) {
84
- const start = this.context.coordinateConversion.pixelToData({
85
- x: this.startPoint[0],
86
- y: this.startPoint[1],
87
- });
88
- const end = this.context.coordinateConversion.pixelToData({
89
- x: this.endPoint[0],
90
- y: this.endPoint[1],
91
- });
92
-
93
- if (start && end) {
94
- // Use the pane index from the start point (assume drawing starts and ends in same pane or use start pane)
95
- const paneIndex = start.paneIndex || 0;
96
-
97
- this.context.addDrawing({
98
- id: `line-${Date.now()}`,
99
- type: 'line',
100
- points: [start, end],
101
- paneIndex: paneIndex,
102
- style: {
103
- color: '#3b82f6',
104
- lineWidth: 2,
105
- },
106
- });
107
- }
108
- }
109
-
110
- // Cleanup local ZRender graphic as it's now part of the chart series
111
- this.removeGraphic();
112
- this.context.disableTools();
113
- }
114
- };
115
-
116
- private saveDataCoordinates() {
117
- // No longer needed
118
- }
119
-
120
- private updateGraphicFromData() {
121
- // No longer needed
122
- }
123
-
124
- private enableClearListeners(): void {
125
- // No longer needed
126
- }
127
-
128
- private clearHandlers: any = {};
129
-
130
- private disableClearListeners(): void {
131
- // No longer needed
132
- }
133
-
134
- private onMouseMove = (params: any) => {
135
- if (this.state !== 'drawing') return;
136
- this.endPoint = [params.offsetX, params.offsetY];
137
- this.updateGraphic();
138
- };
139
-
140
- // --- Graphics ---
141
-
142
- private initGraphic(): void {
143
- if (this.group) return;
144
-
145
- this.group = new echarts.graphic.Group();
146
-
147
- this.line = new echarts.graphic.Line({
148
- shape: { x1: 0, y1: 0, x2: 0, y2: 0 },
149
- style: { stroke: '#3b82f6', lineWidth: 2 },
150
- z: 100,
151
- });
152
-
153
- this.startCircle = new echarts.graphic.Circle({
154
- shape: { cx: 0, cy: 0, r: 4 },
155
- style: { fill: '#fff', stroke: '#3b82f6', lineWidth: 1 },
156
- z: 101,
157
- });
158
-
159
- this.endCircle = new echarts.graphic.Circle({
160
- shape: { cx: 0, cy: 0, r: 4 },
161
- style: { fill: '#fff', stroke: '#3b82f6', lineWidth: 1 },
162
- z: 101,
163
- });
164
-
165
- this.group.add(this.line);
166
- this.group.add(this.startCircle);
167
- this.group.add(this.endCircle);
168
-
169
- this.zr.add(this.group);
170
- }
171
-
172
- private removeGraphic(): void {
173
- if (this.group) {
174
- this.zr.remove(this.group);
175
- this.group = null;
176
- this.disableClearListeners();
177
- }
178
- }
179
-
180
- private updateGraphic(): void {
181
- if (!this.startPoint || !this.endPoint || !this.group) return;
182
-
183
- const [x1, y1] = this.startPoint;
184
- const [x2, y2] = this.endPoint;
185
-
186
- this.line.setShape({ x1, y1, x2, y2 });
187
- this.startCircle.setShape({ cx: x1, cy: y1 });
188
- this.endCircle.setShape({ cx: x2, cy: y2 });
189
- }
190
- }
1
+ import { AbstractPlugin } from '../../components/AbstractPlugin';
2
+ import { LineDrawingRenderer } from './LineDrawingRenderer';
3
+ import * as echarts from 'echarts';
4
+
5
+ type PluginState = 'idle' | 'drawing' | 'finished';
6
+
7
+ export class LineTool extends AbstractPlugin {
8
+ private zr!: any;
9
+ private state: PluginState = 'idle';
10
+ private startPoint: number[] | null = null;
11
+ private endPoint: number[] | null = null;
12
+
13
+ // ZRender Elements
14
+ private group: any = null;
15
+ private line: any = null;
16
+ private startCircle: any = null;
17
+ private endCircle: any = null;
18
+
19
+ constructor(options: { name?: string; icon?: string } = {}) {
20
+ super({
21
+ id: 'trend-line',
22
+ name: options?.name || 'Trend Line',
23
+ icon:
24
+ options?.icon ||
25
+ `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="2" y1="22" x2="22" y2="2" /></svg>`,
26
+ });
27
+ }
28
+
29
+ protected onInit(): void {
30
+ this.zr = this.chart.getZr();
31
+ this.context.registerDrawingRenderer(new LineDrawingRenderer());
32
+ }
33
+
34
+ protected onActivate(): void {
35
+ this.state = 'idle';
36
+ this.chart.getZr().setCursorStyle('crosshair');
37
+
38
+ this.zr.on('click', this.onClick);
39
+ this.zr.on('mousemove', this.onMouseMove);
40
+ }
41
+
42
+ protected onDeactivate(): void {
43
+ this.state = 'idle';
44
+ this.chart.getZr().setCursorStyle('default');
45
+
46
+ this.zr.off('click', this.onClick);
47
+ this.zr.off('mousemove', this.onMouseMove);
48
+
49
+ // @ts-ignore - state type comparison
50
+ if (this.state === 'drawing') {
51
+ this.removeGraphic();
52
+ }
53
+ }
54
+
55
+ protected onDestroy(): void {
56
+ this.removeGraphic();
57
+ }
58
+
59
+ // --- Interaction Handlers ---
60
+
61
+ private onClick = (params: any) => {
62
+ if (this.state === 'idle') {
63
+ this.state = 'drawing';
64
+ this.startPoint = this.getPoint(params);
65
+ this.endPoint = this.getPoint(params);
66
+ this.initGraphic();
67
+ this.updateGraphic();
68
+ } else if (this.state === 'drawing') {
69
+ this.state = 'finished';
70
+ this.endPoint = this.getPoint(params);
71
+ this.updateGraphic();
72
+
73
+ // Convert to native chart drawing
74
+ if (this.startPoint && this.endPoint) {
75
+ const start = this.context.coordinateConversion.pixelToData({
76
+ x: this.startPoint[0],
77
+ y: this.startPoint[1],
78
+ });
79
+ const end = this.context.coordinateConversion.pixelToData({
80
+ x: this.endPoint[0],
81
+ y: this.endPoint[1],
82
+ });
83
+
84
+ if (start && end) {
85
+ const paneIndex = start.paneIndex || 0;
86
+
87
+ this.context.addDrawing({
88
+ id: `line-${Date.now()}`,
89
+ type: 'line',
90
+ points: [start, end],
91
+ paneIndex: paneIndex,
92
+ style: {
93
+ color: '#3b82f6',
94
+ lineWidth: 2,
95
+ },
96
+ });
97
+ }
98
+ }
99
+
100
+ // Cleanup local ZRender graphic as it's now part of the chart series
101
+ this.removeGraphic();
102
+ this.context.disableTools();
103
+ }
104
+ };
105
+
106
+ private onMouseMove = (params: any) => {
107
+ if (this.state !== 'drawing') return;
108
+ this.endPoint = this.getPoint(params);
109
+ this.updateGraphic();
110
+ };
111
+
112
+ // --- Graphics ---
113
+
114
+ private initGraphic(): void {
115
+ if (this.group) return;
116
+
117
+ this.group = new echarts.graphic.Group();
118
+
119
+ this.line = new echarts.graphic.Line({
120
+ shape: { x1: 0, y1: 0, x2: 0, y2: 0 },
121
+ style: { stroke: '#3b82f6', lineWidth: 2 },
122
+ z: 100,
123
+ });
124
+
125
+ this.startCircle = new echarts.graphic.Circle({
126
+ shape: { cx: 0, cy: 0, r: 4 },
127
+ style: { fill: '#fff', stroke: '#3b82f6', lineWidth: 1 },
128
+ z: 101,
129
+ });
130
+
131
+ this.endCircle = new echarts.graphic.Circle({
132
+ shape: { cx: 0, cy: 0, r: 4 },
133
+ style: { fill: '#fff', stroke: '#3b82f6', lineWidth: 1 },
134
+ z: 101,
135
+ });
136
+
137
+ this.group.add(this.line);
138
+ this.group.add(this.startCircle);
139
+ this.group.add(this.endCircle);
140
+
141
+ this.zr.add(this.group);
142
+ }
143
+
144
+ private removeGraphic(): void {
145
+ if (this.group) {
146
+ this.zr.remove(this.group);
147
+ this.group = null;
148
+ }
149
+ }
150
+
151
+ private updateGraphic(): void {
152
+ if (!this.startPoint || !this.endPoint || !this.group) return;
153
+
154
+ const [x1, y1] = this.startPoint;
155
+ const [x2, y2] = this.endPoint;
156
+
157
+ this.line.setShape({ x1, y1, x2, y2 });
158
+ this.startCircle.setShape({ cx: x1, cy: y1 });
159
+ this.endCircle.setShape({ cx: x2, cy: y2 });
160
+ }
161
+ }
@@ -0,0 +1,2 @@
1
+ export { LineTool } from './LineTool';
2
+ export { LineDrawingRenderer } from './LineDrawingRenderer';