!!!###!!!title=VChart Basic Principles——VisActor/VChart Contributing Documents!!!###!!!!!!###!!!description=---title: 1 VChart Basic Principles key words: VisActor,VChart,VTable,VStrory,VMind,VGrammar,VRender,Visualization,Chart,Data,Table,Graph,Gis,LLM---!!!###!!!

1.1 Chart Composition

Terminology

  • Mark: Basic graphic elements (basic primitives), such as lines, points, rectangles, etc.

  • Series: Responsible for the visual representation of specific types of data, including a set of primitives and their corresponding chart logic, such as a series of lines in a line chart

  • Region: Defines the spatial area of the chart, associates one or more series, handles interaction and animation, provides coordinate systems

  • Component: Elements that assist in reading and interacting with the chart, such as legends, axes, tips, etc.

  • Layout: Manages the layout of the chart, including the position and size of regions and components

  • Chart: The abstract concept of the entire chart, including elements on the view such as layout, components, and regions, as well as data and all elements needed to form a table

Structural Relationships

Simple Chart Example

Combination Chart Example

Same Region

The above image is a combination chart, which simply means there are multiple series groups, with bar and line being the two series above.

  • If we do not configure specifically, all series will be associated with one region, so they will overlap and share certain coordinates.

  • Each series can have its own data source, or the data source can be configured directly on the chart, with the series associated through fromDataId or fromDataIndex. In the current example, we choose to configure it on the chart.

Different Region

In this example, it is also a combination chart, but its two series appear in different regions. As mentioned above, we use layout to manage the layout of regions. In this example, we used the following code:

  layout: {
    type: 'grid',
    col: 4,
    row: 3,
    elements: [
      {
        modelId: 'legend',
        col: 0,
        colSpan: 4,
        row: 0
      },
      {
        modelId: 'pie-region',
        col: 0,
        colSpan: 2,
        row: 1
      },
      {
        modelId: 'axis-left',
        col: 2,
        row: 1
      },
      {
        modelId: 'bar-region',
        col: 3,
        row: 1
      },
      {
        modelId: 'axis-bottom',
        col: 3,
        row: 2
      }
    ]
  },    

The above uses a grid-like method to manage the layout of regions and components. We use these modelId to associate the configuration of the corresponding region and component:

  region: [
    {
      id: 'pie-region'
    },
    {
      id: 'bar-region'
    }
  ],
  axes: [
    {
      id: 'axis-left',
      regionId: 'bar-region',
      orient: 'left'
    },
    {
      id: 'axis-bottom',
      regionId: 'bar-region',
      orient: 'bottom'
    }
  ]    

1.2 VChart Architecture and Source Code Structure

1.2.1 Relationship between VChart, VGrammar, and VRender

These three are the core components of the VisActor visualization system, and their relationship is hierarchical, from bottom to top:

VRender (Bottom Layer)

VRender is a low-level visualization rendering engine responsible for the most basic graphic drawing and rendering tasks:

  • It provides rich visualization rendering features, including custom animations, element combinations, and narrative arrangements

  • It is the foundation of the VisActor visualization system, providing rendering capabilities for upper-level libraries

  • VRender offers a plugin system for flexible extensions

  • It can seamlessly switch between 2D/3D effects

  • It handles low-level Canvas operations, graphic drawing, scene management, etc.

VGrammar (Middle Layer)

VGrammar is a visualization grammar library based on VRender:

  • It uses declarative syntax to describe data visualization

  • VGrammar maps data to visual elements, handling data transformations, marks, scales, etc.

  • It provides more advanced APIs, simplifying the process of creating complex visualizations

  • VGrammar is responsible for chart syntax definition, data mapping, automatic layout, etc.

  • It is essentially a further encapsulation of VRender, adding more visualization grammar concepts

VChart (Top Layer)

VChart is the top-level chart component library:

  • It is built on VGrammar, encapsulating common chart types (bar charts, pie charts, line charts, etc.)

  • VChart provides ready-to-use chart components, so users do not need to understand the underlying graphic syntax

  • It has cross-platform features, automatically adapting to desktop, H5, and various mini-program environments

  • VChart offers complete data narrative capabilities, including comprehensive annotations, animations, flow control, and narrative templates

  • It is aimed at end-users, providing the most user-friendly visualization interface and API

Summary of Relationships

The architectural relationship of these three can be understood as:

VChart (图表组件库)
VGrammar (可视化语法)
VRender (渲染引擎)
浏览器/Canvas/WebGL    

From the code implementation perspective:

  • VChart uses VGrammar to define and build charts

  • VGrammar uses VRender for actual drawing and rendering

  • Finally, VRender controls the underlying Canvas/WebGL to draw graphics

This layered architecture allows developers to choose different levels of tools as needed: if highly customized visualization is required, VRender or VGrammar can be used directly; if quick creation of standard charts is needed, VChart can be used.

1.2.2 Relationship and Source Code Structure of Internal Components in VChart

The overall architecture adopts a modular design, with the core divided into the following main parts:

  • Core Engine (Core): The central controller of VChart, responsible for organizing the collaboration of various modules

  • Chart: Specific implementations of various chart types

  • Series: Responsible for mapping data to graphics in the chart

  • Mark: Basic graphic elements

  • Region: Defines the area for chart rendering

  • Component: Additional components such as axes, legends, etc.

  • Layout: Handles the position calculation of various elements in the chart

  • Event: Handles user interactions

  • Scale: Related to data mapping and scales

  • Data Processing (Data): Data transformation and processing

Core Module

VChart Core Class

The VChart class is the entry point of the entire chart library, responsible for instantiating and managing the entire chart lifecycle.

