目录
使用配置项原因:(默认效果显示不佳,需要自行调整)
ECharts的工具箱(Toolbox)中提供了导出图片,数据视图,动态类型切换,数据区域缩放,重置五个内置工具,本部分的内容主要介绍数据视图中的optionToContent/contentToOption两个配置项的用法。
按照官网的配置项手册介绍为这两个配置项的含义为图1所示:
图1 optionToContent官网说明
这之后官网提供了一个optionToContent的举例,但对于contentToOption的说明并没有提供举例,为了方便大家理解,博主自己做了一个简单地例子,方便大家后期完善。
toolbox中的数据视(dataview)图方便用户可以查看当前图表的数据内容,如图2所示,点击了数据视图(dataview)之后会出现所有数据的内容展示,如图3所示。
图2 点击数据视图
图3 数据视图默认效果
通过图3可以看出,数据视图(dataview)默认的效果并不理想,列名与数据内容并没有完全对齐。这种数据的展示方式对于用户来说非常不友好。数据视图(dataview)中的optionToContent/contentToOption可以修正这一问题。
开始:
optionToContent配置项:用于将已经图表的option的数据内容对应到content中,content即为图3中显示的数据内容。
contentToOption配置项:用于将已经修改后的数据内容对应到option中。也就是说可以通过HTML+JS的方式在content区域中修改图表中的数据,然后由contentToOption配置项将修改的结果反馈回ECharts实例以实现修改图表数据的效果。
1、由图表数据——数据视图
如图4所示,点击数据视图按钮之后出现了类似列表形式的数据。optionToContent配置项可以修改这些数据的显示形式,修改之后的结果如图5所示。
图4 点击数据视图演示
图5 使用optionToContent设置之后
程序展示:
(完整代码在最后面,着急的同学可以直接翻到最后复制粘贴。)
optionToContent: function (opt) {
var axisData = opt.xAxis[0].data;
var series = opt.series;
var table = '<table style="width:100%;text-align:center" id="dataTable"><tbody><tr>'
+ '<td>' +'时间' + '</td>'
+ '<td>' + series[0].name + '</td>'
+ '<td>' + series[1].name + '</td>'
+ '</tr>';
for (var i = 0, l = axisData.length; i < l; i++) {
table += '<tr>'
+ '<td><input type="text" value="' + axisData[i] + '"></td>'
+ '<td><input type="text" id="max" value="' + series[0].data[i] + '"></td>'
+ '<td><input type="text" id="min" value="' + series[1].data[i] + '"></td>'
+ '</tr>';
}
table += '</tbody></table>';
return table;
},
程序说明:
optionToContent接收一个匿名函数,函数中支持opt参数,opt即当前图表的option对象。
这段代码主要完成了将opt对象中X轴的data数据对应到图5中的第一列,series[0]中的数据对应到第二列,series[1]中的数据对应到第三列。
下面将逐条介绍程序的内容,如果读者能够看懂上面的程序,可以跳过这部分内容。
逐行解释:
①“var axisData = opt.xAxis[0].data;”获取了X轴的data数据存放到axisData之中,axisData是个数组;
②“var series = opt.series;”获取了series对象存放到了series之中,series是个对象数组;
③接下来5行,使用拼接字符串的形式创建了一个table的表头,将表头的字符串存放在变量“table”之中。
④重点来了:接下来通过循环的方式构建表格的每一行,每行的第一列数据取自axisData[i]即日期数据,每行第二列数据取自series[0]的data[i],每行第三列数据取自series[1]的data[i],循环次数以日期数量为限。
⑤循环结束后table拼接完成了,再加上“table += '</tbody></table>';”结束table字符串的拼接。
⑥最后不要忘记了return table,否则图标上任何内容都没有了。
特别说明:
①readOnly失效,看过配置项手册的同学应该知道,数据视图中提供了一个readOnly配置项,用于控制数据视图是否可编辑,当readOnly为false的时候,数据视图是可以修改数据的,那么还需要上面写这一大堆这么麻烦做什么?实际上在使用optionToContent配置项的时候readOnly默认已经失效了,也就是无论它设置什么,都不起作用了。
②修改数据:单纯构建表格是不能够实现表格内数据修改的,这一点是HTML的特点,因此在拼接table字符串的时候加入了input标签,目的是拼接出能够自由修改数据的表格。
2、数据视图——绘制图表
这一部分的内容是将修改后的数据视图中的数据反馈到折线图中。这一部分功能需要用到contentToOption配置项,这一配置项在官网中并没有举例说明,博主是在查找了一些资料之后经过多次尝试实现的。
contentToOption配置项同样也支持匿名函数,但是有一点需要注意,contentToOption配置项需要两个参数,第一个参数为DOM对象,第二个参数为option对象。其中DOM对象指的是整个数据视图的表格对象。
例如,如下代码:
contentToOption: function(table,opt){
console.log(table)}
控制台输出的是如图6所示的通过optionToContent刚刚拼接的那个table字符串生成的表格。
图6 输出DOM对象
很明显,通过这个DOM对象不是很方便的获取到input标签中的用户输入的内容。因此通过如下代码,进行了相应的设置。
contentToOption: function(table,opt){
var inputMaxArr=[];
inputMax=document.querySelectorAll("#max");
console.log(inputMax);
for(var i=0;i<inputMax.length;i++){
inputMaxArr.push(inputMax[i].value)
}
console.log(inputMaxArr)
opt.series[0].data=inputMaxArr;
var inputMinArr=[];
inputMin=document.querySelectorAll("#min");
for(var i=0;i<inputMin.length;i++){
inputMinArr.push(inputMin[i].value)
}
opt.series[1].data=inputMinArr;
return opt;
}
下面将逐条介绍程序的内容,如果读者能够看懂上面的程序,可以跳过这部分内容。
逐行解释:
①“inputMax=document.querySelectorAll("#max");”找到所有id值为max的HTML标签(input),存放到inputMax数组之中。
②接下来将inputMax中的所有内容获取出来,即获取到所有数据视图表格中的数据,将其push到inputMaxArr之中,将这些数据替换到opt.series[0].data之中。
③用上面同样的方法找到所有id值为的HTML标签(input),存放到input数组之中,将其中的数据push到inputMinArr之中,将这些数据替换到opt.series[1].data之中。
④最后return opt返回到函数。
至此contentToOption设置完成,实现了数据的写回。
完整程序前端:
(echarts.js文件请自行补充。)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="js/echarts.js"></script>
</head>
<body>
<div id="main" style="width: 900px; height: 600px"></div>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById("main"));
var option = {
color: ["red", 'green', 'blue', 'yellow', 'grey', '#FA8072'], //使用自己预定义的颜色
tooltip: {
trigger: 'axis'
},
legend: { //配置图例组件
x: 300, data: ['最高', '最低']
},
toolbox: { //配置工具箱组件
show: true, //设置是否显示工具箱组件
orient: 'horizontal',
x: 'right',
y: 'top',
color: ['#1e90ff', '#22bb22', '#4b0082', '#d2691e'],
backgroundColor: 'rgba(0,0,0,0)', //设置工具箱背景颜色
borderColor: '#ccc', //设置工具箱边框颜色
borderWidth: 1, //设置工具箱边框线宽,单位px,默认为0(无边框)
padding: 5, //设置工具箱内边距,单位px,默认各方向内边距为5
showTitle: true,
feature: {
mark: { //设置标记
show: true,
title: {
mark: '辅助线-开关',
markUndo: '辅助线-删除',
markClear: '辅助线-清空'
},
lineStyle: { width: 1, color: '#1e90ff', type: 'dashed' }
},
dataZoom: { //设置数据区域缩放
show: true,
title: { dataZoom: '区域缩放', dataZoomReset: '区域缩放-后退' }
},
dataView: { //设置数据视图
show: true, title: '数据视图',
readOnly: false, lang: ['数据视图', '关闭', '刷新'],
optionToContent: function (opt) {
var axisData = opt.xAxis[0].data;
var series = opt.series;
var table = '<table style="width:100%;text-align:center" id="dataTable"><tbody><tr>'
+ '<td>' +'时间' + '</td>'
+ '<td>' + series[0].name + '</td>'
+ '<td>' + series[1].name + '</td>'
+ '</tr>';
for (var i = 0, l = axisData.length; i < l; i++) {
table += '<tr>'
+ '<td><input type="text" value="' + axisData[i] + '"></td>'
+ '<td><input type="text" id="max" value="' + series[0].data[i] + '"></td>'
+ '<td><input type="text" id="min" value="' + series[1].data[i] + '"></td>'
+ '</tr>';
}
table += '</tbody></table>';
return table;
},
contentToOption: function(table,opt){
var inputMaxArr=[];
inputMax=document.querySelectorAll("#max");
for(var i=0;i<inputMax.length;i++){
inputMaxArr.push(inputMax[i].value)
}
opt.series[0].data=inputMaxArr;
var inputMinArr=[];
inputMin=document.querySelectorAll("#min");
for(var i=0;i<inputMin.length;i++){
inputMinArr.push(inputMin[i].value)
}
opt.series[1].data=inputMinArr;
return opt;
}
},
magicType: { //设置动态类型切换
show: true,
title: {
line: '动态类型切换-折线图',
bar: '动态类型切换-柱状图',
stack: '动态类型切换-堆积',
tiled: '动态类型切换-平铺'
},
type: ['line', 'bar', 'stack', 'tiled']
},
restore: { //设置数据重置
show: true, title: '还原', color: 'black'
},
saveAsImage: { //设置导出图片
show: true, title: '保存为图片',
type: 'jpeg', lang: ['单击本地保存']
},
myTool: { //设置自定义工具按钮
show: true, title: '自定义扩展方法',
//设置改变默认的图标为一个特定的图标
icon:'image://data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7',
// icon: 'image://http://echarts.baidu.com/images/favicon.png',
onclick: function () { alert('广科院,大数据与人工智能学院') }
}
}
},
calculable: true,
dataZoom: { //配置数据区域缩放
show: true, realtime: true,
start: 20, end: 80
},
xAxis: [ //配置x轴坐标系
{
type: 'category', boundaryGap: false,
data: function () {
var list = [];
for (var i = 1; i <= 30; i++) { list.push('2020-03-' + i); }
return list;
}()
}
],
yAxis: [ //配置y轴坐标系
{ type: 'value' }
],
series: [ //配置数据系列
{ //设置数据系列1
name: '最高', type: 'line', smooth: true,
data: function () {
var list = [];
for (var i = 1; i <= 30; i++) {
list.push(Math.round(Math.random() * 30) + 10);
}
return list;
}()
},
{ //设置数据系列2
name: '最低',
type: 'line', smooth: true,
data: function () {
var list = [];
for (var i = 1; i <= 30; i++) {
list.push(Math.round(Math.random() * 10));
}
return list;
}()
}
]
};
myChart.setOption(option);
</script>
</body>
</html>