Skip to content

feat(graphic): optional template-based graphic slot API#969

Merged
Justineo merged 43 commits intomainfrom
feat/graphics
Feb 14, 2026
Merged

feat(graphic): optional template-based graphic slot API#969
Justineo merged 43 commits intomainfrom
feat/graphics

Conversation

@Justineo
Copy link
Member

@Justineo Justineo commented Feb 7, 2026

Background

Native ECharts option.graphic is powerful but painful in Vue-heavy projects:

  • Deep object trees and verbose config reduce readability.
  • Dynamic rendering with v-if / v-for / reactive bindings is awkward.
  • Event wiring and node tree updates are manual and error-prone.

This PR introduces an opt-in, template-based graphic API while preserving existing VChart behavior and compatibility.


Design Overview

1) Optional entry, no default bundle inflation

  • New subpath entry: vue-echarts/graphic
  • #graphic support is enabled only after explicit import (import "vue-echarts/graphic" or G* component imports).
  • Main entry vue-echarts stays lean.

2) Explicit semantics with stable behavior

  • #graphic and option.graphic are mutually exclusive in practice.
  • If both are provided, slot output wins (with dev warning).
  • manual-update semantics are preserved:
    • Auto mode: reactive slot changes are applied automatically.
    • Manual mode: users commit via chartRef.setOption(...).

