Vue + HighCharts 画不同高度的3D饼/环图

前言:由于公司可视化数字大屏项目需要用到了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
                    }

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

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Vue2 和 Highcharts 是两个不同的技术,可以结合使用来实现数据可视化功能。 Vue2 是一种流行的 JavaScript 框架,用于构建用户界面。它提供了一些方便的工具和组件,使开发者能够更轻松地构建交互式和响应式的应用程序。 Highcharts 是一个用于创建交互式表的 JavaScript 库。它支持多种类型的表,包括线性、柱状等,并且提供了丰富的配置选项和 API,使开发者能够自定义和控制表的外观和行为。 要在 Vue2 中使用 Highcharts,你可以按照以下步骤进行操作: 1. 安装 Highcharts:可以使用 npm 或者 yarn 安装 Highcharts 库。 ``` npm install highcharts --save ``` 2. 在 Vue2 项目中引入 Highcharts 库: 在需要使用 Highcharts 的组件中,可以通过 `import` 或者 `require` 语句引入 Highcharts 库。 ``` import Highcharts from 'highcharts' ``` 3. 创建 Highcharts 表: 在 Vue2 组件中,可以使用 `mounted` 或者其他适合的生命周期钩子函数,在组件渲染完成后创建 Highcharts 表。 ``` mounted() { Highcharts.chart('chart-container', { // 配置选项和数据 }) } ``` 4. 在模板中定义表容器: 在组件的模板中,使用一个空的元素作为表的容器,指定一个唯一的 ID,供 Highcharts 创建表时使用。 ``` <template> <div id="chart-container"></div> </template> ``` 以上是一个简单的使用示例,你可以根据具体需求和 Highcharts 的文档进行更高级的配置和使用。希望能帮到你!
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱吃香菜的胡先森

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

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

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

打赏作者

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

抵扣说明:

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

余额充值