From 2cb1e5cc9a8c6ded506996d81b28428da2ec7ad5 Mon Sep 17 00:00:00 2001 From: TechQuery Date: Sun, 18 Feb 2024 02:03:29 +0800 Subject: [PATCH] [fix] some Rendering bugs of ECharts elements [add] ECharts example for testing --- package.json | 1 + pnpm-lock.yaml | 8 ++++-- source/component/ECharts/Chart.tsx | 35 ++++++++++++++++++------ source/component/ECharts/Option.tsx | 8 +++--- source/component/ECharts/Proxy.ts | 8 +++--- source/page/Map/component/VirusChart.tsx | 27 ++++++++++++++++++ source/page/Map/index.tsx | 2 +- 7 files changed, 69 insertions(+), 20 deletions(-) diff --git a/package.json b/package.json index 12026b9..eee4c2f 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "dom-renderer": "^2.1.4", "echarts": "^5.4.3", "github-web-widget": "^4.0.0-rc.2", + "iterable-observer": "^1.0.1", "js-base64": "^3.7.6", "koajax": "^0.9.6", "lodash.debounce": "^4.0.8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d377ebc..507d7c2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,7 +7,7 @@ settings: dependencies: boot-cell: specifier: ^2.0.0-beta.20 - version: 2.0.0-beta.20(typescript@5.3.3) + version: 2.0.0-beta.20(iterable-observer@1.0.1)(typescript@5.3.3) browser-unhandled-rejection: specifier: ^1.0.2 version: 1.0.2 @@ -26,6 +26,9 @@ dependencies: github-web-widget: specifier: ^4.0.0-rc.2 version: 4.0.0-rc.2(typescript@5.3.3) + iterable-observer: + specifier: ^1.0.1 + version: 1.0.1 js-base64: specifier: ^3.7.6 version: 3.7.6 @@ -3253,7 +3256,7 @@ packages: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} dev: true - /boot-cell@2.0.0-beta.20(typescript@5.3.3): + /boot-cell@2.0.0-beta.20(iterable-observer@1.0.1)(typescript@5.3.3): resolution: {integrity: sha512-WToNDj7UZN0/CTruXW30RMfoOgyLEbOVP4Y8EMlX0obGQkSTvYef//EYv8Pvg9KH2p1srQNtjGDK6Oe1vT2IEg==} peerDependencies: '@fortawesome/fontawesome-free': ^6 @@ -3267,6 +3270,7 @@ packages: '@swc/helpers': 0.5.6 classnames: 2.5.1 dom-renderer: 2.1.4(typescript@5.3.3) + iterable-observer: 1.0.1 mobx: 6.12.0 regenerator-runtime: 0.14.1 web-cell: 3.0.0-rc.15(typescript@5.3.3) diff --git a/source/component/ECharts/Chart.tsx b/source/component/ECharts/Chart.tsx index 47fe7aa..b262e9a 100644 --- a/source/component/ECharts/Chart.tsx +++ b/source/component/ECharts/Chart.tsx @@ -2,8 +2,9 @@ import { JsxProps } from 'dom-renderer'; import { EChartsOption, ResizeOpts } from 'echarts'; import { ECharts, init } from 'echarts/core'; import { ECBasicOption } from 'echarts/types/dist/shared'; +import { Observable } from 'iterable-observer'; import debounce from 'lodash.debounce'; -import { CustomElement, parseDOM } from 'web-utility'; +import { CustomElement, parseDOM, sleep } from 'web-utility'; import { ProxyElement } from './Proxy'; import { @@ -32,6 +33,10 @@ export interface EChartsElementProps export type EChartsElementState = EChartsElementProps & EChartsOption; +const DefaultOptions: EChartsOption = { + grid: {} +}; + export class EChartsElement extends ProxyElement implements CustomElement @@ -51,15 +56,17 @@ export class EChartsElement return this.#type; } + get options() { + return this.#core.getOption(); + } + constructor() { super(); this.attachShadow({ mode: 'open' }).append( parseDOM('
')[0] ); - this.addEventListener('optionchange', ({ detail }: CustomEvent) => - this.setOption(detail) - ); + this.#boot(); } connectedCallback() { @@ -71,7 +78,7 @@ export class EChartsElement disconnectedCallback() { globalThis.removeEventListener?.('resize', this.handleResize); - this.#core.dispose(); + this.#core?.dispose(); } async #init(type: ChartType) { @@ -88,7 +95,7 @@ export class EChartsElement for (const [event, handler, selector] of this.#eventHandlers) if (selector) this.onChild(event, selector, handler); - else this.on(event, handler); + else this.listen(event, handler); this.#eventHandlers.length = 0; @@ -97,6 +104,16 @@ export class EChartsElement this.#eventData.length = 0; } + async #boot() { + for await (const { detail } of Observable.fromEvent( + this, + 'optionchange' + )) { + this.setOption(detail); + await sleep(0.5); + } + } + async setOption(data: EChartsOption) { if (!this.#core) { this.#eventData.push(data); @@ -109,7 +126,7 @@ export class EChartsElement else if (key in BUILTIN_CHARTS_MAP) await loadChart(key as ECChartOptionName); - this.#core.setOption(data, false, true); + this.#core.setOption({ ...DefaultOptions, ...data }, false, true); } setProperty(key: string, value: any) { @@ -118,7 +135,7 @@ export class EChartsElement this.setOption(this.toJSON()); } - on(event: ZRElementEventName, handler: ZRElementEventHandler) { + listen(event: ZRElementEventName, handler: ZRElementEventHandler) { if (this.#core) this.#core.getZr().on(event, handler); else this.#eventHandlers.push([event, handler]); } @@ -132,7 +149,7 @@ export class EChartsElement else this.#eventHandlers.push([event, handler, selector]); } - off(event: ZRElementEventName, handler: ZRElementEventHandler) { + forget(event: ZRElementEventName, handler: ZRElementEventHandler) { if (this.#core) this.#core.getZr().off(event, handler); else { const index = this.#eventHandlers.findIndex( diff --git a/source/component/ECharts/Option.tsx b/source/component/ECharts/Option.tsx index fcad55c..b654a30 100644 --- a/source/component/ECharts/Option.tsx +++ b/source/component/ECharts/Option.tsx @@ -25,7 +25,7 @@ export abstract class ECOptionElement implements CustomElement { get chartTagName() { - return toCamelCase(this.tagName.split('-')[1].toLowerCase()); + return toCamelCase(this.tagName.replace(/^ec-/i, '').toLowerCase()); } get isSeries() { @@ -39,7 +39,7 @@ export abstract class ECOptionElement connectedCallback() { for (const [key, value] of Object.entries(this.toJSON())) if (EventKeyPattern.test(key) && typeof value === 'function') - this.on( + this.listen( key.slice(2) as ZRElementEventName, value as ZRElementEventHandler ); @@ -65,7 +65,7 @@ export abstract class ECOptionElement ); } - on(event: ZRElementEventName, handler: ZRElementEventHandler) { + listen(event: ZRElementEventName, handler: ZRElementEventHandler) { if (this.isConnected) this.closest('ec-chart')?.onChild( event, @@ -74,7 +74,7 @@ export abstract class ECOptionElement ); } - off(event: ZRElementEventName, handler: ZRElementEventHandler) { + forget(event: ZRElementEventName, handler: ZRElementEventHandler) { if (this.isConnected) this.closest('ec-chart')?.offChild( event, diff --git a/source/component/ECharts/Proxy.ts b/source/component/ECharts/Proxy.ts index 1663a6d..2258a21 100644 --- a/source/component/ECharts/Proxy.ts +++ b/source/component/ECharts/Proxy.ts @@ -18,8 +18,8 @@ export abstract class ProxyElement extends HTMLElement { ); } - abstract on(event: string, handler: (event: any) => any): any; - abstract off(event: string, handler: (event: any) => any): any; + abstract listen(event: string, handler: (event: any) => any): any; + abstract forget(event: string, handler: (event: any) => any): any; setProperty(key: string, value: any) { const oldValue = this.#data[key], @@ -36,7 +36,7 @@ export abstract class ProxyElement extends HTMLElement { else super.removeAttribute(name); break; case 'function': - if (EventKeyPattern.test(key)) this.on(eventName, value); + if (EventKeyPattern.test(key)) this.listen(eventName, value); break; default: if (value != null) super.setAttribute(name, value + ''); @@ -44,7 +44,7 @@ export abstract class ProxyElement extends HTMLElement { EventKeyPattern.test(key) && typeof oldValue === 'function' ) - this.off(eventName, value); + this.forget(eventName, value); else super.removeAttribute(name); } } diff --git a/source/page/Map/component/VirusChart.tsx b/source/page/Map/component/VirusChart.tsx index 45694df..c9b9305 100644 --- a/source/page/Map/component/VirusChart.tsx +++ b/source/page/Map/component/VirusChart.tsx @@ -260,6 +260,33 @@ export class VirusChart return ( <> + + + + + + + + + + + + + )} - + ); }