测试 ECharts图表

这篇文章用来检查本站的 ECharts 代码块能力。下面会依次跑一遍 JSON/YAML/TOML option、JS option、异步 JS option、相对资源文件,以及 widthheightrendererthemejsasync 这些参数,方便以后改样式或插件时快速回归。

JSON 基础柱状图

源码:

md
```echarts {height-360}
{
"tooltip": { "trigger": "axis" },
"xAxis": {
"type": "category",
"data": ["2009", "2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2022", "2023", "2024", "2026"]
},
"yAxis": { "type": "value" },
"series": [
{
"name": "文章数",
"type": "bar",
"data": [3, 3, 3, 10, 15, 10, 9, 8, 12, 10, 3, 7, 5, 9]
}
]
}
```

效果:

{"tooltip":{"trigger":"axis"},"xAxis":{"type":"category","data":["2009","2010","2011","2012","2013","2014","2015","2016","2017","2018","2022","2023","2024","2026"]},"yAxis":{"type":"value"},"series":[{"name":"文章数","type":"bar","data":[3,3,3,10,15,10,9,8,12,10,3,7,5,9]}]}

JSON 堆叠折线和工具箱

这个例子直接写完整 ECharts option,用来确认图例、工具箱、堆叠折线和面积样式是否都能正常渲染。

源码:

md
```echarts {height-420}
{
"title": { "text": "一周内容入口趋势", "left": "center", "top": 8 },
"tooltip": { "trigger": "axis" },
"legend": { "top": 44, "data": ["首页", "搜索", "标签", "RSS", "外链"] },
"toolbox": {
"right": 12,
"feature": {
"saveAsImage": { "title": "保存" },
"dataZoom": { "title": { "zoom": "缩放", "back": "还原" } },
"restore": { "title": "重置" }
}
},
"grid": { "left": 42, "right": 24, "top": 92, "bottom": 36, "containLabel": true },
"xAxis": {
"type": "category",
"boundaryGap": false,
"data": ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
},
"yAxis": { "type": "value" },
"series": [
{ "name": "首页", "type": "line", "stack": "总量", "smooth": true, "areaStyle": {}, "data": [120, 132, 101, 134, 90, 230, 210] },
{ "name": "搜索", "type": "line", "stack": "总量", "smooth": true, "areaStyle": {}, "data": [220, 182, 191, 234, 290, 330, 310] },
{ "name": "标签", "type": "line", "stack": "总量", "smooth": true, "areaStyle": {}, "data": [150, 232, 201, 154, 190, 330, 410] },
{ "name": "RSS", "type": "line", "stack": "总量", "smooth": true, "areaStyle": {}, "data": [82, 93, 90, 93, 129, 133, 132] },
{ "name": "外链", "type": "line", "stack": "总量", "smooth": true, "areaStyle": {}, "data": [62, 72, 71, 74, 90, 93, 88] }
]
}
```

效果:

{"title":{"text":"一周内容入口趋势","left":"center","top":8},"tooltip":{"trigger":"axis"},"legend":{"top":44,"data":["首页","搜索","标签","RSS","外链"]},"toolbox":{"right":12,"feature":{"saveAsImage":{"title":"保存"},"dataZoom":{"title":{"zoom":"缩放","back":"还原"}},"restore":{"title":"重置"}}},"grid":{"left":42,"right":24,"top":92,"bottom":36,"containLabel":true},"xAxis":{"type":"category","boundaryGap":false,"data":["周一","周二","周三","周四","周五","周六","周日"]},"yAxis":{"type":"value"},"series":[{"name":"首页","type":"line","stack":"总量","smooth":true,"areaStyle":{},"data":[120,132,101,134,90,230,210]},{"name":"搜索","type":"line","stack":"总量","smooth":true,"areaStyle":{},"data":[220,182,191,234,290,330,310]},{"name":"标签","type":"line","stack":"总量","smooth":true,"areaStyle":{},"data":[150,232,201,154,190,330,410]},{"name":"RSS","type":"line","stack":"总量","smooth":true,"areaStyle":{},"data":[82,93,90,93,129,133,132]},{"name":"外链","type":"line","stack":"总量","smooth":true,"areaStyle":{},"data":[62,72,71,74,90,93,88]}]}

环形图和尺寸参数

源码:

md
```echarts {height-320}
{
"tooltip": { "trigger": "item" },
"legend": { "bottom": 0 },
"series": [
{
"name": "分类",
"type": "pie",
"radius": ["42%", "68%"],
"center": ["50%", "45%"],
"avoidLabelOverlap": true,
"data": [
{ "name": "技术备忘", "value": 43 },
{ "name": "随笔感悟", "value": 28 },
{ "name": "生活点滴", "value": 12 },
{ "name": "博客相关", "value": 10 },
{ "name": "游戏娱乐", "value": 8 },
{ "name": "测试", "value": 5 }
]
}
]
}
```

效果:

{"tooltip":{"trigger":"item"},"legend":{"bottom":0},"series":[{"name":"分类","type":"pie","radius":["42%","68%"],"center":["50%","45%"],"avoidLabelOverlap":true,"data":[{"name":"技术备忘","value":43},{"name":"随笔感悟","value":28},{"name":"生活点滴","value":12},{"name":"博客相关","value":10},{"name":"游戏娱乐","value":8},{"name":"测试","value":5}]}]}

JS 代码和 Dataset 混合图

js 参数启用 JavaScript 模式,可通过 echarts 参数使用 echarts.graphic

源码:

md
```echarts {height-420 js}
return {
title: { text: "文章质量指标", left: "center", top: 8 },
tooltip: { trigger: "axis" },
legend: { top: 44 },
dataset: {
source: [
["月份", "发布", "修订", "评论", "平均阅读"],
["1月", 4, 7, 18, 420],
["2月", 3, 6, 12, 390],
["3月", 5, 10, 26, 560],
["4月", 2, 4, 10, 330],
["5月", 6, 13, 31, 680],
["6月", 8, 16, 44, 760]
]
},
grid: { left: 48, right: 56, top: 92, bottom: 42 },
xAxis: { type: "category" },
yAxis: [
{ type: "value", name: "数量" },
{ type: "value", name: "阅读", position: "right" }
],
series: [
{ type: "bar", name: "发布" },
{ type: "bar", name: "修订" },
{ type: "bar", name: "评论" },
{
type: "line",
name: "平均阅读",
yAxisIndex: 1,
smooth: true,
symbolSize: 9,
lineStyle: { width: 3 },
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: "rgba(84, 112, 198, 0.28)" },
{ offset: 1, color: "rgba(84, 112, 198, 0.02)" }
])
}
}
]
};
```

效果:

return { title: { text: "文章质量指标", left: "center", top: 8 }, tooltip: { trigger: "axis" }, legend: { top: 44 }, dataset: { source: [ ["月份", "发布", "修订", "评论", "平均阅读"], ["1月", 4, 7, 18, 420], ["2月", 3, 6, 12, 390], ["3月", 5, 10, 26, 560], ["4月", 2, 4, 10, 330], ["5月", 6, 13, 31, 680], ["6月", 8, 16, 44, 760] ] }, grid: { left: 48, right: 56, top: 92, bottom: 42 }, xAxis: { type: "category" }, yAxis: [ { type: "value", name: "数量" }, { type: "value", name: "阅读", position: "right" } ], series: [ { type: "bar", name: "发布" }, { type: "bar", name: "修订" }, { type: "bar", name: "评论" }, { type: "line", name: "平均阅读", yAxisIndex: 1, smooth: true, symbolSize: 9, lineStyle: { width: 3 }, areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: "rgba(84, 112, 198, 0.28)" }, { offset: 1, color: "rgba(84, 112, 198, 0.02)" } ]) } } ] };

JS 对象字面量和 VisualMap

源码:

