echarts实现一个双层饼图,外层饼图显示数据分布规律,内层饼图展示总的统计数据。

447 阅读4分钟

echarts实现一个双层饼图,外层饼图显示数据分布规律,内层饼图展示总的统计数据。

  • echats版本号:5.2.1
  1. 效果图

image.png

  1. 实现过程

    • 确定饼图位置

                      grid: {
                          left: 0,
                          top: 0,
                          right: 0,
                          bottom: 0,
                          containLabel: true
                      },
      
    • 确定饼图中各个色块的颜色,按照数据先后依次显示颜色

                      color: [{
                          type: 'linear',
                          colorStops: [{
                              offset: 0, color: '#0ebeff' // 0% 处的颜色
                          }, {
                              offset: 1, color: '#5e95e6' // 100% 处的颜色
                          }]
                      }, {
                          type: 'linear',
                          colorStops: [{
                              offset: 0, color: '#e39429' // 0% 处的颜色
                          }, {
                              offset: 1, color: '#eb8c0b' // 100% 处的颜色
                          }]
                      }, {
                          type: 'linear',
                          colorStops: [{
                              offset: 0, color: '#32b640' // 0% 处的颜色
                          }, {
                              offset: 1, color: '#2dd43e' // 100% 处的颜色
                          }]
                      }]
      
    • 确定饼图的标题,数组中第一个元素是饼图中间的统计数据总和,第二个元素是饼图底部的标题

      注:在饼图中间对齐的重点是,top,left及textAlign、textVerticalAlign属性

                      title: [ title: [{
                          text: data.reduce((preValue, current) => {
                              return preValue + current.value
                          }, 0),
              
                          top: '43%',// 文字显示的距离饼图顶部的距离,
                          left: '34%', // 文字显示距离饼图左侧的距离
                          textAlign: 'center', // 以left的距离为中心点居中对齐
                          textVerticalAlign: 'middle',// 以top的距离为轴线进行垂直对齐
                          textStyle: {
                              color: '#FFFFFF',
                              fontWeight: 'bold',
                              textShadowColor: '#61A7FF',
                              textShadowBlur: 7,
                              textShadowOffsetX: 0,
                              textShadowOffsetY: 2
                          },
                          zlevel: 5
                      }, {
                          text: 'pie',
                          left: '34%',
                          top: '76%',
                          textAlign: 'center',
                          textStyle: {
                              fontWeight: 'normal',
                              fontSize: 14,
                              color: '#C0D7FF',
                              fontFamily: 'PingFangSC-Regular, PingFang SC'
                          },
                      }],
      
    • 自定义饼图的legend显示

                      legend: {
                          icon: "circle",
                          left: "70%",
                          // top: "20%",
                          itemHeight: 5,
                          textStyle: {
                              color: "#E6F7FF",
                          },
                          data: data.map(item => item.name),
                          formatter: function (name) {//格式化lenged显示
                              let value = data.filter(item => item.name === name)[0].value
                              let arr = ["{a|" + name + "}", "{b|" + value + "}"]
                              return arr.join("");
                          },
                          textStyle: {
                              // 为了图例与第二行文字对齐,需要设置两个样式的padding,把文字顶到合适的位置,然后为了上下行的间隔,设置了第2行文字的行高
                              rich: {
                                  a: {
                                      fontSize: 14,
                                      color: '#EFEFEF',
                                      // align: 'center',
                                      verticalAlign: 'middle',
                                      padding: 0,
                                      lineHeight: 50,
                                      padding: [20, 15, 20, -12]
                                  },
                                  b: {
                                      fontSize: 18,
                                      color: "#FFFFFF",
                                      // align: 'center',
                                      fontWeight: 700,
                                      verticalAlign: 'middle',
                                      lineHeight: 50,
                                      padding: [20, 15, 20, -12]
                                  }
                              },
                          }
                      }
      
    • 饼图样式

      注意点:需保证两层饼图的中心点相同,由饼图的radius属性确认饼图的显示范围。

                      series: [
                          {
                              name: 'pietest',
                              type: "pie",
                              radius: ["45%", "55%"],
                              center: ["35%", "45%"],
                              avoidLabelOverlap: false,
                              label: {
                                  show: false
                              },
                              itemStyle: {
                                  normal: {
                                      borderWidth: 10, // 间距的宽度,饼图每个元素之间的间距
                                      borderColor: 'rgba(40,48,65,1)', //背景色
                                  }
                              },
                              emphasis: {
                                  scaleSize: 1.5,
                              },
                              data: data,
                          },
                          {
                              name: "内框",
                              type: "pie",
                              radius: ["0", "35%"],
                              center: ["35%", "45%"],
                              emphasis: {
                                  scale: false,
                              },
                              tooltip: {
                                  show: false,
                              },
                              itemStyle: {
                                  color: {
                                      type: 'linear',
                                      colorStops: [{
                                          offset: 0.03, color: 'rgba(50,105,177,0)' // 0% 处的颜色
                                      }, {
                                          offset: 1, color: '#2F4A71' // 100% 处的颜色
                                      }]
                                  },
                                  borderColor: {
                                      type: 'linear',
                                      colorStops: [{
                                          offset: 0, color: 'rgba(189, 205, 223, 0.11)' // 0% 处的颜色
                                      }, {
                                          offset: 1, color: 'rgba(136, 159, 188, 0.62)' // 100% 处的颜色
                                      }]
                                  }
                              },
                              zlevel: 4,
                              labelLine: {
                                  show: false,
                              },
                              data: [100],
                          },
                      ]
      
  2. 完整代码

 function initEcharts() {
            let data = [{
                name: '测试1',
                value: 100
            }, {
                name: '测试2',
                value: 200
            }, {
                name: '测试3',
                value: 300
            }]
            let option = {
                // 确定饼图的位置
                grid: {
                    left: 0,
                    top: 0,
                    right: 0,
                    bottom: 0,
                    containLabel: true
                },
                color: [{
                    type: 'linear',
                    colorStops: [{
                        offset: 0, color: '#0ebeff' // 0% 处的颜色
                    }, {
                        offset: 1, color: '#5e95e6' // 100% 处的颜色
                    }]
                }, {
                    type: 'linear',
                    colorStops: [{
                        offset: 0, color: '#e39429' // 0% 处的颜色
                    }, {
                        offset: 1, color: '#eb8c0b' // 100% 处的颜色
                    }]
                }, {
                    type: 'linear',
                    colorStops: [{
                        offset: 0, color: '#32b640' // 0% 处的颜色
                    }, {
                        offset: 1, color: '#2dd43e' // 100% 处的颜色
                    }]
                }],
                title: [{
                    text: data.reduce((preValue, current) => {
                        return preValue + current.value
                    }, 0),
        
                    top: '43%',
                    left: '34%',
                    textAlign: 'center',
                    textVerticalAlign: 'middle',
                    textStyle: {
                        color: '#FFFFFF',
                        fontWeight: 'bold',
                        textShadowColor: '#61A7FF',
                        textShadowBlur: 7,
                        textShadowOffsetX: 0,
                        textShadowOffsetY: 2
                    },
                    zlevel: 5
                }, {
                    text: 'pie',
                    left: '34%',
                    top: '76%',
                    textAlign: 'center',
                    textStyle: {
                        fontWeight: 'normal',
                        fontSize: 14,
                        color: '#C0D7FF',
                        fontFamily: 'PingFangSC-Regular, PingFang SC'
                    },
                }],
                tooltip: {
                    trigger: "item",
                    backgroundColor: 'rgba(52, 136, 234,0.7)',
                    borderColor: 'rgb(52, 136, 234)',
                    textStyle: {
                        color: 'rgba(256,256,256)'
                    },
                },
                legend: {
                    icon: "circle",
                    orient: "vertical",
                    x: 'left',
                    y: 'center',
                    left: "70%",
                    itemHeight: 5,
                    textStyle: {
                        color: "#E6F7FF",
                    },
                    data: data.map(item => item.name),
                    formatter: function (name) {
                        let value = data.filter(item => item.name === name)[0].value
                        let arr = ["{a|" + name + "}", "{b|" + value + "}"]
                        return arr.join("");
                    },
                    textStyle: {
                        // 为了图例与第二行文字对齐,需要设置两个样式的padding,把文字顶到合适的位置,然后为了上下行的间隔,设置了第2行文字的行高
                        rich: {
                            a: {
                                fontSize: 14,
                                color: '#EFEFEF',
                                // align: 'center',
                                verticalAlign: 'middle',
                                padding: 0,
                                lineHeight: 50,
                                padding: [20, 15, 20, -12]
                            },
                            b: {
                                fontSize: 18,
                                color: "#FFFFFF",
                                // align: 'center',
                                fontWeight: 700,
                                verticalAlign: 'middle',
                                lineHeight: 50,
                                padding: [20, 15, 20, -12]
                            }
                        },
                    }
                },
                series: [
                    {
                        name: 'pietest',
                        type: "pie",
                        radius: ["45%", "55%"],
                        center: ["35%", "45%"],
                        avoidLabelOverlap: false,
                        label: {
                            show: false
                        },
                        itemStyle: {
                            normal: {
                                borderWidth: 10, // 间距的宽度
                                borderColor: 'rgba(40,48,65,1)', //背景色
                            }
                        },
                        emphasis: {
                            scaleSize: 1.5,
                        },
                        data: data,
                    },
                    {
                        name: "内框",
                        type: "pie",
                        radius: ["0", "35%"],
                        center: ["35%", "45%"],
                        emphasis: {
                            scale: false,
                        },
                        tooltip: {
                            show: false,
                        },
                        itemStyle: {
                            color: {
                                type: 'linear',
                                colorStops: [{
                                    offset: 0.03, color: 'rgba(50,105,177,0)' // 0% 处的颜色
                                }, {
                                    offset: 1, color: '#2F4A71' // 100% 处的颜色
                                }]
                            },
                            borderColor: {
                                type: 'linear',
                                colorStops: [{
                                    offset: 0, color: 'rgba(189, 205, 223, 0.11)' // 0% 处的颜色
                                }, {
                                    offset: 1, color: 'rgba(136, 159, 188, 0.62)' // 100% 处的颜色
                                }]
                            }
                        },
                        zlevel: 4,
                        labelLine: {
                            show: false,
                        },
                        data: [100],
                    },
                ]
            }
            let echartsDom = document.getElementById('pie');
            myChart = echarts.init(echartsDom);
            myChart.setOption(option)
        }