echart饼图的legend

legend是图例,echart里的一个参数。

既然legend是echart的参数,那么echart能自己控制呀,为什么要用html来画?

是这样,需求要求图例的文字在右侧,是分成了两部分,左右对齐的。如下图:



解决方案有三个,一个是自己用html+css画。那么需要echart的图例能隐藏,只显示饼图,另外饼图的每个颜色我能控制,这样能把颜色带到自己的css里。所幸这些条件都能到达到。

方案二是使用lengd的属性,把文字拆成两部分,再用textStyle的rich来控制。

最后一方案是计算刚好宽度的空格来填充中间的空格。这个方案不太行,对不齐。因为空格的单位太大,左边文字中英文宽度又不一致。

方案一

html代码:

<div class="main_box_left">
    <div id="warnComputeChart"></div>
    <div class="chartLegend">
        <div>
            <div class="chartLegendLeft">
                <div style="border:0px solid #f00;background-color:#f00;border-radius: 20%;"></div>
                <div>中石油</div>
            </div>
            <div>85次</div>
        </div>
        <div>
            <div class="chartLegendLeft">
                <div style="border:0px solid #f00;background-color:#5670c3;border-radius: 20%;"></div>
                <div>中石化</div>
            </div>
            <div>76次</div>
        </div>
        <div>
            <div class="chartLegendLeft">
                <div style="border:0px solid #f00;background-color:#98cc7a;border-radius: 20%;"></div>
                <div>壳牌</div>
            </div>
            <div>45次</div>
        </div>
        <div>
            <div class="chartLegendLeft">
                <div style="border:0px solid #f00;background-color:#f6c861;border-radius: 20%;"></div>
                <div>其他</div>
            </div>
            <div>46次</div>
        </div>
    </div>
</div>

css代码:

#warnComputeChart,#warnGusTypeChart{
  width:100%;
  height:100%;
}
.main_box_left{
  &:extend(.main_box);
  display: flex;
  flex-direction:row;
  flex-wrap:nowrap;
  justify-content:space-between;
  align-items:center;
  /*
  justify-content:flex-start;
  align-items:center;
  */
}
.chartLegend{
  height:100%;
  line-height: 100%;
  display: flex;
  flex-direction:column;
  flex-wrap:nowrap;
  justify-content:center;
  align-items:center;
}
.chartLegend > div{
  width:100%;
  display: flex;
  flex-direction:row;
  flex-wrap:nowrap;
  justify-content:space-between;
  align-items:center;

  margin:3rem 0rem;
}
.chartLegendLeft{
  height:14rem;
  line-height: 14rem;

  display: flex;
  flex-direction:row;
  flex-wrap:nowrap;
  justify-content:left;
  align-items:center;
}
.chartLegendLeft div:nth-child(1){
  height:14rem;
  line-height: 14rem;
  width:21rem;
  
}

echart js配置:

//设置canvas宽度
$("#"+id).width($("#"+id).height());
//设置legend宽度
let chartParent=$($("#"+id).parent());
chartParent.find(".chartLegend").width(chartParent.width()-$("#"+id).width()-10);

let centerPx=$("#"+id).height()/2;
let titleWidth=getTextWidth(title,"bolder 18 MicrosoftYaHei");
//console.log("titleWidth:"+titleWidth+" "+centerPx+" "+(centerPx-titleWidth/2));
let chartDom = document.getElementById(id);
let myChart = echarts.init(chartDom, null, {
    renderer: 'canvas',
    useDirtyRect: false
});
let app = {};

let option;


option = {
    title:{
        show:true,
        text:title,
        textAlign:"center",
        left:(centerPx-titleWidth/2)+5,
        top:"center",
        /*
        left:"center",
        top:"center",
        */
        subtext:subTitle,
        textStyle: {
            fontWeight: 'bolder',
            fontSize: 18
        }
    },
    tooltip: {
      trigger: 'item'
    },
    legend: {
        show: false,
        top: 'center',
        right: '0',
        orient: 'vertical'
    },
    series: [
      {
        name: '',
        type: 'pie',
        radius: ['80%', '95%'],
        /*center: ['0%', '50%'],*/
        center:[centerPx+"px",centerPx+"px"],
        left:'left',
        top:0,
        avoidLabelOverlap: false,
        label: {
          show: false,
          position: 'center'
        },
        emphasis: {
          label: {
            show: false,
            fontSize: '40',
            fontWeight: 'bold'
          }
        },
        labelLine: {
          show: false
        },
        data: chartData
      }
    ]
  };
  if (option && typeof option === 'object') {
    myChart.setOption(option);
}

window.addEventListener('resize', myChart.resize);


方案二,

传入echart的series.data.name的字符串分成几部分,中间以空格分开,如:

中xx   85次
这样左边的左对齐,右边的右对齐。

echart的legend属性这么写:

legend: {
    show: true,
    orient: 'vertical',
    right:10,
    top:'center',
    align:'left',
    tooltip: {
      show: false
    },
    
    formatter: function (name) {
      //分成两部分
      let spName=name.trim().split(/\s+/); 
      var arr = [
        '{a| ' + spName[0] + '}  ',
        '{b| ' + spName[1] + '}  ',
      ];
      return arr.join('');
      
  },
  textStyle: {
      //rich放在textStyle里面
      rich: {
          a: {
              align: 'left',
              fontSize: 12,
              color: "#000",
              width: widths[0],
              padding: [0, 0, 0, 0]
          },
          b: {
              align: 'right',
              fontSize: 12,
              color: "#000",
              width: widths[1],
              padding: [0, 0, 0, 0],
          }
      },
      /*
      borderWidth:1,
      borderType:'solid',
      borderColor:'#f00',
      */
      width:150

  }

},



方案三,也实现一下。

js代码:

var font="bolder 18 MicrosoftYaHei";
function getTxtWidth(text) {
  // re-use canvas object for better performance
  var canvas =  document.createElement("canvas");
  var context = canvas.getContext("2d"); 
  context.font = font;
  var metrics = context.measureText(text);
  return metrics.width;
}
function toFixedBit(beforeTxt,afterTxt,maxChars) {
  let maxWidth=getTxtWidth(maxChars);
  if(beforeTxt==null || afterTxt==null){
    return "";
  }
  let splitChar="";
  let charLen=(getTxtWidth(beforeTxt)+getTxtWidth(afterTxt));
  let fixLen=maxWidth-charLen;
  let splitLen=0;
  while(fixLen>0){
    charLen=charLen+getTxtWidth(" ");
    splitLen++;
    fixLen=maxWidth-charLen;
  }
  for(let i=0;i<splitLen;i++){
    splitChar+=" ";
  }

  return beforeTxt+splitChar+afterTxt;
}


调用toFixedBit来生成字符串:

js:

let maxChars="中xx   85次";
let chartData=[
    { value: 85, name: toFixedBit('中xx', '85次',maxChars) ,itemStyle:{color:"#f00"}},
    { value: 76, name: toFixedBit('中x化', '76次',maxChars) ,itemStyle:{color:"#5670c3"}},
    { value: 45, name: toFixedBit('k牌', '45次',maxChars) ,itemStyle:{color:"#98cc7a"}},
    { value: 46, name: toFixedBit('其他', '46次',maxChars) ,itemStyle:{color:"#f6c861"}}
];



文/程忠 浏览次数:0次   2022-06-16 07:34:05

相关阅读


评论:
点击刷新