拓扑图库
一 、前言
目前drawtool.js已经服务于四个以上的项目。
二 、drawtool.js提供的功能
drawtool.js 为图(包含树)这样结构的数据的界面化,提供了解决方案。
即: 为点和线的图形操作提供了方案。
可以举例以下几种情况
- 画一个流程图。
- 画一个组织架构图。
- 画一个城市交通图。
可以看下面的demo
三、 drawtool.js提供的API
1.引入
drawtool.js支持nodeJs引入,AMD规范引入、CMD规范引入和直接引入。
标签直接引入:
drawtool.css 是内置样式表,可以方便覆盖。
<link rel="stylesheet" type="text/css" href="../drawtool/drawtool.css">
<script type="text/javascript" src="../drawtool/drawtool.js"></script>
drawtool也支持npm安装
npm install drawtool
安装后引入如下:
import Drawtool from 'drawtool';
import 'drawtool/drawtool.css';
2.初始化
页面放置一个div,drawtool.js会根据div的大小初始化一个画布。
html
<div id="canvas" class="canvas"></div>
style
#canvas{
width: 800px;
height: 400px;
background: #fafafa;
}
javascript
var canvas = document.getElementById('canvas');
var drawtool = new Drawtool(canvas);
3 全局属性配置
drawtool.js 在初始化的过程中可以配置一些常用属性。
可配置属性包括下面:
序号 | 属性 | 含义 | 默认值 |
1 | lineColor | 线的颜色 | #26b7d0 |
2 | lineHoverColor | 线处于hover状态的颜色 | rgba(200, 200, 200, 0.4) |
3 | arrowColor | 箭头的颜色 | #444 |
4 | lineStyle | 线有无箭头 arrow有箭头 none无箭头 | arrow |
5 | lineType | 线性 broken 折线 bezier贝塞尔曲线 straight 直线 | bezier |
6 | auto | 是否自动计算控制点,只对折线有效。 true自动计算, false不自动计算 | true |
7 | lineActiveColor | 线处于激活状态颜色 | #2177C7 |
var canvas = document.getElementById('canvas');
var setting = {
lineColor: '#26b7d0',
lineHoverColor: '#aaa',
arrowColor: '#444',
lineStyle: 'arrow',
lineType: 'broken',
auto: false
};
var drawtool = new Drawtool(canvas, setting);
注意:此处配置为全局性的,权重级别最低。
4.增加节点
drawtool.js的节点是用dom构造,这样做是为了更灵活的操作节点。
配置一个节点有四个属性:
属性 | 说明 |
pos | 节点添加的位置坐标 x为横坐标, y为纵坐标 |
template | 可以传入html字符串模板或者一个dom元素,drawtool.js将会为html模板创建一个节点容器,若是html字符串,则innerHTML方法将模板写入节点容器。若是dom元素,则会直接将dom元素插入节点容器。 |
anchors | 连线点的相对坐标,以html模板的中心为坐标系原点。 |
nodeid | 节点id, 为数值类型,不传入会自动递增构造。 |
若是采用vue等无dom开发,可以在template内传入dom。
addNode方法的返回值是节点dom,dom上挂载了nodeid属性。
var option = {
pos:{x:20,y:20},
template: "<div class='node js-node'>test</div>",
anchors:[[0, 20],[40, 20],[20, 0],[20, 40]]
};
var node = drawtool.addNode(option);
console.log(node.nodeid);
5.删除节点
通过nodeid可以删除节点。nodeid可以通过dom获取。
删除节点的同时,会将与之相连的线条全部删除。
// jquery代码示例
var nodeid = $('.js-node').get(0).nodeid;
drawtool.deleteNodeById(nodeid);
6.清除画布
清除画布是删除drawtool.js上面所有的节点和连线。
drawtool.clear();
7.事件监听
drawtool.js提供了事件监听切面,让我们可以控制连线点击等操作。而对于节点事件的操作,则全部交给dom完成。
drawtool.js提供的事件如下:
序号 | 方法 | 含义 | 说明 |
1 | clickLine | 点击连线 | 参数是当前点击的线条 |
2 | deleteLineBefore | 删除连线之前 | 参数是当前线条,返回true表示可以删除,返回false不删除。 缺省为true。 |
3 | deleteLineAfter | 删除连线之后 | 参数是当前线条 |
4 | linkLineBefore | 连线前 | 参数是当前线条,此时为点击第二个连线点,返回true表示可以连线,返回false不连线。 缺省为true。 |
5 | linkLineAfter | 连线后 | 参数是当前线条 |
6 | linkLineStart | 开始连线 | 参数是当前线条,此处是设置局部线性配置的地方。 |
可以使用如下监听方式:
drawtool.listen({
clickLine: function (line) {
console.log(line);
},
deleteLineBefore: function (line) {
return true;
},
deleteLineAfter: function (line) {
console.log(line);
},
linkLineBefore: function (line) {
return true;
},
linkLineAfter: function (line) {
console.log(line);
}
});
drawtool.js也支持下列调用
drawtool.listen('linkLineStart', function (line) {
console.log(line);
});
注意:
– drawtool.js不支持重复绑定,重复绑定会引发覆盖操作。
– 所有的事件方法,this都指向drawtool实例。
8.局部属性设置
drawtool.js局部属性是针对线条设置的,它覆盖全局属性。
通过对linkLineStart的监听,调用线条的方法,可以完成局部属性设置。
支持三种局部属性:
- setStyle 箭头设置, arrow,none;
- setType 线性设置, broken,bezier,straight
- setAuto 是否自动计算,只支持折线, true,false
// 动态设置线的样式
drawtool.listen('linkLineStart', function (line) {
line.setStyle('arrow');
line.setType('broken');
line.setAuto(false);
});
9.禁用模式
drawtool.js可以设置禁用模式
drawtool.setDisabled(true);
setDisabled方法接收一个布尔值,
true为禁用模式,false为非禁用模式。
禁用模式下,点线事件失效,但可以通过api调用。
10.存为图片
drawtool.js利用svg和canvas合成图片。。
若有图片,受svg限制,必须使用img标签引入图片,使用background将不会被支持导出。
drawtool.getImage(fn, deep);
fn – 回调方法,函数类型。参数为base64编码。
deep – 是否深获取,布尔类型,true为下载图片。
drawtool.getImage(function(res) {
console.log(res);
}, true);
注意:受浏览器兼容影响,ie浏览器不支持,若完成复杂的图片存储,建议采用其他插件配合完成。
11.数据存储
drawtool.js内部管理节点栈和连线栈。我们可以通过接口,来获取数组格式的节点和连线。
var lineArr = drawtool.getAllLines();
var nodeArr = drawtool.getAllNodesInfo();
localStorage.setItem('lineArr', JSON.stringify(lineArr));
localStorage.setItem('nodeArr', JSON.stringify(nodeArr));
drawtool.js还管理了所有的canvas上的所有dom,我们也可以获取。
var domArr = drawtool.getAllNodes();
12.数据读取
drawtool.js可以直接读取节点和连线数组,来初始化画布。
init方法可以直接读取drawtool.js输出的数据。
var lineArr = JSON.parse(localStorage.getItem('lineArr'));
var nodeArr = JSON.parse(localStorage.getItem('nodeArr'));
drawtool.init(nodeArr, lineArr);
13.vue中使用
drawtool.js没有对dom进行控制,而是通过addNode方法将dom的操作权转让给外界。也即drawtool.js不干涉dom行为,只提供一个节点容器。
例如下面:
可以构造一个node模板
<template>
<div>
<div @contextmenu="show">
<div>A</div>
<button v-if="option" @click="deletes">删除</button>
</div>
</div>
</template>
<script>
export default {
name: 'node',
data() {
return {
option: false
};
},
methods: {
show() {
this.option = !this.option;
},
deletes() {
this.$emit('deleteClick', null);
}
}
};
</script>
然后在主模块中做如下操作:
let option = {
pos: {
x: 30,
y: 50
},
template: this.$refs.node.$el,
anchors: [
[0, 20],
[40, 20],
[20, 0],
[20, 40]
]
};
this.drawtool.addNode(option);
四、 性能
drawtool.js最大性能问题是事件和渲染,
事件:drawtool.js 内部实现了自己的事件方法,优化管理事件。
渲染:drawtool.js 采用局部渲染方法,保证最小程度的重绘。
五、 自我保护
1. 数据私有化
drawtool.js所有数据都采用getter/setter获取和设置。
2. 动态class
drawtool.js提供了dom的标准化获取方法,不建议使用dom操作来获取和操作dom,因此drawtool.js会将关键的dom采用动态class生成方法,来防止外界直接操作dom。
六、 存在的问题
- 线上文字未实现。
七、 代码demo
版本: 1.1.1
代码量:28k
版本: 1.2.0
代码量:53k