Standard Line Chart Implementation
import { Line } from '@antv/g2plot';
const url = 'https://gw.alipayobjects.com/os/bmw-prod/1d565782-dde4-4bb6-8946-ea6a38ccf184.json';
async function initBasicChart() {
const response = await fetch(url);
const seriesData = await response.json();
const chartInstance = new Line('chart-mount-point', {
data: seriesData,
padding: 'auto',
xField: 'month',
yField: 'indexValue',
xAxis: {
tickCount: 5,
},
});
chartInstance.render();
}
initBasicChart();
Sample dataset structure:
[
{ "month": "2010-01", "indexValue": 1998 },
{ "month": "2010-02", "indexValue": 1850 },
{ "month": "2010-03", "indexValue": 1720 }
]
(Note: Full dataset spans multiple years as per original source)
Smooth Curve Variation
To generate a flowing line instead of sharp angles, enable the smooth property.
import { Line } from '@antv/g2plot';
const loadAndRenderSmooth = async () => {
const res = await fetch('https://gw.alipayobjects.com/os/bmw-prod/1d565782-dde4-4bb6-8946-ea6a38ccf184.json');
const metrics = await res.json();
const smoothChart = new Line('container', {
data: metrics,
xField: 'month',
yField: 'indexValue',
smooth: true,
xAxis: { tickCount: 5 },
});
smoothChart.render();
};
loadAndRenderSmooth();
Point Style Configuration
Customize point markers with shape, size, and interaction states.
import { Line } from '@antv/g2plot';
const localizedData = [
{ year: '1991', value: 3 },
{ year: '1992', value: 4 },
{ year: '1993', value: 3.5 },
{ year: '1994', value: 5 },
{ year: '1995', value: 4.9 },
{ year: '1996', value: 6 },
{ year: '1997', value: 7 },
{ year: '1998', value: 9 },
{ year: '1999', value: 13 },
];
const styleConfig = new Line('mount-node', {
data: localizedData,
xField: 'year',
yField: 'value',
label: {},
point: {
size: 5,
shape: 'diamond',
style: {
fill: 'white',
stroke: '#5B8FF9',
lineWidth: 2,
},
},
tooltip: { showMarkers: false },
state: {
active: {
style: {
shadowBlur: 4,
stroke: '#000',
fill: 'red',
},
},
},
interactions: [{ type: 'marker-active' }],
});
styleConfig.render();
Y-Axis Reflection
Flip the coordinate system vertically by setting reflect to 'y'. This usually requires moving the X-axis to the top.
import { Line } from '@antv/g2plot';
const flipChartData = [
{ Date: '2021-10-01', rating: 1 },
{ Date: '2021-10-02', rating: 3 },
{ Date: '2021-10-03', rating: 8 },
{ Date: '2021-10-04', rating: 12 },
{ Date: '2021-10-05', rating: 30 },
];
const reflectYChart = new Line('dom-target', {
data: flipChartData,
padding: 'auto',
xField: 'Date',
yField: 'rating',
reflect: 'y',
xAxis: {
position: 'top',
},
});
reflectYChart.render();
Sliding Zoom (Mini Map)
Implement interactive range selection using the slider configuration.
import { Line } from '@antv/g2plot';
const loadDataWithSlider = async () => {
const result = await fetch('https://gw.alipayobjects.com/os/bmw-prod/1d565782-dde4-4bb6-8946-ea6a38ccf184.json').then(r => r.json());
const zoomChart = new Line('container', {
data: result,
padding: 'auto',
xField: 'month',
yField: 'indexValue',
xAxis: { tickCount: 5 },
slider: {
start: 0.1,
end: 0.5,
},
});
zoomChart.render();
};
loadDataWithSlider();
Custom Animated Markers
Register a custom shape for specific points to display animations like pulsing effects.
import { G2, Line } from '@antv/g2plot';
G2.registerShape('point', 'pulse-point', {
draw(opts, group) {
const coords = opts.x;
const renderGroup = group.addGroup();
if (opts.data.time === '14.20' && opts.data.date === 'today') {
const rings = [];
for(let i=0; i<3; i++) {
rings.push(renderGroup.addShape('circle', {
attrs: {
cx: coords.x,
cy: coords.y,
r: 10,
fill: opts.color,
opacity: 0.5,
},
}));
}
const animateOpts = (ring, delay) => ({
duration: 1800,
easing: 'easeLinear',
repeat: true,
delay: delay,
});
rings[0].animate({ r: 20, opacity: 0 }, animateOpts(rings[0], 0));
rings[1].animate({ r: 20, opacity: 0 }, animateOpts(rings[1], 600));
rings[2].animate({ r: 20, opacity: 0 }, animateOpts(rings[2], 1200));
renderGroup.addShape('circle', { attrs: { x: coords.x, y: coords.y, r: 6, fill: opts.color, opacity: 0.7 } });
renderGroup.addShape('circle', { attrs: { x: coords.x, y: coords.y, r: 1.5, fill: opts.color } });
}
return renderGroup;
},
});
const getCPUData = async () => {
const resp = await fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/cpu-data.json');
return resp.json();
};
(async () => {
const cpuSeries = await getCPUData();
const animatedPlot = new Line('canvas-node', {
autoFit: true,
height: 500,
data: cpuSeries,
meta: {
cpu: { time: { type: 'cat' }, max: 100, min: 0 },
},
xField: 'time',
yField: 'cpu',
seriesField: 'date',
tooltip: { showMarkers: false },
point: { shape: 'pulse-point' },
});
animatedPlot.render();
})();
Conditional Styling via Annotations
Highlight regions based on statistical calculations like median.
import { Line } from '@antv/g2plot';
const conditionalRender = async () => {
const source = await fetch('https://gw.alipayobjects.com/os/bmw-prod/1d565782-dde4-4bb6-8946-ea6a38ccf184.json').then(r => r.json());
const statLine = new Line('node-area', {
data: source,
padding: 'auto',
xField: 'month',
yField: 'indexValue',
annotations: [
{
type: 'regionFilter',
start: ['min', 'median'],
end: ['max', '0'],
color: '#F4664A',
},
{
type: 'text',
position: ['min', 'median'],
content: 'Median Value',
offsetY: -4,
style: { textBaseline: 'bottom' },
},
{
type: 'line',
start: ['min', 'median'],
end: ['max', 'median'],
style: { stroke: '#F4664A', lineDash: [2, 2] },
},
],
});
statLine.render();
};
conditionalRender();
Interactive Custom Markers
Create complex hover interactions by registering a custom action for geometry elements.
import { Line, G2 } from '@antv/g2plot';
import { each, findIndex } from '@antv/util';
const { InteractionAction, registerInteraction, registerAction } = G2;
const customDataSet = [
{ year: '1991', value: 3 }, { year: '1992', value: 4 }, { year: '1993', value: 3.5 },
{ year: '1994', value: 5 }, { year: '1995', value: 4.9 }, { year: '1996', value: 6 },
{ year: '1997', value: 7 }, { year: '1998', value: 9 }, { year: '1999', value: 13 },
];
G2.registerShape('point', 'double-ring', {
draw(ctxConfig, groupContainer) {
const target = { x: ctxConfig.x, y: ctxConfig.y };
const wrapper = groupContainer.addGroup();
wrapper.addShape('circle', {
name: 'outer-shell',
attrs: { x: target.x, y: target.y, fill: ctxConfig.color || 'red', opacity: 0.5, r: 6 },
});
wrapper.addShape('circle', {
name: 'inner-core',
attrs: { x: target.x, y: target.y, fill: ctxConfig.color || 'red', opacity: 1, r: 2 },
});
return wrapper;
},
});
class MarkerControl extends InteractionAction {
executeActivate() {
const viewRef = this.getView();
const eventData = this.context.event;
if (eventData.data) {
const itemsList = eventData.data.items;
const pts = viewRef.geometries.filter(g => g.type === 'point');
pts.forEach(geom => {
geom.elements.forEach((elem, idx) => {
const isActive = findIndex(itemsList, item => item.data === elem.data) !== -1;
const children = elem.shape.getChildren();
if (isActive) {
children[0].animate({ r: 10, opacity: 0.2 }, { duration: 1800, easing: 'easeLinear', repeat: true });
children[1].animate({ r: 6, opacity: 0.4 }, { duration: 800, easing: 'easeLinear', repeat: true });
} else {
this.resetElementState(elem);
}
});
});
}
}
reset() {
const viewRef = this.getView();
const allPts = viewRef.geometries.filter(g => g.type === 'point');
allPts.forEach(pt => pt.elements.forEach(el => this.resetElementState(el)));
}
resetElementState(element) {
const [c0, c1] = element.shape.getChildren();
c0.stopAnimate();
c1.stopAnimate();
const { r: r0, opacity: op0 } = c0.get('attrs');
c0.attr({ r: r0, opacity: op0 });
const { r: r1, opacity: op1 } = c1.get('attrs');
c1.attr({ r: r1, opacity: op1 });
}
getView() {
return this.context.view;
}
}
registerAction('marker-action-control', MarkerControl);
registerInteraction('custom-marker-interact', {
start: [{ trigger: 'tooltip:show', action: 'marker-action-control:active' }],
end: [{ trigger: 'tooltip:hide', action: 'marker-action-control:reset' }],
});
const customInteractChart = new Line('mount-point-2', {
data: customDataSet,
xField: 'year',
yField: 'value',
label: {},
point: {
size: 5,
shape: 'double-ring',
style: { fill: 'white', stroke: '#5B8FF9', lineWidth: 2 },
},
tooltip: { showMarkers: false },
state: {
active: { style: { shadowBlur: 4, stroke: '#000', fill: 'red' } },
},
interactions: [{ type: 'custom-marker-interact' }],
});
customInteractChart.render();