ECharts文档


参考文章

参考文章

更新记录

更新记录

更新记录

2023-11-30 [3.5.0 -> 3.6.0]

  1. 使用IntersectionObserver API实现懒加载
  2. 使用ResizeObserver API实现宽度自适应

2023-11-26 [3.1.0 -> 3.5.0]

  1. 增加JavaScript 严格模式(use strict)
  2. 取消myChart的随机数id

2023-11-26 [3.0.0 -> 3.1.0]

  1. 增加 !function(){}() ,暂时解决pjax报错问题
  2. 增加 async=\”async\” ,避免阻塞 查了一下这个只能用在外链的情况下

2023-11-25 [2.0.0 -> 3.0.0]

  1. 增加页面宽度自适应(参考文档)
  2. 增加完全自定义参数内容

2023-11-24 [1.0.1 -> 2.0.0]

  1. 暂时能用

2023-11-24 起始

  1. 其实网上有现成的ECharts标签插件,但功能简单且不能更改ECharts JS库版本,不能设置渲染器类型,存在重复引入ECharts JS库.所以就参考糖果屋店长的Tag Plugins Plus外挂标签,然后在hexo-tag-echarts4的基础上进行修改.
  • 记录

    宽度自适应

    增加懒加载


自定义ECharts标签

ECharts标签魔改方案
  1. 新建 themes/butterfly/scripts/tag/echarts.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
'use strict'

const { escapeDiacritic } = require('hexo-util')

function echartsMaps(args, content) {
args = args.join(' ').split(',')
const Id = ((Math.random() * 9999) | 0)
const Width = args[0] ? args[0] : '85%'
const Height = args[1] ? args[1] : '400'
const Mode = args[2] ? args[2] : 'null'
const Renderer = args[3] ? args[3] : 'svg'
// 布局
let result = '';
if (Width == 'diy') {
result += `${escapeDiacritic(content)}`;
} else {
result += `<div id="echarts_${Id}" style="width:${Width};height:${Height}px;"></div>`;
result += `<script async data-pjax>`;
result += `!function () {`;
result += ` "use strict";`;
result += ` const GetID = document.getElementById("echarts_${Id}");`;
result += ` function naokuo_lazyLoad() {`;
result += ` var myChart = echarts.init(GetID,${Mode}, { renderer: '${Renderer}' });`;
result += ` var option;`;
result += ` ${escapeDiacritic(content)}`;
result += ` option && myChart.setOption(option);`;
result += ` naokuo.resizeObserver(myChart.resize,GetID,2500);`;
result += ` };`;
result += ` naokuo.intersectionObserver(naokuo_lazyLoad, GetID);`;
result += `}();`;
result += `</script>`;
}
return result;
}

hexo.extend.tag.register('图表', echartsMaps, { ends: true })
hexo.extend.tag.register('echarts', echartsMaps, { ends: true })
  1. 引入ECharts javascript文件
1
2
3
4
5
inject:
head:
# Apache ECharts开源可视化图表库
- <script src="https://npm.elemecdn.com/echarts@5.4.3/dist/echarts.min.js"></script>
- <script src="https://cdn.cbd.int/hexo-tag-echarts-plus@3.6.4/lib/scripts/naokuo_package.js"></script>

ECharts标签 插件化

ECharts标签 插件化
  1. 安装插件,在博客根目录[Blogroot]下打开终端,运行以下指令:
1
npm install hexo-tag-echarts-plus --save
  1. 添加配置信息,以下为写法示例
    在站点配置文件_config.yml或者主题配置文件_config.butterfly.yml中添加
1
2
3
4
5
6
7
8
# tag_echarts-plus
# see https://naokuo.top/posts/336fb21e/
tag_echarts:
enable: true # 开关
priority: 5 #过滤器优先权
CDN:
tag_echarts_js: https://npm.elemecdn.com/echarts@5.4.3/dist/echarts.min.js
echarts_lazyload_js: https://unpkg.com/hexo-tag-echarts-plus@latest/lib/scripts/naokuo_package.js
  1. 参数释义
参数备选值/类型释义
enabletrue/false【必选】控制开关
prioritynumber【可选】过滤器优先级,数值越小,执行越早,默认为10,选填
CDN.tag_echarts_jsURL【可选】echarts标签的JS依赖,为避免CDN缓存延迟,建议将@latest改为具体版本号

使用 ECharts 标签

1
2
3
4
5
6
7
8
9
{% 图表 '宽','高','模式(null/dark)','渲染器类型(svg/canvas)' %}
[其他自定义参数]
option = {

[图表参数]

};