// packages/vchart/src/core/vchart.ts
export class VChart implements IVChart {
  readonly id = createID();
  
  // 用于注册图表、组件、系列等
  static useRegisters(comps: (() => void)[]) { ... }
  static useChart(charts: IChartConstructor[]) { ... }
  static useSeries(series: ISeriesConstructor[]) { ... }
  
  // 核心渲染流程
  renderSync(morphConfig?: IMorphConfig) { ... }
  async renderAsync(morphConfig?: IMorphConfig) { ... }
  
  // 数据更新方法
  updateData(id: StringOrNumber, data: DataView | Datum[] | string, ...) { ... }
  updateSpec(spec: ISpec, forceMerge: boolean = false, ...) { ... }
  
  // 状态管理
  setSelected(datum: MaybeArray<any> | null, ...) { ... }
  setHovered(datum: MaybeArray<Datum> | null, ...) { ... }
}    

The lifecycle of VChart mainly includes:

  • Initialization of configuration and data

  • Creating chart instance

  • Layout calculation

  • Rendering

  • Interaction event handling

  • Update and destruction

Module Chart Class (Chart)

The chart module implements various types of charts, such as bar charts, line charts, pie charts, etc., all inheriting from BaseChart.

// packages/vchart/src/chart/base/base-chart.ts
export class BaseChart<T extends IChartSpec> extends CompilableBase implements IChart {
  readonly type: string = 'chart';
  readonly seriesType: string;
  
  protected _regions: IRegion[] = [];
  protected _series: ISeries[] = [];
  protected _components: IComponent[] = [];
  
  protected _layoutFunc: LayoutCallBack;
  protected _layoutRect: IRect = { ... };
  
  layout(params: ILayoutParams): void { ... }
  compile() { ... }
}    

For example, BarChart inherits from BaseChart

export class BarChart<T extends IBarChartSpec = IBarChartSpec> extends BaseChart<T> {
  static readonly type: string = ChartTypeEnum.bar;
  static readonly seriesType: string = SeriesTypeEnum.bar;
  static readonly transformerConstructor = BarChartSpecTransformer;
  readonly transformerConstructor = BarChartSpecTransformer;
  readonly type: string = ChartTypeEnum.bar;
  readonly seriesType: string = SeriesTypeEnum.bar;
}    

The chart module is responsible for:

  • Determining the chart type and layout

  • Managing the contained areas, series, and components

  • Handling the overall mapping from data to visual elements

Series Module (Series)

The series module is the core mapping from data to visual representation, with different series types corresponding to different graphical representations.

// packages/vchart/src/series/base/base-series.ts
export abstract class BaseSeries<T extends ISeriesSpec> extends BaseModel<T> implements ISeries {
  readonly type: string = 'series';
  readonly coordinate: CoordinateType = 'none';
  
  protected _region: IRegion;
  protected _rootMark: IGroupMark = null;
  protected _seriesMark: Maybe<IMark> = null;
  
  protected _rawData!: DataView;
  protected _data: SeriesData = null;
  
  abstract initMark(): void;
  abstract initMarkStyle(): void;
  abstract dataToPosition(data: Datum, checkInViewData?: boolean): IPoint;
}    

The series module is responsible for:

  • Converting data to graphical marks

  • Handling data mapping for specific chart types

  • Managing the style and state of marks

Mark Module

Marks are the most basic visual elements, such as lines, rectangles, points, etc., which are the basic units that make up a chart. The corresponding code is implemented in the packages/vchart/src/mark directory.

The mark is responsible for:

  • Implementing specific graphic rendering

  • Handling interaction states (such as highlighting, selection)

  • Binding with data

Region Module

A region defines the rendering position of a chart on the canvas and can contain multiple series. The corresponding code is in the packages/vchart/src/region directory.

The region module is responsible for:

  • Determining the position and size of each sub-region in the chart

  • Managing the series contained within

  • Handling layout relationships between regions

Component Module

Components are auxiliary elements in the chart other than data graphics, such as axes, legends, titles, etc. Various component implementations are in the packages/vchart/src/component directory.

The component module is responsible for:

  • Rendering various auxiliary elements

  • Interacting with users (such as legend clicks)

  • Collaborating with the main chart

Layout Module

The layout module is responsible for calculating the position and size of each element in the chart. The corresponding code is in the packages/vchart/src/layout directory, specifically including:

  • Calculating element positions

  • Adjusting to fit container size

  • Handling hierarchical relationships between elements

Event Module

The event module handles user interactions and internal events, specifically including:

  • Handling user interaction events (such as clicks, hover)

  • Distributing internal events

  • Triggering data updates and rendering updates

Scale Module

The scale module is responsible for mapping conversions from data to visual attributes, specifically including:

  • Handling the mapping of data to visual space

  • Managing various scales (linear, discrete, color, etc.)

  • Calculating the range and ticks of axes

Data Module

The data module handles the conversion and processing of raw data, specifically including:

  • Parsing and converting data

  • Statistical calculations

  • Handling missing and outlier values

Rendering Process

The rendering process of VChart mainly includes the following steps:

  • Initialization: Create a VChart instance through spec configuration

  • Compilation: Parse the configuration, create various components and series

  • Layout: Calculate the position and size of each element

  • Data Processing: Process and convert data

  • Rendering Preparation: Bind data to marks

  • Actual Rendering: Draw marks on the canvas

  • Interaction Binding: Bind various interaction events

Data Update Process

When data or configuration changes:

  • Call the updateData or updateSpec method

  • Reprocess affected data

  • Update related scales

  • Relayout (if needed)

  • Update affected marks

  • Trigger re-rendering

This document was revised and organized by

玄魂