highcharts不同高低的3d饼状图窗口变化后错位问题

highcharts yekong

在之前我们实现了highcharts实现不同高低的3d饼状图效果,但是在窗口大小变化后,3d饼状图会错位,全部跑到下方去了,就像倒过来一样,类似下图:

highcharts不同高低的3d饼状图窗口变化后错位问题

解决办法:

我们只需要监听窗口变化,当窗口变化后,重绘一下就可以了。

mounted() {
    this.drawEcharts();
    window.addEventListener('resize', this.handleResize);
  },
  beforeUnmount() { // 在 Vue 2 中使用 beforeDestroy
    window.removeEventListener('resize', this.handleResize);
  },
  methods: {
    handleResize() {
      this.drawEcharts(); // 重新绘制图表
    },
    drawEcharts() {
      var that = this;
      // 修改3d饼图绘制过程
      const each = Highcharts.each
      const round = Math.round
      const cos = Math.cos
      const sin = Math.sin
      const deg2rad = Math.deg2rad
      Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'translate', function (proceed) {
        proceed.apply(this, [].slice.call(arguments, 1))
        // Do not do this if the chart is not 3D
        if (!this.chart.is3d()) {
          return
        }
        const series = this
        const chart = series.chart
        const options = chart.options
        const seriesOptions = series.options
        const depth = seriesOptions.depth || 0
        const options3d = options.chart.options3d
        const alpha = options3d.alpha
        const beta = options3d.beta
        var z = seriesOptions.stacking ? (seriesOptions.stack || 0) * depth : series._i * depth
        z += depth / 2
        if (seriesOptions.grouping !== false) {
          z = 0
        }
        each(series.data, function (point) {
          const shapeArgs = point.shapeArgs
          var angle
          point.shapeType = 'arc3d'
          var ran = point.options.h
          shapeArgs.z = z
          shapeArgs.depth = depth * 0.75 + ran
          shapeArgs.alpha = alpha
          shapeArgs.beta = beta
          shapeArgs.center = series.center
          shapeArgs.ran = ran
          angle = (shapeArgs.end + shapeArgs.start) / 2
          point.slicedTranslation = {
            translateX: round(cos(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad)),
            translateY: round(sin(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad))
          }
        })
      });
      (function (H) {
        H.wrap(Highcharts.SVGRenderer.prototype, 'arc3dPath', function (proceed) {
          // Run original proceed method
          const ret = proceed.apply(this, [].slice.call(arguments, 1))
          ret.zTop = (ret.zOut + 0.5) / 100
          return ret
        })
      }(Highcharts))
      // 生成不同高度的3d饼图
      Highcharts.chart(that.$refs.echarts, {
        tooltip: {
          enabled: false
        },
        chart: {
          type: 'pie',
          animation: false,
          backgroundColor: 'rgba(0,0,0,0)',

          events: {
            load: function () {
              const each2 = Highcharts.each
              const points2 = this.series[0].points
              each2(points2, function (p, i) {
                p.graphic.attr({
                  translateY: -p.shapeArgs.ran
                })
                p.graphic.side1.attr({
                  translateY: -p.shapeArgs.ran
                })
                p.graphic.side2.attr({
                  translateY: -p.shapeArgs.ran
                })
              })
            }
          },
          options3d: {
            enabled: true,
            alpha: 65
          }
        },
        title: {
          show: 'false',
          text: null
        },
        subtitle: {
          text: null
        },
        credits: {
          enabled: false
        },
        legend: { // 【图例】位置样式
          backgroundColor: 'rgba(0,0,0,0)',
          shadow: false,
          layout: 'vertical',
          align: 'right', // 水平方向位置
          verticalAlign: 'top', // 垂直方向位置
          x: 0, // 距离x轴的距离
          y: 100, // 距离Y轴的距离
          symbolPadding: 10,
          symbolHeight: 14,
          itemStyle: {
            lineHeight: '24px',
            fontSize: '16px',
            color: '#fff'
          },
          labelFormatter: function () {
            /*
            *  格式化函数可用的变量:this, 可以用 console.log(this) 来查看包含的详细信息
            *  this 代表当前数据列对象,所以默认的实现是 return this.name
            */
            return this.name + this.h + '%'
          }
        },
        plotOptions: {
          pie: {
            allowPointSelect: false,
            cursor: 'pointer',
            animation: false,
            center: ['50%', '50%'],
            depth: 20,
            size: '80%',
            innerSize: 80,
            lineWidth: 1,
            borderWidth: 1,
            states: {
              hover: {
                halo: {
                  size: 1 // 移除 hover 状态下的光晕效果
                },
                // brightness: 1 // hover 状态下亮度增加,相当于透明度减少
              },
              inactive: {
                opacity: 0.5 // 非激活状态下的透明度
              }
            },
            tooltip: {
              enabled: false // 禁用默认 tooltip
            },
            dataLabels: {
              enabled: false,
              padding: 0,
              distance: 10,
              connectorColor: 'silver',
              connectorPadding: 1, // 控制引导线的长度
              useHTML: true, // 允许使用HTML标签
              formatter: function () {
                // 使用HTML标签自定义样式
                var nameStyle = '<span style="font-size: 14px; font-family: MicrosoftYaHei; font-weight: 400; color: #FFFFFF;">' + this.point.name + '</span>';
                var percentageStyle = '<span style="font-size: 20px; font-family: yejing; font-weight: normal; color: #FFFFFF;">' + Highcharts.numberFormat(this.percentage, 0) + '%</span>';
                return nameStyle + ': ' + percentageStyle; // 将样式组合起来
              }
            },
            // 显示图例
            showInLegend: false
          }
        },
        series: [{
          type: 'pie',
          name: '占比',
          // h 是高度  y是占的圆环长度
          colorByPoint: true,
          colors: [
            { // 注意!!!如果是柱状图请使用color,如果是面积图请使用fillColor
              linearGradient: {
                x1: 0,
                y1: 1,
                x2: 1,
                y2: 0
              },
              stops: [
                [0, '#19596d'],
                [1, '#2ea1b2']
              ]
            }, { // 注意!!!如果是柱状图请使用color,如果是面积图请使用fillColor
              linearGradient: {
                x1: 0,
                y1: 1,
                x2: 1,
                y2: 0
              },
              stops: [
                [0, '#ee7529'],
                [1, '#f5a86c']
              ]
            }, { // 注意!!!如果是柱状图请使用color,如果是面积图请使用fillColor
              linearGradient: {
                x1: 0,
                y1: 1,
                x2: 1,
                y2: 0
              },
              stops: [
                [0, '#f5c055'],
                [1, '#967b3d']
              ]
            }, { // 注意!!!如果是柱状图请使用color,如果是面积图请使用fillColor
              linearGradient: {
                x1: 0,
                y1: 1,
                x2: 1,
                y2: 0
              },
              stops: [
                [0, '#2d7bb5'],
                [1, '#1a5784']
              ]
            }, { // 注意!!!如果是柱状图请使用color,如果是面积图请使用fillColor
              linearGradient: {
                x1: 0,
                y1: 1,
                x2: 1,
                y2: 0
              },
              stops: [
                [0, 'rgba(184, 234, 255, 1.00)'],
                [1, 'rgba(138, 223, 255, 1.00)']
              ]
            }],
          data: [
            {name: 'A类', y: 28, h: 60},
            {name: 'B类', y: 20, h: 20},
            {name: 'C类', y: 10, h: 32},
            {name: 'D类', y: 6, h: 45},
            {name: 'E类', y: 6, h: 45}
          ]
        }],
      })
    }
  }
喜欢