@vmz/plugin-echarts 0.0.0 → 0.0.2

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 CHANGED
@@ -1,3 +1,28 @@
1
1
  # @vmz/plugin-echarts
2
2
 
3
- Placeholder package (0.0.0). Reserved for the VMZ project.
3
+ ## Turn product data into an interactive view 📈
4
+
5
+ Tables are excellent for exact values, but they are poor at revealing a trend, an outlier, a changing distribution, or the relationship between several metrics. `@vmz/plugin-echarts` brings Apache ECharts to VMZ applications for the moments when users need to explore data rather than merely read it.
6
+
7
+ ECharts is a mature choice for dashboards, analytics panels, monitoring surfaces, reports, and embedded product insights. It offers a broad chart vocabulary and rich interaction without asking the surrounding VMZ page to become a chart-specific application.
8
+
9
+ ## Where it fits
10
+
11
+ | Scenario | What ECharts adds |
12
+ |---|---|
13
+ | Operational dashboard | Dense, interactive views over changing metrics |
14
+ | Product analytics | Trends, comparisons, filters, and drill-down behavior |
15
+ | Technical documentation | Live visual examples when a static diagram is not enough |
16
+ | Existing ECharts product | A native VMZ boundary around familiar chart options |
17
+
18
+ ## ECharts or Mermaid?
19
+
20
+ - Choose **ECharts** when the visualization is driven by data and users need tooltips, zooming, filtering, or exploration.
21
+ - Choose **Mermaid** when the visual explains a process, architecture, state machine, or sequence authored as text.
22
+ - Use ordinary content and tables when exact values matter more than visual exploration.
23
+
24
+ ## Keep the chart in its place
25
+
26
+ ECharts owns drawing and interaction inside its host region. VMZ owns the page, data boundary, Island/client placement, lifetime, SSR fallback, tests, and delivery decision.
27
+
28
+ That separation matters on real dashboards: a powerful chart should become interactive when useful without forcing navigation, surrounding content, and every other panel into one eager browser runtime. ✨
@@ -0,0 +1,34 @@
1
+ <template>
2
+ <div class="echarts-host" data-vmz-echarts style="min-height: 320px; width: 100%"></div>
3
+ </template>
4
+
5
+ <script client>
6
+ import { mountEcharts } from '@vmz/plugin-echarts/runtime';
7
+
8
+ export default class Echarts {
9
+ public option: any = null;
10
+ public theme: string | null = null;
11
+ public renderer: string = 'canvas';
12
+
13
+ #api: { setOption: (o: any, notMerge?: boolean) => void; dispose: () => void } | null = null;
14
+
15
+ async onMount() {
16
+ const root = this.__vmzDomRoot;
17
+ const el =
18
+ (root && root.nodeType === 1 && root.matches?.('[data-vmz-echarts]') && root) ||
19
+ root?.querySelector?.('[data-vmz-echarts]') ||
20
+ root;
21
+ if (!el || el.nodeType !== 1) return;
22
+ this.#api = await mountEcharts(el, {
23
+ option: this.option,
24
+ theme: this.theme,
25
+ renderer: this.renderer === 'svg' ? 'svg' : 'canvas',
26
+ });
27
+ }
28
+
29
+ onDestroy() {
30
+ this.#api?.dispose();
31
+ this.#api = null;
32
+ }
33
+ }
34
+ </script>
package/package.json CHANGED
@@ -1,10 +1,38 @@
1
1
  {
2
2
  "name": "@vmz/plugin-echarts",
3
- "version": "0.0.0",
4
- "description": "VMZ placeholder — not for production use.",
3
+ "version": "0.0.2",
4
+ "type": "module",
5
+ "description": "VMZ ECharts chart adapter - <Echarts>",
5
6
  "license": "MIT",
6
- "private": false,
7
- "files": [
8
- "README.md"
9
- ]
7
+ "main": "./vmz.plugin.ts",
8
+ "types": "./vmz.plugin.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./vmz.plugin.ts",
12
+ "default": "./vmz.plugin.ts"
13
+ },
14
+ "./runtime": {
15
+ "types": "./runtime.ts",
16
+ "default": "./runtime.ts"
17
+ }
18
+ },
19
+ "dependencies": {
20
+ "@vmz/plugin": "0.0.2"
21
+ },
22
+ "peerDependencies": {
23
+ "echarts": ">=5"
24
+ },
25
+ "keywords": [
26
+ "vmz",
27
+ "plugin",
28
+ "echarts",
29
+ "chart"
30
+ ],
31
+ "publishConfig": {
32
+ "access": "public"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/doki-land/vmz-framework.git"
37
+ }
10
38
  }
package/runtime.ts ADDED
@@ -0,0 +1,52 @@
1
+ /**
2
+ * ECharts mount helper (browser). Peer: echarts.
3
+ * Parallel to DaVinci (declarative track); prefer for production charts while DaVinci matures.
4
+ */
5
+
6
+ export type MountEchartsOptions = {
7
+ option?: Record<string, unknown> | null;
8
+ theme?: string | object | null;
9
+ renderer?: 'canvas' | 'svg';
10
+ };
11
+
12
+ export async function mountEcharts(el: HTMLElement, opts: MountEchartsOptions = {}) {
13
+ const echarts = await import('echarts');
14
+ const chart = echarts.init(el, opts.theme ?? undefined, {
15
+ renderer: opts.renderer ?? 'canvas',
16
+ });
17
+ if (opts.option) {
18
+ chart.setOption(opts.option);
19
+ }
20
+ const onResize = () => {
21
+ chart.resize();
22
+ };
23
+ if (typeof ResizeObserver !== 'undefined') {
24
+ const ro = new ResizeObserver(onResize);
25
+ ro.observe(el);
26
+ return {
27
+ chart,
28
+ setOption: (option: Record<string, unknown>, notMerge?: boolean) => {
29
+ chart.setOption(option, notMerge);
30
+ },
31
+ dispose: () => {
32
+ ro.disconnect();
33
+ chart.dispose();
34
+ },
35
+ };
36
+ }
37
+ if (typeof window !== 'undefined') {
38
+ window.addEventListener('resize', onResize);
39
+ }
40
+ return {
41
+ chart,
42
+ setOption: (option: Record<string, unknown>, notMerge?: boolean) => {
43
+ chart.setOption(option, notMerge);
44
+ },
45
+ dispose: () => {
46
+ if (typeof window !== 'undefined') {
47
+ window.removeEventListener('resize', onResize);
48
+ }
49
+ chart.dispose();
50
+ },
51
+ };
52
+ }
package/vmz.plugin.ts ADDED
@@ -0,0 +1,46 @@
1
+ import { definePlugin, loadPluginSource } from '@vmz/plugin';
2
+
3
+ const source = loadPluginSource(import.meta.url, 'components/Echarts.vmz');
4
+
5
+ export default definePlugin({
6
+ name: '@vmz/plugin-echarts',
7
+ version: '0.1.0',
8
+ protocol: '0.1.0',
9
+ stages: ['workspace_resolve', 'analyzer'],
10
+ deterministic: true,
11
+ async contribute(ctx) {
12
+ if (ctx.stage === 'workspace_resolve') {
13
+ return {
14
+ stage: 'workspace_resolve',
15
+ cacheKey: `@vmz/plugin-echarts:Echarts.vmz:${source.contentHash.slice(0, 12)}`,
16
+ items: [
17
+ {
18
+ id: 'component-echarts',
19
+ kind: 'source',
20
+ path: 'src/components/Echarts.vmz',
21
+ content: source.content,
22
+ contentHash: source.contentHash,
23
+ materialize: true,
24
+ },
25
+ ],
26
+ };
27
+ }
28
+ if (ctx.stage === 'analyzer') {
29
+ return {
30
+ stage: 'analyzer',
31
+ cacheKey: '@vmz/plugin-echarts:analyzer',
32
+ items: [
33
+ {
34
+ id: 'component-echarts-online',
35
+ kind: 'analyzer',
36
+ path: 'src/components/Echarts.vmz',
37
+ severity: 'advice',
38
+ message: 'Echarts component online',
39
+ code: 'vmz.plugin.echarts',
40
+ },
41
+ ],
42
+ };
43
+ }
44
+ return { stage: ctx.stage, items: [] };
45
+ },
46
+ });