jointjs自动布局库graphlib使用

前言

今天同事写了个jointjs+自动布局库graphlib的例子。例子很简单,创建了三个元素,并采用自动布局方式展示。此处有个坑:graphlib、drag库需要放在jointjs上面。

 

代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<link rel="stylesheet" type="text/css" href="./css/joint.css" />
		<link rel="stylesheet" type="text/css" href="./css/vendor.min.css" />
		<link rel="stylesheet" type="text/css" href="./css/bootstrap.min.css" />

		<!-- 引入Dagre -->
		<script src="https://cdn.jsdelivr.net/npm/dagre@0.8.5/dist/dagre.min.js"></script>

		<!-- 引入Graphlib -->
		<script src="https://cdn.jsdelivr.net/npm/graphlib@2.1.7/dist/graphlib.min.js"></script>

		<!-- dependencies -->
		<script src="./js/jquery.2.1.40.min.js"></script>
		<script src="./js/lodash.4.17.14.js"></script>
		<script src="./js/backbone.1.4.0.js"></script>
		<script src="./js/joint.2.2.1.js"></script>
		<script src="./js/bootstrap.min.js"></script>
	</head>
	<body>
		<div class="container">
			<div id="paper"></div>
		</div>
	</body>

	<script>
		/** 初始化画布 */
		function initGraph() {
			this.nodes = [{
					id: 1,
					label: 'node1'
				},
				{
					id: 2,
					label: 'node2'
				},
				{
					id: 3,
					label: 'node3'
				}
			];
			this.links = [{
					from: 1,
					to: 2
				},
				{
					from: 1,
					to: 3
				}
			];
			this.nodeList = [];
			this.linkList = [];
			let paper = document.getElementById('paper');
			this.graph = new joint.dia.Graph();
			this.paper = new joint.dia.Paper({
				dagre: dagre,
				graphlib: graphlib,
				el: paper,
				model: this.graph,
				width: '100%',
				height: 'calc(100vh - 100px)',
				background: {
					color: '#f5f5f5'
				},
				// drawGrid: true,
				// gridSize: 20,
			});
		}

		/** 创建节点 */
		function createNode() {
			this.nodes.forEach(ele => {
				let node = new joint.shapes.standard.Rectangle({
					id: ele.id,
					size: {
						width: 100,
						height: 50
					},
					attrs: {
						body: {
							fill: '#ddd',
							stroke: 'none'
						},
						text: {
							text: ele.label
						}
					}
				});
				this.nodeList.push(node);
			})
			this.graph.addCell(this.nodeList);
		}

		/** 创建连线 */
		function createLink() {
			this.links.forEach(ele => {
				let link = new joint.shapes.standard.Link({
					source: {
						id: ele.from
					},
					target: {
						id: ele.to
					},
					attrs: {
						line: {
							stroke: '#aaa',
							strokeWidth: 1
						}
					}
				});
				this.linkList.push(link);
			})
			this.graph.addCell(this.linkList);
		}

		/** 画布节点自动布局 */
		function randomLayout() {
			joint.layout.DirectedGraph.layout(this.graph, {
				/** 布局方向 TB | BT | LR | RL */
				rankDir: "LR",
				/** 表示列之间间隔的像素数 */
				rankSep: 200,
				/** 相同列中相邻接点之间的间隔的像素数 */
				nodeSep: 80,
				/** 同一列中相临边之间间隔的像素数 */
				edgeSep: 50
			});
		}

		/** svgpanzoom 画布拖拽、缩放 */
		function svgPanZoom() {
			if (this.nodes.length) {
				let svgZoom = svgPanZoom('#paper svg', {
					/** 是否可拖拽 */
					panEnabled: true,
					/** 是否可缩放 */
					zoomEnabled: true,
					/** 双击放大 */
					dblClickZoomEnabled: false,
					/** 可缩小至的最小倍数 */
					minZoom: 0.01,
					/** 可放大至的最大倍数 */
					maxZoom: 100,
					/** 是否自适应画布尺寸 */
					fit: true,
					/** 图是否居中 */
					center: true,
					/** 判断是否是节点的拖拽 */
					beforePan: (oldPan, newPan) => {
						if (this.currCell) {
							return false;
						}
					}
				})
				svgZoom.setZoomScaleSensitivity(0.5);
				/** fit:true 元素数量较少时,会引起元素过度放大,当缩放率大于1时,将图像缩小为1;小于等于1时,为体现出边距更显美观,整体缩放至0.9 */
				let {
					sx,
					sy
				} = this.paper.scale();
				if (sx > 1) {
					svgZoom.zoom(1 / sx);
				} else {
					svgZoom.zoom(0.9);
				}
			}
		}

		function paperEvent() {
			this.paper.on('element:pointerdown', (cellView, evt, x, y) => {
				this.currCell = cellView;
			})
			this.paper.on('cell:pointerup blank:pointerup', (cellView, evt, x, y) => {
				this.currCell = null;
			})
		}

		initGraph();
		createNode();
		createLink();
		randomLayout();
		//svgPanZoom();
		//paperEvent();
	</script>

</html>

 

效果

版权声明:
作者:小何
链接:https://ligo100.cn/qianduanjishu/591.html
来源:小何博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
< <上一篇
下一篇>>
文章目录
关闭
目 录