Often when presenting charts, different graphical elements have their own meanings, and in information display, it is necessary to emphasize or compare certain elements. By switching the state of graphical elements to display data, this process also needs to focus on visual effects, providing a more natural visual experience when the state changes.
Interpretation of State Animation (including
state and normal
State Change Animation, Animation Triggered at Any Time
State animation refers to the animation effects triggered when chart elements change according to their current state. In VChart, the design of state animation allows developers to define specific animation behaviors for different states (such as enter, update, exit, etc.). Specifically, normal state animation refers to those animations that loop or persist, running continuously after the chart is rendered until explicitly stopped.
1. Animation Configuration Structure
IAnimationSpec Interface
The IAnimationSpec interface defines the basic structure of animation configuration, which includes animation settings for different states. For normal animations, it can be specified through the animationNormal property:
Here, IMarkAnimateSpec is a generic interface used to describe the animation configuration of specific elements (such as each bar in a bar chart). In this way, developers can define personalized normal animation effects for each element.
2. Animation Manager
AnimateManager Class
The AnimateManager class is responsible for managing and coordinating the state of all animations. It implements the IAnimate interface and provides methods to update and retrieve animation states. For normal animations, the AnimateManager ensures that these animations automatically start after the chart rendering is complete and can be paused or resumed as needed.
When chart elements enter the normal state, the updateAnimateState method is called and the state is passed to the internal state management logic. This allows all eligible elements to perform the corresponding normal animation.
3. Animation Configuration Generation
animationConfig Function
To simplify the merging process between user configuration and default configuration, VChart provides a helper function called animationConfig. This function iterates over all possible animation states and constructs the final animation configuration object based on the user-provided configuration or the default configuration.
function animationConfig<Presetextendsstring>(
defaultConfig: MarkAnimationSpec = {},
userConfig?: Partial<Record<IAnimationState, boolean | IStateAnimateSpec<Preset> | IAnimationConfig | IAnimationConfig[]>>,
params?: { dataIndex: (datum: any, params: any) => number; dataCount: () => number; }
): MarkAnimationSpec {
const config = {} as MarkAnimationSpec;
for (let i = 0; i < AnimationStates.length; i++) {
const state = AnimationStates[i];
const userStateConfig = userConfig ? userConfig[state] : undefined;
if (userStateConfig === false) continue;
if (state === 'normal') {
userStateConfig && (config.normal = userStateConfig as IAnimationTypeConfig);
continue;
}
let defaultStateConfig: IAnimationConfig[];
if (isArray(defaultConfig[state])) {
defaultStateConfig = defaultConfig[state] as IAnimationConfig[];
} else {
defaultStateConfig = [{ ...DEFAULT_ANIMATION_CONFIG[state], ...defaultConfig[state] } as any];
}
config[state] = defaultStateConfig;
}
return config;
}
This function handles the animation configuration merging in the normal state, ensuring that the user-provided configuration can be correctly applied to specific graphic elements. If the user does not provide a custom normal animation configuration, the default configuration is used.
4. Specific Implementation of
Taking a scatter plot as an example, suppose we want to add a slight pulse effect to each data point as a normal animation. Here are the detailed implementation steps:
Define Animation Configuration: First, specify the animationNormal configuration for the scatter plot series in the chart configuration. Here we can choose the built-in pulse animation type and adjust its duration and easing function.
Register Animation: Next, we need to ensure that the pulse animation has been correctly registered in the system. This step is usually completed at project startup or explicitly called where needed.
import { Factory } from '@visactor/vchart';
import { pulseAnimation } from './series/scatter/animation';
Factory.registerAnimation('pulse', pulseAnimation);
The pulseAnimation function here defines the specific logic of the pulse animation, such as how to change the transparency or size of graphic elements.
Initialize the chart instance: With the above configuration, we can initialize a VChart instance and pass the configuration to it. This will trigger the rendering process of the chart and apply the corresponding animation effects.
Trigger Animation: Once the chart is rendered, all data points will automatically start executing the normal animation. This animation will continuously loop while the chart exists, unless explicitly stopped.
// 如果需要暂停所有正在进行的 normal 动画
chart.pauseAnimation();
// 恢复之前暂停的 normal 动画
chart.resumeAnimation();
5. Execution of Animation Tasks
IAnimationTask Interface
For complex animation sequences, VChart introduces the IAnimationTask interface to describe the data structure of animation tasks. Each task includes a time offset, an action queue, and a list of successor tasks, forming a chain-like animation execution mechanism.
This design allows multiple animation tasks to be executed sequentially or concurrently, achieving more complex and delicate animation effects. For normal animations, it can work as part of an independent task chain, collaborating with other animation tasks.
6. Example: Creating a Scatter Plot with
Below is an example of creating a scatter plot with normal animation, illustrating how to use VChart's state animation system to implement the basic process.
Step 1: Define Animation Configuration
First, we need to define the basic configuration of the scatter plot, including the data source and other visual attributes. At the same time, we will specify the normal animation configuration here to ensure that each data point can perform the pulse effect.
Ensure that the required pulse animation has been correctly registered in the system. This step is usually completed at project startup or explicitly called where needed.
import { Factory } from '@visactor/vchart';
import { pulseAnimation } from './series/scatter/animation';
Factory.registerAnimation('pulse', pulseAnimation);
Step 3: Initialize the Chart Instance
With the above configuration, we can initialize a VChart instance and pass the configuration to it. This step will trigger the chart rendering process and apply the corresponding animation effects.
Once the chart is rendered, all data points will automatically start executing the normal animation. This animation will continue to loop as long as the chart exists, unless explicitly stopped.
// 如果需要暂停所有正在进行的 normal 动画
chart.pauseAnimation();
// 恢复之前暂停的 normal 动画
chart.resumeAnimation();
Step 5: Dynamically Control Animation
In some cases, you may want to dynamically control the behavior of the normal animation, such as changing the speed or style of the animation. VChart provides flexible methods to achieve this.
AnimateManager not only manages normal animations but also handles animation transitions in other states. For example, when new data is added, the animation in the enter state is triggered; when data is updated, the animation in the update state takes effect; and when data is removed, the animation in the exit state comes into play.
class AnimateManager extends StateManager implements IAnimate {
updateAnimateState(state: AnimationStateEnum, noRender?: boolean) {
if (state === AnimationStateEnum.update) {
// 更新状态下的动画逻辑
} else if (state === AnimationStateEnum.appear) {
// 出现状态下的动画逻辑
} else if (state === AnimationStateEnum.normal) {
// normal 状态下的动画逻辑
this.updateState(
{
animationState: {
callback: (datum: any, element: IElement) => state
}
},
noRender
);
}
}
}
In this example, when the element enters the normal state, the updateAnimateState method will update the element's state and trigger the corresponding animation logic. This means that each data point will execute the animation according to the preset normal animation configuration until the state changes again.
8. Animation Lifecycle Management
Event Listeners and Hooks
To better manage the animation lifecycle, VChart provides a series of event listeners and hook functions. For example, the VGRAMMAR_HOOK_EVENT.AFTER_DO_RENDER event can be triggered after the chart is initially rendered, while the VGRAMMAR_HOOK_EVENT.ANIMATION_END will be triggered at the end of the animation.
This code demonstrates how to start the normal animation immediately after the chart rendering is completed, and how to seamlessly switch to the normal animation after the entrance animation ends. This design ensures a smooth transition between animations, enhancing the user experience.
Summary
Through the above steps, we have detailed the implementation principle of the normal state animation in VChart. The normal animation, as a type of state animation, is mainly used to describe the animation effect of chart elements continuously existing in a stable state. VChart ensures the flexibility and maintainability of the normal animation through modular design, factory pattern, state manager pattern, and event-driven mechanism. Developers can easily customize different types of normal animation effects according to actual needs, thereby enhancing the visual appeal and interactive experience of the chart.
This document was revised and organized by the following personnel