乘风原创程序

  • vue+highcharts实现3D饼图效果
  • 2022/3/28 17:10:45
  • 本文实例为大家分享了vue+highcharts实现3d饼图效果的具体代码,供大家参考,具体内容如下

    这是最终效果

    <template>
    <div class="big-box">
    ? <div class="com-container" ref="container" style="width:380px;height:300px;">
    ? </div>
    ? <div class="tulibox">
    ? ? <div v-for="(item,index) in peidata" :key="index" class="tuliboxitem">
    ? ? ? <span class="name">{{item.name}}</span> ? <span class="value">{{item.y}}%</span>
    ? ? </div>
    ? </div>
    </div>
    </template>
    
    <script>
    import highcharts from 'highcharts'
    
    export default {
    ? props: {},
    ? data () {
    ? ? return {
    ? ? ? peidata: [
    ? ? ? ? { name: '输电', y: 28, h: 60 },
    ? ? ? ? { name: '变电', y: 20, h: 20 },
    ? ? ? ? { name: '配电', y: 10, h: 32 },
    ? ? ? ? { name: '新业务', y: 6, h: 45 }
    ? ? ? ]
    ? ? }
    ? },
    ? computed: {},
    ? updated () {},
    ? created () {},
    ? mounted () {
    ? ? this.initchart()
    ? ? const that = this
    ? ? window.onresize = function () { that.initchart() }
    ? },
    ? methods: {
    ? ? 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饼图
    ? ? ? const highecharts = this.$refs.container
    ? ? ? highcharts.chart(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: true,
    ? ? ? ? ? ? cursor: 'pointer',
    ? ? ? ? ? ? depth: 35,
    ? ? ? ? ? ? innersize: 180,
    ? ? ? ? ? ? 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']
    ? ? ? ? ? ? ? ]
    ? ? ? ? ? ? }],
    ? ? ? ? ? data: this.peidata
    ? ? ? ? }]
    ? ? ? })
    ? ? }
    ? },
    ? components: {}
    }
    </script>
    
    <style scoped lang="less">
    .com-container{
    ? ? width: 380px;
    ? ? height: 300px;
    ? ? padding-right: 20px;
    }
    .big-box{
    ? ? display: flex;
    ? ? background-image: url('../img/dizuo.png');
    ? ? background-repeat: no-repeat;
    ? ? background-position: 25px 144px;
    ? ? padding-top: 20px;
    }
    .tulibox{
    ? padding-top: 65px;
    ? .tuliboxitem{
    ? ? position: relative;
    ? ? margin: 10px 0;
    ? ? .name{
    ? ? ? font-size: 18px;
    ? ? ? color: #fefeff;
    ? ? ? padding-right: 20px;
    ? ? }
    ? ? .value{
    ? ? ? font-size: 22px;
    ? ? ? color: #0cd2ea;
    ? ? }
    ? }
    ? .tuliboxitem::before{
    ? ? ?content: "";
    ? ? ?position: absolute;
    ? ? ?width: 16px;
    ? ? height: 16px;
    ? ? top: 7px;
    ? ? border-radius: 50%;
    ? ? left: -33px;
    ? }
    ? .tuliboxitem:nth-child(1)::before{
    ? ? ? background-color: #fff600;
    ? }
    ? .tuliboxitem:nth-child(2)::before{
    ? ? ? background-color: #209fed;
    ? }
    ? .tuliboxitem:nth-child(3)::before{
    ? ? ? background-color: #808ec7;
    ? }
    ? .tuliboxitem:nth-child(4)::before{
    ? ? ? background-color: #ee6b26;
    ? }
    }
    </style>