需求开发一个饼状图,要求:点击右侧的模块,左侧饼状图对应的变化
效果如下:
遇到的问题:
在实际项目开发过程中,碰到了一个棘手的问题,那就是,右侧显示的legend模块后面的数字显示不是
很好做,因为在echarts配置项option里,左侧的tooltip里的模块名name
是和右侧legend显示的值是对应的,这么说不太好理解,举个例子,例如,如下截图
显然,tooltip中的模块title不能这么显示,但是echarts里面的默认配置就是这样,如果想做成 legend显示
模块名+数字,tooltip弹框里只显示 模块名的话,就需要用到 legend
里的formatter属性了,但是使用formatter的过程中,会碰到一个问题 ,那就是不是很好动态传值到formatter函数里面,我是这么解决的
生命一个常量optionData,给它传值,然后,放到 设置 legend属性之前,这样,formatter 李曼就能直接使用外面传进去的值了
this.optionData = this.option.series[0].data; // 赋值给常量 optionData const
optionData= this.optionData; this.option.legend = { formatter(params) { //
params 是模块的名字 if (optionData.length) { // 这里的optionData就是外面的常量的值,我是拼了一个数组传进来的
// 然后这里根据模块名的值,也就是params的值,动态的拼成自己想要的显示样子 switch (params) { case "Very High
Risk": return params + " " + optionData[0].value; break; case "High Risk":
return params + " " + optionData[1].value; break; case "Medium Risk": return
params+ " " + optionData[2].value; break; case "Low Risk": return params + " " +
optionData[3].value; break; case "Very Low Risk": return params + " " +
optionData[4].value; break; default: return ""; } } }
上代码
<template> <div id="leftEchartPie" ref="leftEchartPie" ></div> </template> <
script> export default { props: { leftPieData: { type: Object, default: {} } },
data() { return { myChart: null, option: null, optionData: [] }; }, watch: {
leftPieData: { // immediate: true, deep: true, handler(leftPieData) { if (
leftPieData) { this.initChart(leftPieData); } } } }, mounted() { const option =
{ title: { zlevel: 0, text: null, rich: { value: { color: "#3F495A", fontSize:
14, lineHeight: 16 }, name: { color: "#3F495A", fontSize: 14, lineHeight: 16 } }
, top: "center", left: "30%", textAlign: "center", textStyle: { rich: { value: {
color: "#3F495A", fontSize: 14, lineHeight: 16 }, name: { color: "#3F495A",
lineHeight: 16 } } } }, tooltip: { show: true, trigger: "item", formatter: "{a}
<br/>{b}: {c} ({d}%)" }, legend: {}, series: [ { name: "Security Status", type:
"pie", center: ["30%", "50%"], radius: ["80%", "45%"], itemStyle: { borderWidth:
6, borderColor: "#fff" }, hoverAnimation: false, avoidLabelOverlap: false, label
: { show: false, position: "center" }, emphasis: { label: { show: false,
fontSize: "30", fontWeight: "bold" } }, labelLine: { show: false }, data: [] } ]
}; this.option = option; var dom = document.getElementById("leftEchartPie"); var
myChart= this.echarts.init(dom); this.myChart = myChart; let that = this; //
监听resize window.addEventListener("resize", function() { that.mychart.resize(); }
); }, methods: { initChart(leftPieData) { this.option.text = [ "{name|Total}",
"{value|" + leftPieData.totalNum + "}" ].join("\n"); this.option.legend.data = [
`Very High Risk`, `High Risk`, `Medium Risk`, `Low Risk`, `Very Low Risk` ];
this.option.series[0].data = [ { value: this.leftPieData.veryHighRiskNum, name:
`Very High Risk`, itemStyle: { color: "#FF4D4F" } }, { value: this.leftPieData.
highRiskNum, name: `High Risk`, itemStyle: { color: "#FA9314" } }, { value: this
.leftPieData.mediumRiskNum, name: `Medium Risk`, itemStyle: { color: "#FACB14" }
}, { value: this.leftPieData.lowRiskNum, name: `Low Risk`, itemStyle: { color:
"#4ED6CC" } }, { value: this.leftPieData.veryLowNum, name: `Very Low Risk`,
itemStyle: { color: "#2BD374" } } ]; this.optionData = this.option.series[0].
data; const optionData = this.optionData; this.option.legend = { orient:
"vertical", left: "60%", top: "middle", icon: "circle", itemHeight: 7, //改变圆圈大小
// data: [], formatter(params) { if (optionData.length) { switch (params) { case
"Very High Risk": return params + " " + optionData[0].value; break; case "High
Risk": return params + " " + optionData[1].value; break; case "Medium Risk":
return params + " " + optionData[2].value; break; case "Low Risk": return params
+ " " + optionData[3].value; break; case "Very Low Risk": return params + " " +
optionData[4].value; break; default: return ""; } } } }; // 绘制图表 this.myChart.
setOption(this.option); } } }; </script> <style> #leftEchartPie { width: 100%;
height: calc(100% - 60px); } </style>