自定义图例
- 前言
- 自定义图例的饼状图
- 图例换行
前言
之前做过各种各样需求的Echarts图表,通过查找博客和查看官网配置项api,都能实现,但是很久不用的话,再去做某些一样功能需求的图表,有些配置项还是需要反复查看,或者去搜索,所以我特意开了一个可视化专栏,去把使用过的可视化记录下来,也方便日后自己复用或者为他人提供便利!
这次就记录一下自定义图例布局样式和图例换行的实现,
我会把整个图表实现的代码都带出来,如果日后项目中用到类似的需求,也可以直接拿去!
自定义图例的饼状图
案例实现如下图;
主要实现功能代码块 legend:
legend: { orient: 'vertical', //竖向展示 left:'45%', height:'60%', //图例容器的高度,超过会换行展示 top:'28%', icon:'circle', //图标样式设置 itemWidth:10, //图标宽设置 itemHeight:10, //图标长设置 itemGap:12, //图标之间的距离 data:legendData, //图例数据 formatter: function(name) {// 图例自定义展示设置 let total = 0 let target for (let i = 0; i < dataValue.length; i++) { total += dataValue[i].value if (dataValue[i].name === name) { target = dataValue[i].value } } var arr = [ '{name|' + name + '}', '{targer|' + target + '}' ] return arr.join(' ') }, textStyle: { // 设置样式 padding: [2, 0, 0, 0], rich: { name: { fontSize: 14, width: 75 }, targer: { fontSize: 14, width: 38, color: '#c1c1c1' } } } },
复制
下面我把上面饼状图实现的代码全部贴出来,如下:
<template> <div id="myChartOne" style="height: 240px;"></div> </template> <script> import Vue from 'vue' export default { data(){ return{ echartData: [], } }, mounted(){ this.getEchartData() }, methods:{ getEchartData(){ Vue.axios.get('/getReportDataOne', {}).then(res => { if(res.status == 200){ this.echartData = res.data this.initEchart(this.echartData) } }) }, initEchart(dataValue){ var chartDom = document.getElementById('myChartOne'); var myChart = this.$echarts.init(chartDom); var legendData = [] dataValue.forEach(item => { legendData.push(item.name) }) var option; option = { title:[ { text: `23043`, subtext:'供应商总数(个)', itemGap:6, left:'22%', top:'42%', textAlign: 'center', textStyle: { color: '#000', fontWeight: 'bold', fontSize: 18, }, subtextStyle:{ color: '#000', fontWeight: 'normal', fontSize: 15, } }, { text: `供应商状态(单位:个)`, itemGap:6, left:'45%', top:'18%', textStyle: { color: '#000', fontWeight: 'bold', fontSize: 14, }, }, ], tooltip: { trigger: 'item', extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);', backgroundColor:'rgba(255,255,255,.8)', confine: true , textStyle:{ color: '#3d3d3d' , fontSize: 14 , }, formatter: function(params) { const result = params.data return ` <div style="padding:10px 20px 10px 10px"> <div> ${params.marker} <span style="font-size:14px;font-weight:700">${params.name}供应商</span> </div> <ul style="margin-left:20px"> <li style="padding:3px 0;">${params.name}-战略型<span style="margin-left:10px;">${result.zhanlue}</span></li> <li style="padding:3px 0;">${params.name}-优选型<span style="margin-left:10px;">${result.youxuan}</span></li> <li style="padding:3px 0;">${params.name}-维持型<span style="margin-left:10px;">${result.weichi}</span></li> <li style="padding:3px 0;">${params.name}-淘汰型<span style="margin-left:10px;">${result.taotai}</span></li> </ul> </div> ` } }, color:['#2d5fff','#3dd070','#fe8e00','#ff5959','#bb5ce6','#37d0f6','#1ee8c9','#d9cd49','#f43ba9'], legend: { orient: 'vertical', left:'45%', height:'60%', top:'28%', icon:'circle', itemWidth:10, itemHeight:10, itemGap:12, data:legendData, formatter: function(name) { // 添加 let total = 0 let target for (let i = 0; i < dataValue.length; i++) { total += dataValue[i].value if (dataValue[i].name === name) { target = dataValue[i].value } } var arr = [ '{a|' + name + '}', '{c|' + target + '}' ] return arr.join(' ') }, textStyle: { // 添加 padding: [2, 0, 0, 0], rich: { a: { fontSize: 14, width: 75 }, c: { fontSize: 14, width: 38, color: '#c1c1c1' } } } }, series: [ { name: 'Access From', type: 'pie', center: ["23%", "50%"],//饼状图位置 radius: ['50%', '75%'], avoidLabelOverlap: false, label: { show: false, position: 'center' }, labelLine: { show: false }, data:dataValue } ] }; option && myChart.setOption(option); myChart.on('click', (params) => { console.log('点击了', params); this.$router.push({name:'reportSupplierDetail',query:{component:'tableOne'}}) }); window.addEventListener("resize", () => { myChart.resize(); }); } } } </script>
复制
由于后端还没有写接口,所以数据我只自己mock的,数据格式如下:
[ { "value": 23,"zhanlue":3,"youxuan":10,"weichi":5,"taotai":5,"name": "已注册" }, { "value": 20,"zhanlue":4,"youxuan":6,"weichi":7,"taotai":3,"name": "潜在" }, { "value": 30,"zhanlue":4,"youxuan":15,"weichi":7,"taotai":4,"name": "整改中" }, { "value": 50,"zhanlue":20,"youxuan":10,"weichi":10,"taotai":10,"name": "暂停合作" }, { "value": 6,"zhanlue":2,"youxuan":2,"weichi":1,"taotai":1,"name": "黑名单" }, { "value": 10,"zhanlue":4,"youxuan":6,"weichi":7,"taotai":3,"name": "合格" }, { "value": 45,"zhanlue":14,"youxuan":10,"weichi":11,"taotai":10,"name": "资质到期" }, { "value": 8,"zhanlue":4,"youxuan":1,"weichi":2,"taotai":1,"name": "冻结" }, { "value": 50,"zhanlue":30,"youxuan":5,"weichi":5,"taotai":10,"name": "已退出" } ]
复制
如果你没有使用mockJs,可以直接把数据放到data中的 echartData: [ ]里,非常方便,开袋即用!
图例换行
案例实现如下图:
这个图表展示其实跟上图是一模一样的,这里我们就不展示图表实现的全部代码啦,就把图库换行的功能实现代码 legend 展示出来;
其实很简单,就是写法都和上面一样就是加了一个换行符“\n” :
legend: { left:'55%', top:'middle', icon:'circle', orient:'vertical', itemWidth:10, itemHeight:10, data:legendData, //格式化图例文本 formatter(name) { var num var a for (var i = 0; i < dataValue.length; i++) { if (dataValue[i].name == name) { num = dataValue[i].value; a = ((dataValue[i].value/ dataValue[i].total) * 100).toFixed(2)+ '%' } } return [ `{name|${name}}{a| ${a}}`, ` {num|${num} 个}`, ].join("\n"); }, textStyle:{ fontSize: 14, padding: [28, 5, 0, 0],//上,右,下,左 rich:{ name:{ fontSize: 14, // color: "#000", fontWeight:'bolder', padding: [0, 0, 0, 0]//上,右,下,左 }, num: { fontSize: 14, color:'#c1c1c1', //align:'center', padding: [6, 0,6,0], }, a: { fontSize: 14, color:'#c1c1c1', padding: [0, 0,0,6], }, } } },
复制
formatter(name) { var num var a for (var i = 0; i < dataValue.length; i++) { if (dataValue[i].name == name) { num = dataValue[i].value; a = ((dataValue[i].value/ dataValue[i].total) * 100).toFixed(2)+ '%' } } return [ `{name|${name}}{a| ${a}}`, ` {num|${num} 个}`, ].join("\n"); },
复制
formatter函数最后return这里,我写的是个数组然后拼成字符串,这样写是直观,你也可以直接写成字符串,记得加上换行符就行;