本文讲的是如何定制Echarts的tree图。主要包括下载、全局变量名修改、左键菜单添加、右键菜单添加、内容缩放、文本过滤高亮等。
一 说明
Echarts中提供了tree图,但实际项目中,该tree图并不一定能完全满足项目需求。例如:需要在鼠标右键到节点上添加一个下拉菜单,并且能进行操作。因此,就需要要对该图表进行定制。
二 代码下载
实际项目开发中,可能只需要一个tree图,就没必要下载全量的Echarts代码包了,因为完整的Echarts代码包非常大,10多万行代码呢,为提高项目性能,建议只下载用到的图标和组件。
而Echarts也非常人性化的提供了在线定制构建能力,可以实现按需下载:http://www.echartsjs.com/builder.html
三 全局变量名修改
实际项目中可能已经引入了Echarts,但该Echarts版本存在问题:当前使用的Echarts版本太老了,该版本中还没有我们将要用到的Tree图,而要将整个版本升级到最新版本,或者有Tree图的版本,可能会导致之前图表出现接口不一致导致的BUG,尤其是已经上线或者即将上线的项目,这种升级风险很大。
一个比较好的解决方案就是:引入两套Echarts代码。
但必须解决两套Echarts图表代码冲突的问题,而这个冲突主要是Echarts对外提供的全局变量windows.echarts。只需要将一个Echarts代码包中的全局变量修改掉,然后使用修改后的全局变量生成图表即可。
在下载的Echarts包中(uglify混淆后的包),搜echarts,将下边位置的echarts修改为dlgTreeEcharts:
没有做uglify混淆压缩的Echarts包中,修改echarts的位置如下:
定制完后,生成图表代码如下:
var myChart = dlgTreeEcharts.init(document.getElementById('main'));
四 hover菜单
Echarts提供了比较多的事件接口,其中click、mouseover等是最基础的事件。
详细参考:http://www.echartsjs.com/api.html#events
1 myChart.on('mouseover', function (params) { 2 console.log(params); 3 $('.left-hover-menu').css({ 4 'display': 'block', 5 'left': params.event.offsetX + 15, 6 'top' : params.event.offsetY + 15 7 }); 8 }); 9 myChart.on('mouseout', function (params) { 10 console.log('out'); 11 $('.left-hover-menu').css({ 12 'display': 'none', 13 'left': '-9999px', 14 'top' : '-9999px' 15 }); 16 });
上边代码中,mouseover用于显示绝对定位的菜单,并设置其位置;mouseout用于隐藏菜单。
五 右键菜单
Echarts还提供了一个contextmenu事件,用于鼠标右击时触发。
详细见:
http://echarts.baidu.com/tutorial.html#ECharts%20%E4%B8%AD%E7%9A%84%E4%BA%8B%E4%BB%B6%E5%92%8C%E8%A1%8C%E4%B8%BA
http://www.echartsjs.com/api.html#events
注意:在添加右键菜单时,首先要给整个树图外层容器DOM绑定一个右键事件,返回false,避免浏览器默认事件触发,出现默认菜单。
1 $('.tree-container').bind("contextmenu", function () { return false; });//防止默认菜单弹出 2 myChart.on('contextmenu', function (params) { 3 $('.right-click-menu').css({ 4 'display': 'block', 5 'left': params.event.offsetX + 15, 6 'top' : params.event.offsetY + 15 7 }); 8 }); 9 $('.tree-container').click(function () { 10 $('.right-click-menu').css({ 11 'display': 'none', 12 'left': '-9999px', 13 'top' : '-9999px' 14 }); 15 })
六 缩放功能
Echarts中专门提供了用于缩放的组件datazoom,但tree图并没用用到该组件。这点令不少人大感恼火,研究尝试很久,使用datazoom配置到tree图后就是不生效甚至报错。最后,无意中看到tree的series中有个配置项是roam,用于控制缩放和平移,不按套路出牌啊,藏得真深。
很简单,设置roam为true,缩放和平移功能都有了。
roam官方介绍:http://www.echartsjs.com/option.html#series-tree.roam
七 文字过滤高亮
实际项目中,有这样的需求:由于树的节点特别多,需要提供搜索功能,例如:输入‘报表’,需要查找所有节点name中包含‘报表’两个字的,并将其高亮显示。
这个可以通过Echarts提供的富文本标签和Tree组件的series.label.formatter来实现。
http://www.echartsjs.com/tutorial.html#%E5%AF%8C%E6%96%87%E6%9C%AC%E6%A0%87%E7%AD%BE
http://www.echartsjs.com/option.html#series-tree.label.formatter
http://www.echartsjs.com/option.html#series-tree.label.rich
详细代码如下:
1 label : { 2 normal: { 3 position: 'left', 4 verticalAlign: 'middle', 5 align: 'right', 6 fontSize: 15, 7 formatter: function (param) { 8 if (param.name.match('Tra')) { 9 return '{a|' + param.name + '}' 10 } else { 11 return param.name; 12 } 13 }, 14 rich: { 15 a: { 16 color: 'red', 17 lineHeight: 10 18 } 19 } 20 } 21 }
代码说明:上边代码中,formatter通过设置为函数,对name进行判断,看是否有匹配的关键字‘Tra’(用户搜索的关键字,Tra只是举个例子),如果匹配上了,就返回一个匹配富文本的格式;下边的rich就是富文本样式设置。
实际效果如下:
八 各级文字位置设置
Echarts对各级文字位置有个自适应设置:该节点展开时,文字自动放到左侧;节点收起来时,文字自动放到右侧了。
实际项目中,为了达到视觉上整齐效果,需要无论节点是否展开都将文字设置为一个位置。
实现方法:
data接口中,有个label属性,label属性中的position用于设置当前节点的文字位置,可以通过这个接口将该级文本设置为固定位置。
注意:不要设置label.align属性,否则可能位置有偏差。
设置方法如下:
效果如下:
八 完整示例代码
说明:由于data数据很多,没有在下边显示,可以参考Echarts官网示例数据:http://www.echartsjs.com/examples/editor.html?c=tree-basic
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <script src="echarts.min.js"></script> 7 <script src="jquery.js"></script> 8 <style> 9 .tree-container { 10 border: 1px solid grey; 11 position: relative; 12 } 13 14 .left-hover-menu { 15 position: absolute; 16 border: 1px solid grey; 17 left: -99999px; 18 top: -999999px; 19 } 20 21 .right-click-menu { 22 position: absolute; 23 border: 1px solid blue; 24 left: -99999px; 25 top: -999999px; 26 } 27 </style> 28 </head> 29 <body> 30 <div class="tree-container"> 31 <div id="main" style=" 1200px;height:1000px;"></div> 32 </div> 33 34 <div class="left-hover-menu"> 35 <div>中文名: 报表</div> 36 <div>英文名:data charts</div> 37 <div>产品域定义:用于记录各种数据.</div> 38 </div> 39 40 <div class="right-click-menu"> 41 <div>新增业务对象</div> 42 <div>编辑</div> 43 <div>删除</div> 44 </div> 45 46 <script type="text/javascript"> 47 48 var myChart = dlgTreeEcharts.init(document.getElementById('main')); 49 50 myChart.setOption(option = { 51 tooltip: { 52 show: false 53 }, 54 series: [ 55 { 56 type: 'tree', 57 data: [data], 58 top: '1%', 59 left: '7%', 60 bottom: '1%', 61 right: '20%', 62 symbolSize: 7, 63 label: { 64 normal: { 65 position: 'left', 66 verticalAlign: 'middle', 67 align: 'right', 68 fontSize: 15, 69 formatter: function (param) { 70 if (param.name.match('Tra')) { 71 return '{a|' + param.name + '}' 72 } else { 73 return param.name; 74 } 75 }, 76 rich: { 77 a: { 78 color: 'red', 79 lineHeight: 10 80 } 81 } 82 }, 83 emphasis: { 84 fontSize: 25 85 } 86 }, 87 leaves: { 88 label: { 89 normal: { 90 position: 'right', 91 verticalAlign: 'middle', 92 align: 'left' 93 }, 94 95 } 96 }, 97 expandAndCollapse: true, 98 roam: true, // 缩放 99 animationDuration: 550, 100 animationDurationUpdate: 750 101 } 102 ] 103 }); 104 105 myChart.on('mouseover', function (params) { 106 console.log(params); 107 $('.left-hover-menu').css({ 108 'display': 'block', 109 'left': params.event.offsetX + 15, 110 'top': params.event.offsetY + 15 111 }); 112 }); 113 myChart.on('mouseout', function (params) { 114 console.log('out'); 115 $('.left-hover-menu').css({ 116 'display': 'none', 117 'left': '-9999px', 118 'top': '-9999px' 119 }); 120 }); 121 122 $('.tree-container').bind("contextmenu", function () { 123 return false; 124 });//防止默认菜单弹出 125 myChart.on('contextmenu', function (params) { 126 $('.right-click-menu').css({ 127 'display': 'block', 128 'left': params.event.offsetX + 15, 129 'top': params.event.offsetY + 15 130 }); 131 }); 132 $('.tree-container').click(function () { 133 $('.right-click-menu').css({ 134 'display': 'none', 135 'left': '-9999px', 136 'top': '-9999px' 137 }); 138 }); 139 </script> 140 </body> 141 </html>
参考资料&内容来源:
Echarts官网:http://www.echartsjs.com/option.html#title