转换入口 (convert.ts)
入口文件 covert.ts 提供了核心方法 convertVChartToSvg,该方法主要承担以下几个重要职责:
-
获取
**stage**信息:通过传入的 vchart 实例对象,调用getStage方法获取到 vrender 的图形场景树stage,这是后续操作的基础。 -
设置视口属性:从
stage中提取视窗信息viewBox,并基于此生成 svg 视窗属性。这些属性定义了 svg 图形的显示区域和大小,确保图形在 svg 环境中能够正确呈现。 -
处理背景:检查
stage的背景信息background,若存在背景,则调用convertCommonStyle方法将其转换为 svg 所需的矩形元素样式。 -
生成 SVG 标签:将处理好的背景矩形元素和
stage子节点转换后的 svg 元素组合起来,生成完整的 svg 标签字符串并返回。
export const convertVChartToSvg = (vchart: any): string => {
// 1. 获取舞台信息
const stage = vchart.getStage();
// 2. 设置视口属性
const viewBox = stage.viewBox;
const attrs = {
width: `${width}px`,
height: `${height}px`,
viewBox: `${x} ${y} ${width} ${height}`,
};
// 3. 处理背景
const background = stage.background;
let backgroundRect = "";
if (background) {
const style = convertCommonStyle({ fill: background }, stage);
// ...
}
// 4. 生成SVG标签
return `<svg version="1.1" xmlns="http://www.w3.org/2000/svg" ...>
${backgroundRect}
${stage.children.map((child: any) => parseGroup(child)).join("")}
</svg>`;
};
图形转换核心 (graphic.ts)
graphic.ts 作为 SVG 转换模块中的核心图形处理文件,肩负着将各种图形元素转换为 SVG 节点的重任。该模块支持多种图形类型的转换,涵盖基础图形(如路径、矩形、圆弧等)和复杂图形group。
组合图形处理
parseGroup 是解析图形的主要入口函数,它通过递归处理子节点类型,逐步生成 svg 元素。具体实现步骤如下:
-
基础检查:首先检查传入的
group对象是否有效,若group不存在或无效,则直接返回空字符串。需要说明的是,stage本身也是一种特殊的group -
属性合并:将
group的主题样式theme?.combinedTheme?.[group.type]和自身属性group.attribute进行合并,确保图形能够继承正确的样式。 -
根据类型处理:当
group的类型为group时,表明这是一个组合图形。此时,先调用convertCommonStyle方法生成通用样式,然后对group的子元素进行排序,排序依据是子元素的zIndex属性(若不存在zIndex,则默认为 0)。排序完成后,递归调用parseGroup方法处理每个子元素,并将结果组合起来,生成最终的组合图形 svg 元素。 -
处理其他类型:若
group不是组合图形类型,也就是简单图元,则调用parseSimpleGraphic方法处理其他类型的图形。
export const parseGroup = (group: any): string => {
// 1. 基础检查
if (!group ||!group.isValid()) {
return "";
}
// 2. 属性合并
const attribute = {
...group.theme?.combinedTheme?.[group.type],
...group.attribute
};
// 3. 根据类型处理
if (group.type === "group") {
// 处理组合图形
const commonStyle = convertCommonStyle(attribute, group);
const children = group.children;
// 排序子元素
children.sort((a: any, b: any) => {
return (a.attribute.zIndex ?? 0) - (b.attribute.zIndex ?? 0);
});
// 生成组合内容
return `<g class="${name}" ${/*...*/}>
${children.map(child => parseGroup(child)).join("")}
</g>`;
}
// 4. 处理其他类型
return parseSimpleGraphic(attribute, group);
};
组合图形处理具备以下几个关键特性:
-
支持主题样式继承:确保组合图形能够继承正确的主题样式,保持整体风格的一致性。
-
维护子元素渲染顺序:通过
zIndex属性对子元素进行排序,保证图形在渲染时的顺序正确,避免出现遮挡等问题。 -
递归处理嵌套结构:能够处理复杂的嵌套组合图形,确保每一层子元素都能正确转换为 svg 元素。
SVG 节点生成器
export const generateSvgNode = ( graphic: any, type: string, style: any, defs: { shadow?: string; pattern?: string; gradient?: string } ): string => { const name = graphic.name; // 处理样式类名 if (name) { style.class = name; } // 生成定义内容 const defContent = generateDefs(defs); // 生成节点字符串 let nodeStr = `${defContent}<${type} ${convertStyleToString(style)} ${defs.shadow? 'filter="url(#' + generateShadowId(graphic) + ')"' : ""} />`; // 处理图案填充 if (defs.pattern) { // ...处理 pattern 相关逻辑 } return nodeStr; };
这个函数是图形节点生成的核心,主要具备以下功能:
-
处理图形名称和样式:将图形的名称应用到样式的类名中,方便在样式表中进行针对性的样式设置。
-
生成渐变、阴影等定义:根据传入的
defs对象,生成渐变、阴影等 SVG 定义内容,为图形添加丰富的视觉效果。 -
支持图案填充:若存在图案填充相关的配置
defs.pattern,则进行相应的处理,使图形能够实现图案填充效果。
基础图形转换
export const parseSimpleGraphic = (attribute: any, group: any) => { // 1. 处理通用样式 const commonStyle = convertCommonStyle(attribute, group); // 2. 生成定义内容 const defs = { gradient: generateGradient(attribute, group), pattern: generatePattern(attribute, group), shadow: generateShadow(attribute, group), }; // 3. 根据图形类型分发处理 if (group.type === "arc") { return generateSvgNode(/*...*/); } if (group.type === "polygon") { return generateSvgNode(/*...*/); } // ... 其他图形类型处理 };
该函数负责处理基础图形的转换工作,支持多种基础图形类型,具体包括:
-
圆弧 (arc)
-
多边形 (polygon)
-
路径 (path)
-
符号 (symbol)
-
文本 (text)
-
富文本 (richtext)
-
线条 (line)
-
区域 (area)
-
矩形 (rect)
通过以上各个部分的协同工作,vchart-svg-plugin 实现了将 vchart 渲染内容高效、准确地转换为 svg 字符串的功能。