前言:由于公司可视化数字大屏项目需要用到了3D饼图和3D环图,所以在博客里记录一下!如果能帮到你,那么点个赞吧,哈哈哈。

话不多说,直接先上效果图:
3D饼图
在这里插入图片描述
3D环图
在这里插入图片描述
下面是步骤以及代码:

1.npm 安装 highcharts

npm install highcharts --save

2.在main.js中引用 highcharts, 注意:画3D图需要使用到 highcharts里面的 highcharts-3d

import Highcharts from 'highcharts'
 
import Highcharts3d from 'highcharts/highcharts-3d'
 
Highcharts3d(Highcharts)

3D饼图:
HTML:

<template>
    <div class="absolute-left-right-top-bottom charts-main">
        <div class="content">
            <highcharts :options="chartOptions1" class="content-pic"></highcharts>
        </div>
    </div>
</template>

JS:

<script>
import { Chart } from 'highcharts-vue'
import Highcharts from 'highcharts'
import Highcharts3d from 'highcharts/highcharts-3d'

Highcharts3d(Highcharts)

export default {
    name: 'theHospitalStatistics',
    components: {
        'highcharts': Chart
    },
    data() {
        return {
            chartOptions1: {
                credits: {
                    enabled: false
                },
                exporting: { enabled: false },
                chart: {
                    type: 'pie',
                    plotBackgroundColor: null,
                    plotBorderWidth: null,
                    backgroundColor: null,
                    animation: false,
                    options3d: {
                        enabled: true,
                        // 延y轴向内的倾斜角度
                        alpha: 75,
                        // 外旋转角度
                        beta: 0
                    }
                },
                title: {
                    text: null
                },
                tooltip: {
                    // 数据提示框的背景颜色
                    backgroundColor: 'rgba(50,71,179,0.4)',
                    // 边框颜色
                    // borderColor:'rgba(206,94,74,.9)',
                    style: {
                        fontSize: 24,
                        color: '#16D8E9'
                    },
                    useHTML: true, // 是否使用HTML编辑提示信息
                    formatter: function() {
                        // console.log(this) // 控制台输出可以看到有很多属性
                        if (this.point.name === '治愈') {
                            return '<span style="color:#00E5E3; font-size: 20px">' + this.series.name + '</span>' + '<br>' + '<span style="color:#E9F4FF; font-size: 16px">' + this.point.name + ' : ' + '</span>' + '<span style="color:#763FF7; font-size: 24px; font-weight: bold">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                        } else if (this.point.name === '好转') {
                            return '<span style="color:#00E5E3; font-size: 20px">' + this.series.name + '</span>' + '<br>' + '<span style="color:#E9F4FF; font-size: 16px">' + this.point.name + ' : ' + '</span>' + '<span style="color:#e42af8; font-size: 24px; font-weight: bold">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                        } else if (this.point.name === '死亡') {
                            return '<span style="color:#00E5E3; font-size: 20px">' + this.series.name + '</span>' + '<br>' + '<span style="color:#E9F4FF; font-size: 16px">' + this.point.name + ' : ' + '</span>' + '<span style="color:#67cee8; font-size: 24px; font-weight: bold">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                        } else if (this.point.name === '其他') {
                            return '<span style="color:#00E5E3; font-size: 20px">' + this.series.name + '</span>' + '<br>' + '<span style="color:#E9F4FF; font-size: 16px">' + this.point.name + ' : ' + '</span>' + '<span style="color:#4061f7; font-size: 24px; font-weight: bold">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                        }
                    },
                    valueDecimals: 2 // 数据值保留小数位数
                },
                legend: {
                    itemStyle: {
                        fontSize : 18,
                        color: '#00FCF9',
                        fontFamily: 'MicrosoftYaHei',
                        fontWeight: 400
                    }
                },
                plotOptions: {
                    pie: {
                        // 每个扇块能否选中
                        allowPointSelect: false,
                        // 鼠标指针
                        cursor: 'pointer',
                        // 饼图的厚度
                        depth: 70,
                        // 空心
                        innerSize: '0%',
                        textShadow: false,
                        shadow: false,
                        // 提示信息
                        dataLabels: {
                            // 是否显示饼图的线形tip
                            enabled: true,
                            // 设置引导线的长度
                            distance: 25,
                            style: {
                                color: '#E9F4FF',
                                fontSize: 14,
                                fontWeight: 'bold'
                            },
                            formatter: function() { // 设置字体与引导线和饼图颜色一致
                                if (this.point.name === '治愈') {
                                    return '<span style="color:#00FCF9; font-size: 20px">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                                } else if (this.point.name === '好转') {
                                    return '<span style="color:#00FCF9; font-size: 20px">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                                } else if (this.point.name === '死亡') {
                                    return '<span style="color:#00FCF9; font-size: 20px">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                                } else if (this.point.name === '其他') {
                                    return '<span style="color:#00FCF9; font-size: 20px">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                                }
                            }
                        }
                    }
                },
                // colors: ['#763FF7', '#e42af8', '#67cee8', '#4061f7'],
                series: [{
                    type: 'pie',
                    name: '挂号类别分布',
                    size: '65%',
                    startAngle: 220, // 调整饼图的角度   方向:顺时针
                    showInLegend: true, // 是否打开图例
                    colorByPoint: true,
                    data: [
                        {
                            name: '治愈',
                            y: 56.21,
                            h: 50, // 高度
                            sliced: false, // 是否突出
                            selected: false // 是否一直不透明
                        },
                        {
                            name: '好转',
                            y: 38.96,
                            h: 30, // 高度
                            sliced: false, // 是否突出
                            selected: false // 是否一直不透明
                        },
                        {
                            name: '其他',
                            y: 4.83,
                            h: 10, // 高度
                            sliced: false, // 是否突出
                            selected: false // 是否一直不透明
                        },
                        {
                            name: '死亡',
                            y: 1.83,
                            h: 10, // 高度
                            sliced: false, // 是否突出
                            selected: false // 是否一直不透明
                        }
                    ]
                }]
            }
        }
    },
    created() {
        // 设置颜色渐变
        this.setcolor();
        // 设置饼图高度
        this.setOptonHeight();
    },
    mounted() {

    },
    methods: {
        setcolor() {
            // 颜色的填充
            let color1 = ['#763FF7', '#e42af8', '#67cee8', '#4061f7'] // 16D8E9
            let color2 = ['#480ecd', '#a834ea', '#51b3ea', '#3101c6']
            Highcharts.getOptions().colors = Highcharts.map(
                Highcharts.getOptions().colors,
                function(color, index) {
                    return {
                        radialGradient: { cx: 0.5, cy: 0.3, r: 0.7 },
                        stops: [
                            [0, color1[index]],
                            [1, color2[index]] // darken
                        ]
                    }
                }
            )
        },
        setOptonHeight() {
            var each = Highcharts.each,
                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));
                // Do not do this if the chart is not 3D
                if (!this.chart.is3d()) {
                    return;
                }
                var 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;
                }
                each(series.data, function(point) {
                    var shapeArgs = point.shapeArgs,
                        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
                    var ret = proceed.apply(this, [].slice.call(arguments, 1));
                    ret.zTop = (ret.zOut + 0.5) / 100;
                    return ret;
                });
            }(Highcharts))
        }
    }
}
</script>

3D环图
环图与饼图的代码区别只有一个 innerSize 空心率的设置,我这边设置的为 50%。

// 空心
innerSize: ‘50%’,

HTML:

<template>
    <div class="absolute-left-right-top-bottom charts-main">
        <div class="content">
            <highcharts :options="chartOptions1" class="content-pic"></highcharts>
        </div>
    </div>
</template>

JS:

<script>
import { Chart } from 'highcharts-vue'
import Highcharts from 'highcharts'
import Highcharts3d from 'highcharts/highcharts-3d'

Highcharts3d(Highcharts)

export default {
    name: 'deliveryWay',
    components: {
        'highcharts': Chart
    },
    data() {
        return {
            chartOptions1: {
                credits: {
                    enabled: false
                },
                exporting: { enabled: false },
                chart: {
                    type: 'pie',
                    plotBackgroundColor: null,
                    plotBorderWidth: null,
                    backgroundColor: null,

                    options3d: {
                        enabled: true,
                        // 延y轴向内的倾斜角度
                        alpha: 75,
                        // 外旋转角度
                        beta: 0
                    }
                },
                title: {
                    text: null
                },
                tooltip: {
                    // 数据提示框的背景颜色
                    backgroundColor: 'rgba(50,71,179,0.4)',
                    // 边框颜色
                    // borderColor:'rgba(206,94,74,.9)',
                    style: {
                        fontSize: 24,
                        color: '#16D8E9'
                    },
                    useHTML: true, // 是否使用HTML编辑提示信息
                    formatter: function() {
                        // console.log(this) // 控制台输出可以看到有很多属性
                        if (this.point.name === '顺产率') {
                            return '<span style="color:#00E5E3; font-size: 20px">' + this.series.name + '</span>' + '<br>' + '<span style="color:#E9F4FF; font-size: 16px">' + this.point.name + ' : ' + '</span>' + '<span style="color:#26C4FF; font-size: 24px; font-weight: bold">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                        } else if (this.point.name === '剖宫产率') {
                            return '<span style="color:#00E5E3; font-size: 20px">' + this.series.name + '</span>' + '<br>' + '<span style="color:#E9F4FF; font-size: 16px">' + this.point.name + ' : ' + '</span>' + '<span style="color:#CA78F9; font-size: 24px; font-weight: bold">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                        }
                    },
                    valueDecimals: 2 // 数据值保留小数位数
                },
                legend: {
                    itemStyle: {
                        fontSize : 18,
                        color: '#00FCF9',
                        fontFamily: 'MicrosoftYaHei',
                        fontWeight: 400
                    }
                },
                plotOptions: {
                    pie: {
                        // 每个扇块能否选中
                        allowPointSelect: false,
                        // 鼠标指针
                        cursor: 'pointer',
                        // 饼图的厚度
                        depth: 70,
                        // 空心
                        innerSize: '50%',
                        textShadow: false,
                        shadow: false,
                        // 提示信息
                        dataLabels: {
                            // 是否显示饼图的线形tip
                            enabled: true,
                            // 设置引导线的长度
                            distance: 25,
                            style: {
                                color: '#E9F4FF',
                                fontSize: 14,
                                fontWeight: 'bold'
                            },
                            formatter: function() { // 设置字体与引导线和饼图颜色一致
                                if (this.point.name === '顺产率') {
                                    return '<span style="color:#00FCF9; font-size: 20px">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                                    // return '<span style="color:#26C4FF; font-size: 24px">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>' + '<br>' + '<span style="color:#E9F4FF; font-size: 16px">' + this.point.name + '</span>';
                                } else if (this.point.name === '剖宫产率') {
                                    return '<span style="color:#00FCF9; font-size: 20px">' + Highcharts.numberFormat(this.percentage, 2) + '%' + '</span>';
                                }
                            }
                        },
                        states: {
                            inactive: {
                                opacity: 0.7,
                                size: '120%'
                            },
                            hover: {
                                halo: {
                                    size: '120%',
                                    attributes: {
                                        fill: Highcharts.getOptions().colors[2],
                                        'stroke-width': 2,
                                        stroke: Highcharts.getOptions().colors[1]
                                    }
                                }
                            }
                        }
                    }
                },
                series: [{
                    type: 'pie',
                    name: '挂号类别分布',
                    size: '65%',
                    startAngle: 220, // 调整饼图的角度   方向:顺时针
                    showInLegend: true, // 是否打开图例
                    colorByPoint: true,
                    data: [
                        {
                            name: '顺产率',
                            y: 60.48,
                            h: 50, // 高度
                            sliced: false, // 是否突出
                            selected: false // 是否一直不透明
                        },
                        {
                            name: '剖宫产率',
                            y: 39.52,
                            h: 10, // 高度
                            sliced: false, // 是否突出
                            selected: false // 是否一直不透明
                        }
                    ]
                }]
            }
        }
    },
    created() {
        // 设置颜色渐变
        this.setcolor()
        // 设置饼图高度
        this.setOptonHeight()
    },
    mounted() {

    },
    methods: {
        setcolor() {
            // 颜色的填充
            let color1 = ['rgba(0, 66, 178, 0.4)', 'rgba(203, 50, 245, 0.6)'] // 16D8E9 rgba(203, 50, 245, 0.4)
            let color2 = ['#00b3ff', '#c633f4']
            Highcharts.getOptions().colors = Highcharts.map(
                Highcharts.getOptions().colors,
                function(color, index) {
                    return {
                        radialGradient: { cx: 0.5, cy: 0.3, r: 0.7 },
                        // radialGradient: { cx: 1, cy: 1, r: 1 },
                        stops: [
                            [0, color1[index]],
                            [1, color2[index]] // darken
                        ]
                    }
                }
            )
        },
        setOptonHeight() {
            var each = Highcharts.each,
                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))
                    // Do not do this if the chart is not 3D
                    if (!this.chart.is3d()) {
                        return
                    }
                    var 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
                    }
                    each(series.data, function(point) {
                        var shapeArgs = point.shapeArgs,
                            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
                    var ret = proceed.apply(this, [].slice.call(arguments, 1))
                    ret.zTop = (ret.zOut + 0.5) / 100
                    return ret
                })
            })(Highcharts)
        }
    }
}
</script>

分割线

当将alpha: 245时,但是将3D饼/环图倒过来时会出现颜色穿透,我个人也在网上找了很久没有找到解决办法,所以就没有倒过来。

options3d: {
                        enabled: true,
                        // 延y轴向内的倾斜角度
                        alpha: 245,
                        // 外旋转角度
                        beta: 0
                    }

颜色穿透:
在这里插入图片描述
在这里插入图片描述

Logo

前往低代码交流专区

更多推荐