文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

在vue中怎么封装G2图表

2023-06-30 11:33

关注

本篇内容介绍了“在vue中怎么封装G2图表”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

vue封装G2图表

<template>    <div id="id"></div></template>
<script>import G2 from '@antv/g2'import { DataSet } from '@antv/data-set'export default {    name: 'pie',    data () {        return {            chart: null        };    },    props:{        gtwopiedata:{            type: Array        },        // gtwopiecolor:{        //     type: Array        // },    },    methods:{        g2pie(){            if(this.chart){     // 如果存在的话就删除图表再重新生成                this.chart.destroy()            }            var startAngle = - Math.PI / 2 - Math.PI / 4;            var data = this.gtwopiedata.data;            var ds = new DataSet();            var dv = ds.createView().source(data);            dv.transform({                type: 'percent',                field: 'value',                dimension: 'type',                as: 'percent'            });            this.chart = new G2.Chart({                container: 'id',                forceFit: true,                height: this.gtwopiedata.height,                padding: 'auto'            });            this.chart.source(dv);            this.chart.legend(false);            this.chart.coord('theta', {                radius: 0.75,                innerRadius: 0.5,                startAngle: startAngle,                endAngle: startAngle + Math.PI * 2            });            this.chart.intervalStack().position('value').color('type', this.gtwopiedata.color).opacity(1).label('percent', {                offset: -20,                textStyle: {                    fill: 'white',                    fontSize: 12,                    shadowBlur: 2,                    shadowColor: 'rgba(0, 0, 0, .45)'                },                formatter: function formatter(val) {                    return parseInt(val * 100) + '%';                }            });            this.chart.guide().html({                position: ['50%', '50%'],                html: '<div class="g2-guide-html"><p class="title">'+this.gtwopiedata.title+'</p></div>'            });            this.chart.render();            //draw label            var OFFSET = 20;            var APPEND_OFFSET = 50;            var LINEHEIGHT = 60;            var coord = this.chart.get('coord'); // 获取坐标系对象            var center = coord.center; // 极坐标圆心坐标            var r = coord.radius; // 极坐标半径            var canvas = this.chart.get('canvas');            var canvasWidth = this.chart.get('width');            var canvasHeight = this.chart.get('height');            var labelGroup = canvas.addGroup();            var labels = [];            // addPieLabel(this.chart);            var halves = [[], []];            var data = dv.rows;            var angle = startAngle;                    for (var i = 0; i < data.length; i++) {                var percent = data[i].percent;                var targetAngle = angle + Math.PI * 2 * percent;                var middleAngle = angle + (targetAngle - angle) / 2;                angle = targetAngle;                var edgePoint = this.getEndPoint(center, middleAngle, r);                var routerPoint = this.getEndPoint(center, middleAngle, r + OFFSET);                //label                var label = {                    _anchor: edgePoint,                    _router: routerPoint,                    _data: data[i],                    x: routerPoint.x,                    y: routerPoint.y,                    r: r + OFFSET,                    fill: '#bfbfbf'                };                // 判断文本的方向                if (edgePoint.x < center.x) {                    label._side = 'left';                    halves[0].push(label);                } else {                    label._side = 'right';                    halves[1].push(label);                }            } // end of for                    var maxCountForOneSide = parseInt(canvasHeight / LINEHEIGHT, 10);            halves.forEach(function(half, index) {                // step 2: reduce labels                if (half.length > maxCountForOneSide) {                    half.sort(function(a, b) {                    return b._percent - a._percent;                    });                    half.splice(maxCountForOneSide, half.length - maxCountForOneSide);                }                            // step 3: distribute position (x and y)                half.sort(function(a, b) {                    return a.y - b.y;                });                // antiCollision(half, index);                var startY = center.y - r - OFFSET - LINEHEIGHT;                var overlapping = true;                var totalH = canvasHeight;                var i = void 0;                            var maxY = 0;                var minY = Number.MIN_VALUE;                var boxes = half.map(function(label) {                    var labelY = label.y;                    if (labelY > maxY) {                    maxY = labelY;                    }                    if (labelY < minY) {                    minY = labelY;                    }                    return {                    size: LINEHEIGHT,                    targets: [labelY - startY]                    };                });                if (maxY - startY > totalH) {                    totalH = maxY - startY;                }                            while (overlapping) {                    boxes.forEach(function(box) {                    var target = (Math.min.apply(minY, box.targets) + Math.max.apply(minY, box.targets)) / 2;                    box.pos = Math.min(Math.max(minY, target - box.size / 2), totalH - box.size);                    });                                // detect overlapping and join boxes                    overlapping = false;                    i = boxes.length;                    while (i--) {                    if (i > 0) {                        var previousBox = boxes[i - 1];                        var box = boxes[i];                        if (previousBox.pos + previousBox.size > box.pos) {                        // overlapping                        previousBox.size += box.size;                        previousBox.targets = previousBox.targets.concat(box.targets);                                    // overflow, shift up                        if (previousBox.pos + previousBox.size > totalH) {                            previousBox.pos = totalH - previousBox.size;                        }                        boxes.splice(i, 1); // removing box                        overlapping = true;                        }                    }                    }                }                            // step 4: normalize y and adjust x                i = 0;                boxes.forEach(function(b) {                    var posInCompositeBox = startY; // middle of the label                    b.targets.forEach(function() {                    half[i].y = b.pos + posInCompositeBox + LINEHEIGHT / 2;                    posInCompositeBox += LINEHEIGHT;                    i++;                    });                });                            // (x - cx)^2 + (y - cy)^2 = totalR^2                half.forEach(function(label) {                    var rPow2 = label.r * label.r;                    var dyPow2 = Math.pow(Math.abs(label.y - center.y), 2);                    if (rPow2 < dyPow2) {                        label.x = center.x;                    } else {                        var dx = Math.sqrt(rPow2 - dyPow2);                        if (!index) {                            // left                            label.x = center.x - dx;                        } else {                            // right                            label.x = center.x + dx;                        }                    }                    // drawLabel(label);                    var _anchor = label._anchor,                    _router = label._router,                    fill = label.fill,                    y = label.y;                                var labelAttrs = {                        y: y,                        fontSize: 12, // 字体大小                        fill: '#808080',                        text: label._data.type + '\n' + label._data.value,                        textBaseline: 'bottom'                    };                    var lastPoint = {                        y: y                    };                                if (label._side === 'left') {                        // 具体文本的位置                        lastPoint.x = APPEND_OFFSET;                        labelAttrs.x = APPEND_OFFSET; // 左侧文本左对齐并贴着画布最左侧边缘                        labelAttrs.textAlign = 'left';                    } else {                        lastPoint.x = canvasWidth - APPEND_OFFSET;                        labelAttrs.x = canvasWidth - APPEND_OFFSET; // 右侧文本右对齐并贴着画布最右侧边缘                        labelAttrs.textAlign = 'right';                    }                                // 绘制文本                    var text = labelGroup.addShape('Text', {                        attrs: labelAttrs                    });                    labels.push(text);                    // 绘制连接线                    var points = void 0;                    if (_router.y !== y) {                        // 文本位置做过调整                        points = [[_anchor.x, _anchor.y], [_router.x, y], [lastPoint.x, lastPoint.y]];                    } else {                        points = [[_anchor.x, _anchor.y], [_router.x, _router.y], [lastPoint.x, lastPoint.y]];                    }                                labelGroup.addShape('polyline', {                        attrs: {                            points: points,                            lineWidth: 1,                            stroke: fill                        }                    });                });            });            canvas.draw();            // this.chart.on('afterpaint', function() {            //   addPieLabel(this.chart);            // });        },        // g2获取饼图点位置        getEndPoint(center, angle, r) {            return {                x: center.x + r * Math.cos(angle),                y: center.y + r * Math.sin(angle)            };        }    },    watch: {        gtwopiedata: function (val, oldVal) {    // 监听数据,当发生变化时,触发回调函数绘制图表,使用mounted无法正常绘制            // if(this.dothisfun){                this.g2pie(val);            //     this.dothisfun = false            // }        }    },    // mounted(){    //     this.g2pie();    // }}</script>
<style scoped>    #id{        width: 100%;        height: 100%;    }</style>

本来是想将生成的方法封装到js文件中的,但是不知道为什么,import G2 进入js文件之后,vue便会卡在92%无法继续热更新,node的cpu占用率也会饱满,所以只好封装在.vue文件中,以子组件的形式被父组件调用。

本处需要注意的第一个问题,即为data中定义的chart,如果不定义,直接用let chart = new G2.chart(),也确实能够正常生成图表,但是当数据更新的时候,便会重新渲染生成新的图表,此时页面上会同时存在多个图表,所以需要提前定义chart,并使用this.chart = new G2.chart()。

本处需要注意的第二个问题,即为使用mounted钩子函数运行此函数时,因为并未检测到数据变化,所以不会生成有效图表,所以需要使用watch监听数据变化,当发生变化的时候,执行方法渲染图表。 

vue引入G2图表

G2 是一套基于图形语法理论的可视化底层引擎,以数据驱动,提供图形语法与交互语法,具有高度的易用性和扩展性。使用 G2,你可以无需关注图表各种繁琐的实现细节,一条语句即可使用 Canvas 或 SVG 构建出各种各样的可交互的统计图表;

线上示例

在vue中怎么封装G2图表

特性

介绍一下在vue中使用G2

安装G2依赖:

npm instal @antv/g2

在绘图前我们需要为 G2 准备一个 DOM 容器:

<div id="c1"></div>

执行代码:

    import * as G2 from '@antv/g2';      export default {    mounted() {           const data = [                { genre: 'Sports', sold: 275 },                { genre: 'Strategy', sold: 115 },                { genre: 'Action', sold: 120 },                { genre: 'Shooter', sold: 350 },                { genre: 'Other', sold: 150 },            ];            // Step 1: 创建 Chart 对象            const chart = new G2.Chart({                container: 'c1', // 指定图表容器 ID                width: 600, // 指定图表宽度                height: 300, // 指定图表高度            });            // Step 2: 载入数据源            chart.data(data);            // Step 3:创建图形语法,绘制柱状图            chart.interval().position('genre*sold');            // Step 4: 渲染图表            chart.render();    }  }

效果展示:

在vue中怎么封装G2图表

“在vue中怎么封装G2图表”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