2025-04-07
前端可视化
00

目录

学习笔记
核心概念
踩坑
使用技巧
个人感受

曾经用过AntV/g2开发过报表相关项目,当记了一点笔记(个人草稿,不推荐阅读)

吐槽一句, 之前用过Echart 配置项很繁琐,有些细节的配置要找半天,所以这次用了antV,官方声称所谓的渐进式语法函数式编程声明式API看起来很美好,但是要学习它的概念,最重要的还是绕不开繁琐的配置项,踩坑挺多的,毕竟图表太复杂了!

这里只是按照我的理解,记录我的理解、感受及遇到的问题, 推荐还是先认真过一遍 官方文档@antv/g2

学习笔记

  1. 首先需要认真过一下官网, 这是最新版本的文档,重点是了解相关概念。
  2. 接着再看一遍V4版本的文档, 貌似文档是不连续的,v5的文档是基于v4的,当时还v5貌似没放出来,所以用的时V4.2
  3. 另外再补充一下 V2版本的官网,因为在查问题的时候,包括google搜索、问GPT4、github issues 等很多内容都是V2版本的,比较坑

核心概念

G2是一个简介的渐进式语法,主要用于制作基于网页的可视化。它提供一它函数风格式、声明形式的API和组件化的编程规范,希望能帮助用户能快速完成报表搭建的需求

image.png

  • 滚动条 Scrollbar
  • 坐标轴 axis
  • 图例legend : 图表的辅助元素,用于图表中数据的筛选。
  • 提示信息: Tooltip
    • 相关事件tooltip:showtooltip:changetooltip:hide
  • 图形标注 Annotation
  • 滑块 Slider
  • 滚动条 Scrollbar

视图模型:视图区域 > 绘制区域 > 主区域 > 内容区域

tooltip 官方文档

一个复杂案例

js
.tooltip({ title: (d) => d[this.config.xKey], // 标题 items: [(d, index, data, column) => { return { color: COLORS[dataIndexs.indexOf(d.name)], name: d.name, value: d.count, }; }], // 数据项 })

还有更高级的自定义模版

js
.interaction('tooltip', { // render 回调方法返回一个innerHTML 或者 DOM render: (event, { title, items }) => `<div> <h4 style="padding:0 0 4px;margin:0;font-weight: normal;color: #999">${title}</h4> <ul style="list-style: none;padding: 0;margin:0"> <li style="display:flex;align-items: center;"> <span style="background-color: ${items[1].color};height:10px;width:10px;display:inline-block;border-radius:50%"></span> &nbsp;${this.config.y1Title}&emsp;&emsp;${items[1].value} </li> <li style="display:flex;align-items: center;"> <span style="background-color: ${items[0].color};height:10px;width:10px;display:inline-block;border-radius:50%"></span> &nbsp;${this.config.y2Title}&emsp;&emsp;${items[0].value * 100}% </li> </ul> </div>`, })

legend

当只有单一指标是不显示图例的,

当有多个指标(分组柱状图、分组折线图)会展示图例

图例的配置

js
.legend('size', { // ... })

图例踩坑

  1. 无法跟坐标轴右对齐

网上说 v3 v4版本可以设置offsetX解决,v5(我使用的版本)是 transfrom 原文 然后我试了并没有卵用,

我想到自己绘制图例,由于图例和图表有checkbox效果,这条路太费劲

我又想到自定义图例

  1. 自定义的图例文字与图标不能上下对齐

可参考这个案例

js
.legend({ color: { transform: 'translate(100, 0)', itemMarker: (_, index) => () => { const { document } = chart.getContext().canvas; const image = document.createElement('image', { style: { width: 20, height: 20, anchor: '0.5 0.5', src: logo[index][1], }, }); return image; }, itemMarkerSize: 40, itemLabelText: (_, index) => logo[index][0], }, })

官方将图例分成两块 图片+ 文字,itemMarker方法里只支持创建image,由于图片和文字无法上下对齐(左右可以调,我偷懒不做demo了),那么图例就不能放在右上角了

我提了一种居中方案, UI 比较纠结, 还的折腾

js
.legend('color', { layout: { // 当该值为对象时,是flex布局 justContent: 'center', flexDirection: 'column', }, })

最后将antV版本从5.1.15 升级到 5.1.19,在显示y轴文字的情况下勉强对齐了

  1. 滚动条与图例的冲突

分组柱状图、分组折线图会展示图例,当X轴太长是须展示滚动条,当拖动滚动调试图例发生抖动(往上移动了)

解决方案 容器追加样式

js
new G2.Chart({ paddingTop: 50, paddingBottom: 10, marginTop: 10, })

其实还有个问题, X轴和滚动条之间间距太大, 实在没有办法了

踩坑

  1. 网上很多v2版本的解决方案,与v4不兼容
  2. 分组柱状图,柱子之间间距控制 无法控制, 通过设置滚动条解决
  3. 滚动条不支持样式自定义,好在 默认效果,UI接受了
  4. 没有分组(指标=坐标轴数量)时不显示图例,有分组才显示图例
  5. 同时渲染多个相同的图表,滚动条可能无法滚动,解决方案串行渲染
    • 后来发现同时渲染不同的方法也会出问题,我写了一个队列异步渲染的方法
js
const queue = []; let isFlushPending = false; async function queueFlush() { if (!isFlushPending) { isFlushPending = true; await sleep(0); for (const it of queue) { it.cb(); await sleep(it.ms); } queue.length = 0; isFlushPending = false; } } /** * 因 antV 同时渲染多张图表时 可能会存在问题 * 因此每渲染一张图表要等待一定时间再渲染下一张图表 */ export function queuePostFlushCb(cb, ms = 0) { queue.push({ cb, ms }); queueFlush(); } // 使用 queuePostFlushCb(() => { // todo 渲染图表 }, 100/*渲染时间间隔*/)

使用技巧

  1. 注折混合图, 在同一个图层 多次渲染 得到 柱状图 + 折线图
  2. 滚动轴,需要动态计算轴的占比

个人感受

  1. ant的函数式编程语法写出的代码相对而言比Echart好一些
  2. ant内部却是做了很多事情,比如图例的颜色、换行展示等,它的目标是让开发者更少的配置,但是带来的问题是如果UI有高度自定义的效果实现起来比较困难。

本文作者:郭郭同学

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.14.8