Echarts南丁格尔玫瑰图(环形图、饼图)不支持分别控制每个玫瑰的弧度与半径的解决方法

        今天做一个南丁格尔玫瑰图发现无论使用哪种方式都没办法单独控制每个玫瑰的半径与弧度,要么(radius)弧度跟半径一起变化,要么(area)就每段环形弧度一样只能控制半径。然后转换思路打算有多少段环形(玫瑰)就做多少个环形图,每个环形图只展示一段环形,其他环形隐藏,把每个环形图展示的那一段环形叠加在一起,这样就能单独控制每个环的弧度与半径,并且样式上能做到和南丁格尔玫瑰图类似:

var warnCnt = 70,normalCnt = 40,toExeCnt = 60,failCnt = 10;//环的弧度(入参)
var totalCnt = 101;
		if(warnCnt < 1 && normalCnt < 1 && toExeCnt < 1 && failCnt < 1){
		  warnCnt = null;
		  normalCnt = null;
		  toExeCnt = null;
		  failCnt = 0;//无数据时默认失败
		}
 
		var inWidth = '45%'; //内环半径
		var fontWidth = '46%'; //文字环半径
		var outWidth = ['82%','77%','72%','67%']; //外环半径数组(必须从大到小)
 
		var allCnt = [ //环弧度排序以确定外环半径
		  {cSize:warnCnt, name:0},
		  {cSize:normalCnt, name:1},
		  {cSize:toExeCnt, name:2},
		  {cSize:failCnt, name:3}
		  ].sort(function (a, b) { return b.cSize - a.cSize; });
  
		var warnWidth = outWidth[allCnt.map(item => item.name).indexOf(0)];//预警环外半径
		var normalWidth = outWidth[allCnt.map(item => item.name).indexOf(1)];//正常环外半径
		var toExeWidth = outWidth[allCnt.map(item => item.name).indexOf(2)];//待执行环外半径
		var failWidth = outWidth[allCnt.map(item => item.name).indexOf(3)];//失败环外半径
 
		//环名字  
		var warnName = '预警', normalName = '正常', toExeName = '待执行', failName = '失败';
 
		//环颜色
		var warnRGB = 'rgb(255,90,90)', 
		    normalRGB = 'rgb(100,255,100)', 
		    toExeRGB = 'rgb(20,120,255)', 
		    failRGB = 'rgb(175,175,175)';
    
		//百分比文字大小(tip及环外label)
		var perFontSize = 10;
		
		var option;
 
		option = {
		  trigger: "none",
		  silent: true,//取消鼠标交互
		  series: [
		    {
		      type: 'pie',
		      radius: [fontWidth],//中间文字环
		      color: {
		          type: 'linear',
		          x: 0,//右
		          y: 0,//下
		          x2: 0,//左
		          y2: 1,//上
		          colorStops: [{//文字环背景颜色
		              offset: 0, color: 'rgb(7,37,68)' // 0% 处的颜色
		          }, {
		              offset: 1, color: 'rgb(75,9,92)' // 100% 处的颜色
		          }]
	       	  },
		      avoidLabelOverlap: false,
		      data: [{name: "某某总数",value: totalCnt}],
		      label: {
		        show: true,
					  position: 'center',
		        formatter: '{c|{c}}\n{b|{b}}',
		        rich:{
              c:{
                  color:'rgb(255,255,255)',
                  padding:[0,10],
                  fontSize:60
              },
              b:{
                  color:'rgb(153,137,169)',
                  padding:[0,10],
                  fontSize:25
              }
            }
		      },
		      labelLine: {
		        show: false
		  		}
		    },
		    {
		      type: 'pie',
		      data: [
		        { value: warnCnt, name: warnName, itemStyle: { color: warnRGB }, index: 0, status:4},
		        { value: normalCnt, name: normalName, itemStyle: { opacity : 0 }, label:{show: false}, status:1},
		        { value: toExeCnt, name: toExeName, itemStyle: { opacity : 0 }, label:{show: false}, status:2},
		        { value: failCnt, name: failName, itemStyle: { opacity : 0 }, label:{show: false}, status:3} 
		      ].sort(function (a, b) { return b.value - a.value; }),//环弧度排序以确定环位置
		      radius: [inWidth,warnWidth],//预警环(红)
		      avoidLabelOverlap: true,
		      itemStyle: {
		        borderRadius: 4,
		        borderWidth: 2
		      },
		      label: {
		        formatter:function (params) {
		          if(params.value==0){  //为0时不显示百分比
		            return '' 
		          }else{
		            return params.percent.toFixed(1)+'%'
		          }
		        },
		        fontSize:perFontSize,
		        color:warnRGB
		      },
		      labelLine: {
						length: 6,
						length2: 4,
						smooth: true
		  		},
				minShowLabelAngle: 0.001
		    },
		    {
		      type: 'pie',
		      data: [
		        { value: warnCnt, name: warnName, itemStyle: { opacity : 0 }, label:{show: false}, status:4},
		        { value: normalCnt, name: normalName, itemStyle: { color: normalRGB }, index: 1, status:1},
		        { value: toExeCnt, name: toExeName, itemStyle: { opacity : 0 }, label:{show: false}, status:2},
		        { value: failCnt, name: failName, itemStyle: { opacity : 0 }, label:{show: false}, status:3} 
		      ].sort(function (a, b) { return b.value - a.value; }),//环弧度排序以确定环位置
		      radius: [inWidth,normalWidth],//正常环(绿)
		      avoidLabelOverlap: true,
		      itemStyle: {
		        borderRadius: 4,
		        borderWidth: 2
		      },
		      label: {
		        formatter:function (params) {
		          if(params.value==0){  //为0时不显示百分比
		            return '' 
		          }else{
		            return params.percent.toFixed(1)+'%'
		          }
		        },
		        fontSize:perFontSize,
		        color:normalRGB,
		      },
		      labelLine: {
						length: 6,
						length2: 4,
						smooth: true
		  		},
				minShowLabelAngle: 0.001
		    },
		    {
		      type: 'pie',
		      data: [
		        { value: warnCnt, name: warnName, itemStyle: { opacity : 0 }, label:{show: false}, status:4},
		        { value: normalCnt, name: normalName, itemStyle: { opacity : 0 }, label:{show: false}, status:1},
		        { value: toExeCnt, name: toExeName, itemStyle: { color: toExeRGB }, index: 0, status:2},
		        { value: failCnt, name: failName, itemStyle: { opacity : 0 }, label:{show: false}, status:3} 
		      ].sort(function (a, b) { return b.value - a.value; }),//环弧度排序以确定环位置
		      radius: [inWidth,toExeWidth],//待执行环(蓝)
		      avoidLabelOverlap: true,
		      itemStyle: {
		        borderRadius: 4,
		        borderWidth: 2
		      },
		      label: {
		        formatter:function (params) {
		          if(params.value==0){  //为0时不显示百分比
		            return '' 
		          }else{
		            return params.percent.toFixed(1)+'%'
		          }
		        },
		        fontSize:perFontSize,
		        color:toExeRGB
		      },
		      labelLine: {
						length: 6,
						length2: 4,
						smooth: true
		  		},
				minShowLabelAngle: 0.001
		    },
		    {
		      type: 'pie',
		      data: [
		        { value: warnCnt, name: warnName, itemStyle: { opacity : 0 }, label:{show: false}, status:4},
		        { value: normalCnt, name: normalName, itemStyle: { opacity : 0 }, label:{show: false}, status:1},
		        { value: toExeCnt, name: toExeName, itemStyle: { opacity : 0 }, label:{show: false}, status:2},
		        { value: failCnt, name: failName, itemStyle: { color: failRGB }, index: 0, status:3} 
		      ].sort(function (a, b) { return b.value - a.value; }),//环弧度排序以确定环位置
		      radius: [inWidth,failWidth],//失败环(灰)
		      avoidLabelOverlap: true,
		      itemStyle: {
		        borderRadius: 4,
		        borderWidth: 2
		      },
		      label: {
		        formatter:function (params) {
		          if(params.value==0){  //为0时不显示百分比
		            return '' 
		          }else{
		            return params.percent.toFixed(1)+'%'
		          }
		        },
		        fontSize:perFontSize,
		        color:failRGB
		      },
		      labelLine: {
						length: 6,
						length2: 4,
						smooth: true
		  		},
				minShowLabelAngle: 0.001
		    }
		  ]
		};

最终效果:


版权声明:本文为weixin_43852260原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。