一键导入
echarts
Create powerful interactive charts with Apache ECharts - balanced ease-of-use and customization
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Create powerful interactive charts with Apache ECharts - balanced ease-of-use and customization
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | echarts |
| version | 1.0.0 |
| description | Create powerful interactive charts with Apache ECharts - balanced ease-of-use and customization |
| author | workspace-hub |
| category | data-visualization |
| tags | ["charts","echarts","apache","interactive","typescript","mobile"] |
| platforms | ["web","javascript","typescript"] |
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!
Save/publish analysis or computation results from ANY ecosystem repo to Hugging Face as a queryable, viewer-renderable dataset. Use when the user wants to "save results to hugging face", "publish dataset to HF", "hugging face data saving", "save analysis results", "hf dataset", "make results queryable", or "render via datasets-server API". Reshapes nested results into flat parquet tables, writes a dataset card with a viewer `configs:` block and provenance, applies license/public-vs-private routing, enforces a domain data-quality gate (faithful-to-source != correct), publishes to `aceengineer/<repo>-<projection>`, and verifies via the datasets-server API.
Diagnose and fix a machine whose equivalence-state fingerprint publish is absent, stale, or gate-length slow (the wh#3500 pre-push RUN_ALL deadlock signature). Use when the equality matrix shows PUBLISH-GATED / PUBLISH-STALE / MISSING-EVIDENCE on the publish-health row, or the sentinel reports absent-fingerprint / publish-slow divergences.
Bootstrap a registered private client wiki from the committed generic template.
Build worldenergydata drill-down pages (field hub, well timelines, insight/norm pages) with the proven validate-first playbook, the fractal IA grammar, honesty rules, and the exact wed CI gotchas.
Diagnose and reduce git repository bloat — multi-GB .git, slow git status/fetch/clone caused by large binaries committed to history. Consolidates packs and enables the untracked-cache (always-safe wins), then plans an operator-gated history rewrite that strips only large already-deleted blobs. Use when a repo's .git is multiple GB, git ops are slow, or the user mentions "repo bloat", "shrink/slim .git", "git filter-repo", "repo health", or large binaries in git history. Safe to point at any workspace-hub repo.
Mandatory planning workflow for ALL GitHub issues — plan, review, approve, then implement.