3) Clean internal boundaries with pragmatic coupling

  • Core keeps only minimal extension coordination logic.
  • Graphic complexity is isolated under src/graphic/*:
    • vnode/node collection
    • graphic option building
    • event normalization + binding sync
    • slot mount/render bridge

Public API

Enable graphic slot support

import "vue-echarts/graphic";
// or
import { GGroup, GRect, GText, GCircle } from "vue-echarts/graphic";

#graphic slot

<VChart :option="option">
  <template #graphic>
    <GGroup>
      <GRect ... />
      <GText ... />
    </GGroup>
  </template>
</VChart>

G* components

The entry exports declarative components for common graphic primitives (e.g. GGroup, GRect, GCircle, GText, GLine, GPolyline, GPolygon, GImage, GSector, GRing, GArc, GBezierCurve, GCompoundPath).

Type behavior

  • Slot type augmentation (graphic) is also opt-in and only active after importing vue-echarts/graphic.

Changes to existing modules

Core / Runtime

  • src/extensions.ts
    • Introduces lightweight extension registration.
    • Adds dedupe by extension key and factory identity.
  • src/ECharts.ts
    • Integrates extension patch/render lifecycle.
    • Adds warning path for unavailable #graphic slot.
  • src/composables/slot.ts
    • Supports extension-driven slots.

New graphic runtime modules

  • src/graphic/extension.ts
    • Connects collector output to chart updates.
    • Normalizes handlers and syncs chart event bindings incrementally.
  • src/graphic/collector.ts
    • Handles registration/unregistration, ordering, snapshots, flush scheduling.
    • Includes no-op fast path and structure version tracking.
  • src/graphic/build.ts + src/graphic/build-helpers.ts
    • Builds stable ECharts graphic option from collected nodes.
  • src/graphic/mount.ts
    • Mount bridge that collects #graphic vnode trees.
  • src/graphic/components.ts + component-factory.ts + props/marker/context/warn helpers
    • Factory-based G* components.
    • Explicit component marker replaces fragile name-prefix detection.
    • Centralized warnings.

Demo

  • Adds/refactors Graphic Overlay demo:
    • demo/examples/GraphicOverlay.vue
    • demo/examples/graphic-overlay/*
  • Splits data/layout/tokens and improves light/dark consistency.

Tests

  • Adds runtime/extension/mount/behavior tests for graphic.
  • Splits large slot tests into focused suites (order/manual/events/edge).
  • Adds shared helpers to reduce duplication.
  • Coverage remains 100%.

Docs

  • Updates README.md and README.zh-Hans.md with:
    • opt-in import model
    • #graphic semantics and caveats
    • link to upstream ECharts graphic docs

Compatibility

  • No breaking changes.
  • Existing users who do not import vue-echarts/graphic are unaffected.

Verification

Executed on this branch:

  • pnpm lint
  • pnpm typecheck
  • pnpm test
  • pnpm test:coverage (100/100/100/100)
  • pnpm build

Copilot AI review requested due to automatic review settings February 7, 2026 15:40
@Justineo Justineo requested a review from a team as a code owner February 7, 2026 15:40
@vercel
Copy link

vercel bot commented Feb 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vue-echarts Ready Ready Preview, Comment Feb 14, 2026 6:35pm

Request Review

@Justineo Justineo changed the title feat(graphic): add optional template-based graphic slot API feat(graphic): optional template-based graphic slot API Feb 7, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c24da8374b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds an opt-in template-based #graphic slot API for Vue ECharts by introducing a vue-echarts/graphic subpath entry that registers a graphic extension and exports G* declarative components, plus comprehensive tests/demo/docs updates.

Changes:

  • Add a global VChart extension registry and integrate extension patch/render hooks into ECharts.
  • Introduce vue-echarts/graphic entry with collector/build/mount logic and G* components for declarative option.graphic.
  • Add extensive test coverage, a new demo example, and README documentation for the new slot API.

Reviewed changes

Copilot reviewed 40 out of 40 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
tsdown.config.ts Build config updated to emit a new graphic entry bundle.
package.json Adds ./graphic export mapping for JS + types output.
src/extensions.ts Introduces global extension registry + slot-type augmentation interface.
src/composables/slot.ts Extends slot typing via VChartExtensionSlots and skips graphic in callback-slot processing.
src/ECharts.ts Wires extension patch/render into core lifecycle; adds #graphic missing-entry warning and theme+graphic reapply behavior.
src/graphic/index.ts New opt-in entry that registers the graphic extension and exports G* components.
src/graphic/extension.ts New runtime extension bridging slot collection → option.graphic building → incremental event binding + update requests.
src/graphic/mount.ts New mount component to collect vnode order and host the slot render tree off-DOM via Teleport.
src/graphic/collector.ts New collector with pass-based registration/unregistration, coalesced flush, fingerprinting, and warn-once support.
src/graphic/build.ts Builds stable ECharts graphic.elements from collected nodes and order.
src/graphic/build-helpers.ts Helpers for style/shape/info construction and prop pruning by type.
src/graphic/components.ts Declares G* components using the component factory.
src/graphic/component-factory.ts Factory to register nodes into collector, extract handlers, provide group parenting, and warn on misuse.
src/graphic/context.ts Injection keys for collector, parent id, and order map.
src/graphic/constants.ts Shared prop/style/shape key lists and per-type shape keys.
src/graphic/marker.ts Adds a symbol marker to identify graphic components reliably.
src/graphic/props-common.ts Defines common prop surface for G* components.
src/graphic/props-shape.ts Defines shape-related props for G* components.
src/graphic/slots.ts Module augmentation to add optional graphic slot typing when entry is imported.
src/graphic/warn.ts Centralizes warning codes and messages for the graphic feature.
tests/helpers/dom.ts Adds async warn-capture helper for browser tests.
tests/helpers/graphic-slot.ts Adds shared helpers for graphic slot test suites.
tests/echarts.browser.test.ts Adds regression test for theme updates when chart ref is missing.
tests/graphic.node.test.ts Adds node-only tests for build/collector behavior and edge cases.
tests/graphic-mount.node.test.ts Adds SSR/node tests for mount behavior.
tests/graphic-extension.node.test.ts Adds node tests for extension dedupe, binding sync, warnings, and side-effect registration.
tests/graphic-components.browser.test.ts Adds browser tests for G* registration/unregistration, parent propagation, and warnings.
tests/graphic-slot-order.browser.test.ts Adds browser tests for order stability across v-if/v-for and tree changes.
tests/graphic-slot-events.browser.test.ts Adds browser tests for chart event binding and reactive handler updates.
tests/graphic-slot-manual.browser.test.ts Adds browser tests for manual-update semantics with graphic slot.
tests/graphic-slot-edge.browser.test.ts Adds browser tests for integration/edge behavior (missing entry, override, theme reapply, clear, batching, no-op).
tests/graphic-behavior.browser.test.ts Adds real-echarts integration tests covering merge/remove behaviors.
demo/examples/GraphicOverlay.vue New demo showcasing the declarative graphic overlay usage.
demo/Demo.vue Registers and renders the new GraphicOverlay demo page.
demo/examples/graphic-overlay/types.ts Demo-specific types for layout and tokens.
demo/examples/graphic-overlay/useGraphicOverlayData.ts Demo data + interactions for overlay.
demo/examples/graphic-overlay/useGraphicOverlayLayout.ts Demo layout algorithm for overlay positioning.
demo/examples/graphic-overlay/GraphicOverlayTokens.ts Demo theme token resolution for light/dark.
README.md Documents optional #graphic slot entry and usage in English.
README.zh-Hans.md Documents optional #graphic slot entry and usage in Chinese.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codecov-commenter
Copy link

codecov-commenter commented Feb 7, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (d1de473) to head (fe434ae).
⚠️ Report is 52 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##              main      #969    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files            9        25    +16     
  Lines          331       853   +522     
  Branches        39       204   +165     
==========================================
+ Hits           331       853   +522     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Feb 7, 2026

Open in StackBlitz

npm i https://pkg.pr.new/vue-echarts@969

commit: fe434ae

@Justineo Justineo merged commit 9665847 into main Feb 14, 2026
9 checks passed
@Justineo Justineo deleted the feat/graphics branch February 14, 2026 18:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants