自定义图例
- 前言
- 自定义图例的饼状图
- 图例换行
前言
之前做过各种各样需求的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这里,我写的是个数组然后拼成字符串,这样写是直观,你也可以直接写成字符串,记得加上换行符就行;