问题背景
在工作中有个需求需要画一幅“树图”,本想使用echarts进行绘制的。奈何echarts的label中不支持formatter html,即html文本的渲染。故为了使图的节点更具有交互性,这里选择使用jointjs。
问题解决
jointjs是一个js图表库,其可在浏览器的网页中创建可交互的图表工具,它依赖于js与SVG。(这个在网页渲染后可以在浏览器按F12查看页面元素看到)
基本使用
关于jointjs的使用以及在jointjs元素中使用html这些在官方的文档中已经很详细了。我这里也只当加一下自己的理解翻译了。首先还是来回顾下它的基本使用吧。
- 配置
这个主要就是配置下jointjs的相关js库,官方网页有下载的资源和示例。如果这里还想用bootstrap,可以将其也包含进来。最后将这些资源放入到html的head标签里面。我这里盗用下官方的图吧。
- 画图
下来就是在网页中画图了。jointjs画图的步骤还是很人性化的。其跟我们平时画流程图的步骤一样,准备纸张,在纸张里画好对应的节点图,然后将图形之间连线。jointjs的步骤也是如此。下来就看看官方的hello world吧。其代码如下:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/2.1.0/joint.css" />
</head>
<body>
<!-- content -->
// 在网页中定义一个盒子
<div id="myholder"></div>
<!-- dependencies -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/2.1.0/joint.js"></script>
<!-- code -->
<script type="text/javascript">
// 定义一个图表模板。我这里理解应该是jointjs想将纸上面的图表作为一个整体图表模板进行管理。官方文档也说了在纸张上画的图形元素都需要进行加入到模板里才能在网页上渲染出来
var graph = new joint.dia.Graph;
// 定义一张纸。包括纸的背景颜色、长宽之类的。只有有了纸,我们才能在上面画画
var paper = new joint.dia.Paper({
el: document.getElementById('myholder'),
//这里相当于将graph图表模板放入到纸张里面了。纸张到时候就会渲染graph里面的图形元素,我们只需要将想画的图形元素放入graph模板里就可以了
model: graph,
width: 600,
height: 100,
gridSize: 1
});
// 在纸上面画一个矩形。jointjs已为我们定义好了一些矩形、圆角矩形、三角形等形状供选择,我们可以通过“new一个矩形的对象”来在纸上画一个矩形
var rect = new joint.shapes.standard.Rectangle();
// 矩形的位置。以纸张左上角为原点,相当于以纸张左上角为原点的y轴箭头向下、x轴箭头向右的二维坐标系中画图形
rect.position(100, 30);
// 矩形的长宽
rect.resize(100, 40);
// 矩形的属性。包括填充色、里面的文字、字体的颜色等
rect.attr({
body: {
fill: 'blue'
},
label: {
text: 'Hello',
fill: 'white'
}
});
// 最后别忘了加入到图表模板中
rect.addTo(graph);
// 定义另一个矩形。这里用了colone函数,clone了上一个矩形的部分属性,如长、宽等。
var rect2 = rect.clone();
rect2.translate(300, 0);
rect2.attr('label/text', 'World!');
// 加入到图表模板中
rect2.addTo(graph);
//定义一条连接线,将两个矩形连接起来。
var link = new joint.shapes.standard.Link();
//连接线的起点
link.source(rect);
// 连接线的终点
link.target(rect2);
// 也添加到图表模板中
link.addTo(graph);
</script>
</body>
</html>
代码生成的效果如下,截一张官方图放这。
jointjs画图的整个过程走下来,跟我们在纸上画流程图的过程是一样的。
在jonitjs元素中使用html
这个过程其实相当于要给纸张里面的图形元素加上html元素,比如按钮之类的。比如我们要给上面hello_world中的矩形里面加入一个按钮。不幸的是jointjs中并没有那种现成的可利用的个性化定制图形。不过幸运的是jointjs给了我们足够的接口,让我们可以随心所欲的定义自己需求的图形元素(这里感觉跟Android中的自定义view很像)。好了,废话不多说,先看官方教程吧,我这里也权当翻译吧。
(function() {
// 创建图表模板
var graph = new joint.dia.Graph;
// 定义纸张
var paper = new joint.dia.Paper({<