md
```echarts {height-420 js}
(() => {
const points = [
["技术备忘", 43, 18, 760],
["随笔感悟", 28, 30, 640],
["生活点滴", 12, 14, 380],
["博客相关", 10, 12, 420],
["游戏娱乐", 8, 9, 300],
["测试", 5, 6, 260]
];
return {
title: { text: "分类规模和互动", left: "center", top: 8 },
tooltip: {
formatter: (params) => {
const item = params.data;
return `${item[0]}<br>文章:${item[1]}<br>评论:${item[2]}<br>阅读:${item[3]}`;
}
},
grid: { left: 52, right: 30, top: 72, bottom: 52 },
xAxis: { name: "文章数", type: "value" },
yAxis: { name: "评论数", type: "value" },
visualMap: {
min: 240,
max: 800,
dimension: 3,
right: 8,
top: 82,
text: ["高阅读", "低阅读"],
calculable: true
},
series: [
{
name: "分类",
type: "scatter",
symbolSize: (data) => Math.max(18, Math.sqrt(data[3]) * 2.2),
data: points,
label: { show: true, formatter: (params) => params.data[0], position: "top" },
emphasis: { focus: "series" }
}
]
};
})()
```

效果:

(() => { const points = [ ["技术备忘", 43, 18, 760], ["随笔感悟", 28, 30, 640], ["生活点滴", 12, 14, 380], ["博客相关", 10, 12, 420], ["游戏娱乐", 8, 9, 300], ["测试", 5, 6, 260] ]; return { title: { text: "分类规模和互动", left: "center", top: 8 }, tooltip: { formatter: (params) => { const item = params.data; return `${item[0]}<br>文章:${item[1]}<br>评论:${item[2]}<br>阅读:${item[3]}`; } }, grid: { left: 52, right: 30, top: 72, bottom: 52 }, xAxis: { name: "文章数", type: "value" }, yAxis: { name: "评论数", type: "value" }, visualMap: { min: 240, max: 800, dimension: 3, right: 8, top: 82, text: ["高阅读", "低阅读"], calculable: true }, series: [ { name: "分类", type: "scatter", symbolSize: (data) => Math.max(18, Math.sqrt(data[3]) * 2.2), data: points, label: { show: true, formatter: (params) => params.data[0], position: "top" }, emphasis: { focus: "series" } } ] }; })()

多坐标系雷达图和仪表盘

源码:

md
```echarts {height-440 js}
return {
title: [
{ text: "维护状态雷达", left: "24%", top: 10, textAlign: "center" },
{ text: "发布节奏", left: "75%", top: 10, textAlign: "center" }
],
tooltip: {},
radar: {
center: ["26%", "55%"],
radius: "58%",
indicator: [
{ name: "内容完整", max: 100 },
{ name: "代码整洁", max: 100 },
{ name: "图片处理", max: 100 },
{ name: "移动适配", max: 100 },
{ name: "可维护性", max: 100 }
]
},
series: [
{
type: "radar",
areaStyle: { opacity: 0.18 },
data: [
{ name: "当前", value: [86, 78, 92, 84, 80] },
{ name: "目标", value: [92, 88, 96, 90, 88] }
]
},
{
type: "gauge",
center: ["75%", "58%"],
radius: "68%",
min: 0,
max: 30,
progress: { show: true, width: 12 },
axisLine: { lineStyle: { width: 12 } },
detail: { valueAnimation: true, formatter: "{value} 篇/月" },
data: [{ value: 18, name: "近期峰值" }]
}
]
};
```

效果:

return { title: [ { text: "维护状态雷达", left: "24%", top: 10, textAlign: "center" }, { text: "发布节奏", left: "75%", top: 10, textAlign: "center" } ], tooltip: {}, radar: { center: ["26%", "55%"], radius: "58%", indicator: [ { name: "内容完整", max: 100 }, { name: "代码整洁", max: 100 }, { name: "图片处理", max: 100 }, { name: "移动适配", max: 100 }, { name: "可维护性", max: 100 } ] }, series: [ { type: "radar", areaStyle: { opacity: 0.18 }, data: [ { name: "当前", value: [86, 78, 92, 84, 80] }, { name: "目标", value: [92, 88, 96, 90, 88] } ] }, { type: "gauge", center: ["75%", "58%"], radius: "68%", min: 0, max: 30, progress: { show: true, width: 12 }, axisLine: { lineStyle: { width: 12 } }, detail: { valueAnimation: true, formatter: "{value} 篇/月" }, data: [{ value: 18, name: "近期峰值" }] } ] };

DataZoom 长序列趋势

源码:

md
```echarts {width-full height-360 js}
(() => {
const dates = Array.from({ length: 42 }, (_, index) => `6-${String(index + 1).padStart(2, "0")}`);
const values = dates.map((_, index) => Math.round(42 + Math.sin(index / 3) * 18 + index * 1.7));
return {
title: { text: "连续访问趋势", left: "center", top: 8 },
tooltip: { trigger: "axis" },
grid: { left: 48, right: 24, top: 64, bottom: 76 },
xAxis: { type: "category", boundaryGap: false, data: dates },
yAxis: { type: "value" },
dataZoom: [
{ type: "inside", start: 35, end: 100 },
{ start: 35, end: 100, bottom: 20 }
],
series: [
{
name: "访问",
type: "line",
smooth: true,
symbol: "none",
areaStyle: {},
data: values
}
]
};
})()
```

效果:

(() => { const dates = Array.from({ length: 42 }, (_, index) => `6-${String(index + 1).padStart(2, "0")}`); const values = dates.map((_, index) => Math.round(42 + Math.sin(index / 3) * 18 + index * 1.7)); return { title: { text: "连续访问趋势", left: "center", top: 8 }, tooltip: { trigger: "axis" }, grid: { left: 48, right: 24, top: 64, bottom: 76 }, xAxis: { type: "category", boundaryGap: false, data: dates }, yAxis: { type: "value" }, dataZoom: [ { type: "inside", start: 35, end: 100 }, { start: 35, end: 100, bottom: 20 } ], series: [ { name: "访问", type: "line", smooth: true, symbol: "none", areaStyle: {}, data: values } ] }; })()

Async 异步热力图

源码:

md
```echarts {height-360 js async}
async () => {
const days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
const hours = ["0", "4", "8", "12", "16", "20"];
const data = await Promise.resolve(
days.flatMap((day, dayIndex) =>
hours.map((hour, hourIndex) => [
hourIndex,
dayIndex,
Math.round((Math.sin(dayIndex + 1) + 1.4) * (hourIndex + 2) * 8)
])
)
);
return {
title: { text: "访问热力分布", left: "center", top: 8 },
tooltip: {
position: "top",
formatter: (params) => `${days[params.value[1]]} ${hours[params.value[0]]}:00<br>${params.value[2]} 次`
},
grid: { top: 68, left: 48, right: 24, bottom: 46 },
xAxis: { type: "category", data: hours.map((hour) => `${hour}:00`), splitArea: { show: true } },
yAxis: { type: "category", data: days, splitArea: { show: true } },
visualMap: {
min: 0,
max: 120,
calculable: true,
orient: "horizontal",
left: "center",
bottom: 8
},
series: [
{
name: "访问",
type: "heatmap",
data,
label: { show: true },
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: "rgba(0, 0, 0, 0.35)"
}
}
}
]
};
}
```

效果:

async () => { const days = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]; const hours = ["0", "4", "8", "12", "16", "20"]; const data = await Promise.resolve( days.flatMap((day, dayIndex) => hours.map((hour, hourIndex) => [ hourIndex, dayIndex, Math.round((Math.sin(dayIndex + 1) + 1.4) * (hourIndex + 2) * 8) ]) ) ); return { title: { text: "访问热力分布", left: "center", top: 8 }, tooltip: { position: "top", formatter: (params) => `${days[params.value[1]]} ${hours[params.value[0]]}:00<br>${params.value[2]} 次` }, grid: { top: 68, left: 48, right: 24, bottom: 46 }, xAxis: { type: "category", data: hours.map((hour) => `${hour}:00`), splitArea: { show: true } }, yAxis: { type: "category", data: days, splitArea: { show: true } }, visualMap: { min: 0, max: 120, calculable: true, orient: "horizontal", left: "center", bottom: 8 }, series: [ { name: "访问", type: "heatmap", data, label: { show: true }, emphasis: { itemStyle: { shadowBlur: 10, shadowColor: "rgba(0, 0, 0, 0.35)" } } } ] }; }

无参数默认设置

不传任何参数时,默认宽度 100%,高度 30rem。

源码:

md
```echarts
{
"tooltip": { "trigger": "axis" },
"xAxis": {
"type": "category",
"data": ["A", "B", "C", "D", "E"]
},
"yAxis": { "type": "value" },
"series": [
{
"type": "bar",
"data": [10, 22, 16, 30, 18]
}
]
}
```

效果:

{"tooltip":{"trigger":"axis"},"xAxis":{"type":"category","data":["A","B","C","D","E"]},"yAxis":{"type":"value"},"series":[{"type":"bar","data":[10,22,16,30,18]}]}

YAML 资源文件

使用 src 读取文章目录下的 YAML 文件,构建时会解析成 ECharts option。

源码:

md
```echarts {src=./monthly-visits.yaml height=360}
```

效果:

{"tooltip":{"trigger":"axis"},"legend":{"data":["访问","评论"]},"grid":{"left":36,"right":18,"top":44,"bottom":28},"xAxis":{"type":"category","boundaryGap":false,"data":["周一","周二","周三","周四","周五","周六","周日"]},"yAxis":{"type":"value"},"series":[{"name":"访问","type":"line","smooth":true,"data":[120,180,150,230,210,260,310]},{"name":"评论","type":"line","smooth":true,"data":[12,18,15,24,21,28,33]}]}

TOML 资源文件

使用 format=toml.toml 后缀都会进入 TOML 解析。

源码:

md
```echarts {src=./category-share.toml height=360}
```

效果:

{"tooltip":{"trigger":"item"},"legend":{"orient":"vertical","left":"left"},"series":[{"name":"内容","type":"pie","radius":["42%","68%"],"avoidLabelOverlap":true,"data":[{"name":"技术","value":42},{"name":"生活","value":26},{"name":"随笔","value":18},{"name":"游戏","value":14}]}]}

JS 资源文件

JS 文件可以返回对象,也可以返回函数。函数会收到 { echarts, chart } 上下文。

源码:

md
```echarts {src=./dynamic-option.js height=360 js renderer=svg}
```

效果:

({ echarts }) => ({ tooltip: { trigger: 'axis' }, grid: { left: 36, right: 18, top: 36, bottom: 28 }, xAxis: { type: 'category', data: ['一月', '二月', '三月', '四月', '五月', '六月'], }, yAxis: { type: 'value' }, series: [ { name: '阅读', type: 'bar', data: [32, 45, 38, 54, 62, 71], itemStyle: { borderRadius: [4, 4, 0, 0], color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: '#6f83d8' }, { offset: 1, color: '#d9def8' }, ]), }, }, ], })

指定像素宽度

除了 width-full,还可以用 width-600 设置固定像素宽度。

源码:

md
```echarts {width-600 height-360}
{
"tooltip": { "trigger": "axis" },
"xAxis": {
"type": "category",
"data": ["A", "B", "C", "D", "E", "F"]
},
"yAxis": { "type": "value" },
"series": [
{
"type": "bar",
"data": [5, 10, 15, 20, 25, 30]
}
]
}
```

效果:

{"tooltip":{"trigger":"axis"},"xAxis":{"type":"category","data":["A","B","C","D","E","F"]},"yAxis":{"type":"value"},"series":[{"type":"bar","data":[5,10,15,20,25,30]}]}