Skip to content

Commit c1df53b

Browse files
committed
Add plugin system
1 parent 2a05841 commit c1df53b

File tree

16 files changed

+1716
-672
lines changed

16 files changed

+1716
-672
lines changed

demo/qfchart-demo.html

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ <h1>QFChart Library Demo</h1>
155155
height: 10,
156156
titleColor: "#ff9900",
157157
});
158+
159+
// Register Measure Tool Plugin
160+
const measureTool = new QFChart.MeasureTool();
161+
chart.registerPlugin(measureTool);
158162
});
159163
</script>
160164
</body>

docs/api.md

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,31 @@ new QFChart(container: HTMLElement, options?: QFChartOptions)
2323
### Methods
2424

2525
#### `setMarketData(data: OHLCV[])`
26+
2627
Sets the main OHLCV data for the candlestick chart.
2728

2829
- **data**: Array of `OHLCV` objects.
2930

3031
#### `addIndicator(id: string, plots: IndicatorPlots, options?: IndicatorOptions)`
32+
3133
Adds an indicator to the chart.
3234

3335
- **id**: Unique identifier for the indicator.
3436
- **plots**: Object containing plot data definitions.
35-
- **options**:
36-
- `isOverlay`: (boolean) If `true`, renders on the main chart. If `false`, creates a new pane below.
37-
- `height`: (number) Height percentage for the new pane (e.g., `15` for 15%).
37+
- **options**:
38+
- `isOverlay`: (boolean) If `true`, renders on the main chart. If `false`, creates a new pane below.
39+
- `height`: (number) Height percentage for the new pane (e.g., `15` for 15%).
3840

3941
#### `removeIndicator(id: string)`
42+
4043
Removes an indicator by its ID and redraws the layout.
4144

4245
#### `resize()`
46+
4347
Manually triggers a resize of the chart. Useful if the container size changes programmatically.
4448

4549
#### `destroy()`
50+
4651
Cleans up event listeners and disposes of the ECharts instance.
4752

4853
---
@@ -53,29 +58,29 @@ Cleans up event listeners and disposes of the ECharts instance.
5358

5459
Configuration object passed to the constructor.
5560

56-
| Property | Type | Default | Description |
57-
|----------|------|---------|-------------|
58-
| `title` | `string` | `"Market"` | Main chart title displayed in tooltip. |
59-
| `height` | `string` \| `number` | - | Explicit height for the container. |
60-
| `padding` | `number` | `0.2` | Vertical padding for auto-scaling (0-1). |
61-
| `upColor` | `string` | `"#00da3c"` | Color for bullish candles. |
62-
| `downColor` | `string` | `"#ec0000"` | Color for bearish candles. |
63-
| `backgroundColor` | `string` | `"#1e293b"` | Chart background color. |
64-
| `tooltip` | `object` | `{ position: 'floating' }` | Tooltip configuration (see Layouts). |
65-
| `dataZoom` | `object` | - | Configuration for the zoom slider. |
61+
| Property | Type | Default | Description |
62+
| ----------------- | -------------------- | -------------------------- | ---------------------------------------- |
63+
| `title` | `string` | `"Market"` | Main chart title displayed in tooltip. |
64+
| `height` | `string` \| `number` | - | Explicit height for the container. |
65+
| `padding` | `number` | `0.2` | Vertical padding for auto-scaling (0-1). |
66+
| `upColor` | `string` | `"#00da3c"` | Color for bullish candles. |
67+
| `downColor` | `string` | `"#ec0000"` | Color for bearish candles. |
68+
| `backgroundColor` | `string` | `"#1e293b"` | Chart background color. |
69+
| `tooltip` | `object` | `{ position: 'floating' }` | Tooltip configuration (see Layouts). |
70+
| `dataZoom` | `object` | - | Configuration for the zoom slider. |
6671

6772
### `OHLCV`
6873

6974
Data structure for a single candle.
7075

7176
```typescript
7277
interface OHLCV {
73-
time: number; // Timestamp (ms or s)
74-
open: number;
75-
high: number;
76-
low: number;
77-
close: number;
78-
volume?: number;
78+
time: number; // Timestamp (ms)
79+
open: number;
80+
high: number;
81+
low: number;
82+
close: number;
83+
volume?: number;
7984
}
8085
```
8186

@@ -85,12 +90,17 @@ Definition of a single data series within an indicator.
8590

8691
```typescript
8792
interface IndicatorPlot {
88-
data: IndicatorPoint[];
89-
options: {
90-
style: 'line' | 'histogram' | 'columns' | 'circles' | 'cross' | 'background';
91-
color: string;
92-
linewidth?: number;
93-
}
93+
data: IndicatorPoint[];
94+
options: {
95+
style:
96+
| "line"
97+
| "histogram"
98+
| "columns"
99+
| "circles"
100+
| "cross"
101+
| "background";
102+
color: string;
103+
linewidth?: number;
104+
};
94105
}
95106
```
96-

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ permalink: /
1616
- **Overlay Indicators**: Add indicators directly on top of the main chart (e.g., SMA, Bollinger Bands).
1717
- **Flexible Layouts**: Configurable sidebars for tooltips (Left/Right/Floating) to avoid obstructing the chart.
1818
- **Dynamic Resizing**: Automatically handles window resizing and layout adjustments.
19+
- **Plugin System**: Extensible architecture for adding interactive tools (e.g., Measure Tool).
1920
- **TypeScript Support**: Written in TypeScript with full type definitions.
2021

