It is not only a fully functional graph visualization library, but also an explorer of data relationships.
!!!###!!!title=VRender 1.1.0 Upgrade Guide——VisActor/VRender tutorial documents!!!###!!!!!!###!!!description=VRender 1.1.0 is a stable release for the state system, animation semantics, and app-scoped multi-environment runtime. The main contract is that state styles, animation frames, and static graphic attributes are now clearly separated.This guide is for users upgrading from 1.0.x or a 1.1.0 alpha version, especially projects that use VRender through VChart, VTable, or custom rendering integrations. It covers structural changes, breaking changes, and migration steps for all upgrade users.!!!###!!!
VRender 1.1.0 Upgrade Guide
VRender 1.1.0 is a stable release for the state system, animation semantics, and app-scoped multi-environment runtime. The main contract is that state styles, animation frames, and static graphic attributes are now clearly separated.
This guide is for users upgrading from 1.0.x or a 1.1.0 alpha version, especially projects that use VRender through VChart, VTable, or custom rendering integrations. It covers structural changes, breaking changes, and migration steps for all upgrade users.
Install
After the release is published:
npm install @visactor/vrender@1.1.0
If you depend on individual VRender packages, keep @visactor/vrender-core, @visactor/vrender-animate, @visactor/vrender-components, and @visactor/vrender-kits on the same version.
Highlights
State System
The static truth model is:
baseAttributes + resolvedStatePatch -> attribute
Key changes:
sharedStateDefinitions is the recommended surface for shared state definitions.
Dynamic resolvers receive a valid StateResolveContext.graphic.
graphic.states is the local graphic state-definition surface. Shared states should use sharedStateDefinitions.
Dynamic state styles should be written as StateDefinition.resolver; graphic.stateProxy has been removed.
Animation
Key changes:
Animation frames are not the static truth source.
For appear/fade animations, set the final static attributes first, then use animate().from(...) for the start frame.
animate().to(...) should not be used as the API that commits endpoints to baseAttributes.
Sibling update animation configs no longer pre-commit attributes owned by another update item.
Built-in TagPointsUpdate can read target points/segments from the standard update target source.
scaleIn now supports fromScale, fromScaleX, and fromScaleY.
App-Scoped Runtime
Recommended app creators:
createBrowserVRenderApp()
createNodeVRenderApp()
createWxVRenderApp()
createLynxVRenderApp()
createHarmonyVRenderApp()
Create concrete views with app.createStage(). The old root-level createStage() remains as a compatibility surface, but new code should use app-scoped entries.
Structure and Compatibility Boundaries
Root and Default Entries Stay Full-Featured
The @visactor/vrender root/default entry remains the complete, easy-to-use entry. VRender 1.1.0 does not remove expected full capabilities from the default entry for bundle-size optimization.
Bundle-sensitive products should build their own profiles with narrower public subpaths/registers instead of expecting the default entry to become a lite entry.
Optional Capabilities Use Explicit Registers and Profiles
Optional capabilities are exposed through narrower public subpaths and registers, for example:
If an upper layer wants on-demand loading, expose user-facing profiles such as full, basic, richtext, story, and disappear. If a lite/profile selection does not include an animation type or component capability, the upper layer should report that clearly instead of asking VRender to auto-load full in graphic hot paths.
Component and Plugin Registration Is Explicit
VRender 1.1.0 makes component, plugin, and custom animation registration boundaries clearer:
Full/root entries keep full registration behavior.
Lite/simple/profile entries can register only the required graphics, renderers, pickers, bounds, components, plugins, or custom animations.
Custom animation can register basic, richtext, disappear, story, or the full surface.
The poptip plugin is explicit. Use loadPoptip() or installPoptipToApp(app); it is not part of the default bootstrap.
Custom Runtime Contributions Use a Runtime Installer
If an upper layer injects renderer contributions, draw interceptors, or picker contributions, use the runtime contribution installer instead of directly managing VRender DI/container refresh order:
When app is omitted, VRender records the module as a pending runtime contribution and refreshes any shared apps that already exist. It does not create a new app. New apps created later install the pending module after their default bootstrap, so replacement modules can see built-in contribution tokens before calling rebind.
When an app already exists or is passed by the host, pass it explicitly:
Use { picker: CanvasPickerContribution } in targets when the module registers picker contributions. The same module object is loaded once per binding context, so it is safe for an upper layer to call the installer before app creation and again after resolving the app.
Breaking Changes
graphic.stateProxy has been removed. Use StateDefinition.resolver for dynamic state styles.
Once a graphic is bound to a shared-state scope, state definitions should come from sharedStateDefinitions; local graphic.states no longer serves as a missing-state fallback.
Animation frames are not static truth. animate().to(...) remains a valid animation API, but it is not the API that commits endpoints to baseAttributes.
Do not use clearStates() to refresh the same state set. When the resolved patch changes while the state set stays the same, use setStates(states, { animate, animateSameStatePatchChange }).
VRender 1.1.0 removes or narrows alpha-only, uncommitted, and replaced internal paths, including old deferred state/perf hooks, old animation target fallback drafts, unpublished source shells, and dead source. External code should not deep import those internals.
Resolvers can read graphic, baseAttributes, activeStates, effectiveStates, and the current resolvedPatch. If a resolver depends on external inputs, declare declaredAffectedKeys so VRender can diff and animate the patch correctly.
Do not call clearStates() before setStates() just to refresh the same state. That loses the previous resolved patch and can make the graphic flash back to normal attributes before animating into the state attributes again.
to() describes an animation endpoint, not a baseAttributes commit API.
scaleIn Start Scale
scaleIn supports explicit start scales:
{
type: 'scaleIn',
options: {
fromScale: 0 }
}
If the final attributes are:
{
scaleX: 2,
scaleY: 3}
the animation runs from 0 -> 2 and 0 -> 3. Without fromScale, the default behavior is unchanged: VRender infers the start from the current attribute.scaleX/scaleY ?? 0.
Avoid clearStates() before same-state refresh. Do not use normalAttrs as a snapshot or restore source. Replace stateProxy with states + StateDefinition.resolver or sharedStateDefinitions.
If you maintain VChart, VTable, or another upper-layer integration, also check the removed API and call-chain log for deleted pre-release APIs and old call chains:
Do not rely on animate().to(...) to write baseAttributes.
Check scaleIn:
If the business expectation is to scale in from invisible, pass options.fromScale: 0.
Do not encode the animation start by writing final style scaleX: 0 or scaleY: 0.
Check environments:
Keep Browser and Node smoke tests.
If wx, Lynx, or Harmony are used, verify rendering, animation, event picking, and release in the real host.
Do not expand stable claims for Taro, Feishu, or TT before real-host smoke.
Check optional capability profiles:
The root/full entry can continue to be used; upgrading does not require switching to an on-demand profile.
If an upper layer exposes lite/simple/profile entries, list the included graphics, components, plugins, and custom animation registers explicitly.
If poptip is needed, call loadPoptip() before App creation or installPoptipToApp(app) when an App already exists.
Do not let component top-level imports or default bootstrap implicitly register poptip, because that breaks the bundle boundary of simple/lite entries.
Troubleshooting
A graphic flashes back to normal attributes after update
This usually means the caller clears states before setting the same states again. Use:
Also make sure shared definitions or resolver inputs are actually invalidated and recomputed.
A fade appear graphic disappears after animation
Set the final static attributes first, then use animate().from(...) for the start frame.
scaleIn has no visible scale animation
If final attrs already include scaleX/scaleY, the default inferred start can equal the final scale. Pass:
{
type: 'scaleIn',
options: { fromScale: 0 }
}
Node image export fails
Check:
Node version matches the native ABI of the installed canvas package.
The node-canvas package is passed through createNodeVRenderApp({ envParams }).
Stage has explicit width and height.
Will bundle size always decrease after upgrading?
No. VRender 1.1.0 adds app-scoped runtime, multi-environment entries, stable state/animation semantics, and public subpaths/registers. The full/root entry remains complete. Bundle-size savings require upper layers to use narrower entries or profiles.
When should I use
If an App already exists and you need to install the poptip plugin into that App's runtime context, use:
import { installPoptipToApp } from '@visactor/vrender-components';
installPoptipToApp(app);
This API requires an explicit app argument so caller mistakes fail early. If the App has not been created yet and you only need to register poptip capability globally, use loadPoptip().
When should I use
Use it for upper-layer custom renderer contribution modules, for example table split-border rendering, custom draw interceptors, or chart/table picker extensions. It handles both states:
no app yet: save the runtime contribution module for future app bootstrap and refresh existing shared apps if any;
app already exists: reinstall the requested app registry targets for that app.
It is not a replacement for default VRender bootstrap and does not auto-load arbitrary optional features.
Not Included in the 1.1.0 Stable Contract
Tier 1 claims for Taro, Feishu, or TT.
Full multi-environment isolation inside one JS runtime.
Automatic fine-grained on-demand assembly as an equivalent replacement for root package defaults; savings require explicit profile/register selection by upper layers.
Moving glyph sub-graphic state into the shared-state main path.
Additional memory or constructor representation optimizations.