初入图形绘制框架 JointJS
Graph & Paper
Paper 是渲染我们提供的数据的,表示的是视图层(View)。数据和逻辑在 Graph 中操作,表示的是数据层和控制层(Model & Controller)。
在 Graph 中,有两个基本的图形——Element 和 Link。Element 是我们视图层所看到的可以控制、移动等操作的元素(椭圆、圆形、矩形等);Link 就是链接这些元素的线条。
const graph = new joint.dia.Graph({}, { cellNamespace: joint.shapes });
const paper = new joint.dia.Paper({
el: document.getElementById("myholder"),
model: graph,
width: window.innerWidth - 100,
height: window.innerHeight - 100,
cellViewNamespace: joint.shapes,
gridSize: 10,
drawGrid: true,
background: {
color: "rgba(0, 255, 0, 0.3)"
}
});
以上就创建好了一个 Graph 和 Paper,Paper 就是实际的 HTML 中的一个容器,因此 el
指定一个 div 容器作为 Paper。
JointJS 在 H5 中的效果全都是一组 g 标签,g 下面有 SVG 的基本图形:text、rect、circle 等。
tip:[start]
在 JointJS 中,我们可以把一个图形理解成一个 g 标签,或者说一个容器。容器下面许多的子图形,而我们 define 函数定义的就是一个容器,其下有许多的子图形。
一个图形是由一个 g 包裹起来的,其下面的图形是一个个子图形,一个图形的组成不单是一个矩形,也可以是矩形+圆形等各种复杂的图形组成。
tip:[end]
Cell & Element
在 JointJS 文档的事件一节中,会看到 cell:xxx
、element:xxx
,两种事件,但效果上都是相同的。它们的关系是:
- Cell:
Cell
是 JointJS 中的基本构建块,它是所有图形元素的基类。Cell
代表图形元素的数据模型,它包含了元素的属性和样式信息,但不直接处理渲染或交互逻辑。Cell
可以是Element
(图形元素)或Link
(连接线),因此它是这两者的通用父类。 - Element:
Element
是Cell
的一种特殊类型,代表图形元素,如矩形、圆形、文本框等,可以在图形画布上进行可视化渲染。Element
继承自Cell
,因此具有Cell
的所有属性和方法,同时还有一些特定于图形渲染和交互的属性和方法。Element
对象可以直接添加到图形画布上,并且可以通过编辑和拖拽等交互操作来进行修改。
Cell
是所有图形元素和连接线的通用数据模型,而 Element
是一种特殊类型的 Cell
,用于表示图形元素,具有可视化渲染和交互能力。
举个例子:在一个简单的流程图中,矩形、圆形、箭头等元素都可以通过创建对应的 Element 对象来表示,而这些 Element 对象的数据模型都是 Cell 的实例。这样,你可以将这些元素添加到 JointJS 图形画布上,并进行相应的渲染和交互操作。
上手体验
- 创建第一个矩形。
- 通过
rect1.clone()
克隆一个矩形。 - 通过
graph.addCells
添加这些图形到 Graph 中,也可以通过图形的addTo
函数添加到 Graph 中。
const rect1 = new joint.shapes.standard.Rectangle();
rect1.position(100, 30);
rect1.resize(100, 40);
rect1.attr({
body: {
fill: "blue"
},
label: {
text: "Hello",
fill: "white"
}
});
// rect.addTo(graph);
const rect2 = rect1.clone();
rect2.translate(300, 0);
rect2.attr("label/text", "World!");
// rect.addTo(graph);
const link = new joint.shapes.standard.Link();
link.source(rect1);
link.target(rect2);
graph.addCells(rect1, rect2, link);
多个 Paper
多个 Paper 可以与一个 Graph 关联,Graph 发生变化之后可以与之关联的多个 Paper 同时渲染结果。创建一个主 Paper 和一个缩略 Paper,Graph 关联多个 Paper:
const graph = new joint.dia.Graph({}, { cellNamespace: joint.shapes });
const mainPaper = new joint.dia.Paper({
el: mainPaperEl,
model: graph,
width: document.documentElement.clientWidth,
height: document.documentElement.clientHeight,
cellViewNamespace: joint.shapes,
gridSize: 10,
drawGrid: true,
background: {
color: "rgba(0, 255, 0, 0.3)"
}
});
const viewPaper = new joint.dia.Paper({
el: viewPaperEl,
model: graph,
width: document.documentElement.clientWidth / 4,
height: document.documentElement.clientHeight / 4,
gridSize: 1,
interactive: false,
cellViewNamespace: joint.shapes
});
因此,需要两个 div 容器装着两个视图:
<div class="content">
<div class="paper" id="paper-multiple-papers"></div>
<div class="paper" id="paper-multiple-papers-small"></div>
</div>
拖动主要的视图中的图形,同时会反馈到右下角的 mini 视图: