ECharts Data Transformation: How to Use registerExternalTransform for Custom Pipelines
ECharts provides a data-transform pipeline that processes raw datasets through configurable steps before rendering, and you can register custom transforms using registerExternalTransform with a namespaced type string like myLib:transformName.
Apache ECharts implements a powerful data transformation system that allows developers to manipulate dataset sources before they reach the series rendering stage. The pipeline operates through DataTransformOption objects and supports both built-in operations and user-defined extensions. Understanding how to leverage registerExternalTransform enables you to implement domain-specific data manipulations while maintaining type safety and performance.
Understanding the ECharts Data Transform Architecture
The transformation engine is centralized in src/data/helper/transform.ts and revolves around several key abstractions that ensure safe data manipulation.
Core Interfaces and Types
According to the source code in src/data/helper/transform.ts (lines 40-57), the pipeline relies on two primary interfaces:
DataTransformOption(lines 40-48): Defines a transform step with atypestring and optionalconfigobject.ExternalDataTransform(lines 50-57): The interface your custom transform must implement, requiring atypeproperty and atransformfunction.
The ExternalDataTransform interface specifies that your transform function receives an object containing upstream, upstreamList, and config parameters, and must return either a single result object or an array of results.
The ExternalSource Safety Wrapper
When transforms execute, ECharts does not expose internal Source objects directly. Instead, it wraps upstream data in an ExternalSource instance (src/data/helper/transform.ts, lines 92-158). This wrapper provides read-only helper methods including:
getRawData()- Retrieves the raw array-rows.retrieveValue()- Safe value extraction.cloneRawData()- Immutable data copying.
This design protects the internal data model while giving transform authors sufficient access to manipulate data.
Global Registration and Pipeline Execution
The registerExternalTransform function (src/data/helper/transform.ts, lines 33-61) maintains a global registry map where transforms are stored under their namespaced keys. When ECharts processes a dataset, applyDataTransform (lines 63-89) serves as the entry point that:
- Splits the type string on
:to identify the namespace. - Retrieves the registered
ExternalDataTransformfrom the global map. - Creates
ExternalSourcewrappers for upstream datasets. - Invokes the transform function and normalizes the output through
applySingleDataTransform(lines 92-140).
How to Register an External Transform with registerExternalTransform
To add custom transformation logic to your ECharts installation, you must implement the ExternalDataTransform interface and register it globally.
Namespace Requirements and Type Naming
ECharts requires external transforms to use namespaced type strings following the pattern namespace:transformName (e.g., myLib:double or custom:aggregate). Built-in transforms reside under the echarts: namespace and can be referenced without the prefix (e.g., filter instead of echarts:filter).
Implementing the Transform Interface
Your transform object must satisfy the ExternalDataTransform interface defined in the source code. The transform function receives an object with three properties:
upstream: AnExternalSourceinstance for single-source transforms.upstreamList: An array ofExternalSourceobjects for multi-source transforms.config: The configuration object passed from the chart option.
The function must return an object containing at minimum a data property (the transformed rows), and optionally a dimensions array if the output schema differs from the input.
Practical Example: Creating a Custom Transform
Here is a complete implementation of a transform that doubles numeric values, demonstrating the patterns found in src/data/helper/transform.ts:
// my-double-transform.ts
import { registerExternalTransform, ExternalDataTransform } from 'echarts/src/data/helper/transform';
const doubleTransform: ExternalDataTransform = {
type: 'myLib:double',
transform({ upstream }) {
// Access raw data through the ExternalSource wrapper
const data = upstream.getRawData();
const doubled = data.map(row => {
return row.map(value =>
typeof value === 'number' ? value * 2 : value
);
});
// Return transformed data; dimensions inherited from upstream
return { data: doubled };
}
};
// Register globally once during application initialization
registerExternalTransform(doubleTransform);
This implementation follows the exact interface requirements specified in the source code, using the read-only getRawData() method provided by ExternalSource rather than accessing internal data structures directly. The src/component/transform.ts file ensures this registration API is available to extension authors.
Using Custom Transforms in Chart Options
Once registered, external transforms integrate seamlessly into the ECharts option schema alongside built-in transforms.
Single Transform Application
Apply your registered transform to a dataset using the transform property:
const option = {
dataset: {
source: [
['item', 'value'],
['A', 10],
['B', 20],
['C', 30]
],
transform: { type: 'myLib:double' }
},
series: [
{
type: 'bar',
encode: { x: 'item', y: 'value' }
}
]
};
When rendered, ECharts locates myLib:double in the registry via applyDataTransform, executes the transformation, and the bar series receives doubled values [20, 40, 60].
Chaining Multiple Transforms
The transform property accepts an array to create processing pipelines:
const option = {
dataset: {
source: [
['category', 'sales', 'profit'],
['A', 100, 30],
['B', 150, 45],
['C', 200, 60]
],
transform: [
{ type: 'filter', config: { dimension: 'profit', lt: 50 } },
{ type: 'myLib:double', config: { dimension: 'sales' } }
]
},
series: [{ type: 'bar' }]
};
ECharts processes transforms sequentially using applySingleDataTransform for each step. The pipeline executes in order: first filtering rows where profit is less than 50, then doubling the sales values for the remaining rows.
Summary
- ECharts data transformation operates through a pipeline architecture defined in
src/data/helper/transform.tsthat processes datasets before series rendering. registerExternalTransformstores custom transforms in a global registry using namespaced keys likemyLib:transformName.- The
ExternalSourcewrapper (lines 92-158) provides safe, read-only access to upstream data through methods likegetRawData()andretrieveValue(). - Transform implementations must return objects with a
dataproperty containing the transformed rows, optionally includingdimensionsfor schema changes. - Transforms can be chained in arrays to create complex processing pipelines, mixing built-in transforms (under the
echartsnamespace) with custom external transforms.
Frequently Asked Questions
What is the difference between built-in and external transforms in ECharts?
Built-in transforms are registered under the echarts: namespace and can be referenced without the prefix (e.g., filter or sort), while external transforms require explicit namespaced types like myLib:custom. Both implement the same ExternalDataTransform interface and execute through the same applyDataTransform pipeline in src/data/helper/transform.ts.
How does the ExternalSource protect internal data models?
The ExternalSource class defined in src/data/helper/transform.ts (lines 92-158) wraps the internal Source objects and exposes only specific read-only methods such as getRawData(), retrieveValue(), and cloneRawData(). This prevents transform functions from corrupting ECharts' internal state while providing sufficient functionality for data manipulation.
Can I chain multiple external transforms in ECharts?
Yes, the transform property in dataset options accepts an array of DataTransformOption objects. ECharts processes these sequentially through applySingleDataTransform, passing the output of each step as the input to the next. You can mix built-in transforms and custom external transforms in the same pipeline array.
Where are external transforms stored in the ECharts codebase?
External transforms are stored in a global map maintained by the registerExternalTransform function in src/data/helper/transform.ts (lines 33-61). The src/component/transform.ts file loads the necessary install module to make the registration API available to extension authors, while the core logic resides in the transform helper module.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →