@fulate/echart 1.0.0

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/README.md ADDED
@@ -0,0 +1,70 @@
1
+ # `@fulate/echart`
2
+
3
+ > 文档角色:`GUIDE`。权威来源:ECharts adapter 源码 TSDoc 与测试;Core/UI 场景生命周期见各自指南。
4
+
5
+ `@fulate/echart` 提供 `EChartsShape`、`EChartsProperties`、`EChartsPool` 和 clipboard plugin。图表实例在 Worker surface
6
+ 中运行,Fulate 场景只保存 authored/runtime 图表配置,不把 Worker pool 或 surface identity 写入
7
+ JSON、History 或 clipboard。
8
+
9
+ ## 配置 Worker pool
10
+
11
+ 每个 Root 提供一个 `EChartsPool`:
12
+
13
+ ```ts
14
+ import { EChartsPool, eChartsPoolKey } from "@fulate/echart";
15
+
16
+ const pool = new EChartsPool({
17
+ echartsUrl: "https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.esm.min.js",
18
+ size: 2
19
+ });
20
+ root.provide(eChartsPoolKey, pool);
21
+ ```
22
+
23
+ `size` 省略时使用默认 Worker 数量。应用负责在 Root 生命周期结束时调用 `pool.dispose()`。
24
+
25
+ ## EChartsShape
26
+
27
+ ```ts
28
+ const chart = new EChartsShape({
29
+ width: 640,
30
+ height: 360,
31
+ echarts: { option: { series: [] } }
32
+ });
33
+ ```
34
+
35
+ `echarts` 是 whole-value authored/runtime 字段。`setOptions({ echarts })` 替换持久配置;
36
+ `setRuntimeOptions({ echarts })` 只覆盖当前运行态,`clearRuntimeOptions(["echarts"])` 恢复最新
37
+ 持久值。有效`theme`引用变化会重建surface;`option`、`notMerge`或`lazyUpdate`变化且theme未变时
38
+ 复用当前surface并发送一次`set-option`。width、height、DPR或Viewport scale变化只发送`resize`;
39
+ ECharts逻辑宽高始终等于authored宽高,字号、间距、线宽和原始option保持不变。Shape按
40
+ `Viewport scale × DPR × 2`计算`renderPixelRatio`,再按单图`8 × 1024 × 1024`像素预算裁剪上限;
41
+ 该倍率没有固定下限。Worker把最终倍率映射到ECharts的`devicePixelRatio`渲染参数,输出
42
+ `authored尺寸 × renderPixelRatio`的位图。Layer把位图绘制到authored宽高,经过Viewport后按固定
43
+ 质量倍率下采样。Viewport CSS preview和animated focus期间复用已有frame,settle后的真实重绘只按
44
+ 最终倍率发送一次`resize`。DPR变化复用当前ECharts实例。相同有效字段为noop;Shape尚未激活时
45
+ 不创建surface,激活时直接采用当前有效配置。
46
+ `setOption()`仍可直接调用当前Worker内原生ECharts的增量更新,不改变authored配置。
47
+
48
+ `EChartsProperties`是公开的properties基类;`EChartsShape<Properties, Option>`与Rectangle/Image一样
49
+ 提供默认类型参数,并允许子类通过构造器第二参数交付扩展properties。surface始终由EChartsShape内部
50
+ 唯一持有,不属于公开properties或子类配置。
51
+
52
+ ## Action 与事件
53
+
54
+ `dispatchAction(payload, options?)` 将可 structured-clone 的 action 发给 Worker。通过
55
+ `addEChartsEventListener(name, listener)` 订阅原生或扩展事件;返回 cleanup,订阅会跨 surface
56
+ 重建保持。custom action 由 ECharts 扩展自己注册,Fulate 不重复注册。
57
+
58
+ Scene鼠标坐标转成图元authored-local后原样进入Worker;Viewport scale、DPR和超采样质量都不参与
59
+ 坐标换算。custom action返回的坐标同样是authored-local,可直接交回Scene几何。
60
+
61
+ ## Clipboard
62
+
63
+ `eChartsClipboardPlugin` 按 `Select` 实例显式安装:
64
+
65
+ ```ts
66
+ const select = new Select().useClipboard(eChartsClipboardPlugin);
67
+ ```
68
+
69
+ 复制数据只包含图表配置和几何选项;恢复前应先在目标 Root 提供 pool。该 adapter 不引入旧格式
70
+ 迁移或第二套运行路径。
@@ -0,0 +1,5 @@
1
+ import { EChartsShape } from "./shape";
2
+ export declare const eChartsClipboardPlugin: {
3
+ readonly type: "echarts";
4
+ readonly deserialize: (data: Record<string, any>) => EChartsShape<import("./shape").EChartsProperties, import("./shape").EChartsShapeOption<any>>;
5
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,106 @@
1
+ import { BitmapFrameEmitter, runWorkerSurfaceHost } from "@fulate/ui/worker-surface-worker";
2
+
3
+ //#region packages/echart/src/worker-surface.ts
4
+ /** ECharts-specific renderer state owned by one Worker surface. */
5
+ var EChartsWorkerSurface = class {
6
+ canvas;
7
+ chart;
8
+ frames;
9
+ chartRenderPixelRatio;
10
+ frameRenderPixelRatio;
11
+ eventListeners = /* @__PURE__ */ new Map();
12
+ constructor(echarts, input, emitFrame, emitOutput) {
13
+ this.emitOutput = emitOutput;
14
+ const { authoredWidth, authoredHeight, renderPixelRatio, theme, option, notMerge, lazyUpdate } = input;
15
+ this.canvas = new OffscreenCanvas(authoredWidth * renderPixelRatio, authoredHeight * renderPixelRatio);
16
+ this.chartRenderPixelRatio = this.frameRenderPixelRatio = renderPixelRatio;
17
+ this.chart = echarts.init(this.canvas, theme ?? null, {
18
+ width: authoredWidth,
19
+ height: authoredHeight,
20
+ devicePixelRatio: renderPixelRatio
21
+ });
22
+ this.frames = new BitmapFrameEmitter(() => this.getFrameCanvas(), emitFrame);
23
+ this.chart.on("rendered", () => this.frames.request());
24
+ this.chart.setOption(option, notMerge, lazyUpdate);
25
+ }
26
+ receive(command) {
27
+ switch (command.type) {
28
+ case "set-option":
29
+ this.chart.setOption(command.option, command.notMerge, command.lazyUpdate);
30
+ break;
31
+ case "dispatch-action":
32
+ this.chart.dispatchAction(command.payload, command.opt);
33
+ break;
34
+ case "event":
35
+ this.chart.getZr().handler.dispatch(command.name, {
36
+ zrX: command.x,
37
+ zrY: command.y,
38
+ clientX: command.x,
39
+ clientY: command.y,
40
+ preventDefault: () => {},
41
+ stopPropagation: () => {}
42
+ });
43
+ break;
44
+ case "add-event-listener": {
45
+ const listener = (params) => {
46
+ this.emitOutput({
47
+ type: "event",
48
+ name: command.name,
49
+ params
50
+ });
51
+ };
52
+ this.eventListeners.set(command.name, listener);
53
+ this.chart.on(command.name, listener);
54
+ break;
55
+ }
56
+ case "remove-event-listener":
57
+ this.chart.off(command.name, this.eventListeners.get(command.name));
58
+ this.eventListeners.delete(command.name);
59
+ break;
60
+ case "resize":
61
+ this.frameRenderPixelRatio = command.renderPixelRatio;
62
+ this.chart.resize({
63
+ width: command.authoredWidth,
64
+ height: command.authoredHeight
65
+ });
66
+ break;
67
+ case "visibility":
68
+ if (command.visible) {
69
+ this.chart.getZr().animation.resume();
70
+ this.frames.resume();
71
+ } else {
72
+ this.frames.pause();
73
+ this.chart.getZr().animation.pause();
74
+ }
75
+ break;
76
+ }
77
+ }
78
+ dispose() {
79
+ this.frames.dispose();
80
+ this.eventListeners.clear();
81
+ this.chart.dispose();
82
+ }
83
+ getFrameCanvas() {
84
+ if (this.frameRenderPixelRatio === this.chartRenderPixelRatio) return this.canvas;
85
+ return this.chart.renderToCanvas({ pixelRatio: this.frameRenderPixelRatio });
86
+ }
87
+ };
88
+
89
+ //#endregion
90
+ //#region packages/echart/src/echart-worker.ts
91
+ runWorkerSurfaceHost({
92
+ async initialize(input) {
93
+ const module = await import(
94
+ /* @vite-ignore */
95
+ input.echartsUrl
96
+ );
97
+ const echarts = module.default ?? module;
98
+ echarts.setPlatformAPI({ createCanvas: () => new OffscreenCanvas(1, 1) });
99
+ return echarts;
100
+ },
101
+ create(echarts, input, emitFrame, emitOutput) {
102
+ return new EChartsWorkerSurface(echarts, input, emitFrame, emitOutput);
103
+ }
104
+ });
105
+
106
+ //#endregion
@@ -0,0 +1,6 @@
1
+ export { EChartsPool, eChartsPoolKey } from "./pool";
2
+ export type { EChartsPoolOptions } from "./pool";
3
+ export { EChartsProperties, EChartsShape } from "./shape";
4
+ export type { EChartsEventListener, EChartsShapeOption, EChartsShapeOptionPatch } from "./shape";
5
+ export type { EChartsActionPayload, EChartsDispatchActionOptions, EChartsInitOpts } from "./protocol";
6
+ export { eChartsClipboardPlugin } from "./clipboard";
package/dist/index.js ADDED
@@ -0,0 +1,266 @@
1
+ import { Bitmap, RectangleProperties, RectangleTransform, WorkerSurfacePool } from "@fulate/ui";
2
+ import { createPointView } from "@fulate/share";
3
+
4
+ //#region packages/echart/src/pool.ts
5
+ const eChartsPoolKey = Symbol();
6
+ /** Configures one independent ECharts backend over the shared surface pool. */
7
+ var EChartsPool = class {
8
+ surfaces;
9
+ constructor(options) {
10
+ const { echartsUrl, size = 2 } = options;
11
+ this.surfaces = new WorkerSurfacePool({
12
+ size,
13
+ initialize: { echartsUrl: String(echartsUrl) },
14
+ createWorker: () => new Worker(new URL("./echart-worker.js", import.meta.url), { type: "module" })
15
+ });
16
+ }
17
+ /** @internal Creates the renderer for one active EChartsShape. */
18
+ create(input, onFrame, onOutput) {
19
+ return this.surfaces.create(input, onFrame, onOutput);
20
+ }
21
+ dispose() {
22
+ this.surfaces.dispose();
23
+ }
24
+ };
25
+
26
+ //#endregion
27
+ //#region packages/echart/src/shape.ts
28
+ const RENDER_QUALITY = 2;
29
+ const BITMAP_PIXEL_BUDGET = 8 * 1024 * 1024;
30
+ /** Public properties base for typed EChartsShape subclasses. */
31
+ var EChartsProperties = class extends RectangleProperties {
32
+ echarts;
33
+ constructor(options = {}) {
34
+ super(options);
35
+ this.echarts = options.echarts ?? { option: {} };
36
+ }
37
+ };
38
+ var EChartsTransform = class extends RectangleTransform {
39
+ hasInView() {
40
+ const inView = super.hasInView();
41
+ this.element.syncChartVisibility(inView);
42
+ return inView;
43
+ }
44
+ };
45
+ var EChartsShape = class extends Bitmap {
46
+ type = "echarts";
47
+ surface = null;
48
+ lastVisibility;
49
+ sentAuthoredWidth = 0;
50
+ sentAuthoredHeight = 0;
51
+ sentRenderPixelRatio = 0;
52
+ cleanups = [];
53
+ eChartsEventListeners = /* @__PURE__ */ new Map();
54
+ /** Current effective chart configuration, including runtime overrides. */
55
+ get echarts() {
56
+ return this.propertyState.echarts;
57
+ }
58
+ constructor(options, properties = new EChartsProperties(options), Transform = EChartsTransform) {
59
+ super(options, properties, Transform);
60
+ }
61
+ /** Sends one native incremental ECharts update outside authored state. */
62
+ setOption(option, notMerge, lazyUpdate) {
63
+ this.surface?.post({
64
+ type: "set-option",
65
+ option,
66
+ notMerge,
67
+ lazyUpdate
68
+ });
69
+ }
70
+ /**
71
+ * Dispatches one action to the current native ECharts instance in its Worker.
72
+ * Registered action events return through `addEChartsEventListener()`.
73
+ */
74
+ dispatchAction(payload, opt) {
75
+ this.surface?.post({
76
+ type: "dispatch-action",
77
+ payload,
78
+ opt
79
+ });
80
+ }
81
+ /**
82
+ * Subscribes to one native ECharts instance event across the Worker boundary.
83
+ * Custom action events must be registered by the loaded ECharts extension.
84
+ * The returned cleanup survives chart restarts and removes this subscription.
85
+ */
86
+ addEChartsEventListener(name, listener) {
87
+ let listeners = this.eChartsEventListeners.get(name);
88
+ if (!listeners) {
89
+ listeners = /* @__PURE__ */ new Set();
90
+ this.eChartsEventListeners.set(name, listeners);
91
+ this.surface?.post({
92
+ type: "add-event-listener",
93
+ name
94
+ });
95
+ }
96
+ listeners.add(listener);
97
+ return () => {
98
+ const current = this.eChartsEventListeners.get(name);
99
+ if (!current) return;
100
+ current.delete(listener);
101
+ if (current.size > 0) return;
102
+ this.eChartsEventListeners.delete(name);
103
+ this.surface?.post({
104
+ type: "remove-event-listener",
105
+ name
106
+ });
107
+ };
108
+ }
109
+ resizeChart() {
110
+ const surface = this.surface;
111
+ if (!surface) return;
112
+ const authoredWidth = this.width;
113
+ const authoredHeight = this.height;
114
+ const renderPixelRatio = this.chartRenderPixelRatio;
115
+ if (authoredWidth === this.sentAuthoredWidth && authoredHeight === this.sentAuthoredHeight && renderPixelRatio === this.sentRenderPixelRatio) return;
116
+ this.sentAuthoredWidth = authoredWidth;
117
+ this.sentAuthoredHeight = authoredHeight;
118
+ this.sentRenderPixelRatio = renderPixelRatio;
119
+ surface.post({
120
+ type: "resize",
121
+ authoredWidth,
122
+ authoredHeight,
123
+ renderPixelRatio
124
+ });
125
+ }
126
+ onPropertiesChanged(current, changes) {
127
+ super.onPropertiesChanged(current, changes);
128
+ if (!this.isActive) return;
129
+ if (changes.has("echarts")) {
130
+ const previous = changes.get("echarts");
131
+ const next = current.echarts;
132
+ if (!Object.is(previous.theme, next.theme)) {
133
+ this.restartChart();
134
+ return;
135
+ }
136
+ if (!Object.is(previous.option, next.option) || !Object.is(previous.notMerge, next.notMerge) || !Object.is(previous.lazyUpdate, next.lazyUpdate)) this.setOption(next.option, next.notMerge, next.lazyUpdate);
137
+ }
138
+ if (changes.has("width") || changes.has("height")) this.resizeChart();
139
+ }
140
+ onActivate(root, layer) {
141
+ super.onActivate(root, layer);
142
+ this.startChart(root.inject(eChartsPoolKey));
143
+ }
144
+ onDeactivate(root, layer) {
145
+ this.stopChart();
146
+ super.onDeactivate(root, layer);
147
+ }
148
+ onUnmount() {
149
+ this.stopChart();
150
+ this.eChartsEventListeners.clear();
151
+ super.onUnmount();
152
+ }
153
+ paintContent(ctx) {
154
+ this.resizeChart();
155
+ this.syncChartVisibility(true);
156
+ this.paintBitmap(ctx, this.width, this.height);
157
+ }
158
+ /** @internal Synchronizes ECharts animation with the actual paint path. */
159
+ syncChartVisibility(visible) {
160
+ const surface = this.surface;
161
+ if (!surface || visible === this.lastVisibility) return;
162
+ this.lastVisibility = visible;
163
+ surface.post({
164
+ type: "visibility",
165
+ visible
166
+ });
167
+ }
168
+ startChart(pool) {
169
+ const input = {
170
+ authoredWidth: this.width,
171
+ authoredHeight: this.height,
172
+ renderPixelRatio: this.chartRenderPixelRatio,
173
+ ...this.echarts
174
+ };
175
+ this.sentAuthoredWidth = input.authoredWidth;
176
+ this.sentAuthoredHeight = input.authoredHeight;
177
+ this.sentRenderPixelRatio = input.renderPixelRatio;
178
+ this.lastVisibility = void 0;
179
+ this.surface = pool.create(input, (bitmap) => this.presentBitmap(bitmap), (output) => this.receiveEChartsOutput(output));
180
+ for (const name of this.eChartsEventListeners.keys()) this.surface.post({
181
+ type: "add-event-listener",
182
+ name
183
+ });
184
+ this.bindEvents();
185
+ }
186
+ restartChart() {
187
+ const pool = this.root.inject(eChartsPoolKey);
188
+ this.stopChart();
189
+ this.startChart(pool);
190
+ }
191
+ stopChart() {
192
+ this.surface?.dispose();
193
+ this.surface = null;
194
+ this.lastVisibility = void 0;
195
+ this.cleanups.forEach((cleanup) => cleanup());
196
+ this.cleanups = [];
197
+ }
198
+ toLocal(event) {
199
+ return this.transform.toLocal(createPointView(event.detail.x, event.detail.y)) ?? createPointView(-1e3, -1e3);
200
+ }
201
+ forwardEvent(name) {
202
+ return (event) => {
203
+ const local = this.toLocal(event);
204
+ this.surface?.post({
205
+ type: "event",
206
+ name,
207
+ x: local.x,
208
+ y: local.y
209
+ });
210
+ };
211
+ }
212
+ get chartRenderPixelRatio() {
213
+ const budgetRatio = Math.sqrt(BITMAP_PIXEL_BUDGET / (this.width * this.height));
214
+ return Math.min(this.renderPixelRatio * RENDER_QUALITY, budgetRatio);
215
+ }
216
+ receiveEChartsOutput(output) {
217
+ const listeners = this.eChartsEventListeners.get(output.name);
218
+ if (!listeners) return;
219
+ for (const listener of listeners) {
220
+ if (this.eChartsEventListeners.get(output.name) !== listeners) return;
221
+ listener(output.params);
222
+ }
223
+ }
224
+ bindEvents() {
225
+ const bind = (name, handler) => {
226
+ this.cleanups.push(this.addEventListener(name, handler));
227
+ };
228
+ bind("click", this.forwardEvent("click"));
229
+ bind("dblclick", this.forwardEvent("dblclick"));
230
+ bind("mouseenter", this.forwardEvent("mouseover"));
231
+ bind("pointermove", this.forwardEvent("mousemove"));
232
+ bind("pointerdown", this.forwardEvent("mousedown"));
233
+ bind("pointerup", this.forwardEvent("mouseup"));
234
+ bind("contextmenu", this.forwardEvent("contextmenu"));
235
+ bind("mouseleave", () => {
236
+ this.surface?.post({
237
+ type: "event",
238
+ name: "mouseout",
239
+ x: -1e3,
240
+ y: -1e3
241
+ });
242
+ this.surface?.post({
243
+ type: "event",
244
+ name: "globalout",
245
+ x: -1e3,
246
+ y: -1e3
247
+ });
248
+ });
249
+ }
250
+ };
251
+
252
+ //#endregion
253
+ //#region packages/echart/src/clipboard.ts
254
+ const eChartsClipboardPlugin = {
255
+ type: "echarts",
256
+ deserialize(data) {
257
+ const { type: _type, children: _children, echarts: echartsOptions, ...shapeOptions } = data;
258
+ return new EChartsShape({
259
+ ...shapeOptions,
260
+ echarts: echartsOptions
261
+ });
262
+ }
263
+ };
264
+
265
+ //#endregion
266
+ export { EChartsPool, EChartsProperties, EChartsShape, eChartsClipboardPlugin, eChartsPoolKey };
package/dist/pool.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { type WorkerSurfaceHandle } from "@fulate/ui";
2
+ import type { EChartsCommand, EChartsOutput, EChartsSurfaceCreate } from "./protocol";
3
+ export interface EChartsPoolOptions {
4
+ echartsUrl: string | URL;
5
+ size?: number;
6
+ }
7
+ export declare const eChartsPoolKey: unique symbol;
8
+ /** Configures one independent ECharts backend over the shared surface pool. */
9
+ export declare class EChartsPool {
10
+ private readonly surfaces;
11
+ constructor(options: EChartsPoolOptions);
12
+ /** @internal Creates the renderer for one active EChartsShape. */
13
+ create(input: EChartsSurfaceCreate, onFrame: (bitmap: ImageBitmap) => void, onOutput?: (output: EChartsOutput) => void): WorkerSurfaceHandle<EChartsCommand>;
14
+ dispose(): void;
15
+ }
@@ -0,0 +1,58 @@
1
+ export interface EChartsInitOpts {
2
+ theme?: string | object;
3
+ option: any;
4
+ notMerge?: boolean;
5
+ lazyUpdate?: boolean;
6
+ }
7
+ export interface EChartsWorkerInitialize {
8
+ echartsUrl: string;
9
+ }
10
+ export interface EChartsSurfaceCreate extends EChartsInitOpts {
11
+ /** ECharts logical layout width in authored-local units. */
12
+ authoredWidth: number;
13
+ /** ECharts logical layout height in authored-local units. */
14
+ authoredHeight: number;
15
+ /** Physical bitmap pixels per authored-local unit. */
16
+ renderPixelRatio: number;
17
+ }
18
+ export interface EChartsActionPayload {
19
+ type: string;
20
+ }
21
+ export type EChartsDispatchActionOptions = boolean | Readonly<{
22
+ silent?: boolean;
23
+ flush?: boolean;
24
+ }>;
25
+ export type EChartsCommand = {
26
+ type: "set-option";
27
+ option: any;
28
+ notMerge?: boolean;
29
+ lazyUpdate?: boolean;
30
+ } | {
31
+ type: "dispatch-action";
32
+ payload: EChartsActionPayload;
33
+ opt?: EChartsDispatchActionOptions;
34
+ } | {
35
+ type: "resize";
36
+ authoredWidth: number;
37
+ authoredHeight: number;
38
+ renderPixelRatio: number;
39
+ } | {
40
+ type: "event";
41
+ name: string;
42
+ x: number;
43
+ y: number;
44
+ } | {
45
+ type: "add-event-listener";
46
+ name: string;
47
+ } | {
48
+ type: "remove-event-listener";
49
+ name: string;
50
+ } | {
51
+ type: "visibility";
52
+ visible: boolean;
53
+ };
54
+ export interface EChartsOutput {
55
+ type: "event";
56
+ name: string;
57
+ params: any;
58
+ }
@@ -0,0 +1,57 @@
1
+ import type { ElementTransformClass, Layer, PropertyChanges, Root } from "@fulate/core";
2
+ import { Bitmap, RectangleProperties, type RectangleOption, type RectangleOptionPatch } from "@fulate/ui";
3
+ import type { EChartsActionPayload, EChartsDispatchActionOptions, EChartsInitOpts } from "./protocol";
4
+ export type EChartsEventListener<Params = any> = (params: Params) => void;
5
+ /** Whole-value chart configuration owned by authored/runtime property state. */
6
+ export interface EChartsShapeOption<T = EChartsShape> extends RectangleOption<T> {
7
+ echarts: EChartsInitOpts;
8
+ }
9
+ /** Authored/runtime patch; `echarts` is adopted as one whole value. */
10
+ export type EChartsShapeOptionPatch<O extends EChartsShapeOption<any> = EChartsShapeOption> = RectangleOptionPatch<O>;
11
+ /** Public properties base for typed EChartsShape subclasses. */
12
+ export declare class EChartsProperties extends RectangleProperties {
13
+ echarts: EChartsInitOpts;
14
+ constructor(options?: Partial<EChartsShapeOption>);
15
+ }
16
+ export declare class EChartsShape<P extends EChartsProperties = EChartsProperties, O extends EChartsShapeOption<any> = EChartsShapeOption<any>> extends Bitmap<P, O> {
17
+ readonly type: string;
18
+ private surface;
19
+ private lastVisibility;
20
+ private sentAuthoredWidth;
21
+ private sentAuthoredHeight;
22
+ private sentRenderPixelRatio;
23
+ private cleanups;
24
+ private readonly eChartsEventListeners;
25
+ /** Current effective chart configuration, including runtime overrides. */
26
+ get echarts(): EChartsInitOpts;
27
+ constructor(options: NoInfer<O>, properties?: P, Transform?: ElementTransformClass);
28
+ /** Sends one native incremental ECharts update outside authored state. */
29
+ setOption(option: any, notMerge?: boolean, lazyUpdate?: boolean): void;
30
+ /**
31
+ * Dispatches one action to the current native ECharts instance in its Worker.
32
+ * Registered action events return through `addEChartsEventListener()`.
33
+ */
34
+ dispatchAction<Payload extends EChartsActionPayload>(payload: Payload, opt?: EChartsDispatchActionOptions): void;
35
+ /**
36
+ * Subscribes to one native ECharts instance event across the Worker boundary.
37
+ * Custom action events must be registered by the loaded ECharts extension.
38
+ * The returned cleanup survives chart restarts and removes this subscription.
39
+ */
40
+ addEChartsEventListener<Params = any>(name: string, listener: EChartsEventListener<Params>): () => void;
41
+ resizeChart(): void;
42
+ protected onPropertiesChanged(current: P, changes: PropertyChanges): void;
43
+ protected onActivate(root: Root | null, layer: Layer | null): void;
44
+ protected onDeactivate(root: Root | null, layer: Layer | null): void;
45
+ protected onUnmount(): void;
46
+ protected paintContent(ctx: CanvasRenderingContext2D): void;
47
+ /** @internal Synchronizes ECharts animation with the actual paint path. */
48
+ syncChartVisibility(visible: boolean): void;
49
+ private startChart;
50
+ private restartChart;
51
+ private stopChart;
52
+ private toLocal;
53
+ private forwardEvent;
54
+ private get chartRenderPixelRatio();
55
+ private receiveEChartsOutput;
56
+ private bindEvents;
57
+ }
@@ -0,0 +1,16 @@
1
+ import { type WorkerSurface } from "@fulate/ui/worker-surface-worker";
2
+ import type { EChartsCommand, EChartsOutput, EChartsSurfaceCreate } from "./protocol";
3
+ /** ECharts-specific renderer state owned by one Worker surface. */
4
+ export declare class EChartsWorkerSurface implements WorkerSurface<EChartsCommand> {
5
+ private readonly emitOutput;
6
+ private readonly canvas;
7
+ private readonly chart;
8
+ private readonly frames;
9
+ private readonly chartRenderPixelRatio;
10
+ private frameRenderPixelRatio;
11
+ private readonly eventListeners;
12
+ constructor(echarts: any, input: EChartsSurfaceCreate, emitFrame: (bitmap: ImageBitmap) => void, emitOutput: (output: EChartsOutput) => void);
13
+ receive(command: EChartsCommand): void;
14
+ dispose(): void;
15
+ private getFrameCanvas;
16
+ }
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@fulate/echart",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist"
15
+ ],
16
+ "license": "MIT",
17
+ "scripts": {
18
+ "test": "vitest run --config vitest.config.ts"
19
+ },
20
+ "dependencies": {
21
+ "@fulate/share": "*",
22
+ "@fulate/core": "*",
23
+ "@fulate/ui": "*"
24
+ }
25
+ }