用echartsjs 实现散点图与table表格双向交互,以及实现echarts取自于table数据,和自定义echarts提示内容
本人研究echarts已经有一段时间了,今天就分享几个关于echarts的小技巧。虽然看起来简单,但做起来却很繁琐,不过实用性倒是很好。
在一个大的页面中,左边为table表格,右边为echarts的散点图。
需求一,实现echarts中所有的散点取自table中的数据。
需求二:两个交互,交互1,点击左边的table中数据时,先实现table重新隔行变色,然后左边被点击的数据背景颜色变黄,右边的散点图点亮。通过table控制散点图。
交互2:当点击散点图中任意数据时,获取此数据来自于左边散点图的位置,并控制页面滚动到指定位置(本例数据较少,这个方法的作用感觉不明显,但当有大量数据时,这个方法会很有用),先对table进行重新隔行变色,然后左边的table会先重构,接着右边被点击的散点图点亮。通过散点图来控制table表格。
需求三:自定义echarts提示内容。
下图是我做的小demo的简单样式图(不要觉得简单,其实可以在这个基础上增加许多的东西)。
首先我们先引入echarts
<script type="text/javascript" src="js/echarts.js" ></script>
我们先来实现第一个需求。思路:我们通过遍历将table中的数据全部获取,并存入一个数组中,再在series中使用这个数组。
篇幅有限,先在这里放核心代码(文章结尾我会全部的代码):
function gainData() {//将table中的数据赋给information var td = info.getElementsByTagName("td"); for(var i = 0;i<td.length - 1;i++,i++){ var x = td[i].innerText*1; // x轴 var y = td[i+1].innerText*1;// y轴 information.push([// 获取所有散点数据 x, y ]); } } series: [{ name: '销量', type: 'scatter', data: information, },
扩展:当table的数据是动态改变时,其实这里可以给table加上MutationObserver方法,在不刷新页面的情况可以确保散点图与它完全一致,我们这里考虑的是table数据是不改变情况。
实现两个交互:当点击左边table时,先重新加载一次隔行变色(将原先的点击记录清除掉),然后再将被点击的行变色,获取被点击的数据,将此数据存入chose数组中,重新加载echarts散点图(被点亮的值为chose中的值)。
核心代码:
function trclick() {//点击table事件,下方的顺序不要错,还有一定要使用this方法 for (var i = 1; i < tr.length; i++) { tr[i].onclick = function clicktr() { interleavecolor(); //重新加载一次隔行变色 this.style.background = "#FFFF00"; //被点击的变为黄色 var td = this.getElementsByTagName("td"); chosex = td[0].innerText*1;//获取点击的数据 chosey = td[1].innerText*1; operationEcharts(); //重新运行Echarts } } } name: 'CHOSE', type: 'effectScatter', coordinateSystem: 'cartesian2d', data: choseData(),//重新加载echarts时获取chose数组中需要标亮的x、y轴的值,新的数据会标亮 //标亮数据存入chose中 function choseData(){ var chose = []; if(null==chosex||null==chosey){ chosex = 1;//这是一开始默认的标亮数据 chosey = 100; } chose.push([chosex,chosey]);//将获取的值存入chose数组中 return chose; }
交互2:交互2与交互1有两点不同,1,多了一个滚动事件,控制页面滚动到我们可以看到的table指定位置,2,标亮数据来源不同,交互二中点击echarts时,将点击的数据存入chose数组中。
点击echarts的代码:
//如果点击echarts图 myChart.on('click', function (params) { if(params.componentType == 'series') { for (var k = 1; k < tr.length; k++) { var tablex = String(tr[k].children[0].innerHTML); // 表格中的x轴 var tabley = String(tr[k].children[1].innerHTML); // 表格中的y轴 var chartx = String(params.data[0]);// 散点中的x轴 var charty = String(params.data[1]);// 散点中的y轴 if(tablex == chartx && tabley == charty) { interleavecolor(); // 控制页面滚动到指定位置 tr[k].scrollIntoView(); tr[k].style.background = "#FFFF00"; // 对应行变为黄色 chosex = params.data[0]; chosey = params.data[1]; operationEcharts();//重新加载echarts视图 trclick(); break; } } } });
需求三:一般情况下,当我们鼠标移动到数据上时,echarts的原生方法的数据是没有名称,也没有单位的,会给我们造成许多的不便,我们想看到单位和名称就要对formatter的方法进行重写。我们先来看看重新前后的区别。
你会发现重写formatter方法前,数据显示2和300(你会发现根本不知道显示了什么),而重写之后我增加了日期和产量等名称。是不是高大上了一些。而这个2,300是什么数据呢。我们可以通过console.log()这个方法打印出来所有的内容,我们对内容进行拼接,就可以展示任何自己想展示的内容。看下图。
tooltip: { padding: 10, backgroundColor: '#222', borderColor: '#777', borderWidth: 1, formatter: function (param) { // return '<div style="border-bottom: 1px solid rgba(255,255,255,.3); font-size: 18px;padding-bottom: 7px;margin-bottom: 7px">' // + 'table与ECharts交互模式' // + '</div>' // + '日期:' + param.data[0] // + "<div></div>" // + '产量:' + param.data[1]; console.log(param); } }
完整的代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="js/echarts.js" ></script> <title></title> </head> <body> <div id="information"style="width: 400px;float: left;"> <table border="1"> <thead> <tr> <th>日期</th> <th>产量</th> </tr> </thead> <tbody> <tr> <td>1</td> <td>100</td> </tr> <tr> <td>2</td> <td>300</td> </tr> <tr> <td>3</td> <td>700</td> </tr> <tr> <td>4</td> <td>800</td> </tr> <tr> <td>5</td> <td>700</td> </tr> <tr> <td>6</td> <td>200</td> </tr> </tbody> </table> </div> <div id="main"style="width: 600px;height:400px;float: left;"> cccc </div> <script type="text/javascript"> var information = []; // 数据的源头,取自于表格 var info = document.getElementById("information"); var table = info.getElementsByTagName("table"); var tr = table[0].getElementsByTagName("tr"); var myChart = echarts.init(document.getElementById('main')); var chosex,chosey;//被选择的x、y //初始化echarts实例 information gainData();//获取数据源 operationEcharts();//运行echarts trclick();//点击table的数据时右边进行标亮 interleavecolor();//隔行变色 function gainData() {//将table中的数据赋给information var td = info.getElementsByTagName("td"); for(var i = 0;i<td.length - 1;i++,i++){ var x = td[i].innerText*1; // x轴 var y = td[i+1].innerText*1;// y轴 information.push([// 获取所有散点数据 x, y ]); } } //画echarts function operationEcharts(){ var option = { title: { text: 'table与ECharts交互模式' }, tooltip: { padding: 10, backgroundColor: '#222', borderColor: '#777', borderWidth: 1, formatter: function (param) { // return '<div style="border-bottom: 1px solid rgba(255,255,255,.3); font-size: 18px;padding-bottom: 7px;margin-bottom: 7px">' // + 'table与ECharts交互模式' // + '</div>' // + '日期:' + param.data[0] // + "<div></div>" // + '产量:' + param.data[1]; console.log(param); } }, legend: { }, xAxis: { splitLine: {show: false}, axisLine: { lineStyle : { color: { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [{ offset: 0, color: 'red' // 0% 处的颜色 }, { offset: 1, color: 'blue' // 100% 处的颜色 }], globalCoord: false // 缺省为 false }, width: 2, } }, }, yAxis: { splitLine: {show: true}, }, series: [{ name: '销量', type: 'scatter', data: information, }, { name: 'CHOSE', type: 'effectScatter', coordinateSystem: 'cartesian2d', data: choseData(), symbolSize: 12, showEffectOn: 'render', rippleEffect: { brushType: 'stroke' }, hoverAnimation: true, itemStyle: { normal: { shadowBlur: 10, shadowColor: 'rgba(25, 100, 150, 0.5)', shadowOffsetY: 5, color: new echarts.graphic.RadialGradient(0.4, 0.3, 1, [{ offset: 0, color: '#FF4500' }, { offset: 1, color: '#FFFF00' }]) } }, zlevel: 1, label: { emphasis: { show: true, formatter: function (param) { return param.data[2]; }, position: 'top', textStyle: { color : '#FF4500' } } } } ] }; myChart.setOption(option); } //标亮数据 function choseData(){ var chose = []; if(null==chosex||null==chosey){ chosex = 1; chosey = 100; } chose.push([chosex,chosey]); return chose; } function trclick() { for (var i = 1; i < tr.length; i++) { tr[i].onclick = function clicktr() { interleavecolor(); //重新加载一次隔行变色 this.style.background = "#FFFF00"; //被点击的变为黄色 var td = this.getElementsByTagName("td"); chosex = td[0].innerText*1; chosey = td[1].innerText*1; operationEcharts(); //重新运行Echarts } } } //隔行变色 function interleavecolor(){ for (j = 1; j < tr.length; j++) { if(0 != j%2){ tr[j].style.background = "#F0FFF0"; }else{ tr[j].style.background = "#FFFAFA"; } } } //如果点击echarts图 myChart.on('click', function (params) { if(params.componentType == 'series') { for (var k = 1; k < tr.length; k++) { var tablex = String(tr[k].children[0].innerHTML); // 表格中的x轴 var tabley = String(tr[k].children[1].innerHTML); // 表格中的y轴 var chartx = String(params.data[0]);// 散点中的x轴 var charty = String(params.data[1]);// 散点中的y轴 if(tablex == chartx && tabley == charty) { interleavecolor(); // 控制页面滚动到指定位置 tr[k].scrollIntoView(); tr[k].style.background = "#FFFF00"; // 对应行变为黄色 chosex = params.data[0]; chosey = params.data[1]; operationEcharts();//重新加载echarts视图 trclick(); break; } } } }); </script> </body> </html>
View Code
如果你觉得写的不错请点赞,欢迎与我交流学习,谢谢!
转载请表明原出处:http://www.cnblogs.com/liebagefly/p/7961734.html 谢谢!