在Vue项目中使用Gojs
使用GOJS在vue项目中实现拖拉拽的图形化需求,记录了常用功能的实现,需要完整使用的可以去官方文档查看。至此,就能在vue项目中使用Gojs实现简单的双画布托拉拽雪花图需求。
·
文章目录
前言
使用GOJS在vue项目中实现拖拉拽的图形化需求,记录了常用功能的实现,需要完整使用的可以去官方文档查看。
1. Gojs的安装
首先通过npm命令添加go.js插件
npm install gojs --save
2. 在vue项目中的引用
使用时需要在html用dom容器来挂载渲染图像,这里我通常使用div元素
<template>
<div id="wrap">
<div id="chart-wrap">
<div id="myPalette"></div>
<div id="myDiagramDiv"></div>
</div>
<div>
<button type="button" id="SaveButton" @click="save()" class="save-Botton">SAVE</button>
</div>
</div>
</template>
然后看心情在全局main.js文件或在组件中引用
3. js导入
import go from 'gojs' //在export default前
const $ = go.GraphObject.make;
4. 画布初始化
在methods方法中创建init()函数
init() {
var mySelf = this;
mySelf.myDiagram =
$(go.Diagram, "myDiagramDiv",//为DIV.HTML元素创建一个画布
{
//设置画布配置
});
}
画布基础配置
isReadOnly: true, // 只读,无法编辑操作
allowMove: true, // 允许拖动画板
allowDragOut:true, // 允许拖拽节点
allowDelete: true, // 允许删除节点
allowCopy: true, // 允许复制节点
allowClipboard: true, // 允许粘贴节点
allowLink: true,//是否可以绘制新链接。
allowRelink: true,//是否可以重新连接现有链接
initialContentAlignment: go.Spot.Center, // 居中显示
initialAutoScale: go.Diagram.Uniform, // 缩放以使所有内容都适合
"grid.visible": true, //显示网格
"undoManager.isEnabled": true, // 支持 Ctrl-Z 和 Ctrl-Y 操作
"toolManager.hoverDelay": 100, //tooltip提示显示延时
"toolManager.toolTipDuration": 10000, //tooltip持续显示时间
"toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, //有鼠标滚轮事件放大和缩小,而不是向上和向下滚动
"clickCreatingTool.archetypeNodeData": { text: "node258", color: "white" },//允许在后台双击以创建新node258节点
主画布layout配置
本文配置的是雪花关系图,代码段同样放在init()函数中
class DemoForceDirectedLayout extends go.ForceDirectedLayout {
makeNetwork(coll) {
const net = super.makeNetwork(coll);
net.vertexes.each(vertex => {
const node = vertex.node;
if (node !== null) vertex.isFixed = node.isSelected;
});
return net;
}
}
然后在画布中配置layout,这样不会出现新节点产生时与原节点重合的情况
layout: new DemoForceDirectedLayout()
右侧画布配置
initPalette() 放在 methods中,在init()函数中用 mySelf.initPalette();即可显示。
initPalette() {
var mySelf = this;
window.myPalette = $(
go.Palette,
"myPalette", // 必须命名或引用DIV.HTML元素
{
scrollsPageOnFocus: false,
nodeTemplateMap: mySelf.myDiagram.nodeTemplateMap, // 共享myDiagram使用的模板
model: new go.GraphLinksModel([
// 指定调色板的内容
{
category: "node258",
text: "规则"
},
{
category: "node258",
text: "计划1"
},
{
category: "node258",
text: "执行2"
}
])
}
);
}
5. 连接线的配置
mySelf.myDiagram.linkTemplate = $(go.Link, {
selectable: true, //连接线是否可选
relinkableFrom: true,//出发点是否可以改变
relinkableTo: true,//目标点是否可以改变
},new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),//记录loc
$(go.Shape, {
strokeWidth: 2,//节点连接线宽度
stroke: "#F60"//颜色
}),
$(go.Shape, {
toArrow: "Standard",
fill: "red",//箭头填充色
stroke: "blue"//外边框颜色
})//箭头
);
6. 节点的配置
mySelf.myDiagram.nodeTemplateMap.add(//创建名为node258的节点
"node258",
$(go.Node,
"auto",
{//节点配置
movable:true,//是否可拖动
deletable:true,//是否可删除
selectable:true, //是否可选择
selectionAdorned:false, //显示选中边框
// reshapable:true, // 重塑(改变shape形状边界时使用,将影响节点大小)
// resizable: true, // 可调整大小的(手动调整节点大小时,节点内容显示区域时使用)
},new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Panel, //表明需要创建一个panel面板对象//声明创建一个新的面板对象,自定义方式可参考mySelf.myDiagram.nodeTemplate
"Auto", //页面布局为自动
$(go.Shape,//声明构建一个圆形
"Circle", {
fill: "#44CCFF",//内填充色
cursor: "pointer",//指针
stroke: null,//外框颜色null
portId: "",
fromLinkable: true,
fromLinkableSelfNode: false,
fromLinkableDuplicates: true,
toLinkable: true,
toLinkableSelfNode: false,
toLinkableDuplicates: false,
},
new go.Binding("figure", "figure") //声明并创建一个新的图形
),
$(go.TextBlock, {//声明一个可编辑文本域
font: "12pt Helvetica, Arial, sans-serif",
width: 50,
maxSize: new go.Size(360, NaN),
wrap: go.TextBlock.WrapFit, //文本域换行
editable: true, //是否可编辑
margin: 12,
},
new go.Binding("text").makeTwoWay()
),
),
{// 悬浮提示
toolTip:
$("ToolTip",
$(go.TextBlock, { margin: 4 },
new go.Binding("text", "text"))
),
}
)
);
7. 节点数据
第一种
this.myDiagram.model.nodeDataArray = [] //节点数据 格式为[{ key: "Alpha", color: "lightblue", loc: "400 0" }]
this.myDiagram.model.linkDataArray = [] //连线数据 格式为[{ from: "Beta", to: "Alpha" }]
第二种
或者在data中
data() {
return {
nodeData: [],
linkData: [],
}
}
节点与连接线保存的数据格式
nodeData: [
{"category":"node258","text":"规则","key":-1,"loc":"-605.5896437273716 -214.50164873808765"},
{"category":"node258","text":"计划1","key":-2,"loc":"-173.03724493296755 -192.24882726306356"},
],
linkData: [
{"from":-1,"to":-2},
],
mySelf.myDiagram.model.nodeDataArray = mySelf.nodeData;
mySelf.myDiagram.model.linkDataArray = mySelf.linkData;
第三种
let myModel = $(go.GraphLinksModel); //也可以创建link model;需要配置myModel.linkDataArray 如下
myModel.nodeDataArray = mySelf.nodeData;
myModel.linkDataArray = mySelf.linkData;
8 保存
监听画布是否修改
mySelf.myDiagram.addDiagramListener("Modified", e => { //监听画布是否修改
const button = document.getElementById("SaveButton");
if (button) button.disabled = !mySelf.myDiagram.isModified;
const idx = document.title.indexOf("*");
if (mySelf.myDiagram.isModified) {
if (idx < 0) document.title += "*";
} else {
if (idx >= 0) document.title = document.title.slice(0, idx);
}
});
在方法中创建save()函数
save(){
var mySelf = this;
console.log(mySelf.myDiagram.model.toJson());
mySelf.myDiagram.isModified = false;
},
这是里是把修改后的函数打印出来了,如果想存到后端的话也是可以的。
9 源代码
<template>
<div id="wrap">
<div id="chart-wrap">
<div id="myPalette"></div>
<div id="myDiagramDiv"></div>
</div>
<div>
<button type="button" id="SaveButton" @click="save()" class="save-Botton">SAVE</button>
</div>
</div>
</template>
<script>
import go from 'gojs' //在export default前
const $ = go.GraphObject.make;
export default {
data() {
return {
nodeData: [
{"category":"node258","text":"规则","key":-1,"loc":"-605.5896437273716 -214.50164873808765"},
{"category":"node258","text":"计划1","key":-2,"loc":"-173.03724493296755 -192.24882726306356"},
],
linkData: [
{"from":-1,"to":-2},
],
}
},
mounted() {
this.init()
},
methods: {
save(){
var mySelf = this;
console.log(mySelf.myDiagram.model.toJson());
mySelf.myDiagram.isModified = false;
},
init() {
class DemoForceDirectedLayout extends go.ForceDirectedLayout { //布局
makeNetwork(coll) {
const net = super.makeNetwork(coll);
net.vertexes.each(vertex => {
const node = vertex.node;
if (node !== null) vertex.isFixed = node.isSelected;
});
return net;
}
}
var mySelf = this;
mySelf.myDiagram =
$(go.Diagram, "myDiagramDiv", // 为DIV.HTML元素创建一个画布
{
//设置画布配置
initialContentAlignment: go.Spot.Center, // 居中显示
"undoManager.isEnabled": true, // 支持 Ctrl-Z 和 Ctrl-Y 操作
"toolManager.hoverDelay": 100, //tooltip提示显示延时
"toolManager.toolTipDuration": 10000, //tooltip持续显示时间
//isReadOnly:true,//只读
"grid.visible": true, //显示网格
allowMove: true, //允许拖动
allowDragOut:true,
allowDelete: true,
allowCopy: true,
allowClipboard: true, initialAutoScale: go.Diagram.Uniform, // 缩放以使所有内容都适合
"toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, //有鼠标滚轮事件放大和缩小,而不是向上和向下滚动
'clickCreatingTool.archetypeNodeData': { category: 'node258', text: '新节点', notice: ''}, // 双击新建节点(可以写入节点的默认信息);
layout: new DemoForceDirectedLayout()
});
mySelf.myDiagram.linkTemplate = $(go.Link, {
selectable: true, //连接线是否可选
relinkableFrom: true,//出发点是否可以改变
relinkableTo: true,//目标点是否可以改变
},new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Shape, {
strokeWidth: 2,//节点连接线宽度
stroke: "#F60"//颜色
}),
$(go.Shape, {
toArrow: "Standard",
fill: "red",//箭头填充色
stroke: "blue"//外边框颜色
})//箭头
);
mySelf.myDiagram.nodeTemplateMap.add(//创建名为node258的节点
"node258",
$(go.Node,
"auto",
{
movable:true,//是否可拖动
deletable:true,//是否可删除
selectable:true, //是否可选择
selectionAdorned:false, //显示选中边框
// reshapable:true, // 重塑(改变shape形状边界时使用,将影响节点大小)
// resizable: true, // 可调整大小的(手动调整节点大小时,节点内容显示区域时使用)
},new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Panel, //表明需要创建一个panel面板对象//声明创建一个新的面板对象,自定义方式可参考mySelf.myDiagram.nodeTemplate
"Auto", //页面布局为自动
$(go.Shape,//声明构建一个圆形
"Circle", {
fill: "#44CCFF",//内填充色
cursor: "pointer",//指针
stroke: null,//外框颜色null
portId: "",
fromLinkable: true,
fromLinkableSelfNode: false,
fromLinkableDuplicates: true,
toLinkable: true,
toLinkableSelfNode: false,
toLinkableDuplicates: false,
},
new go.Binding("figure", "figure") //声明并创建一个新的图形
),
$(go.TextBlock, {//声明一个可编辑文本域
font: "12pt Helvetica, Arial, sans-serif",
width: 50,
maxSize: new go.Size(360, NaN),
wrap: go.TextBlock.WrapFit, //文本域换行
editable: true, //是否可编辑
margin: 12,
},
new go.Binding("text").makeTwoWay()
),
),
{// 悬浮提示
toolTip:
$("ToolTip",
$(go.TextBlock, { margin: 4 },
new go.Binding("text", "text"))
),
}
)
);
// let myModel = $(go.GraphLinksModel); //也可以创建link model;需要配置myModel.linkDataArray 如下
// myModel.nodeDataArray = mySelf.nodeData;
// myModel.linkDataArray = mySelf.linkData;
// mySelf.myDiagram.model = myModel;
mySelf.myDiagram.model.nodeDataArray = mySelf.nodeData;
mySelf.myDiagram.model.linkDataArray = mySelf.linkData;
mySelf.initPalette();
mySelf.myDiagram.addDiagramListener("Modified", e => { //监听画布是否修改
const button = document.getElementById("SaveButton");
if (button) button.disabled = !mySelf.myDiagram.isModified;
const idx = document.title.indexOf("*");
if (mySelf.myDiagram.isModified) {
if (idx < 0) document.title += "*";
} else {
if (idx >= 0) document.title = document.title.slice(0, idx);
}
});
},
initPalette() {
var mySelf = this;
window.myPalette = $(
go.Palette,
"myPalette", // 必须命名或引用DIV.HTML元素
{
scrollsPageOnFocus: false,
nodeTemplateMap: mySelf.myDiagram.nodeTemplateMap, // 共享myDiagram使用的模板
model: new go.GraphLinksModel([
// 指定调色板的内容
{
category: "node258",
text: "规则"
},
{
category: "node258",
text: "计划1"
},
{
category: "node258",
text: "执行2"
}
])
}
);
},
}
}
</script>
<style lang="less" scoped>
#form-wrap {
padding: 20px 40px;
border: solid 1px rgb(244, 244, 244);
}
#submit {
width: 102px;
height: 40px;
float: right;
margin: 20px 5px 16px 0;
}
#chart-wrap {
width: 100%;
display: flex;
justify-content: space-between;
margin-bottom: 22px;
#myPalette {
width: 180px;
margin-right: 30px;
background-color: white;
border: solid 1px rgb(244, 244, 244);
}
#myDiagramDiv {
flex-grow: 1;
height: 720px;
background-color: white;
border: solid 1px rgb(244, 244, 244);
}
}
#SaveButton{
position: relative;
height: 60px;
width: 100px;
top: -60px;
margin-left: 800px;
background: #82ff90;
}
</style>
总结
至此,就能在vue项目中使用Gojs实现简单的双画布托拉拽雪花图需求。
更多推荐
已为社区贡献1条内容
所有评论(0)