xiaohongshu
xiaohongshu
echarts
Create powerful interactive charts with Apache ECharts - balanced ease-of-use and customization
Full skill instructions
Create stunning, interactive charts with Apache ECharts - the perfect balance of ease-of-use and extensive customization.
Use ECharts when you need:
Avoid when:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
</head>
<body>
<div id="main" style="width: 600px; height: 400px;"></div>
<script>
var myChart = echarts.init(document.getElementById('main'));
var option = {
title: {
text: 'Monthly Sales'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['Sales']
},
xAxis: {
type: 'category',
data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
},
yAxis: {
type: 'value'
},
series: [{
name: 'Sales',
type: 'line',
data: [120, 200, 150, 80, 70, 110],
smooth: true
}]
};
myChart.setOption(option);
</script>
</body>
</html>
var option = {
title: {
text: 'Quarterly Revenue Comparison'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {
data: ['2023', '2024']
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: ['Q1', 'Q2', 'Q3', 'Q4']
},
yAxis: {
type: 'value',
name: 'Revenue (k$)'
},
series: [
{
name: '2023',
type: 'bar',
data: [120, 200, 150, 80],
itemStyle: {
color: '#5470C6'
}
},
{
name: '2024',
type: 'bar',
data: [180, 250, 200, 120],
itemStyle: {
color: '#91CC75'
}
}
]
};
myChart.setOption(option);
var option = {
title: {
text: 'Traffic Sources',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left'
},
series: [
{
name: 'Access From',
type: 'pie',
radius: '50%',
data: [
{ value: 1048, name: 'Search Engine' },
{ value: 735, name: 'Direct' },
{ value: 580, name: 'Email' },
{ value: 484, name: 'Affiliate' },
{ value: 300, name: 'Video Ads' }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
myChart.setOption(option);
// Fetch CSV data
fetch('../data/sales.csv')
.then(response => response.text())
.then(csvText => {
// Parse CSV
const lines = csvText.trim().split('\n');
const headers = lines[0].split(',');
const categories = [];
const values = [];
for (let i = 1; i < lines.length; i++) {
const row = lines[i].split(',');
categories.push(row[0]);
values.push(parseFloat(row[1]));
}
// Create chart
var myChart = echarts.init(document.getElementById('main'));
var option = {
title: { text: 'Sales Data from CSV' },
tooltip: { trigger: 'axis' },
xAxis: {
type: 'category',
data: categories
},
yAxis: { type: 'value' },
series: [{
name: 'Sales',
type: 'line',
data: values,
smooth: true,
areaStyle: {}
}]
};
myChart.setOption(option);
});
var option = {
title: {
text: 'Temperature and Precipitation'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
}
},
legend: {
data: ['Temperature', 'Precipitation']
},
xAxis: {
type: 'category',
data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
},
yAxis: [
{
type: 'value',
name: 'Temperature (°C)',
position: 'left',
axisLabel: {
formatter: '{value} °C'
}
},
{
type: 'value',
name: 'Precipitation (mm)',
position: 'right',
axisLabel: {
formatter: '{value} mm'
}
}
],
series: [
{
name: 'Temperature',
type: 'line',
yAxisIndex: 0,
data: [2, 5, 9, 15, 20, 25],
smooth: true
},
{
name: 'Precipitation',
type: 'bar',
yAxisIndex: 1,
data: [50, 45, 40, 35, 30, 25]
}
]
};
myChart.setOption(option);
// Generate data for a year
function getVirtulData(year) {
const date = +echarts.time.parse(year + '-01-01');
const end = +echarts.time.parse(+year + 1 + '-01-01');
const dayTime = 3600 * 24 * 1000;
const data = [];
for (let time = date; time < end; time += dayTime) {
data.push([
echarts.time.format(time, '{yyyy}-{MM}-{dd}', false),
Math.floor(Math.random() * 10000)
]);
}
return data;
}
var option = {
title: {
text: 'Activity Heatmap Calendar'
},
tooltip: {
position: 'top',
formatter: function (p) {
return p.data[0] + ': ' + p.data[1];
}
},
visualMap: {
min: 0,
max: 10000,
calculable: true,
orient: 'horizontal',
left: 'center',
top: 'top'
},
calendar: {
range: '2024',
cellSize: ['auto', 13]
},
series: {
type: 'heatmap',
coordinateSystem: 'calendar',
data: getVirtulData('2024')
}
};
myChart.setOption(option);
var option = {
title: {
text: 'Performance Score'
},
tooltip: {
formatter: '{a} <br/>{b} : {c}%'
},
series: [
{
name: 'Score',
type: 'gauge',
progress: {
show: true
},
detail: {
valueAnimation: true,
formatter: '{value}%'
},
data: [
{
value: 85,
name: 'Overall Score'
}
]
}
]
};
myChart.setOption(option);
// Animate the value
setInterval(() => {
const newValue = Math.random() * 100;
option.series[0].data[0].value = newValue.toFixed(2);
myChart.setOption(option);
}, 2000);
// Load map data
fetch('https://cdn.jsdelivr.net/npm/echarts/map/json/china.json')
.then(response => response.json())
.then(chinaJson => {
echarts.registerMap('china', chinaJson);
var option = {
title: {
text: 'Sales by Province',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{b}<br/>{c} (units)'
},
visualMap: {
min: 0,
max: 1000,
text: ['High', 'Low'],
calculable: true
},
series: [
{
name: 'Sales',
type: 'map',
map: 'china',
roam: true,
emphasis: {
label: {
show: true
}
},
data: [
{ name: 'Beijing', value: 500 },
{ name: 'Shanghai', value: 800 },
{ name: 'Guangdong', value: 900 },
{ name: 'Zhejiang', value: 700 }
]
}
]
};
myChart.setOption(option);
});
var data = [];
var now = new Date();
function randomData() {
now = new Date(+now + 1000);
return {
name: now.toString(),
value: [
[now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/') + ' ' +
[now.getHours(), now.getMinutes(), now.getSeconds()].join(':'),
Math.round(Math.random() * 100)
]
};
}
// Initialize with 100 points
for (var i = 0; i < 100; i++) {
data.push(randomData());
}
var option = {
title: {
text: 'Real-Time Data Stream'
},
tooltip: {
trigger: 'axis',
formatter: function (params) {
params = params[0];
return params.value[0] + ' : ' + params.value[1];
},
axisPointer: {
animation: false
}
},
xAxis: {
type: 'time',
splitLine: {
show: false
}
},
yAxis: {
type: 'value',
boundaryGap: [0, '100%'],
splitLine: {
show: false
}
},
series: [
{
name: 'Value',
type: 'line',
showSymbol: false,
data: data,
smooth: true
}
]
};
myChart.setOption(option);
// Update every second
setInterval(() => {
data.shift();
data.push(randomData());
myChart.setOption({
series: [{
data: data
}]
});
}, 1000);
// Make chart responsive
window.addEventListener('resize', function() {
myChart.resize();
});
// Or set explicit size
myChart.resize({
width: 800,
height: 600
});
// Show loading
myChart.showLoading();
// Fetch data
fetch('../data/data.json')
.then(response => response.json())
.then(data => {
myChart.hideLoading();
myChart.setOption(option);
});
// Handle no data
if (data.length === 0) {
myChart.setOption({
title: {
text: 'No Data Available',
left: 'center',
top: 'center'
}
});
}
// Use built-in themes
var myChart = echarts.init(document.getElementById('main'), 'dark');
// Or custom theme
var customTheme = {
color: ['#c23531', '#2f4554', '#61a0a8'],
backgroundColor: '#f4f4f4'
};
var myChart = echarts.init(document.getElementById('main'), customTheme);
option = {
series: [{
type: 'line',
// Enable sampling for large datasets
sampling: 'lttb',
// Use progressive rendering
progressive: 1000,
progressiveThreshold: 3000,
data: largeDataArray
}]
};
import * as echarts from 'echarts';
type EChartsOption = echarts.EChartsOption;
const option: EChartsOption = {
title: {
text: 'TypeScript Example'
},
xAxis: {
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [
{
data: [120, 200, 150, 80, 70, 110, 130],
type: 'line'
}
]
};
const chartDom = document.getElementById('main')!;
const myChart = echarts.init(chartDom);
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts@5/dist/echarts.min.js"></script>
npm install echarts
import * as echarts from 'echarts';
// Or import specific modules
import * as echarts from 'echarts/core';
import { LineChart } from 'echarts/charts';
import { GridComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
echarts.use([LineChart, GridComponent, CanvasRenderer]);
option = {
animation: true,
animationDuration: 1000,
animationEasing: 'cubicOut',
animationDelay: function (idx) {
return idx * 50;
}
};
option = {
dataZoom: [
{
type: 'inside', // Mouse wheel zoom
start: 0,
end: 100
},
{
type: 'slider', // Slider zoom
start: 0,
end: 100
}
],
// ... rest of option
};
option = {
brush: {
toolbox: ['rect', 'polygon', 'lineX', 'lineY', 'keep', 'clear'],
xAxisIndex: 0
},
// ... rest of option
};
myChart.on('brushSelected', function (params) {
var brushComponent = params.batch[0];
var selected = brushComponent.selected[0].dataIndex;
console.log('Selected data indices:', selected);
});
// Click event
myChart.on('click', function (params) {
console.log('Clicked:', params);
alert('You clicked on ' + params.name);
});
// Hover event
myChart.on('mouseover', function (params) {
console.log('Hovered:', params);
});
// Custom events
myChart.dispatchAction({
type: 'highlight',
seriesIndex: 0,
dataIndex: 1
});
import { useEffect, useRef } from 'react';
import * as echarts from 'echarts';
function EChartsComponent({ option }) {
const chartRef = useRef(null);
const chartInstance = useRef(null);
useEffect(() => {
if (!chartInstance.current) {
chartInstance.current = echarts.init(chartRef.current);
}
chartInstance.current.setOption(option);
const handleResize = () => chartInstance.current.resize();
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
chartInstance.current?.dispose();
};
}, [option]);
return <div ref={chartRef} style={{ width: '100%', height: '400px' }} />;
}
<template>
<div ref="chart" style="width: 600px; height: 400px;"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
props: ['option'],
mounted() {
this.chart = echarts.init(this.$refs.chart);
this.chart.setOption(this.option);
window.addEventListener('resize', this.handleResize);
},
beforeUnmount() {
window.removeEventListener('resize', this.handleResize);
this.chart.dispose();
},
methods: {
handleResize() {
this.chart.resize();
}
},
watch: {
option: {
deep: true,
handler(newOption) {
this.chart.setOption(newOption);
}
}
}
};
</script>
Use this skill for the best balance of ease-of-use and powerful customization!
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience