0. 效果及场景描述
先放一张效果图,简单描述下业务场景,有一台设备报错后,边框标红展示,且虚线线段置为灰色不再流动,进行告警展示。
1. gojs初始化
网上很多gojs的基础使用,npm安装及介绍就不过多赘述了。
npm 安装引入后,所需页面引入后,进行全局的声明:
import go from 'gojs'
const $ = go.GraphObject.make; // 该声明方便接下来的使用
2. 虚线设置方法
核心就是name设置, 通过状态对线条名字赋值,为下一步动画筛选正常状态的设备做铺垫
$(go.Shape, {strokeWidth: 4, strokeDashArray: [6, 5]}, // 线条设置为虚线效果
new go.Binding("name", param => {
return mySelf.nameSet(param); // 通过状态对线条名字赋值,为下一步动画筛选正常状态的设备做铺垫
}),
new go.Binding("stroke", param => {
return mySelf.colorSet(param);
})),
$(go.Shape,
{toArrow: "Standard", stroke: null}, // 箭头效果
new go.Binding("stroke", param => {
return mySelf.colorSet(param);
}),
new go.Binding("fill", param => {
return mySelf.colorSet(param);
})),
$(go.Panel, "Auto",
$(go.Shape, "RoundedRectangle", // 连杆形状 左边的圆角矩形
{fill: "transparent", stroke: null}),
$(go.TextBlock, // 断开报警信息文字,上图中灰色虚线上的红色X
{
textAlign: "center",
font: "18pt helvetica, arial, sans-serif",
stroke: "red",
margin: 2,
editable: true
},
new go.Binding("text").makeTwoWay()),
$(go.TextBlock, new go.Binding('text', 'text'))
));
3. 动态设置颜色或名称赋值的方法
nameSet(param) {
switch (param.type) {
case 0:
return "dashedLink";
case 1:
return "";
default:
return "dashedLink";
}
},
colorSet(param) {
switch (param.type) {
case 0:
return "#43a298";
case 1:
return "#999";
default:
return "#43a298";
}
},
backgroundSet(param) {
switch (param.type) {
case 0:
return "#43a298";
case 1:
return "#ff5e62";
default:
return "#43a298";
}
},
4. 虚线动画效果
核心就是通过对线条名称筛选,定位状态正常的线条做动画处理
animation() {
const loop = () => {
const mySelf = this;
// clearTimeout(this.animationTimer);
mySelf.animationTimer = setTimeout(() => {
const oldskips = mySelf.myDiagram.skipsUndoManager;
mySelf.myDiagram.skipsUndoManager = true;
// 虚线动画
mySelf.myDiagram.links.each((link) => {
const dashedLinkShape = link.findObject("dashedLink"); // 选择名称为dashedLink进行动画加载
if (dashedLinkShape) {
const off = dashedLinkShape.strokeDashOffset - 3;
// 设置(移动)笔划划动画
dashedLinkShape.strokeDashOffset = (off <= 0) ? 60 : off;
}
});
mySelf.myDiagram.skipsUndoManager = oldskips;
loop();
}, 100);
}
loop()
}
5. 数据源设置
其中节点和线段中的type表示告警状态,0:正常;1:告警
data() {
return {
animationTimer: null,
nodeData: [
{category: "dashed", text: "192.168.0.1", key: 0, source: require('@/assets/img/icon-server.png')},
{category: "dashed", text: "192.168.2.1", key: 1, source: require('@/assets/img/icon-device.png')},
{category: "dashed", text: "192.168.3.1", key: 2, source: require('@/assets/img/icon-device.png')},
{category: "dashed", text: "192.168.4.1", key: 3, type: 1, source: require('@/assets/img/icon-router.png')},
{category: "dashed", text: "192.168.5.1", key: 4, source: require('@/assets/img/icon-router.png')},
{category: "dashed", text: "192.168.6.1", key: 5, type: 1, source: require('@/assets/img/icon-trans.png')},
],
linkData: [
{from: 0, to: 1, type: 0},
{from: 1, to: 3, type: 1, text: 'x'},
{from: 1, to: 2, type: 0},
{from: 1, to: 4, type: 0},
{from: 2, to: 5, type: 1, text: 'x'},
],
}
},
6. 汇总
其实第一次用gojs,感觉是把基础canvas扩展的很好,建议新手入门还是多看下api,官网API地址点这里☞GoJS API
可以满足大部分的使用场景,真的强大~
最后贴上全部的代码
<template>
<div id="myDiagramDiv"></div>
</template>
<script>
import go from 'gojs'
const $ = go.GraphObject.make;
export default {
data() {
return {
animationTimer: null,
nodeData: [
{category: "dashed", text: "192.168.0.1", key: 0, source: require('@/assets/img/icon-server.png')},
{category: "dashed", text: "192.168.2.1", key: 1, source: require('@/assets/img/icon-device.png')},
{category: "dashed", text: "192.168.3.1", key: 2, source: require('@/assets/img/icon-device.png')},
{category: "dashed", text: "192.168.4.1", key: 3, type: 1, source: require('@/assets/img/icon-router.png')},
{category: "dashed", text: "192.168.5.1", key: 4, source: require('@/assets/img/icon-router.png')},
{category: "dashed", text: "192.168.6.1", key: 5, type: 1, source: require('@/assets/img/icon-trans.png')},
],
linkData: [
{from: 0, to: 1, type: 0},
{from: 1, to: 3, type: 1, text: 'x'},
{from: 1, to: 2, type: 0},
{from: 1, to: 4, type: 0},
{from: 2, to: 5, type: 1, text: 'x'},
],
}
},
mounted() {
this.init();
this.animation();
},
destroyed() {
clearTimeout(this.animationTimer);
},
methods: {
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;
}
}
const mySelf = this;
mySelf.myDiagram =
$(go.Diagram, "myDiagramDiv", // 为DIV.HTML元素创建一个画布
{
initialContentAlignment: go.Spot.Center, // 居中显示
"undoManager.isEnabled": false, // 支持 Ctrl-Z 和 Ctrl-Y 操作
"toolManager.hoverDelay": 100, //tooltip提示显示延时
"toolManager.toolTipDuration": 10000, //tooltip持续显示时间
isReadOnly: true,//只读
"grid.visible": false, //显示网格
allowMove: false, //允许拖动
allowDragOut: false,
allowDelete: false,
allowCopy: false,
allowClipboard: true, initialAutoScale: go.Diagram.Uniform, // 缩放以使所有内容都适合
"toolManager.mouseWheelBehavior": go.ToolManager.WheelZoom, //有鼠标滚轮事件放大和缩小,而不是向上和向下滚动
layout: $(go.TreeLayout, // specify a Diagram.layout that arranges trees
{angle: 90, layerSpacing: 90})
});
// 节点模板设置
mySelf.myDiagram.nodeTemplate =
$(go.Node, "auto",
$(go.Shape,
{
width: 150,
height: 70,
fill: $(go.Brush, "Linear", {0: "#f2fcfe", 1: "#c9d6ff"}), // 背景色渐变设置
strokeWidth: 3,
}, new go.Binding("stroke", param => {
return mySelf.backgroundSet(param); // 根据设备状态设置边框颜色
})),
$(go.Picture,
{margin: new go.Margin(17, 0, 0, 12), width: 40, height: 40, background: "transparent"},
new go.Binding("source")),
$(go.TextBlock, {//声明一个可编辑文本域
font: "11pt Helvetica, Arial, sans-serif",
width: 130,
textAlign: 'end',
maxSize: new go.Size(30, NaN),
wrap: go.TextBlock.None,
editable: true,
margin: new go.Margin(30, 0, 0, 10), // 文本margin的设置,遵循css规则:上右下左
},
new go.Binding("stroke", param => {
return mySelf.backgroundSet(param); // 根据设备状态设置文字颜色
}),
new go.Binding("text").makeTwoWay()
),
);
// 节点之间的连线模板
mySelf.myDiagram.linkTemplate = $(go.Link,
{selectable: false}, // 是否可以选中
{
routing: go.Link.AvoidsNodes,
curve: go.Link.JumpOver,
corner: 0,
toShortLength: 0
}, // 曲度相关
new go.Binding("points").makeTwoWay(),
$(go.Shape, {strokeWidth: 4, strokeDashArray: [6, 5]}, // 线条设置为虚线效果
new go.Binding("name", param => { // 通过状态对线条名字赋值,为下一步动画筛选正常状态的设备做铺垫
return mySelf.nameSet(param);
}),
new go.Binding("stroke", param => {
return mySelf.colorSet(param);
})),
$(go.Shape,
{toArrow: "Standard", stroke: null}, // 箭头效果
new go.Binding("stroke", param => {
return mySelf.colorSet(param);
}),
new go.Binding("fill", param => {
return mySelf.colorSet(param);
})),
$(go.Panel, "Auto",
$(go.Shape, "RoundedRectangle", // 连杆形状 左边的圆角矩形
{fill: "transparent", stroke: null}),
$(go.TextBlock, // 断开报警信息文字,上图中灰色虚线上的红色X
{
textAlign: "center",
font: "18pt helvetica, arial, sans-serif",
stroke: "red",
margin: 2,
editable: true
},
new go.Binding("text").makeTwoWay()),
$(go.TextBlock, new go.Binding('text', 'text'))
));
mySelf.myDiagram.model.nodeDataArray = mySelf.nodeData;
mySelf.myDiagram.model.linkDataArray = mySelf.linkData;
},
nameSet(param) {
switch (param.type) {
case 0:
return "dashedLink";
case 1:
return "";
default:
return "dashedLink";
}
},
colorSet(param) {
switch (param.type) {
case 0:
return "#43a298";
case 1:
return "#999";
default:
return "#43a298";
}
},
backgroundSet(param) {
switch (param.type) {
case 0:
return "#43a298";
case 1:
return "#ff5e62";
default:
return "#43a298";
}
},
animation() {
const loop = () => {
const mySelf = this;
// clearTimeout(this.animationTimer);
mySelf.animationTimer = setTimeout(() => {
const oldskips = mySelf.myDiagram.skipsUndoManager;
mySelf.myDiagram.skipsUndoManager = true;
// 虚线动画
mySelf.myDiagram.links.each((link) => {
const dashedLinkShape = link.findObject("dashedLink"); // 选择名称为dashedLink进行动画加载
if (dashedLinkShape) {
const off = dashedLinkShape.strokeDashOffset - 3;
// 设置(移动)笔划划动画
dashedLinkShape.strokeDashOffset = (off <= 0) ? 60 : off;
}
});
mySelf.myDiagram.skipsUndoManager = oldskips;
loop();
}, 100);
}
loop()
}
}
}
</script>
<style lang="less" scoped>
#myDiagramDiv {
height: 900px;
}
</style>