普通html项目中highcharts实现不同高低的3d饼状图效果

highcharts yekong

数据可视化大屏项目中,为了当大屏元素多样化,3d饼状图也是不可缺少的元素,今天整理的是根据数据显示不同高低的饼状图效果。 可能遇到窗口大小变化后会出现错位情况:highcharts不同高低的3d饼状图窗口变化后错位问题

highcharts实现不同高低的3d饼状图效果

首先引入highcharts

这里使用的是10.1.0版本的highcharts

<script src="//cdn.staticfile.org/highcharts/10.1.0/highcharts.js"></script>
<script src="//cdn.staticfile.org/highcharts/10.1.0/highcharts-3d.js"></script>

实例代码

这里如果3d饼状图选中后会往下移动,导致错位,所以这里我们不允许饼状图选中。allowPointSelect: false,

function initChart() {
    // 修改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(document.getElementById('highEcharts'), {
        chart: {
            type: 'pie',
            animation: false,
            backgroundColor: 'rgba(0,0,0,0)',

            events: {
                load: function () {
                    const each = Highcharts.each
                    const points = this.series[0].points
                    each(points, 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',
                center: ['50%', '60%'],
                depth: 20,
                innerSize: 100,
                dataLabels: {
                    enabled: false
                },
                // 显示图例
                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}
            ]
        }]
    })
}

我们还可以使用自定义html来实现legend

我们还可以使用自定义html来实现legend

html

<div class="highEchartsBody">
    <div class="highEcharts" id="highEcharts"></div>
    <div class="highEcharts2">
        <div class="highEcharts2Item">
            <p>A类</p><span>20%</span>
        </div>
        <div class="highEcharts2Item">
            <p>B类</p><span>20%</span>
        </div>
        <div class="highEcharts2Item">
            <p>C类</p><span>20%</span>
        </div>
        <div class="highEcharts2Item">
            <p>D类</p><span>20%</span>
        </div>
        <div class="highEcharts2Item">
            <p>E类</p><span>20%</span>
        </div>
    </div>
</div>

css

.highEchartsBody {
  position: relative;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap;
  flex-direction: row;
  align-content: flex-start;

  .highEcharts {
    position: relative;
    width: 70%;
    height: 100%;
    background: url("../images/item11/bingbg.png") center 80% no-repeat;
  }

  .highEcharts2 {
    position: relative;
    width: 30%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: nowrap;
    flex-direction: column;
    align-content: flex-start;

    .highEcharts2Item {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: nowrap;
      flex-direction: row;
      align-content: flex-start;
      height: 18%;
      position: relative;

      p {
        font-size: px2rem(14);
        font-family: MicrosoftYaHei;
        font-weight: 400;
        position: relative;
        height: 100%;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        flex-wrap: nowrap;
        flex-direction: row;
        align-content: flex-start;
        color: #FFFFFF;
      }

      span {
        font-size: 20px;
        font-family: yejing;
        font-weight: normal;
        margin-left: px2rem(20);
        color: #FFFFFF;
        position: relative;
        height: 100%;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        flex-wrap: nowrap;
        flex-direction: row;
        align-content: flex-start;
        /* 添加发光效果 */
        text-shadow: 0 0 10px #2ea1b2, 0 0 20px #2ea1b2, 0 0 30px #2ea1b2;
      }
    }

    .highEcharts2Item:nth-child(2) {
      span {
        /* 添加发光效果 */
        text-shadow: 0 0 10px #ee7529, 0 0 20px #ee7529, 0 0 30px #ee7529;
      }
    }

    .highEcharts2Item:nth-child(3) {
      span {
        /* 添加发光效果 */
        text-shadow: 0 0 10px #f5c055, 0 0 20px #f5c055, 0 0 30px #f5c055;
      }
    }

    .highEcharts2Item:nth-child(4) {
      span {
        /* 添加发光效果 */
        text-shadow: 0 0 10px #2d7bb5, 0 0 20px #2d7bb5, 0 0 30px #2d7bb5;
      }
    }

    .highEcharts2Item:nth-child(5) {
      span {
        /* 添加发光效果 */
        text-shadow: 0 0 10px rgba(138, 223, 255, 1.00), 0 0 20px rgba(138, 223, 255, 1.00), 0 0 30px rgba(138, 223, 255, 1.00);
      }
    }
  }
}
喜欢