2122
## Installation

docs/plugins.md

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
---
2+
layout: default
3+
title: Plugins
4+
nav_order: 4
5+
---
6+
7+
# Plugin System
8+
9+
QFChart supports a flexible plugin system that allows you to add custom interactive tools and extensions to the chart. Plugins can be used to implement drawing tools, custom overlays, or additional UI controls.
10+
11+
## registering a Plugin
12+
13+
To use a plugin, you must register it with the chart instance.
14+
15+
```javascript
16+
import { QFChart, MeasureTool } from "qfchart";
17+
18+
const chart = new QFChart(container, options);
19+
20+
// 1. Create Plugin Instance
21+
const measureTool = new MeasureTool();
22+
23+
// 2. Register Plugin
24+
chart.registerPlugin(measureTool);
25+
```
26+
27+
Once registered, the plugin will automatically add its button/icon to the chart's toolbar (if applicable).
28+
29+
## Built-in Plugins
30+
31+
### Measure Tool
32+
33+
The `MeasureTool` is a built-in plugin that allows users to measure price and time differences on the chart, similar to TradingView's measure tool.
34+
35+
- **Usage**: Click the ruler icon in the toolbar.
36+
- **Interaction**:
37+
1. **Click** on the chart to start the measurement.
38+
2. **Move** the mouse to drag the measurement box.
39+
3. **Click** again to finish and freeze the measurement.
40+
4. **Click** anywhere else or drag the chart to clear the measurement.
41+
42+
## Creating Custom Plugins
43+
44+
You can create your own plugins by extending the `AbstractPlugin` class or implementing the `Plugin` interface directly. We recommend extending `AbstractPlugin` as it provides useful helpers and automatic event cleanup.
45+
46+
### The AbstractPlugin Base Class
47+
48+
```typescript
49+
import { AbstractPlugin, ChartContext } from "qfchart";
50+
51+
export class MyCustomPlugin extends AbstractPlugin {
52+
constructor() {
53+
super({
54+
id: "my-plugin",
55+
name: "My Plugin",
56+
icon: "<svg>...</svg>", // SVG icon for toolbar
57+
});
58+
}
59+
60+
// Lifecycle Hooks
61+
protected onInit(): void {
62+
console.log("Plugin initialized");
63+
// Access chart instance via this.chart
64+
// Access context via this.context
65+
}
66+
67+
protected onActivate(): void {
68+
console.log("Tool activated");
69+
// Add event listeners automatically managed by the base class
70+
this.on("mouse:move", this.handleMouseMove);
71+
}
72+
73+
protected onDeactivate(): void {
74+
console.log("Tool deactivated");
75+
// Event listeners added with this.on() are automatically removed
76+
}
77+
78+
private handleMouseMove = (params: any) => {
79+
// Handle mouse move
80+
};
81+
}
82+
```
83+
84+
### The Chart Context
85+
86+
The `ChartContext` provides access to the underlying ECharts instance, data, and utility helpers.
87+
88+
```typescript
89+
export interface ChartContext {
90+
// Core Access
91+
getChart(): echarts.ECharts;
92+
getMarketData(): OHLCV[];
93+
getTimeToIndex(): Map<number, number>;
94+
getOptions(): QFChartOptions;
95+
96+
// Event Bus
97+
events: EventBus;
98+
99+
// Helpers
100+
coordinateConversion: {
101+
pixelToData: (point: { x; y }) => { timeIndex; value } | null;
102+
dataToPixel: (point: { timeIndex; value }) => { x; y } | null;
103+
};
104+
105+
// Interaction Control
106+
disableTools(): void; // To disable other active tools
107+
}
108+
```
109+
110+
### Event Bus
111+
112+
The chart exposes an Event Bus via `context.events` for communication between plugins and the chart core. Standard events include:
113+
114+
- `mouse:down`, `mouse:move`, `mouse:up`, `mouse:click`
115+
- `chart:resize`, `chart:dataZoom`, `chart:updated`
116+
- `plugin:activated`, `plugin:deactivated`
117+
118+
### Coordinate Conversion
119+
120+
Use the built-in helpers for easy coordinate mapping:
121+
122+
```typescript
123+
const dataPoint = this.context.coordinateConversion.pixelToData({
124+
x: 100,
125+
y: 200,
126+
});
127+
// Returns { timeIndex: 45, value: 50000.50 }
128+
129+
const pixelPoint = this.context.coordinateConversion.dataToPixel({
130+
timeIndex: 45,
131+
value: 50000,
132+
});
133+
// Returns { x: 100, y: 200 }
134+
```

0 commit comments

Comments
 (0)