{% end图表 %}
  1. 宽: 宽度 (可选:默认85%),带单位(600px)
  2. 高度: 高度 (可选:默认400),不带单位
  3. 模式: null / dark
  4. 渲染器类型: svg / canvas
  5. [图表参数]: 详情见: ECharts文档
  6. 注意: 不能在折叠标签/分栏标签中插入,如果你一定要使用的话请指定宽高
  7. 注意: 参数一定要写全, “,”号间不要留空格
  8. [宽]的参数填diy的话,[图表参数]的内容将全部自定义
  1. SVG

  1. canvas + dark模式

  1. SVG
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{% 图表 '600px','400','null','svg' %}
option = {
title: {
text: 'CDN 占比',
left: 'center'
},
series: [
{
type: 'pie',
radius: '65%',
center: ['50%', '50%'],
selectedMode: 'single',
data: [
{ value: 40, name: 'npm.elemecdn.com' },
{ value: 9, name: 'cdn.bootcdn.net' },
{ value: 21, name: 'npm.onmicrosoft.cn' },
{ value: 20, name: 'unpkg.com' }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
{% end图表 %}
  1. canvas + dark模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{% 图表 '600px','400',"'dark'",'canvas' %}
option = {
title: {
text: 'CDN 占比',
left: 'center'
},
series: [
{
type: 'pie',
radius: '65%',
center: ['50%', '50%'],
selectedMode: 'single',
data: [
{ value: 40, name: 'npm.elemecdn.com' },
{ value: 9, name: 'cdn.bootcdn.net' },
{ value: 21, name: 'npm.onmicrosoft.cn' },
{ value: 20, name: 'unpkg.com' }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
{% end图表 %}

  1. diy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
{% 图表 'diy' %}
<div id="echarts_99742" style="width: 100% ;height: 600px;"></div>
<script async data-pjax>
!function () {
'use strict';
const GetID = document.getElementById('echarts_99742');
function lazyLoad() {
var myChart_99742 = echarts.init(GetID, null, { renderer: 'svg' });
var option;
const data = [];
for (let i = 0; i < 5; ++i) {
data.push(Math.round(Math.random() * 200));
}
option = {
xAxis: {
max: 'dataMax'
},
yAxis: {
type: 'category',
data: ['A', 'B', 'C', 'D', 'E'],
inverse: true,
animationDuration: 300,
animationDurationUpdate: 300,
max: 2 // only the largest 3 bars will be displayed
},
series: [
{
realtimeSort: true,
name: 'X',
type: 'bar',
data: data,
label: {
show: true,
position: 'right',
valueAnimation: true
}
}
],
legend: {
show: true
},
animationDuration: 0,
animationDurationUpdate: 3000,
animationEasing: 'linear',
animationEasingUpdate: 'linear'
};
function run() {
for (var i = 0; i < data.length; ++i) {
if (Math.random() > 0.9) {
data[i] += Math.round(Math.random() * 2000);
} else {
data[i] += Math.round(Math.random() * 200);
}
}
myChart_99742.setOption({
series: [
{
type: 'bar',
data
}
]
});
}
var naokuosetInterval = setInterval(function () {
run();
}, 3000);
setTimeout(function () {
clearTimeout(naokuosetInterval);
naokuosetInterval = null;
}, 10000);
option && myChart_99742.setOption(option);
console.log("echarts加载成功_99742");
// 宽度自适应
naokuo.resizeObserver(myChart_99742.resize,GetID);
};
// 懒加载
naokuo.intersectionObserver(lazyLoad,GetID);
}();
</script>
{% end图表 %}

VS Code 代码片段

1
2
3
4
5
6
7
8
9
10
"插入图表": {
"prefix": "图表",
"body": ["{% 图表 '${1:85%}', '${2:400}', \"${3|null,'dark'|}\", ${4|svg,canvas|} %}",
" option = {",
" $0",
" };",
"{% end图表 %}"
],
"description": "插入图表."
}

更多效果演示

渐变堆叠面积图


堆叠柱状图


可滚动的图例


极坐标系下的堆叠柱状图


气泡图


多雷达图


旭日图使用视觉编码

书籍分布


多标题仪表盘


富文本


漏斗图


时钟仪表盘


动态测试 (持续10秒)

测试2

饼图百分比


点击添加折线图拐点


环形图


半环形图


基础南丁格尔玫瑰图


可拖拽点


外部数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<script src="https://npm.elemecdn.com/jquery@latest/dist/jquery.min.js"></script>
{% 图表 '100%','600',"null",'svg' %}
myChart.showLoading();
$.get('https://cdn.cbd.int/naokuo-blog@1.1.6/json/confidence-band.json', function (data) {
myChart.hideLoading();
var base = -data.reduce(function (min, val) {
return Math.floor(Math.min(min, val.l));
}, Infinity);
myChart.setOption(
(option = {
title: {
text: 'Confidence Band',
subtext: 'Example in MetricsGraphics.js',
left: 'center'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
animation: false,
label: {
backgroundColor: '#ccc',
borderColor: '#aaa',
borderWidth: 1,
shadowBlur: 0,
shadowOffsetX: 0,
shadowOffsetY: 0,
color: '#222'
}
},
formatter: function (params) {
return (
params[2].name +
'<br />' +
((params[2].value - base) * 100).toFixed(1) +
'%'
);
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
data: data.map(function (item) {
return item.date;
}),
axisLabel: {
formatter: function (value, idx) {
var date = new Date(value);
return idx === 0
? value
: [date.getMonth() + 1, date.getDate()].join('-');
}
},
boundaryGap: false
},
yAxis: {
axisLabel: {
formatter: function (val) {
return (val - base) * 100 + '%';
}
},
axisPointer: {
label: {
formatter: function (params) {
return ((params.value - base) * 100).toFixed(1) + '%';
}
}
},
splitNumber: 3
},
series: [
{
name: 'L',
type: 'line',
data: data.map(function (item) {
return item.l + base;
}),
lineStyle: {
opacity: 0
},
stack: 'confidence-band',
symbol: 'none'
},
{
name: 'U',
type: 'line',
data: data.map(function (item) {
return item.u - item.l;
}),
lineStyle: {
opacity: 0
},
areaStyle: {
color: '#ccc'
},
stack: 'confidence-band',
symbol: 'none'
},
{
type: 'line',
data: data.map(function (item) {
return item.value + base;
}),
itemStyle: {
color: '#333'
},
showSymbol: false
}
]
})
);
});
{% end图表 %}