SVG(可缩放矢量图形)是A2UI框架中用于创建高质量矢量图形的重要组件。本专辑将全面介绍SVGPaper组件的使用、SVG形状类型、连接线系统、样式配置以及实际应用案例。

📋 目录
- [SVGPaper 组件概述](#SVGPaper 组件概述 "#svgpaper-%E7%BB%84%E4%BB%B6%E6%A6%82%E8%BF%B0")
- 快速入门
- [SVG 形状类型大全](#SVG 形状类型大全 "#svg-%E5%BD%A2%E7%8A%B6%E7%B1%BB%E5%9E%8B%E5%A4%A7%E5%85%A8")
- 连接线系统
- 样式与渐变
- 实际应用案例
- [API 参考](#API 参考 "#api-%E5%8F%82%E8%80%83")
- 最佳实践
- 常见问题
SVGPaper 组件概述
SVGPaper 是 A2UI 框架中专门用于绘制和管理 SVG 矢量图形的组件。它继承自 Div 组件,提供了丰富的图形创建、编辑和交互功能。
核心特性
- 矢量图形绘制:支持多种预定义形状和自定义路径
- 流程图支持:专门的流程图形状和连接线系统
- 交互支持:点击、悬停、拖拽等交互事件
- 样式配置:丰富的描边、填充、渐变选项
- 响应式设计:自动适应不同屏幕尺寸
- 可访问性:ARIA 属性和键盘导航支持
技术架构
SVGPaper 基于以下技术构建:
- Raphaël SVG 库:轻量级、跨浏览器的 SVG 库
- A2UI 组件体系:标准的 UI 组件生命周期和事件系统
- CSS 变量主题:支持主题切换和自定义样式
快速入门
1. 创建 SVG 画布
html
<!-- 引入核心库和SVGPaper组件 -->
<script type="text/javascript" src="ood/ood.js"></script>
<script type="text/javascript" src="ood/UI/SVGPaper.js"></script>
<!-- 创建画布容器 -->
<div id="svg-container"></div>
<script>
// 创建 SVGPaper 实例
var svgPaper = ood.UI.SVGPaper({
width: '800px',
height: '600px',
scaleChildren: false,
overflow: undefined,
graphicZIndex: 0
}).appendTo('#svg-container');
// 画布创建完成,可以开始添加图形
</script>
2. 添加基本形状
javascript
// 添加圆形
svgPaper.append(
ood.create("ood.svg.circle")
.setHost(svgPaper, "circle1")
.setSvgTag("Shapes:Circle")
.setAttr({
"KEY":{
"cx": 100,
"cy": 100,
"r": 50,
"fill": "#2196F3",
"stroke": "#1976D2",
"stroke-width": 3
}
})
);
// 添加矩形
svgPaper.append(
ood.create("ood.svg.rect")
.setHost(svgPaper, "rect1")
.setSvgTag("Shapes:Rect")
.setAttr({
"KEY":{
"x": 200,
"y": 80,
"width": 120,
"height": 80,
"fill": "90-#4CAF50-#C8E6C9",
"stroke": "#388E3C",
"stroke-width": 2
}
})
);
3. 添加文本和连接线
javascript
// 添加文本
svgPaper.append(
ood.create("ood.svg.text")
.setHost(svgPaper, "text1")
.setSvgTag("Shapes:Text")
.setAttr({
"KEY":{
"x": 150,
"y": 250,
"text": "SVG 示例",
"fill": "#333333",
"font-size": "20px",
"font-weight": "bold"
}
})
);
// 添加连接线
svgPaper.append(
ood.create("ood.svg.connector")
.setHost(svgPaper, "connector1")
.setSvgTag("Connectors:Straight")
.setAttr({
"KEY":{
"path": "M,100,150L,300,150",
"fill": "none",
"stroke": "#666666",
"stroke-width": 2,
"arrow-start": "classic-wide-long",
"arrow-end": "classic-wide-long"
},
"BG":{
"fill": "none",
"stroke": "#FFFFFF",
"stroke-width": 4
}
})
.setFromObj("circle1")
.setFromPoint("bottom")
.setToObj("rect1")
.setToPoint("left")
);
SVG 形状类型大全
基础形状
| 形状ID | 名称 | 描述 | 关键属性 |
|---|---|---|---|
ood.svg.circle |
圆形 | 标准圆形 | cx, cy, r, fill, stroke |
ood.svg.ellipse |
椭圆 | 椭圆形 | cx, cy, rx, ry |
ood.svg.rect |
矩形 | 矩形 | x, y, width, height |
ood.svg.line |
直线 | 直线段 | x1, y1, x2, y2 |
ood.svg.polygon |
多边形 | 多边形 | points |
ood.svg.polyline |
折线 | 折线 | points |
流程图专用形状
SVGPaper 提供了丰富的流程图形状,每个形状都有特定的用途:
流程控制形状
| 形状类型 | 用途 | 示例 |
|---|---|---|
FlowChart:Process |
处理过程 | 服务器处理 |
FlowChart:Decision |
决策判断 | 条件判断 |
FlowChart:Termination |
终止点 | 流程结束 |
数据形状
| 形状类型 | 用途 | 示例 |
|---|---|---|
FlowChart:Data |
数据 | 数据存储 |
FlowChart:Document |
文档 | 报告文档 |
FlowChart:Database |
数据库 | 数据库系统 |
输入输出形状
| 形状类型 | 用途 | 示例 |
|---|---|---|
FlowChart:ManualInput |
手动输入 | 用户输入 |
FlowChart:Display |
显示 | 结果展示 |
存储形状
| 形状类型 | 用途 | 示例 |
|---|---|---|
FlowChart:StoredData |
存储数据 | 数据缓存 |
FlowChart:InternalStorage |
内部存储 | 内存存储 |
组合形状
组合形状是A2UI中特殊的SVG元素,将图形和文本组合在一起:
ood.svg.rectComb
矩形组合形状,支持渐变填充和文本:
javascript
ood.create("ood.svg.rectComb")
.setAttr({
"KEY":{
"x": 40,
"y": 30,
"width": 90,
"height": 50,
"fill": "90-#5198D3-#A1C8F6",
"stroke": "#004A7F"
},
"TEXT":{
"text": "服务器",
"font-size": "12px",
"fill": "#fff",
"font-weight": "bold"
}
})
ood.svg.pathComb
路径组合形状,用于复杂图形:
javascript
ood.create("ood.svg.pathComb")
.setAttr({
"KEY":{
"fill": "90-#5198D3-#A1C8F6",
"stroke": "#004A7F",
"path": "M,319,85C,310.7157314383532,85,304,71.56854048887718,304,55C,304,38.43145548427702,310.7157178477474,25,319,25M,319,85C,319,85,319,85,319,85C,310.7157314383532,85,304,71.56854048887718,304,55C,304,38.43145548427702,310.7157178477474,25,319,25M,319,25C,327.2842655415122,25,334,38.43145548427702,334,55C,334,71.56854048887718,327.2842655415122,85,319,85C,319,85,259,85,259,85C,250.7157118074781,85,244,71.56854048887718,244,55C,244,38.43145548427702,250.7157118074781,25,259,25C,259,25,319,25,319,25"
},
"TEXT":{
"text": "网关",
"font-size": "12px",
"fill": "#fff",
"font-weight": "bold"
}
})
ood.svg.circleComb
圆形组合形状:
javascript
ood.create("ood.svg.circleComb")
.setAttr({
"KEY":{
"cx": 504,
"cy": 55,
"r": 40,
"fill": "90-#5198D3-#A1C8F6",
"stroke": "#004A7F"
},
"TEXT":{
"text": "传感器",
"font-size": "12px",
"fill": "#fff",
"font-weight": "bold"
}
})
连接线系统
连接线是流程图和图表中连接不同元素的纽带。A2UI 提供了强大的连接线系统,支持自动路径计算和智能连接。
连接线类型
1. 直线连接线 (Connectors:Straight)
最简单的连接线类型,两点之间直接连接:
javascript
ood.create("ood.svg.connector")
.setSvgTag("Connectors:Straight")
.setAttr({
"KEY":{
"path": "M,100,100L,300,200",
"fill": "none",
"stroke": "#228B22",
"stroke-width": 2,
"arrow-start": "oval-midium-midium",
"arrow-end": "classic-wide-long"
},
"BG":{
"fill": "none",
"stroke": "#FFFFFF",
"stroke-width": 4
}
})
.setFromObj("shape1")
.setFromPoint("right")
.setToObj("shape2")
.setToPoint("left")
2. 贝塞尔曲线连接线 (Connectors:Bezier)
平滑的曲线连接,适合避免交叉的情况:
javascript
ood.create("ood.svg.connector")
.setSvgTag("Connectors:Bezier")
.setAttr({
"KEY":{
"path": "M,100,100C,150,50,250,250,300,200",
"fill": "none",
"stroke": "#FF5722",
"stroke-width": 2
}
})
3. 流程图连接线 (Connectors:flowchart)
带拐角的连接线,典型的流程图风格:
javascript
ood.create("ood.svg.connector")
.setSvgTag("Connectors:flowchart")
.setAttr({
"KEY":{
"path": "M,100,100L,200,100L,200,200L,300,200",
"fill": "none",
"stroke": "#673AB7",
"stroke-width": 2
}
})
连接点系统
连接线可以连接到形状的特定位置:
javascript
// 连接到形状的不同位置
connector.setFromObj("serverRect") // 起始形状
.setFromPoint("right") // 从右侧连接
.setToObj("gatewayPath") // 目标形状
.setToPoint("left"); // 连接到左侧
支持的位置:
"left":左侧"right":右侧"top":顶部"bottom":底部
箭头样式
连接线支持多种箭头样式:
javascript
// 箭头配置示例
"arrow-start": "classic-wide-long" // 起始箭头
"arrow-end": "oval-midium-midium" // 结束箭头
箭头类型:
- classic :经典箭头
classic-narrow-shortclassic-midium-midiumclassic-wide-long
- oval :椭圆形箭头
oval-midium-midium
- diamond:菱形箭头
- triangle:三角形箭头
样式与渐变
基本样式属性
| 属性 | 类型 | 描述 | 示例 |
|---|---|---|---|
fill |
String | 填充颜色或渐变 | "#FF0000", "90-#FF0000-#0000FF" |
stroke |
String | 描边颜色 | "#333333" |
stroke-width |
Number | 描边宽度 | 2 |
stroke-opacity |
Number | 描边透明度 | 0.8 |
fill-opacity |
Number | 填充透明度 | 0.5 |
opacity |
Number | 整体透明度 | 0.9 |
渐变填充
A2UI 支持多种渐变类型:
1. 线性渐变
javascript
"fill": "90-#5198D3-#A1C8F6"
- 格式:
"角度-起始颜色-结束颜色" - 角度:0-360,0°为从上到下,90°为从左到右
2. 径向渐变
javascript
"fill": "r-#FF0000-#FFFFFF"
- 格式:
"r-起始颜色-结束颜色"
3. 多色渐变
javascript
"fill": "90-#FF0000-#00FF00-#0000FF"
- 支持多个颜色节点
样式应用示例
javascript
// 渐变矩形
var gradientRect = ood.create("ood.svg.rectComb")
.setAttr({
"KEY":{
"x": 100,
"y": 100,
"width": 200,
"height": 100,
"fill": "45-#FF6B6B-#4ECDC4", // 45°线性渐变
"stroke": "#2D3436",
"stroke-width": 3,
"stroke-dasharray": "5,5", // 虚线描边
"rx": 10, // 圆角半径
"ry": 10
},
"TEXT":{
"text": "渐变样式示例",
"font-size": "16px",
"fill": "#FFFFFF",
"font-weight": "bold",
"text-anchor": "middle",
"dy": "0.35em" // 垂直居中调整
}
});
// 添加阴影效果
gradientRect.on("mouseover", function() {
this.attr({
"filter": "url(#shadow)" // SVG滤镜阴影
});
});
gradientRect.on("mouseout", function() {
this.attr({
"filter": "none"
});
});
实际应用案例
案例1:物联网系统架构图
基于用户提供的示例,创建一个完整的物联网系统架构图:
javascript
// 创建物联网系统架构图
function createIoTSystemDiagram(containerId) {
var svgPaper = ood.UI.SVGPaper({
width: '800px',
height: '500px',
scaleChildren: false
}).appendTo(containerId);
// 1. 云服务器
svgPaper.append(
ood.create("ood.svg.rectComb")
.setHost(svgPaper, "cloudServer")
.setSvgTag("FlowChart:Process")
.setAttr({
"KEY":{
"x": 50,
"y": 200,
"width": 120,
"height": 80,
"fill": "90-#4285F4-#8AB4F8",
"stroke": "#1A73E8"
},
"TEXT":{
"text": "云服务器",
"font-size": "14px",
"fill": "#FFFFFF",
"font-weight": "bold"
}
})
);
// 2. 网关设备
svgPaper.append(
ood.create("ood.svg.pathComb")
.setHost(svgPaper, "gateway")
.setSvgTag("FlowChart:DirectData")
.setAttr({
"KEY":{
"fill": "90-#34A853-#81C995",
"stroke": "#1E8E3E",
"path": "M,250,200C,240,200,230,180,230,160C,230,140,240,120,250,120C,250,120,350,120,350,120C,358,120,360,140,360,160C,360,180,358,200,350,200C,350,200,250,200,250,200"
},
"TEXT":{
"text": "智能网关",
"font-size": "14px",
"fill": "#FFFFFF",
"font-weight": "bold"
}
})
);
// 3. 传感器节点
svgPaper.append(
ood.create("ood.svg.circleComb")
.setHost(svgPaper, "sensor")
.setSvgTag("FlowChart:OnPageRefrence")
.setAttr({
"KEY":{
"cx": 550,
"cy": 160,
"r": 60,
"fill": "r-#FBBC05-#FDE293",
"stroke": "#F9AB00"
},
"TEXT":{
"text": "温湿度传感器",
"font-size": "12px",
"fill": "#333333",
"font-weight": "bold"
}
})
);
// 4. 连接线
svgPaper.append(
ood.create("ood.svg.connector")
.setHost(svgPaper, "conn1")
.setSvgTag("Connectors:Straight")
.setAttr({
"KEY":{
"path": "M,170,240L,230,240",
"fill": "none",
"stroke": "#666666",
"stroke-width": 2,
"arrow-end": "classic-wide-long"
}
})
.setFromObj("cloudServer")
.setFromPoint("right")
.setToObj("gateway")
.setToPoint("left")
);
svgPaper.append(
ood.create("ood.svg.connector")
.setHost(svgPaper, "conn2")
.setSvgTag("Connectors:Straight")
.setAttr({
"KEY":{
"path": "M,350,240L,490,240",
"fill": "none",
"stroke": "#666666",
"stroke-width": 2,
"arrow-end": "classic-wide-long"
}
})
.setFromObj("gateway")
.setFromPoint("right")
.setToObj("sensor")
.setToPoint("left")
);
return svgPaper;
}
// 使用示例
var iotDiagram = createIoTSystemDiagram("#diagram-container");
案例2:业务流程管理图
javascript
// 创建订单处理流程图
function createOrderProcessDiagram(containerId) {
var svgPaper = ood.UI.SVGPaper({
width: '1000px',
height: '600px'
}).appendTo(containerId);
var shapes = [];
// 订单接收
shapes.push(svgPaper.append(
ood.create("ood.svg.rectComb")
.setHost(svgPaper, "orderReceive")
.setSvgTag("FlowChart:Process")
.setAttr({
"KEY":{
"x": 100,
"y": 100,
"width": 150,
"height": 60,
"fill": "90-#2196F3-#64B5F6",
"stroke": "#1976D2"
},
"TEXT":{
"text": "订单接收",
"font-size": "14px",
"fill": "#FFFFFF"
}
})
));
// 库存检查(决策)
shapes.push(svgPaper.append(
ood.create("ood.svg.pathComb")
.setHost(svgPaper, "inventoryCheck")
.setSvgTag("FlowChart:Decision")
.setAttr({
"KEY":{
"fill": "90-#FF9800-#FFB74D",
"stroke": "#F57C00",
"path": "M,300,100L,400,160L,300,220L,200,160Z"
},
"TEXT":{
"text": "库存检查",
"font-size": "12px",
"fill": "#FFFFFF"
}
})
));
// 更多流程节点...
// 连接所有节点
for (var i = 0; i < shapes.length - 1; i++) {
svgPaper.append(
ood.create("ood.svg.connector")
.setSvgTag("Connectors:Straight")
.setAttr({
"KEY":{
"path": "M," + (shapes[i].getBBox().x + shapes[i].getBBox().width) + "," + (shapes[i].getBBox().y + shapes[i].getBBox().height/2) +
"L," + (shapes[i+1].getBBox().x) + "," + (shapes[i+1].getBBox().y + shapes[i+1].getBBox().height/2),
"fill": "none",
"stroke": "#666666",
"stroke-width": 2,
"arrow-end": "classic-wide-long"
}
})
.setFromObj(shapes[i].alias)
.setFromPoint("right")
.setToObj(shapes[i+1].alias)
.setToPoint("left")
);
}
return svgPaper;
}
案例3:组织结构图
javascript
// 创建公司组织结构图
function createOrgChart(containerId, orgData) {
var svgPaper = ood.UI.SVGPaper({
width: '1200px',
height: '800px'
}).appendTo(containerId);
// 按层级布局节点
var levelPositions = {};
// 遍历组织数据,创建节点
orgData.forEach(function(dept, index) {
var level = dept.level || 0;
var position = levelPositions[level] || {x: 100, y: 100 + level * 150};
var shape = ood.create("ood.svg.rectComb")
.setHost(svgPaper, "dept_" + dept.id)
.setSvgTag("FlowChart:Document")
.setAttr({
"KEY":{
"x": position.x,
"y": position.y,
"width": 180,
"height": 80,
"fill": getDeptColor(dept.type),
"stroke": "#333333",
"rx": 8,
"ry": 8
},
"TEXT":{
"text": dept.name + "\n" + (dept.manager || ""),
"font-size": "12px",
"fill": "#FFFFFF",
"text-anchor": "middle"
}
});
svgPaper.append(shape);
// 更新位置
levelPositions[level] = {
x: position.x + 220,
y: position.y
};
// 连接到上级部门
if (dept.parentId) {
svgPaper.append(
ood.create("ood.svg.connector")
.setSvgTag("Connectors:Straight")
.setAttr({
"KEY":{
"path": calculateOrgPath(dept.parentId, dept.id),
"fill": "none",
"stroke": "#999999",
"stroke-width": 2
}
})
.setFromObj("dept_" + dept.parentId)
.setFromPoint("bottom")
.setToObj("dept_" + dept.id)
.setToPoint("top")
);
}
});
return svgPaper;
}
// 辅助函数
function getDeptColor(deptType) {
var colors = {
"executive": "90-#D32F2F-#F44336",
"management": "90-#1976D2-#2196F3",
"technical": "90-#388E3C-#4CAF50",
"support": "90-#F57C00-#FF9800"
};
return colors[deptType] || "90-#607D8B-#90A4AE";
}
原始示例代码深度分析
以下是您提供的原始物联网系统流程图代码的详细分析,展示了A2UI中SVG的核心用法:
代码结构解析
javascript
// 1. 创建SVG画布并添加到FormLayout中
host.xui_ui_formlayout1.append(
ood.create("ood.UI.SVGPaper")
.setHost(host,"xui_ui_svgpaper7")
.setLeft("0em")
.setTop("0em")
.setWidth("61.416666666666664em")
.setHeight("9.333333333333334em"),
"A1"
);
关键点:
ood.create("ood.UI.SVGPaper"):创建SVGPaper组件实例.setHost(host,"xui_ui_svgpaper7"):设置宿主和唯一标识符.setWidth()/.setHeight():使用em单位实现响应式设计"A1":布局位置标识符
2. 创建流程图节点
javascript
// 服务器节点(矩形)
host.xui_ui_svgpaper7.append(
ood.create("ood.svg.rectComb")
.setHost(host,"xui_svg_rectcomb1")
.setSvgTag("FlowChart:Process")
.setAttr({
"KEY":{
"x":40,
"y":30,
"width":90,
"height":50,
"fill":"90-#5198D3-#A1C8F6",
"stroke":"#004A7F"
},
"TEXT":{
"text":"服务器",
"font-size":"12px",
"fill":"#fff",
"font-weight":"bold"
}
})
);
技术细节:
ood.svg.rectComb:矩形组合形状类FlowChart:Process:流程图处理节点类型- 渐变填充:
"90-#5198D3-#A1C8F6"(90°线性渐变) - 文本配置:白色粗体,12px大小
3. 创建网关节点(路径形状)
javascript
host.xui_ui_svgpaper7.append(
ood.create("ood.svg.pathComb")
.setHost(host,"xui_svg_pathcomb49")
.setSvgTag("FlowChart:DirectData")
.setAttr({
"KEY":{
"fill":"90-#5198D3-#A1C8F6",
"stroke":"#004A7F",
"path":"M,319,85C,310.7157314383532,85,304,71.56854048887718,304,55C,304,38.43145548427702,310.7157178477474,25,319,25M,319,85C,319,85,319,85,319,85C,310.7157314383532,85,304,71.56854048887718,304,55C,304,38.43145548427702,310.7157178477474,25,319,25M,319,25C,319,25,319,25,319,25C,327.2842655415122,25,334,38.43145548427702,334,55C,334,71.56854048887718,327.2842655415122,85,319,85C,319,85,259,85,259,85C,250.7157118074781,85,244,71.56854048887718,244,55C,244,38.43145548427702,250.7157118074781,25,259,25C,259,25,319,25,319,25"
},
"TEXT":{
"text":"网关",
"font-size":"12px",
"fill":"#fff",
"font-weight":"bold"
}
})
);
路径语法解析:
M:移动到起点 (319,85)C:三次贝塞尔曲线到目标点- 控制点计算确保平滑过渡
- 复杂路径实现专业的流程图符号
4. 传感器节点(圆形)
javascript
host.xui_ui_svgpaper7.append(
ood.create("ood.svg.circleComb")
.setHost(host,"xui_svg_circlecomb1")
.setSvgTag("FlowChart:OnPageRefrence")
.setAttr({
"KEY":{
"cx":504,
"cy":55,
"r":40,
"fill":"90-#5198D3-#A1C8F6",
"stroke":"#004A7F"
},
"TEXT":{
"text":"传感器",
"font-size":"12px",
"fill":"#fff",
"font-weight":"bold"
}
})
);
圆形属性:
cx,cy:圆心坐标,精确定位r:半径大小FlowChart:OnPageRefrence:页面引用类型
5. 智能连接线系统
javascript
// 服务器 → 网关连接线
host.xui_ui_svgpaper7.append(
ood.create("ood.svg.connector")
.setHost(host,"xui_svg_connector19")
.setSvgTag("Connectors:Straight")
.setAttr({
"KEY":{
"path":"M,130,55L,244,55",
"fill":"#B6E026",
"stroke":"#228B22",
"stroke-width":2,
"arrow-start":"oval-midium-midium",
"arrow-end":"classic-wide-long"
},
"BG":{
"fill":"none",
"stroke":"#fff",
"stroke-width":4
}
})
.setFromObj("xui_svg_rectcomb1")
.setFromPoint("right")
.setToObj("xui_svg_pathcomb49")
.setToPoint("left")
);
连接线高级特性:
- 双箭头系统:起始箭头+结束箭头
BG层:白色背景描边,增强可读性- 自动路径计算:基于形状位置
- 智能连接点:
right→left自然流向
设计模式总结
-
分层架构
- SVGPaper(画布层)
- 形状组合(图形层)
- 连接线系统(关系层)
- 文本标注(信息层)
-
样式系统
- 一致性:相同渐变和描边
- 可读性:对比色和适当大小
- 专业性:标准流程图符号
-
交互设计
- 逻辑连接:服务器→网关→传感器
- 视觉引导:箭头方向和路径
- 信息层次:标题和位置
扩展建议
- 动态数据绑定:将节点数据与后端API连接
- 交互增强:添加拖拽、缩放、选择功能
- 主题系统:支持暗色/亮色主题切换
- 导出功能:支持PNG、PDF、SVG格式导出
这个示例展示了A2UI SVG系统的强大功能,从基础形状创建到复杂的流程图构建,为各种数据可视化和图表应用提供了完整的解决方案。
API 参考
SVGPaper 类
构造函数
javascript
new ood.UI.SVGPaper(config)
配置选项
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
width |
String/Object | '32em' |
画布宽度 |
height |
String/Object | '25em' |
画布高度 |
scaleChildren |
Boolean | false |
是否缩放子元素 |
overflow |
String | undefined |
溢出处理 |
graphicZIndex |
Number | 0 |
图形层级 |
实例方法
append(shape)
添加SVG形状到画布。
参数:
shape(Object): SVG形状对象
返回:
- (Object): SVGPaper实例
removeChildren()
移除所有子元素。
返回:
- (Object): SVGPaper实例
getPaper()
获取底层的Raphaël paper对象。
返回:
- (Object): Raphaël paper实例
getSVGString()
获取SVG内容的字符串表示。
返回:
- (String): SVG字符串
setChildren(shapes)
替换所有子元素。
参数:
shapes(Array): 形状对象数组
返回:
- (Object): SVGPaper实例
形状创建 API
ood.create(type)
创建指定类型的SVG形状。
参数:
type(String): 形状类型标识符
返回:
- (Object): 形状实例
常用形状类型
"ood.svg.circle":圆形"ood.svg.rect":矩形"ood.svg.rectComb":矩形组合"ood.svg.pathComb":路径组合"ood.svg.circleComb":圆形组合"ood.svg.connector":连接线
形状配置方法
setHost(host, alias)
设置宿主和别名。
参数:
host(Object): 宿主对象alias(String): 形状别名
返回:
- (Object): 形状实例
setSvgTag(tag)
设置SVG标签类型。
参数:
tag(String): SVG标签标识符
返回:
- (Object): 形状实例
setAttr(attributes)
设置形状属性。
参数:
attributes(Object): 属性对象
返回:
- (Object): 形状实例
连接线配置方法
setFromObj(objAlias)
设置起始形状。
参数:
objAlias(String): 起始形状别名
返回:
- (Object): 连接线实例
setFromPoint(point)
设置起始连接点。
参数:
point(String): 连接点位置(left/right/top/bottom)
返回:
- (Object): 连接线实例
setToObj(objAlias)
设置目标形状。
参数:
objAlias(String): 目标形状别名
返回:
- (Object): 连接线实例
setToPoint(point)
设置目标连接点。
参数:
point(String): 连接点位置(left/right/top/bottom)
返回:
- (Object): 连接线实例
最佳实践
1. 性能优化
批量操作:
javascript
// 不推荐:单独添加每个形状
shapes.forEach(function(shape) {
svgPaper.append(shape);
});
// 推荐:批量添加
svgPaper.setChildren(shapes);
图形复用:
javascript
// 创建模板形状
var templateShape = ood.create("ood.svg.rectComb")
.setAttr({ /* 基础配置 */ });
// 批量创建相似形状
var shapes = data.map(function(item, index) {
return templateShape.clone()
.setHost(svgPaper, "shape_" + index)
.setAttr({
"KEY":{
"x": index * 120,
"y": 100
},
"TEXT":{
"text": item.name
}
});
});
2. 可维护性
模块化设计:
javascript
// 形状工厂
var ShapeFactory = {
createServerNode: function(x, y, name) {
return ood.create("ood.svg.rectComb")
.setSvgTag("FlowChart:Process")
.setAttr({
"KEY":{
"x": x,
"y": y,
"width": 120,
"height": 60,
"fill": "90-#4285F4-#8AB4F8"
},
"TEXT":{
"text": name,
"fill": "#FFFFFF"
}
});
},
createDecisionNode: function(x, y, name) {
return ood.create("ood.svg.pathComb")
.setSvgTag("FlowChart:Decision")
.setAttr({ /* 配置 */ });
}
};
配置集中管理:
javascript
// 样式配置
var StyleConfig = {
colors: {
primary: "90-#4285F4-#8AB4F8",
success: "90-#34A853-#81C995",
warning: "90-#FBBC05-#FDE293",
danger: "90-#EA4335-#F28B82"
},
sizes: {
node: { width: 120, height: 60 },
text: { fontSize: "14px" }
}
};
3. 响应式设计
javascript
// 响应式布局调整
function adjustDiagramLayout(svgPaper, viewportWidth) {
var scale = 1;
if (viewportWidth < 768) {
scale = 0.8;
} else if (viewportWidth < 480) {
scale = 0.6;
}
// 缩放所有形状
svgPaper.each(function(shape) {
shape.attr({
"transform": "scale(" + scale + ")"
});
});
}
// 监听窗口大小变化
window.addEventListener('resize', function() {
adjustDiagramLayout(svgPaper, window.innerWidth);
});
4. 可访问性
javascript
// 增强可访问性
function enhanceAccessibility(svgPaper) {
svgPaper.attr({
"role": "img",
"aria-label": "系统架构图"
});
// 为每个形状添加描述
svgPaper.each(function(shape) {
var text = shape.getAttr("TEXT")?.text || "图形元素";
shape.attr({
"aria-label": text,
"tabindex": "0" // 支持键盘导航
});
});
}
5. 事件处理最佳实践
事件委托模式
javascript
// 为整个画布添加事件委托,而不是为每个形状单独绑定
svgPaper.on("click", ".node-shape", function(event) {
var shape = event.target;
console.log("节点被点击:", shape.alias);
// 高亮显示被点击的节点
shape.attr({
"stroke": "#FF5722",
"stroke-width": 3
});
});
// 添加鼠标悬停效果
svgPaper.on("mouseover", ".node-shape", function(event) {
event.target.attr({
"cursor": "pointer",
"filter": "url(#hover-shadow)"
});
});
svgPaper.on("mouseout", ".node-shape", function(event) {
event.target.attr({
"filter": "none"
});
});
自定义事件系统
javascript
// 创建自定义事件触发器
function createInteractiveShape(svgPaper, config) {
var shape = ood.create(config.type)
.setHost(svgPaper, config.alias)
.setAttr(config.attr);
// 添加自定义事件
shape.on("custom:select", function() {
this.attr({
"fill": "#FFEB3B",
"stroke": "#FF9800"
});
});
shape.on("custom:deselect", function() {
this.attr({
"fill": config.attr.KEY.fill,
"stroke": config.attr.KEY.stroke
});
});
return shape;
}
6. 动画效果应用
平滑过渡动画
javascript
// 创建形状移动动画
function animateShapeMove(shape, targetX, targetY, duration) {
var currentX = shape.attr("x") || shape.attr("cx");
var currentY = shape.attr("y") || shape.attr("cy");
shape.animate({
"x": targetX,
"y": targetY
}, duration, "linear", function() {
console.log("动画完成");
});
}
// 创建连接线流动效果
function createFlowAnimation(connector) {
var path = connector.attr("path");
var length = connector.getTotalLength();
// 创建虚线流动效果
connector.attr({
"stroke-dasharray": "10,5",
"stroke-dashoffset": length
});
connector.animate({
"stroke-dashoffset": 0
}, 2000, "linear", function() {
// 循环动画
connector.attr({
"stroke-dashoffset": length
});
createFlowAnimation(connector);
});
}
交互反馈动画
javascript
// 点击脉冲效果
function createPulseEffect(shape) {
shape.on("click", function() {
var originalStroke = shape.attr("stroke-width");
// 脉冲动画
shape.animate({
"stroke-width": originalStroke * 3
}, 200, ">", function() {
shape.animate({
"stroke-width": originalStroke
}, 300);
});
});
}
// 悬停缩放效果
function createHoverScale(shape) {
shape.on("mouseover", function() {
shape.animate({
"transform": "s1.1"
}, 200);
});
shape.on("mouseout", function() {
shape.animate({
"transform": "s1"
}, 200);
});
}
7. 与其他A2UI组件集成
与MDialog集成创建图形编辑器
javascript
function createSVGEditorDialog() {
var dialog = ood.create("ood.UI.MDialog")
.setTitle("SVG 图形编辑器")
.setWidth("800px")
.setHeight("600px");
// 在对话框中添加SVGPaper
var svgPaper = ood.create("ood.UI.SVGPaper")
.setWidth("100%")
.setHeight("100%");
dialog.append(svgPaper);
// 添加工具栏
var toolbar = ood.create("ood.UI.ToolBar")
.addButton("矩形", function() {
// 创建矩形形状
svgPaper.append(createRectShape());
})
.addButton("圆形", function() {
// 创建圆形形状
svgPaper.append(createCircleShape());
});
dialog.append(toolbar);
return dialog;
}
与MFormLayout集成创建属性编辑器
javascript
function createShapePropertyEditor(shape) {
var form = ood.create("ood.UI.MFormLayout")
.setLabelWidth("100px");
// 添加形状属性编辑控件
form.addItem("x", "位置X", {
type: "textbox",
value: shape.attr("x") || shape.attr("cx"),
onValueChange: function(value) {
shape.attr("x", parseInt(value));
}
});
form.addItem("y", "位置Y", {
type: "textbox",
value: shape.attr("y") || shape.attr("cy"),
onValueChange: function(value) {
shape.attr("y", parseInt(value));
}
});
form.addItem("fill", "填充颜色", {
type: "colorpicker",
value: shape.attr("fill"),
onValueChange: function(value) {
shape.attr("fill", value);
}
});
return form;
}
8. 数据可视化最佳实践
数据绑定模式
javascript
function createDataVisualization(svgPaper, data) {
var maxValue = Math.max.apply(null, data.map(d => d.value));
var barWidth = 40;
var spacing = 20;
data.forEach(function(item, index) {
var barHeight = (item.value / maxValue) * 300;
var x = index * (barWidth + spacing) + 50;
var y = 350 - barHeight;
// 创建数据柱状图
var bar = ood.create("ood.svg.rectComb")
.setHost(svgPaper, "bar_" + index)
.setAttr({
"KEY":{
"x": x,
"y": y,
"width": barWidth,
"height": barHeight,
"fill": getColorByValue(item.value)
},
"TEXT":{
"text": item.label,
"x": x + barWidth/2,
"y": 370,
"text-anchor": "middle",
"font-size": "12px"
}
});
// 添加数值标签
var valueText = ood.create("ood.svg.text")
.setHost(svgPaper, "value_" + index)
.setAttr({
"KEY":{
"x": x + barWidth/2,
"y": y - 10,
"text": item.value,
"text-anchor": "middle",
"font-size": "11px",
"fill": "#333"
}
});
svgPaper.append(bar);
svgPaper.append(valueText);
});
}
function getColorByValue(value) {
if (value > 80) return "90-#FF5252-#FF8A80";
if (value > 60) return "90-#FF9800-#FFCC80";
if (value > 40) return "90-#4CAF50-#A5D6A7";
return "90-#2196F3-#90CAF9";
}
实时数据更新
javascript
// 实时更新数据可视化
function updateDataVisualization(svgPaper, newData) {
// 平滑过渡更新
newData.forEach(function(item, index) {
var bar = svgPaper.getChild("bar_" + index);
if (bar) {
// 计算新的柱状图高度
var maxValue = Math.max.apply(null, newData.map(d => d.value));
var barHeight = (item.value / maxValue) * 300;
var y = 350 - barHeight;
// 动画更新
bar.animate({
"height": barHeight,
"y": y
}, 500);
// 更新数值标签
var valueText = svgPaper.getChild("value_" + index);
if (valueText) {
valueText.animate({
"y": y - 10
}, 500);
valueText.attr({
"text": item.value
});
}
}
});
}
常见问题
1. 图形不显示
可能原因:
- 画布尺寸未正确设置
- 形状坐标超出画布范围
- 样式配置错误
解决方案:
javascript
// 检查画布配置
console.log('画布尺寸:', svgPaper.width(), svgPaper.height());
// 检查形状坐标
shape.attr({
"fill": "#FF0000", // 使用简单颜色测试
"stroke": "#000000"
});
2. 连接线不连接
可能原因:
- 形状别名不正确
- 连接点位置无效
- 路径计算错误
解决方案:
javascript
// 验证形状别名
console.log('起始形状别名:', connector.properties.fromObj);
console.log('目标形状别名:', connector.properties.toObj);
// 检查连接点
console.log('连接点位置:', {
from: connector.properties.fromPoint,
to: connector.properties.toPoint
});
3. 渐变效果不显示
可能原因:
- 渐变格式不正确
- 浏览器不支持
- 颜色值格式错误
解决方案:
javascript
// 使用标准颜色测试
shape.attr({
"fill": "#FF0000" // 替换渐变测试
});
// 检查渐变格式
var gradient = "90-#FF0000-#0000FF";
console.log('渐变格式:', gradient.split('-'));
4. 交互事件不触发
可能原因:
- 事件绑定时机不对
- 事件名不正确
- 形状层级问题
解决方案:
javascript
// 确保在形状渲染后绑定事件
shape.on("click", function() {
console.log('形状被点击');
});
// 检查事件系统
console.log('形状事件监听器:', shape._events);
总结
SVGPaper 是 A2UI 框架中强大的矢量图形组件,为创建复杂的图表、流程图和数据可视化提供了完整的解决方案。通过本专辑的学习,您应该能够:
- 掌握 SVGPaper 的核心功能:创建画布、添加形状、配置样式
- 了解 SVG 形状类型:基础形状、流程图专用形状、组合形状
- 熟练使用连接线系统:直线、曲线、流程图连接线
- 应用高级样式:渐变填充、阴影效果、交互样式
- 构建实际应用:系统架构图、业务流程、组织结构图
下一步建议
- 实践练习:根据本专辑的示例,创建自己的SVG图表
- 探索高级特性:深入研究Raphaël SVG库的高级功能
- 集成数据绑定:将SVG图形与动态数据结合
- 性能优化:对于大规模图形,实施虚拟化和懒加载
- 主题系统:创建可切换的主题样式
相关资源
本专辑基于 A2UI 框架和实际应用案例编写,内容将持续更新和完善。如有任何问题或建议,欢迎提交反馈。
© 2025 A2UI 项目组 | MIT License