js + highcharts 实现3d饼图

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>实现3D饼图</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/highcharts/10.3.2/highcharts.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/highcharts/10.3.2/highcharts-3d.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/highcharts/10.3.2/highcharts-more.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/highcharts/10.3.2/modules/drilldown.js"></script>
</head>

<body>
    <div id="three"></div>
</body>

<script>
    // 饼图实例
    let pie3dChart = null
    // 当前高亮
    let index = 0
    const colorsCopy = ['#73badb', '#4466e1', '#5af3b8', '#ffcf40', '#bee5fb', '#2B8EF3']
    const devDistribution = [
        {
            "name": "已用",
            "value": 467,
            "percent": 77.8,
            "id": 0,
            "y": 467,
            "h": 17
        },
        {
            "name": "未用",
            "value": 133,
            "percent": 22.2,
            "id": 1,
            "y": 133,
            "h": 8
        }
    ]
    const colors = devDistribution.map((ele, i) => {
        const ii = i - colorsCopy.length * Math.floor(i / colorsCopy.length)
        return colorsCopy[ii]
    })
    // 绘制3d饼图
    function pie3d() {
        // 修改3d饼图绘制过程
        let round = Math.round,
            cos = Math.cos,
            sin = Math.sin,
            deg2rad = Math.deg2rad
        Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'translate', function (proceed) {
            proceed.apply(this, [].slice.call(arguments, 1))
            if (!this.chart.is3d()) {
                return
            }
            let series = this,
                chart = series.chart,
                options = chart.options,
                seriesOptions = series.options,
                depth = seriesOptions.depth || 0,
                options3d = options.chart.options3d,
                alpha = options3d.alpha,
                beta = options3d.beta,
                z = seriesOptions.stacking ? (seriesOptions.stack || 0) * depth : series._i * depth
            z += depth / 2
            if (seriesOptions.grouping !== false) {
                z = 0
            }
            series.data.forEach((e) => {
                let shapeArgs = e.shapeArgs,
                    angle
                e.shapeType = 'arc3d'
                let ran = e.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
                e.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) {
                    let ret = proceed.apply(this, [].slice.call(arguments, 1))
                    ret.zTop = (ret.zOut + 0.5) / 100
                    return ret
                })
            })(Highcharts)
        // 生成不同高度的3d饼图
        pie3dChart = Highcharts.chart('three', {
            accessibility: { enabled: false },
            chart: {
                type: 'pie',
                animation: false,
                backgroundColor: '#ffffff00',
                events: {
                    load: function () {
                        let points = this.series[0].points
                        points.forEach((e) => {
                            e.graphic.attr({
                                translateY: -e.shapeArgs.ran,
                            })
                            e.graphic.side1.attr({
                                translateY: -e.shapeArgs.ran,
                            })
                            e.graphic.side2.attr({
                                translateY: -e.shapeArgs.ran,
                            })
                        })
                    },
                },
                options3d: {
                    enabled: true,
                    alpha: 63,
                },
            },
            title: {
                text: null,
            },
            credits: {
                enabled: false, //不显示LOGO
            },
            tooltip: { enabled: false },
            plotOptions: {
                pie: {
                    allowPointSelect: false,
                    cursor: 'pointer',
                    depth: 8,
                    size: 180,
                    innerSize: '70%',
                    colors: colors,
                    dataLabels: {
                        enabled: false,
                    },
                    events: {
                        click: function (e) {
                            // 点击的操作
                            index = e.point.index
                            devDistribution.forEach((ele, index) => {
                                if (e.point.index == index) {
                                    ele.h = 17
                                } else {
                                    ele.h = 8
                                }
                            })
                            update()
                        },
                    },
                },
            },
            series: [
                {
                    type: 'pie',
                    data: devDistribution,
                },
            ],
        })
        // 解决上下颠倒问题
        Highcharts.addEvent(pie3dChart, 'redraw', function () {
            let points = pie3dChart.series[0].points
            points.forEach((e) => {
                e.graphic.attr({
                    translateY: -e.shapeArgs.ran,
                })
                e.graphic.side1.attr({
                    translateY: -e.shapeArgs.ran,
                })
                e.graphic.side2.attr({
                    translateY: -e.shapeArgs.ran,
                })
            })
        })
    }

    // 更新data
    function update() {
        pie3dChart.series[0].update({ data: devDistribution })
    }

    window.onload = () => {
        pie3d()
    }
</script>

</html>

有用的话,赏个赞呗

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaoli_qidian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值