Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to encapsulate G2 Chart in vue

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)05/31 Report--

This article introduces the relevant knowledge of "how to encapsulate G2 charts in vue". Many people will encounter this dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Vue package G2 chart 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) {/ / delete the chart if it exists and regenerate 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:''+ this.gtwopiedata.title+'

); this.chart.render (); / / draw label var OFFSET = 20; var APPEND_OFFSET = 50; var LINEHEIGHT = 60; var coord = this.chart.get ('coord'); / / get coordinate system object var center = coord.center / / polar center coordinates var r = coord.radius; / / polar 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.examples;}); 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 (iMurt -) {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; iTunes;});}) / (x-cx) ^ 2 + (y-cy) ^ 2 = total R ^ 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(); // }} #id{ width: 100%; height: 100%; } 本来是想将生成的方法封装到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 构建出各种各样的可交互的统计图表; 线上示例 特性 ???? 完善的图形语法:数据到图形的映射,能够绘制出所有的图表; ???? 全新的交互语法:通过触发和反馈机制可以组合出各种交互行为,对数据进行探索; ???? 强大的 View 模块:可支持开发个性化的数据多维分析图形; ???? 双引擎渲染:Canvas 或 SVG 任意切换; ???? 可视化组件体系:面向交互、体验优雅; ✨全面拥抱 TypeScript:提供完整的类型定义文件; 介绍一下在vue中使用G2 安装G2依赖: npm instal @antv/g2 在绘图前我们需要为 G2 准备一个 DOM 容器: 执行代码: 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(); } } 效果展示:

This is the end of the content of "how to encapsulate G2 Chart in vue". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report