antvis/G2

Do you want to work on this issue?

You can request for a bounty in order to promote it!

官网示例 API 和 Spec 互转 #6420

lxfu1 posted onGitHub

AntV Open Source Contribution Plan(可选)

  • 我同意将这个 Issue 参与 OSCP 计划

Issue 类型

高级任务

任务介绍

提供一个脚本、工具或者浏览器插件,支持官网 API 和 Spec 模式代码互转(API 转 Spec 优先级高)。

API

import { Chart } from '@antv/g2';

const data = [
  { year: '1951 年', sales: 38 },
  { year: '1952 年', sales: 52 },
  { year: '1956 年', sales: 61 },
  { year: '1957 年', sales: 145 },
  { year: '1958 年', sales: 48 },
  { year: '1959 年', sales: 38 },
  { year: '1960 年', sales: 38 },
  { year: '1962 年', sales: 38 },
];

const chart = new Chart({
  container: 'container',
  autoFit: true,
});

chart
  .interval()
  .coordinate({ transform: [{ type: 'transpose' }] })
  .data(data)
  .encode('x', 'year')
  .encode('y', 'sales');

chart.render();

Spec

import { Chart } from "@antv/g2";

const chart = new Chart({ container: "container" });

chart.options({
  type: "interval",
  autoFit: true,
  data: [
    { year: "1951 年", sales: 38 },
    { year: "1952 年", sales: 52 },
    { year: "1956 年", sales: 61 },
    { year: "1957 年", sales: 145 },
    { year: "1958 年", sales: 48 },
    { year: "1959 年", sales: 38 },
    { year: "1960 年", sales: 38 },
    { year: "1962 年", sales: 38 },
  ],
  encode: { x: "year", y: "sales" },
  coordinate: { transform: [{ type: "transpose" }] },
});

chart.render();

参考说明

No response


我想尝试一下,下面是我的技术文档。

项目名称:g2-convert

计划是开发一个浏览器扩展插件,名为 g2-convert,计划是先用于将 AntV G2 图表的 API 模式代码转换为 Spec 模式。下面是我的技术栈选型:

  • Plasmo:作为浏览器扩展的脚手架。
  • SWC:对于转换的代码,我的想法是使用 ast 语法树来实现,其中 swc 是基于 rust 实现的,可以高效解析和转换 JavaScript/TypeScript 代码。
posted by BQXBQX 4 months ago

@BQXBQX 可以的,你可以先想想这个插件的用户是谁?再决定是否要以插件的形式。

我理解这个事情,分成为技术能力 + 工具形态。

  • 技术能力,就是 api2spec, spec2api 的能力,他是一个函数包的存在
  • 工具形态,决定这个能力怎么呈现给用户,这个形态由你的用户决定

我感觉,如果面向的是开发者,那么应该 vscode 插件更合适,如果是面向 g2 网站的用户,那浏览器插件是合理的。

posted by hustcc 4 months ago

@BQXBQX 可以的,你可以先想想这个插件的用户是谁?再决定是否要以插件的形式。

我理解这个事情,分成为技术能力 + 工具形态。

  • 技术能力,就是 api2spec, spec2api 的能力,他是一个函数包的存在
  • 工具形态,决定这个能力怎么呈现给用户,这个形态由你的用户决定

我感觉,如果面向的是开发者,那么应该 vscode 插件更合适,如果是面向 g2 网站的用户,那浏览器插件是合理的。

嗯嗯,明白了,我会把核心转换代码抽离出来,并基于实现两套插件,分别是 vscodebrowser,并为后续可能需要扩展的功能提供 API 接口,提高复用性。 谢谢指导 🙏

posted by BQXBQX 4 months ago

项目架构

<img width="700" alt="image" src="https://github.com/user-attachments/assets/3a8cf78b-82d8-48f9-9f0f-613f0eaf3ed5" />

具体细节实现

  1. Dependencies 依赖层选型

    技术选型分析:g2.chart.option vs AST(SWC)

    通过研究官方源码,发现官方案例中 api2spec 的实现是基于 g2.chart.option() 完成的。下面是核心实现代码:

     class Chart extends G2Chart {
         options() {
           if (arguments.length !== 0) return super.options(...arguments);
           const options = super.options();
           const { type, children, key, ...rest } = options;
           const topLevel =
             type === 'view' && Array.isArray(children) && children.length === 1
               ? { ...children[0], ...rest }
               : { type, children, ...rest };
           return sortKeys(topLevel);
         }
         render() {
           // 触发自定义事件
           const event = new CustomEvent('spec', {
             detail: {
               options: this.options(),
             },
           });
           window.dispatchEvent(event);
           return super.render();
         }
       }
       return { ...rest, Chart };

    优势:

    • 更新迭代更加稳定,当 G2 API 设计变更时,只需升级依赖即可。

    • 便于扩展浏览器端功能,如 graph preview 等特性。

    • 局限性:*

    • g2.chart.option() 不具备 spec2api 的转换能力。

    • 最终方案:*

    • 同时采用 g2.chart.option()AST(SWC) 两种实现。

    • api2spec:默认使用 g2.chart.option(),同时提供 AST(SWC) 转换能力。

    • spec2api:完全由 AST(SWC) 实现。

  2. vscode 插件交互

    将会实现以下两种交互方式:

    • 右键菜单操作
      • 场景:用户在代码文件或选定的代码片段上右键。
      • 功能:在右键菜单中提供 "Convert to Spec" 或 "Convert to API" 的选项。
      • 实现:通过 VSCode 的 context menu 注册相应的命令,根据光标选中内容进行转换
    • 命令面板操作
      • 场景:用户在 VSCode 中打开命令面板 (Cmd + Shift + P / Ctrl + Shift + P)。
      • 功能:提供两个命令:
        • G2: Convert to Spec Mode
        • G2: Convert to API Mode
      • 实现:用户输入命令后插件对当前选中代码或整个文件执行转换。
  3. 浏览器插件 UI

    下面是浏览器插件的 UI 视觉设计稿

    <img width="651" alt="image" src="https://github.com/user-attachments/assets/c8ef1ca7-042e-4d4d-9d82-b1bd184869c1" />

    <img width="1425" alt="image" src="https://github.com/user-attachments/assets/c58e6b2b-4ada-4bab-9395-47596fef5616" />

  4. 安全性问题

    • 问题描述:

      在使用 g2.chart.option() 方法以实现依赖层时,常常需要在前端动态执行 G2 代码。这种情况下,如果不加以控制,可能会引发代码注入攻击。代码注入攻击可能会导致恶意代码在用户的浏览器中被执行,从而带来安全风险。

    • 解决方法

      可以在代码执行之前使用抽象语法树(AST)解析工具(如 SWC)来动态解析和检查字符串代码。通过这种方式,我们仅保留与 G2 相关的代码,将其他可能存在风险的代码过滤出去。这样做不仅提高了代码的安全性,还确保了仅有合法的操作被执行。

posted by BQXBQX 4 months ago

项目仓库

https://github.com/BQXBQX/G2-convert

目前实现功能

  • api2spec
  • spec2api
  • chrome extension

https://github.com/user-attachments/assets/c7ea9754-2421-4475-bc71-592287e5656b

roadmap

  • 增加单元测试数量,提高转换完成度
  • api2spec 依靠 chart.options runtime 能力,所以需要支持更多依赖,例如 d3-geo-projectiontopojson
  • spec2api 支持 children 模块,实现 spaceLayer 等转换能力
  • 实现 vscode 相关插件
  • 上线 google web store
posted by BQXBQX 4 months ago

有没有统计过转换准确度(goodcase / 全量 G2 示例)?

posted by lxfu1 2 months ago

有没有统计过转换准确度(goodcase / 全量 G2 示例)?

还没有,我来补充一下,目前 api to spec 是仿照官网源码基于 chart.options 实现的,准确度应该较高,spec to api 能力基于是 ast 解析能力实现,还不够健全,需要补充边缘情况。

posted by BQXBQX about 2 months ago

Fund this Issue

$0.00
Funded
Only logged in users can fund an issue

Pull requests