Figma图表插件研发总结,让设计师再也无力吐槽

979 阅读9分钟

VChart Figma 插件

上一篇文章:juejin.cn/post/743195… 我们介绍了Figma图表插件的功能,本篇文章,我们重点介绍研发VChart Figma 图表插件的实践心得。

插件地址: www.figma.com/community/p…

研发实践

VChart Figma 插件在实现的过程中遇到了一些麻烦,也有自己产品需求所带来的一些问题。这部分内容里将会根据开发中实际的遇到的问题介绍一些开发过程中做的事情以供借鉴。

整体架构

在介绍 Figma 整体架构的基础之前先介绍一些背景:

  • VChart Figma 插件需要基于 Figma 平台提供的 API 能力实现图表编辑的相关能力,需要考虑通信 & 渲染元素生成等具体功能的适配;

  • VChart Figma 插件需要嵌入到多个已有的容器插件(各家的 Toolbox)中,以支持不同设计体系下设计师的使用。

VChart Figma 插件整体的实现架构可以划分为四个层面:

暂时无法在飞书文档外展示此内容

  • 应用层:将 Figma 图表编辑的相关能力封装到不同应用中,包括 VChart Figma 插件以及各个设计体系的 toolbox 嵌入内容;

  • Figma 编辑:基于图表编辑的通用能力,提供 Figma 插件产品形态下的功能实现,包括 UI 层的 Figma 图表编辑器应用以及 Sandbox 层的 figma 接口;

  • 图表编辑:提供图表编辑的完整能力,包括编辑器元素的渲染 & 更新、数据解析存储以及诸多自定义能力。并且为应用的 UI 部分提供通用的编辑组件;

  • 底层渲染:支持图表以及各种绘图元素的渲染,提供统一的渲染层描述结构。

图表编辑能力

提供多种不同图表的内置模板,支持数据编辑 & 样式配置功能。

图表编辑能力都通过 VChart-Editor 的核心图表编辑库提供支持。

VChart-Editor 的整体架构技术实现(包括渲染、状态管理、数据源等)。在这里主要针对于 VChart Editor 如何解决不同产品中交互形式与图表形式差异进行补充介绍。

自定义图表编辑

12种图表类型,24种内置模板

VChart Figma 插件模板功能:

  • 应用不同主题:为了适配不同设计体系(以及支持后续的主题编辑功能),所有内置模板的 spec 描述应当尽可能简单,以避免主题不兼容的情况(从本质上来讲,图表的主题也就是图表的默认 spec 配置);

  • 自定义模板:为了方便设计师调整完样式之后复用到其他图表的设计中,Figma 插件提供了自定义模板的能力,因此需要以更加灵活的方式描述图表模板;

  • 多种图表类型 & 多种具体模板:更多的图表类型与模板类型意味着 Figma 插件中需要通过更加灵活的方式来对这些内容进行扩展,而不是针对单个模板进行逐一的添加。

针对这些需求,VChart Editor 提供了非常自由的自定义功能,包括图表模板、数据以及编辑的自定义能力。

自定义图表模板

模板描述了 VChart Editor 如何处理一个图表的 spec 配置,如果将数据整合到 spec 中生成渲染的图表描述。

自定义数据解析

数据解析描述了 VChart Editor 如何处理特定格式的图表数据,例如常规的行列数据或者 CSV 数据与剪切板数据等。

自定义编辑模块

编辑模块描述了特定组件的编辑能力,包括一个组件上通常提供的拖拉拽功能以及特定的交互形态,例如添加标注的功能。

Figma 插件中注册了一个新的图表模板与数据解析来支持相应的功能:

  • 自定义 Spec 图表模板:统一处理不同类型的 spec 图表,并兼容相应的数据映射配置;

  • 自定义 Template 数据解析:解析以及存储包含模板描述的数据结构,适配特定的模板功能。

图表配置描述

在 VChart Figma 插件与图表助手小组件中,不同类型的图表提供了各有差异并且数据众多的样式配置。

Figma 插件柱状图样式配置:

Figma 插件饼图样式配置:

图表助手 柱状图样式配置:

样式配置的过程实际上描述了图表编辑的核心过程:控件编辑 -> 图表应用配置更新 -> 状态回显。当然,编辑器还承担了许多其他的功能,例如撤销重做能力、图上交互能力等,但是这一个过程代表着图表编辑器最重要的核心能力。

从 UI 界面上具体的编辑控件到编辑器中更新的逻辑,VChart Figma 插件与图表助手小组件采用了同样的方案:

  • VChart Editor:VChart Editor 负责维护所有实际的编辑器元素的属性 & 更新以及渲染的过程。对于每个编辑器元素(图表、图形等),VChart Editor 向外抛出一个统一的 IEditorElement 结构来描述其中的元素属性,并提供通用的 updateAttribute 接口支持属性的更新;
  • VChart Editor UI:VChart Editor UI 提供公用的配置编辑面板,其中按照配置的内容划分为每一节 section,section 中包含每一个具体的编辑控件 entry。通过 HOC 的方式,可以基于一份编辑器描述 meta 来自动生成相应的功能面板,并根据不同产品中的设计,注册不同样式/不同交互的自定义编辑控件;
  • 应用层面:在 Figma 插件以及图表助手的应用层面实际上只需要维护编辑器的描述 meta 就能将样式配置的功能映射到具体的编辑器样式配置功能。(在具体的 meta 配置中,配置映射的逻辑还需要一些额外的抽象,例如嵌套的配置面板依赖一些统一的配置转换工具函数 transformer,这些业务层面的逻辑都统一收拢在 meta 的相应处理中)

