赞
踩
vue+jsplumb实现连线绘图,供大家参考,具体内容如下
jsPlumb是一个比较强大的绘图组件,它提供了一种方法,主要用于连接网页上的元素。在现代浏览器中,它使用SVG或者Canvas技术,而对于IE8以下(含IE8)的浏览器,则使用VML技术。
效果如图
1.安装
npm install jsplumb --save
2.main.js 引入
- import jsPlumb from 'jsplumb'
-
- Vue.prototype.$jsPlumb = jsPlumb.jsPlumb
3.封装组件 linkDataJsPlumb.vue
- <template>
- <div>
- <div id="container" class='clear-float'>
- <div class="left">
- <ul>
- <div class='titleContend clear-float'>
- <div class='float firstField'>源表字段</div>
- <div class='float secondField'>类型</div>
- <div class='float thirdField'>描述</div>
- </div>
- <li v-for="(item,index) in leftList" :key="'left' + index" :id="item.nodeId" name="source">
- <div class='titleContend clear-float'>
- <div class='float firstField'>{{item.name}}</div>
- <div class='float secondField'>{{item.name}}</div>
- <div class='float thirdField'>{{item.name}}</div>
- </div>
- </li>
- </ul>
- </div>
- <div class="right">
- <ul>
- <div class='titleContend clear-float'>
- <div class='float firstField'>识别字段</div>
- </div>
- <li v-for="(item,index) in rightList" :key="'right' + index" :id="item.nodeId" name="target">
- <div class='titleContend clear-float'>
- <div class='float firstField'>{{item.name}}</div>
- </div>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </template>
-
- <script>
- export default {
- name: 'linkElementModal',
- props: {
- // 左侧数据 [{ name: 'xxx_left_1', nodeId: 'left_1' }]
- leftList: {
- type: Array,
- default: () => {
- return [];
- }
- },
- // 右侧数据 [{ name: 'xxx_right_1', nodeId: 'right_1' }]
- rightList: {
- type: Array,
- default: () => {
- return [];
- }
- },
- // 默认数据 [{left: 'left_1', right: 'right_1'}]
- value: {
- type: Array,
- default: () => {
- return [];
- }
- }
- },
- data () {
- return {
- jsPlumb: null // 缓存实例化的jsplumb对象
- };
- },
- mounted () {
- this.showPlumb();
- },
- methods: {
- showPlumb () {
- this.jsPlumb = this.$jsPlumb.getInstance({
- Container: 'container', // 选择器id
- EndpointStyle: { radius: 0.11, fill: '#999' }, // 端点样式
- PaintStyle: { stroke: '#999', strokeWidth: 2 }, // 绘画样式,默认8px线宽 #456
- HoverPaintStyle: { stroke: '#994B0A', strokeWidth: 3 }, // 默认悬停样式 默认为null
- ConnectionOverlays: [ // 此处可以设置所有箭头的样式
- ['Arrow', { // 设置参数可以参考中文文档
- location: 1,
- width: 10,
- length: 6,
- paintStyle: {
- stroke: '#999',
- fill: '#999'
- }
- }]
- ],
- Connector: ['Straight'], // 要使用的默认连接器的类型:直线,折线,曲线等
- DrapOptions: { cursor: 'crosshair', zIndex: 2000 }
- });
-
- this.jsPlumb.batch(() => {
- for (let i = 0; i < this.leftList.length; i++) {
- this.initLeaf(this.leftList[i].nodeId, 'source');
- }
- for (let j = 0; j < this.rightList.length; j++) {
- this.initLeaf(this.rightList[j].nodeId, 'target');
- }
- });
-
- this.setjsPlumb(true, true);
-
- // 点击连线
- this.jsPlumb.bind('click', (conn, originalEvent) => {
- this.value.forEach((item, index) => {
- if (item.left == conn.sourceId) {
- this.value.splice(index, 1);
- }
- });
- this.jsPlumb.deleteConnection(conn);
- });
-
- // 连线时触发
- this.jsPlumb.bind('connection', (conn, originalEvent) => {
- let obg = {
- left: conn.sourceId,
- right: conn.targetId
- };
- this.value.push(obg);
- });
-
- // 右键触发
- this.jsPlumb.bind('contextmenu', (conn, originalEvent) => {
- console.log(conn, originalEvent);
- });
- },
- // 初始化规则使其可以连线、拖拽
- initLeaf (id, type) {
- const ins = this.jsPlumb;
- const elem = document.getElementById(id);
- if (type === 'source') {
- ins.makeSource(elem, {
- anchor: [1, 0.5, 0, 0], // 左 上 右 下
- allowLoopback: false, // 允许回连
- maxConnections: 1 // 最大连接数(-1表示不限制)
- });
- } else {
- ins.makeTarget(elem, {
- anchor: [0, 0.5, 0, 0],
- allowLoopback: false,
- maxConnections: 1
- });
- }
- },
- setjsPlumb (sourceFlag, targetFlag) {
- const source = document.getElementsByName('source');
- const target = document.getElementsByName('target');
- this.jsPlumb.setSourceEnabled(source, sourceFlag);
- this.jsPlumb.setTargetEnabled(target, targetFlag);
- this.jsPlumb.setDraggable(source, false); // 是否支持拖拽
- this.jsPlumb.setDraggable(target, false); // 是否支持拖拽
- // 是否含有默认数据
- if (this.value.length > 0) {
- this.initConnect();
- }
- },
- // 默认链接
- initConnect () {
- const jsplumbConnectOptions = {
- isSource: true,
- isTarget: true,
- // 动态锚点、提供了4个方向 Continuous、AutoDefault
- anchor: 'Continuous'
- };
- this.jsPlumb.deleteEveryConnection();
- for (var i = 0; i < this.value.length; i++) {
- let line = this.value[i];
- this.jsPlumb.connect({
- source: line.left,
- target: line.right
- }, jsplumbConnectOptions);
- }
- }
- }
- };
- </script>
-
- <style>
- #container {
- width: 500px;
- padding: 20px;
- position: relative; /*一定加上这句,否则连线位置发生错乱*/
- }
-
- .left {
- float: left;
- width: auto;
- }
- .right {
- float: right;
- width: auto;
- }
-
- .left li,
- .right li {
- list-style: none;
- width: auto;
- }
- </style>
- <style lang='scss' scoped>
- .titleContend {
- width: auto;
- height: 30px;
- line-height: 30px;
- border-bottom: 1px solid #cccccc;
- .float {
- float: left;
- }
- .firstField {
- width: 100px;
- }
- .secondField {
- width: 100px;
- }
- .thirdField {
- width: 80px;
- }
- }
- </style>
4.使用组件
- <linkDataJsPlumb v-model='defaultList' :leftList='leftList' :rightList='rightList'/>
-
- import linkDataJsPlumb from './components/linkDataJsPlumb';
-
- // 左侧数据
- leftList: [
- { name: 'xxx_left_1', nodeId: 'left_1' },
- { name: 'xxx_left_2', nodeId: 'left_2' },
- { name: 'xxx_left_3', nodeId: 'left_3' },
- { name: 'xxx_left_4', nodeId: 'left_4' }
- ],
- rightList: [
- { name: 'xxx_right_1', nodeId: 'right_1' },
- { name: 'xxx_right_2', nodeId: 'right_2' },
- { name: 'xxx_right_3', nodeId: 'right_3' },
- { name: 'xxx_right_4', nodeId: 'right_4' }
- ],
- // 默认值
- defaultList: [
- {left: 'left_1', right: 'right_2'},
- {left: 'left_2', right: 'right_3'},
- {left: 'left_3', right: 'right_1'}
- ]
中文mirrors / wangduanduan / jsplumb-chinese-tutorial · GitCode
使用jsPlumb进行实例化的同时可以传入相关属性的设置。
- this.jsp = jsPlumb.getInstance({
- Anchor: ["Right", "Left"],
- //锚点位置,如left,top,bottom等;对任何没有声明描点的Endpoint设置锚点,
- //用于source或target节点
- //设置为数组可以指定锚点的位置
- Anchors: ["Right", "Left"], //连线的source和target Anchor
- ConnectionsDetachable: false, //连线是否可用鼠标分离
- ConnectionOverlays: [ //连线的叠加组件,如箭头、标签
- //叠加组件-箭头参数设置
- ["Arrow", {
- location: 1,
- visible: true,
- width: 11,
- length: 11,
- id: "ARROW",
- events: {
- click: function () {
- }
- }
- }],
- //叠加组件-标签参数设置
- ["Label", {
- location: 0.1,
- cssClass: "aLabel", //hover时label的样式名
- events: {
- click:info=>{
- console.log(info);
- }
- },
- visible: true
- }]
- ],
- Connector: "Straight",
- //连线的类型,有直线(Sright),有流程图(Flowchart)、贝塞尔曲线(Bezier),State machine(状态机)
- Container: "module",
- //父级元素id;假如页面元素所在上层不同,最外层父级一定要设置
- DoNotThrowErrors: false,
- //如果请求不存在的Anchor、Endpoint或Connector,是否抛异常
- DragOptions : { },//用于配置拖拽元素的参数
- DropOptions : { },//用于配置元素的drop行为的参数
- Endpoint: "Dot", //端点(锚点)的样式声明
- Endpoints: [null, null],
- //用jsPlumb.connect创建连接时,source端点和target端点的样式设置
- EndpointOverlays: [], //端点的叠加物
- EndpointStyle: {fill: 'transparent', stroke: '#1565C0', radius: 4, strokeWidth: 1}, //端点的默认样式
- EndpointStyles: [null, null], //连线的source和target端点的样式
- EndpointHoverStyle: {fill: '#1565C0', stroke: '#1565C0', radius: 4, strokeWidth: 1}, //端点hover时的样式
- EndpointHoverStyles: [null, null], //连线的source和target端点hover时的样式
- HoverPaintStyle: {stroke: '#1565C0', strokeWidth: 3}, //连线hover时的样式
- LabelStyle: {color: "black"}, //标签的默认样式,用css写法。
- LogEnabled: false, //是否开启jsPlumb内部日志
- Overlays: [], //连线和端点的叠加物
- MaxConnections: 10, //端点支持的最大连接数
- PaintStyle: {stroke: '#1565C0', strokeWidth: 1, joinstyle: 'round'}, //连线样式
- ReattachConnections: true, //是否重新连接使用鼠标分离的线?
- RenderMode: "svg", //默认渲染模式
- Scope: "jsPlumb_DefaultScope", //范围,具有相同scope的点才可
- reattach: true,
- })
添加连线
- let params={source: info.sourceId, target: info.targetId};
- let setting=为自定义的jsPlumb设置,也可以不传入
- this.jsp.connect(params,setting);
删除连线
this.jsp.removeAllEndpoints(node)这个方法删除指定的节点和连线,传入的node为节点元素
this.jsp.deleteEveryConnection();这个方法删除所有连线,不需要传入参数
this.jsp.deleteEveryEndpoint();这个方法删除所有节点,不需要传入参数
this.jsp.deleteConnectionsForElement("A-1",{});删除制定的连线,传入节点ID
重绘连线
- this.jsp.repaintEverything()//重绘连线
- this.jsp.setSuspendDrawing(true);
- this.jsp.setSuspendDrawing(false,true);
- 这里第二个参数的true,会使整个jsPlumb立即重绘。
注意:
因为jsPlumb 是通过DOM进行工作的,所以我们需要把jsPlumb初始化 放在mounted声明,
如果是在子组件中完成,需要保证子组件渲染完成才可进行处理,可以放在进行初始化this.$nextTick(()=>{ } )
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。