|
| 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