Meta 内容生成:

对应的图表编辑组件:

Figma 适配

统一的渲染描述

在编辑器的渲染中包含多个不同类型的场景元素:基于 VChart 的图表、基于 VTable 的表格以及基于 VRender 的图形/文字内容。

为了承接这些不同类型的渲染,目前 VChart Editor 通过统一的 VStory 描述收拢不同的渲染内容。VStory 中通过一套统一的 DSL 描述覆盖了不同类型的渲染元素,其中每一个元素都是一个单独的 Character:

图表描述:

{
    characterType: 'vchart', // 'Bar' | 'Line' | 'Combo'
    options: {
        // VChart Spec
        spec: IVchartSpec;
        // 标注
        marker?: any;
        // mark单元素样式配置
        markStyle?: any[];
        // 组样式
        dataGroupSpec?: {
          [key: string]: any;
        };
    }
}

表格元素:

{
    characterType: 'vtable',
    options: {
        // VTable Spec
        spec: ITableSpec;
        // 标注
        marker?: any;
        // mark单元素样式配置
        markStyle?: any[];
        // 组样式
        dataGroupSpec?: {
          [key: string]: any;
        };
    }
}

文本描述:

{
    characterType: 'TextComponent',
    options: {
        text: string | textConfig[];
        fill?: string;
        stroke?: string;
        width?: number;
        height?: number;
        ellipsis?: string | boolean;
        wordBreak?: "break-word" | "break-all";
        ...
    }
}

在渲染层面,VStory 将所有渲染内容整理到一个统一的场景树中:

在最终从 VChart Editor 图表到 Figma 插件生成的图表中,插件只需要描述如何将场景树中每种不同类型的图元(Rect、Arc、Line、Path 等)对应转换到 Figma 中的元素,就能通过遍历将场景树转换到最终的 figma 设计稿内容。

编辑器能力嵌入

目前 VChart Figma 插件除了发布本身的插件以外,还提供了 UD toolbox、Arco Toolbox 以及 Semi Toolbox 的嵌入。不同的容器 Toolbox 提供了不同的插件嵌入方式:

  • Arco 插件 嵌入 方案
  • Semi 插件 嵌入 方案

三者的方案本质上相互类似,本质上都是通过 web 端通过 iframe 嵌入编辑器 UI 部分内容 & figma 端引入编辑器 sandbox 代码 来实现的。主要的区别在于两部分:

  • Web 与 Sandbox 通信:Arco & Semi 提供了额外的通信库来封装 web 与 sandbox 的通信过程,semi 通过原生的 postMessage 进行通信;

  • Sandbox 加载:Arco & Semi 会在执行时动态拉取 sandbox 代码交给自己的 figma 端执行,UD 端直接内嵌接入了 action 包。这也就意味着两者的更新模式存在一些区别:

    • UI & sandbox 都动态拉取的情况下,只需要编辑器端重新部署静态资源就可以更新嵌入插件功能,无需重新部署容器插件;
    • 直接引用 action 包依赖的情况下,如果包功能有所调整,则需要更新依赖并且重新部署容器插件。

(横向对比而言,两者方式各有优劣。动态拉取的方案省去了一些版本的更新部署,而引用 action 包的方式能够更方便的自定义插件在 sandbox 端的能力。)

Figma 插件中 Web 应用与 Sandbox 通信的示意图大致如下:

为了适配多个容器嵌入的方案,VChart Figma 插件也同样将编辑器核心功能拆分为 Action 和 UI 包两部分功能:

  • 功能划分:绝大部分功能由 UI 部分承担,Action 只负责执行部分依赖 figma api 的逻辑,例如数据存储 & 元素生成等;

  • Action 接口设计

    • 提供的接口更为通用(实际上非 iframe 形式的 figma 原生应用开发体验比较糟糕,在性能较差的机器上编译时间较长,同时 sandbox 端的代码也难以调试);

    • 支持不同执行时机 & 适配执行次数(由于网络波动,动态加载的时机可能是无法确定的;同时不同的容器对于 sandbox 代码的执行逻辑也存在差异。)

相关文档 & 链接

VChart 插件目前迭代到了第二个版本,后续也将持续努力完善图表编辑的各项功能,提供更加优秀的用户体验。

最后的最后,欢迎各位设计师以及开发者来体验使用 VChart Figma 插件!如果有任何体验上的不满或者功能上的需求也同样欢迎通过插件评论或者在 VChart 反馈群中与我们进行沟通!