Skip to content

Commit

Permalink
[optimize] simplify Event API (fix #15)
Browse files Browse the repository at this point in the history
  • Loading branch information
TechQuery committed Apr 9, 2024
1 parent ff0ace8 commit 9e9caf8
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 64 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "echarts-jsx",
"version": "1.0.2",
"version": "1.0.4",
"license": "LGPL-3.0",
"author": "shiy2008@gmail.com",
"description": "A real JSX wrapper for ECharts based on TypeScript & Web components",
Expand Down
33 changes: 15 additions & 18 deletions source/Option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ import { CustomElement, toCamelCase } from 'web-utility';

import { EChartsElement } from './renderers/core';
import { ProxyElement } from './Proxy';
import {
EventKeyPattern,
ZRElementEventHandler,
ZRElementEventName
} from './utility';
import { ZRElementEventHandler, ZRElementEventName } from './utility';

export abstract class ECOptionElement
extends ProxyElement<EChartsOption>
Expand Down Expand Up @@ -44,10 +40,11 @@ export abstract class ECOptionElement
if (parent instanceof EChartsElement) return parent;
}

#events: string[] = [];

connectedCallback() {
for (const [key, value] of Object.entries(this.toJSON()))
if (EventKeyPattern.test(key) && typeof value === 'function')
this.addEventListener(key.slice(2), value);
for (const event of this.#events) this.#listen(event);

this.update();
}

Expand All @@ -73,25 +70,25 @@ export abstract class ECOptionElement
#emit: ZRElementEventHandler = detail =>
this.dispatchEvent(new CustomEvent(`ec-${detail.type}`, { detail }));

addEventListener(event: string, handler: EventListener) {
if (!this.isConnected) return;

this.renderer?.onChild(
#listen = (event: string) =>
this.renderer.core.on(
event as ZRElementEventName,
this.eventSelector,
this.#emit
);
addEventListener(event: string, handler: EventListener) {
if (this.renderer) this.#listen(event);
else this.#events.push(event);

super.removeEventListener(`ec-${event}`, handler);
super.addEventListener(`ec-${event}`, handler);
}

removeEventListener(event: string, handler: EventListener) {
if (!this.isConnected) return;
if (this.renderer)
this.renderer.core.off(event as ZRElementEventName, this.#emit);
else this.#events = this.#events.filter(name => name !== event);

this.renderer?.offChild(
event as ZRElementEventName,
this.eventSelector,
this.#emit
);
super.removeEventListener(`ec-${event}`, handler);
}

Expand Down
60 changes: 15 additions & 45 deletions source/renderers/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ export abstract class EChartsElement
extends ProxyElement<EChartsElementState>
implements CustomElement
{
#core?: ECharts;
#eventHandlers: [ZRElementEventName, ZRElementEventHandler, string?][] = [];
core?: ECharts;

#eventHandlers: [ZRElementEventName, ZRElementEventHandler][] = [];
#eventData = [];

get renderer() {
Expand All @@ -36,7 +37,7 @@ export abstract class EChartsElement
}

get options() {
return this.#core.getOption();
return this.core.getOption();
}

constructor() {
Expand All @@ -59,26 +60,22 @@ export abstract class EChartsElement
disconnectedCallback() {
globalThis.removeEventListener?.('resize', this.handleResize);

this.#core?.dispose();
this.core?.dispose();
}

async #init() {
var { theme, initOptions, ...props } = this.toJSON();

this.#core = init(
this.core = init(
this.shadowRoot.firstElementChild as HTMLDivElement,
theme,
{ ...initOptions, renderer: this.renderer }
);
this.setOption({ grid: {}, ...props });

for (const [event, handler, selector] of this.#eventHandlers)
if (selector) this.onChild(event, selector, handler);
else
this.addEventListener(
event,
handler as unknown as EventListener
);
for (const [event, handler] of this.#eventHandlers)
this.addEventListener(event, handler as unknown as EventListener);

this.#eventHandlers.length = 0;

for (const option of this.#eventData) this.setOption(option);
Expand All @@ -95,11 +92,11 @@ export abstract class EChartsElement
}

async setOption(data: EChartsOption) {
if (!this.#core) {
if (!this.core) {
this.#eventData.push(data);
return;
}
this.#core.setOption(data, false, true);
this.core.setOption(data, false, true);
}

setProperty(key: string, value: any) {
Expand All @@ -112,57 +109,30 @@ export abstract class EChartsElement
if (event === 'optionchange')
return super.addEventListener(event, handler);

if (this.#core) this.#core.getZr().on(event, handler);
if (this.core) this.core.getZr().on(event, handler);
else
this.#eventHandlers.push([
event as ZRElementEventName,
handler as unknown as ZRElementEventHandler
]);
}

onChild(
event: ZRElementEventName,
selector: string,
handler: ZRElementEventHandler
) {
if (this.#core) this.#core.on(event, selector, handler);
else this.#eventHandlers.push([event, handler, selector]);
}

removeEventListener(event: string, handler: EventListener) {
if (event === 'optionchange')
return super.removeEventListener(event, handler);

if (this.#core) this.#core.getZr().off(event, handler);
else {
const index = this.#eventHandlers.findIndex(
item =>
item[0] === event &&
item[1] === (handler as unknown as ZRElementEventHandler) &&
!item[2]
);
if (index > -1) this.#eventHandlers.splice(index, 1);
}
}

offChild(
event: ZRElementEventName,
selector: string,
handler: ZRElementEventHandler
) {
if (this.#core) this.#core.off(event, handler);
if (this.core) this.core.getZr().off(event, handler);
else {
const index = this.#eventHandlers.findIndex(
item =>
item[0] === event &&
item[1] === handler &&
item[2] === selector
item[1] === (handler as unknown as ZRElementEventHandler)
);
if (index > -1) this.#eventHandlers.splice(index, 1);
}
}

handleResize = debounce(() =>
this.#core.resize(this.toJSON().resizeOptions)
this.core.resize(this.toJSON().resizeOptions)
);
}

1 comment on commit 9e9caf8

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for echarts-jsx ready!

✅ Preview
https://echarts-q9rpgqkjm-techquerys-projects.vercel.app

Built with commit 9e9caf8.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.