项目需求

使用gojs给嵌入式工程师写一套在设备上运行,可给设备配置属性的界面,配置完成后保存到设备上,图示如下(文字部分打了马赛克)

详细功能

1.左侧“输入”、“输出”及“算法”属性均可拖到右边进行配置,“算法”属性包含在“算法配置”框中,属性数量不限
2.“输入”属性拖到右侧后要指向“算法配置”,同理“输出”属性拖到右侧要从“算法配置”指向“输出”,由此表现输入输出的一个过程
3.所有属性均由若干字段组成,要求可以编辑配置项数据
4.配置完成“保存”数据到设备
5.判断设备是否已有配置,若有,则加载出来,即反向显示图表
6.右上角数据从服务器获取后加载,5s更新一次

功能实现

1.拆分界面,基本布局,太简单,不赘述
2.左侧调色板样式:
⑴ “输入”,“算法”,“输出”不参与配置,仅仅作为文字区分

//矩形,title样式
myDiagram.nodeTemplateMap.add("Title",$$(go.Node, "Table", nodeStyle(),$$(go.Panel, "Auto",$$(go.Shape, "Rectangle",{ minSize: new go.Size(120, 40), stroke: "#eeeeee", strokeWidth: 1 },new go.Binding("fill", "background")),$$(go.TextBlock, "Tablename", {font: "bold 14pt Helvetica, Arial, sans-serif",stroke: "black"},{editable: true},new go.Binding("text"))),// three named ports, one on each side except the top, all output only:makePort("T", go.Spot.Top, go.Spot.Top,  true,false ),makePort("L", go.Spot.Left, go.Spot.Left, true,false ),makePort("R", go.Spot.Right, go.Spot.Right, true, false),makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)
));

效果

⑵因各属性里面还有若干字段要编辑,所以用折叠框来展示,折叠框里面加入表格,表格中填写字段数据,折叠框可展开隐藏表格,但在左侧调色板中需禁止折叠框展开,拖到右侧后才可以展开

//折叠框样式
myDiagram.nodeTemplateMap.add("ExpandePanel",$$(go.Node, "Auto", {selectionAdorned: true,resizable: true,layoutConditions: go.Part.LayoutStandard & ~go.Part.LayoutNodeSized,fromSpot: go.Spot.AllSides,toSpot: go.Spot.AllSides,isShadowed: true,shadowOffset: new go.Point(3, 3),shadowColor: "#C5C1AA",locationSpot: go.Spot.Center},new go.Binding("desiredSize", "visible", function(v) { return new go.Size(NaN, NaN); }).ofObject("LIST"),$$(go.Shape, "RoundedRectangle",{ strokeWidth: 0,cursor: "pointer",minSize:new go.Size(120, 30) },new go.Binding("fill", "background")),$$(go.Panel, "Table",{ margin: 8, stretch: go.GraphObject.Fill},$$(go.RowColumnDefinition, { row: 0, sizing: go.RowColumnDefinition.None }),$$(go.TextBlock,{row: 0, alignment: go.Spot.Center,margin: new go.Margin(0, 24,0,0),  font: "bold 13px sans-serif"},new go.Binding("text", "key")),// the collapse/expand button$$("PanelExpanderButton", "LIST",  { row: 0, alignment: go.Spot.TopRight }),$$(go.Panel, "Vertical",{name: "LIST",row: 1,padding: 1,alignment: go.Spot.TopLeft,defaultAlignment: go.Spot.Left,stretch: go.GraphObject.Horizontal,itemTemplate: itemTempl,visible:false,background: "white"},$$(go.Panel, "Table",{name: "TABLE", stretch: go.GraphObject.Horizontal,minSize: new go.Size(100, 10),defaultAlignment: go.Spot.Left,defaultStretch: go.GraphObject.Horizontal,defaultColumnSeparatorStroke: "gray",defaultRowSeparatorStroke: "gray",itemTemplate: fieldTemplate},$$(go.RowColumnDefinition, makeWidthBinding(0)),$$(go.RowColumnDefinition, makeWidthBinding(1)),$$(go.RowColumnDefinition, makeWidthBinding(2)),new go.Binding("itemArray", "fields"))) )
))

效果

⑶添加“保存”和“加载”按钮

//矩形,button样式1,保存
myDiagram.nodeTemplateMap.add("Button",$$(go.Node, "Auto",nodeStyle(),$$(go.Shape, "Rectangle",{ strokeWidth: 2, stroke: "#76C176" }),$$(go.Panel, "Vertical",$$("Button",{minSize: new go.Size(120, 40)},{click:  diagramTojson},$$(go.TextBlock, "Click me!",{font: "12pt 华文细黑"},new go.Binding("text"))))
));//矩形,button样式2,加载
myDiagram.nodeTemplateMap.add("getButton",$$(go.Node, "Auto",nodeStyle(),$$(go.Shape, "Rectangle",{ strokeWidth: 2, stroke: "#76C176" }),$$(go.Panel, "Vertical",$$("Button",{minSize: new go.Size(120, 40)},{click:  loadDiagram},$$(go.TextBlock, "Click me!",{font: "12pt 华文细黑"},new go.Binding("text"))))
));

效果
3.将“算法配置”框作为固定节点,设置isGroup: true,便可将算法属性拖到框中

//绘制节点模板
myDiagram.nodeTemplate =$$("Node", "Auto",{locationSpot: go.Spot.Center,layerName: "Background"},  // always have regular nodes behind Links$$("Shape", "RoundedRectangle",{fill: "white",fromLinkable: true, toLinkable: true, cursor: "pointer",width:100,height:80},new go.Binding("fill", "color")),$$("TextBlock",{ margin: 8 },  new go.Binding("text", "text")), makePort("L", go.Spot.Left, go.Spot.Left, false, true));
myDiagram.model.nodeDataArray = [{ key: 1, text: "算法配置", color: "#C0818B",isGroup: true },
]

效果
4.拖动属性到右侧之后自动生成连线的问题,这里我们使用gojs事件来实现,可添加监听节点生成事件,当节点拖到右侧生成之后,根据节点的key值来判断是输入属性还是输出属性,之后添加连线即可,这里“算法配置”框设置key值为1,上面代码有显示,其他属性的key值自己设置

//添加监听节点生成事件
myDiagram.addDiagramListener("externalobjectsdropped",function(e) {e.subject.each(function(n){if(n.data.key.indexOf("FTPIN") != -1||n.data.key.indexOf("MQTTIN") != -1||n.data.key.indexOf("HTTPIN") != -1||n.data.key.indexOf("RTSPIN") != -1){myDiagram.model.addLinkData({ from: n.data.key, to: 1 });}if(n.data.key.indexOf("FTPOUT") != -1||n.data.key.indexOf("MQTTOUT") != -1||n.data.key.indexOf("HTTPOUT") != -1){myDiagram.model.addLinkData({ from:1 , to: n.data.key });}});});

5.“保存”,“加载”方法略,所有功能实现,界面如下图

完整代码

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><script src="js/jquery-3.2.1.min.js"></script><script src="js/go-debug.js"></script><script src="https://gojs.net/latest/extensions/Figures.js"></script><script src="js/layer-v3.1.1/layer/layer.js"></script><style>body{width: 100%;height: 100%;margin: 0;padding: 0;position: absolute;}.bg{background:#BFCDE9 ;height: 10%;width: 100%;position: relative;}.logo{width: auto;height: 100%;position: absolute;left: 10px;padding: 10px;}.logo>img{width: auto;height: 80%;}.logo>span{font: 54px bold ;vertical-align: top;margin: 0 20px;text-shadow: 5px 5px 5px grey;color: #070475;}.info{width: auto;height: 30px;position: absolute;right: 10px;bottom: 10px;}.info>div{width: 120px;height: 30px;border-radius: 100px / 100px;text-align: center;color: white;line-height: 30px;float: left;margin-right: 10px;}.content{width: 100%;height: 90%; display: flex; position: relative;}#myDiagramDiv{background-repeat: no-repeat;background-size:100% 100%;flex-grow: 1; background-color: darkgray;/* background-image: url(img/bg.jpg); */}#myPaletteDiv{width: 200px; background:#BFCDE9 ;}</style></head><body><div class="bg"><div class="logo"><img src="img/v-logo.png" /><span>XXXXXXXXXXXXXXXXXXXXXX</span></div><div class="info"><div style="background-color:#A49ED7 ;">NPU <span id="npu">20T</span></div><div style="background-color:#34C2C2 ;">CPU <span id="cpu">300%</span></div><div style="background-color:#EF8F8A ;">MEM <span id="mem">30%</span></div><div style="background-color:#F0637F ;">TMP <span id="tmp">65℃</span></div></div></div><div class="content"><div id="myPaletteDiv"></div><div id="myDiagramDiv"></div></div><script>let nodeDataArray,linkDataArray;$(function(){init();//setInterval(function(){ getData() }, 5000);})function getData(){//获取右上角参数,5秒更新一次var settings = {"url": "/api/systemInformation","method": "GET","timeout": 0,"headers": {"Content-Type": "application/x-www-form-urlencoded"}};$.ajax(settings).done(function (response) {//console.log(JSON.parse(response));$("#npu").html("")$("#cpu").html("")$("#mem").html("")$("#tmp").html("")var data=JSON.parse(response)$("#npu").append(data.npuAble)$("#cpu").append(data.cpu)$("#mem").append(data.memory)$("#tmp").append(data.temperature+"℃")});}function init() {if (window.goSamples) goSamples();  var $$ = go.GraphObject.make; myDiagram =$$(go.Diagram, "myDiagramDiv",{"LinkDrawn": showLinkLabel,  "LinkRelinked": showLinkLabel,"undoManager.isEnabled": true});//链接标签来自“条件”节点,则使其可见//此监听器由“linkdraw”和“LinkRelinked”图表事件调用function showLinkLabel(e) {var label = e.subject.findObject("LABEL");if (label !== null) label.visible = (e.subject.fromNode.data.category === "Conditional");}// LinkingTool和RelinkingTool使用的临时链接也是正交的myDiagram.toolManager.linkingTool.temporaryLink.routing = go.Link.Orthogonal;myDiagram.toolManager.relinkingTool.temporaryLink.routing = go.Link.Orthogonal;function makePort(name, align, spot, output, input) {//此方法未使用到var horizontal = align.equals(go.Spot.Top) || align.equals(go.Spot.Bottom);//连接端口,透明矩形return $$(go.Shape,{fill: "transparent",  // changed to a color in the mouseEnter event handlerstrokeWidth: 0,  // no strokewidth: horizontal ? NaN : 8,  // if not stretching horizontally, just 8 wideheight: !horizontal ? NaN : 8,  // if not stretching vertically, just 8 tallalignment: align,  // align the port on the main Shapestretch: (horizontal ? go.GraphObject.Horizontal : go.GraphObject.Vertical),portId: name,  // declare this object to be a "port"fromSpot: spot,  // declare where links may connect at this portfromLinkable: output,  // declare whether the user may draw links from heretoSpot: spot,  // declare where links may connect at this porttoLinkable: input,  // declare whether the user may draw links to herecursor: "pointer",  // show a different cursor to indicate potential link pointmouseEnter: function(e, port) {  //鼠标悬浮颜色if (!e.diagram.isReadOnly) port.fill = "rgba(255,0,255,0.5)";},mouseLeave: function(e, port) {port.fill = "transparent";}});}// helper definitions for node templatesfunction nodeStyle() {return [new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),{locationSpot: go.Spot.Center}];}function makeWidthBinding(idx) {function getColumnWidth(arr) {if (Array.isArray(arr) && idx < arr.length) return arr[idx];return NaN;}function setColumnWidth(w, data) {var arr = data.widths;if (!arr) arr = [];if (idx >= arr.length) {for (var i = arr.length; i <= idx; i++) arr[i] = NaN;  // default to NaN}arr[idx] = w;return arr;  // need to return the Array (as the value of data.widths)}return [{ column: idx },new go.Binding("width", "widths", getColumnWidth).makeTwoWay(setColumnWidth)]}//加载function loadDiagram(){var settings = {"url": "/api/config","method": "GET","timeout": 0,"headers": {"Content-Type": "application/x-www-form-urlencoded"}};$.ajax(settings).done(function (response) {//console.log(response);nodeDataArray=JSON.parse(response).nodeDataArray;linkDataArray=JSON.parse(response).linkDataArray;if(linkDataArray.length===0){layer.msg('暂无配置可加载',{icon: 5})}else{for(var i=0;i<linkDataArray.length;i++){delete(linkDataArray[i]['points'])}myDiagram.model = $$(go.GraphLinksModel,{copiesArrays: true,copiesArrayObjects: true,nodeDataArray: nodeDataArray,linkDataArray: linkDataArray});}});}//保存数据function diagramTojson() {var dataArray = {}//所有数据数组var diagramJson = myDiagram.model.toJson();var diagramData = JSON.parse(diagramJson).nodeDataArray;//console.log(diagramJson);var ftpArray=[];var mqttArray=[];var httpArray=[];var modelArray=[];var tcpnpuArray=[];var rtspinfoArray=[];for(var i=1;i<diagramData.length;i++){var activeObject = {}//字符串拼接for(var j=0;j<diagramData[i].fields.length;j++){activeObject[diagramData[i].fields[j].name] = diagramData[i].fields[j].info;}if(diagramData[i].key.indexOf("FTP") != -1){ftpArray.push(activeObject)dataArray['ftp']=ftpArray}else if(diagramData[i].key.indexOf("MQTT") != -1){mqttArray.push(activeObject)dataArray['mqtt']=mqttArray}else if(diagramData[i].key.indexOf("HTTP") != -1){httpArray.push(activeObject)dataArray['http']=httpArray}else if(diagramData[i].key.indexOf("MODEL") != -1 ){modelArray.push(activeObject)dataArray['model']=modelArray}else if(diagramData[i].key.indexOf("TCPNPU") != -1 ){tcpnpuArray.push(activeObject)dataArray['tcpnpu']=tcpnpuArray}else if(diagramData[i].key.indexOf("RTSP") != -1 ){rtspinfoArray.push(activeObject)dataArray['rtspinfo']=rtspinfoArray}else{}}var data=JSON.stringify(dataArray)// console.log(data)var settings = {"url": "/api/config","method": "POST","timeout": 0,"headers": {"Content-Type": "application/x-www-form-urlencoded"},"data": {sourceData:diagramJson,combineData:data},};$.ajax(settings).done(function (response) {if(JSON.parse(response).status==='ok')layer.msg('保存成功',{icon: 1})});}function makeLayout(horiz) {if (horiz) {return $$(go.GridLayout,{wrappingWidth: Infinity, alignment: go.GridLayout.Position,cellSize: new go.Size(1, 1), spacing: new go.Size(4, 4)});} else {return $$(go.GridLayout,{wrappingColumn: 1, alignment: go.GridLayout.Position,cellSize: new go.Size(1, 1), spacing: new go.Size(4, 4)});}}function highlightGroup(e, grp, show) {if (!grp) return;e.handled = true;if (show) {var tool = grp.diagram.toolManager.draggingTool;var map = tool.draggedParts || tool.copiedParts; if (grp.canAddMembers(map.toKeySet())) {grp.isHighlighted = true;return;}}grp.isHighlighted = false;}function finishDrop(e, grp) {var ok = (grp !== null? grp.addMembers(grp.diagram.selection, true): e.diagram.commandHandler.addTopLevelParts(e.diagram.selection, true));if (!ok) e.diagram.currentTool.doCancel();}var fieldTemplate =$$(go.Panel, "TableRow", {background: "transparent",  fromSpot: go.Spot.RighttoSpot: go.Spot.Left,// allow drawing links from or to this port:fromLinkable: true, toLinkable: true},$$(go.TextBlock,{column: 1,margin: new go.Margin(0, 2),stretch: go.GraphObject.Horizontal,font: "bold 13px sans-serif",wrap: go.TextBlock.None,overflow: go.TextBlock.OverflowEllipsis,// and disallow drawing links from or to this text:fromLinkable: false, toLinkable: false,editable: true            },new go.Binding("text", "name").makeTwoWay()),$$(go.TextBlock,{column: 2,margin: new go.Margin(0, 2),stretch: go.GraphObject.Horizontal,font: "13px sans-serif",maxLines: 3,overflow: go.TextBlock.OverflowEllipsis,editable: true},new go.Binding("text", "info").makeTwoWay()));var itemTempl =$$(go.Panel, "Horizontal",$$(go.Shape,{ desiredSize: new go.Size(15, 15), strokeJoin: "round", strokeWidth: 3, stroke: null, margin: 2 },new go.Binding("figure", "figure"),new go.Binding("fill", "color"),new go.Binding("stroke", "color")),$$(go.TextBlock,{stroke: "#333333",font: "bold 14px sans-serif"},new go.Binding("text", "name")));//矩形,title样式myDiagram.nodeTemplateMap.add("Title",$$(go.Node, "Table", nodeStyle(),$$(go.Panel, "Auto",$$(go.Shape, "Rectangle",{ minSize: new go.Size(120, 40), stroke: "#eeeeee", strokeWidth: 1 },new go.Binding("fill", "background")),$$(go.TextBlock, "Tablename", {font: "bold 14pt Helvetica, Arial, sans-serif",stroke: "black"},{editable: true},new go.Binding("text"))),// three named ports, one on each side except the top, all output only:makePort("T", go.Spot.Top, go.Spot.Top,  true,false ),makePort("L", go.Spot.Left, go.Spot.Left, true,false ),makePort("R", go.Spot.Right, go.Spot.Right, true, false),makePort("B", go.Spot.Bottom, go.Spot.Bottom, true, false)));//矩形,button样式1myDiagram.nodeTemplateMap.add("Button",$$(go.Node, "Auto",nodeStyle(),$$(go.Shape, "Rectangle",{ strokeWidth: 2, stroke: "#76C176" }),$$(go.Panel, "Vertical",$$("Button",{minSize: new go.Size(120, 40)},{click:  diagramTojson},$$(go.TextBlock, "Click me!",{font: "12pt 华文细黑"},new go.Binding("text"))))));//矩形,button样式2myDiagram.nodeTemplateMap.add("getButton",$$(go.Node, "Auto",nodeStyle(),$$(go.Shape, "Rectangle",{ strokeWidth: 2, stroke: "#76C176" }),$$(go.Panel, "Vertical",$$("Button",{minSize: new go.Size(120, 40)},{click:  loadDiagram},$$(go.TextBlock, "Click me!",{font: "12pt 华文细黑"},new go.Binding("text"))))));//折叠框样式myDiagram.nodeTemplateMap.add("ExpandePanel",$$(go.Node, "Auto", {selectionAdorned: true,resizable: true,layoutConditions: go.Part.LayoutStandard & ~go.Part.LayoutNodeSized,fromSpot: go.Spot.AllSides,toSpot: go.Spot.AllSides,isShadowed: true,shadowOffset: new go.Point(3, 3),shadowColor: "#C5C1AA",locationSpot: go.Spot.Center},new go.Binding("desiredSize", "visible", function(v) { return new go.Size(NaN, NaN); }).ofObject("LIST"),$$(go.Shape, "RoundedRectangle",{ strokeWidth: 0,cursor: "pointer",minSize:new go.Size(120, 30) },new go.Binding("fill", "background")),$$(go.Panel, "Table",{ margin: 8, stretch: go.GraphObject.Fill},$$(go.RowColumnDefinition, { row: 0, sizing: go.RowColumnDefinition.None }),$$(go.TextBlock,{row: 0, alignment: go.Spot.Center,margin: new go.Margin(0, 24,0,0),  font: "bold 13px sans-serif"},new go.Binding("text", "key")),// the collapse/expand button$$("PanelExpanderButton", "LIST",  { row: 0, alignment: go.Spot.TopRight }),$$(go.Panel, "Vertical",{name: "LIST",row: 1,padding: 1,alignment: go.Spot.TopLeft,defaultAlignment: go.Spot.Left,stretch: go.GraphObject.Horizontal,itemTemplate: itemTempl,visible:false,background: "white"},$$(go.Panel, "Table",{name: "TABLE", stretch: go.GraphObject.Horizontal,minSize: new go.Size(100, 10),defaultAlignment: go.Spot.Left,defaultStretch: go.GraphObject.Horizontal,defaultColumnSeparatorStroke: "gray",defaultRowSeparatorStroke: "gray",itemTemplate: fieldTemplate},$$(go.RowColumnDefinition, makeWidthBinding(0)),$$(go.RowColumnDefinition, makeWidthBinding(1)),$$(go.RowColumnDefinition, makeWidthBinding(2)),new go.Binding("itemArray", "fields")))  // end Table Panel)// end Node))//绘制节点模板myDiagram.nodeTemplate =$$("Node", "Auto",{locationSpot: go.Spot.Center,layerName: "Background"},  // always have regular nodes behind Links$$("Shape", "RoundedRectangle",{fill: "white",fromLinkable: true, toLinkable: true, cursor: "pointer",width:100,height:80},new go.Binding("fill", "color")),$$("TextBlock",{ margin: 8 },  // make some extra space for the shape around the textnew go.Binding("text", "text")), // the label shows the node data's keymakePort("L", go.Spot.Left, go.Spot.Left, false, true));//绘制链路模板myDiagram.linkTemplate =$$(go.Link, {routing: go.Link.AvoidsNodes,curve: go.Link.JumpOver,corner: 10},new go.Binding("points").makeTwoWay(),$$(go.Shape,  //突出的形状,通常是透明的{ isPanelMain: true, strokeWidth: 2, stroke: "white", name: "HIGHLIGHT" }),$$(go.Shape,  //链接路径形状{ isPanelMain: true, stroke: "white", strokeWidth: 2 },new go.Binding("stroke", "isSelected", function(sel) { return sel ? "dodgerblue" : "white"; }).ofObject()),$$(go.Shape,  //箭头{ toArrow: "standard", strokeWidth: 0, fill: "white" }),$$(go.Panel, "Auto",  //链接标签,通常不可见{ visible: false, name: "LABEL", segmentIndex: 2, segmentFraction: 0.5 },new go.Binding("visible", "visible").makeTwoWay(),$$(go.Shape, "RoundedRectangle",  //标签形状{ fill: "#F8F8F8", strokeWidth: 0 }),$$(go.TextBlock, "Yes",  //标签{textAlign: "center",font: "10pt helvetica, arial, sans-serif",stroke: "#333333",editable: true},new go.Binding("text").makeTwoWay())));//绘制组模板myDiagram.groupTemplate =$$(go.Group, "Auto",// 设置组属性和排版{background: "transparent",ungroupable: true,mouseDragEnter: function(e, grp, prev) { highlightGroup(e, grp, true); },mouseDragLeave: function(e, grp, next) { highlightGroup(e, grp, false); },computesBoundsAfterDrag: true,mouseDrop: finishDrop,handlesDragDropForMembers: true,  layout: makeLayout(false)},new go.Binding("layout", "horiz", makeLayout),new go.Binding("background", "isHighlighted", function(h) {return h ? "rgba(255,0,0,0.2)" : "transparent";}).ofObject(),$$(go.Shape, "Rectangle",// 红色矩形框{ fill: null, stroke: "#33D3E5", strokeWidth: 2 },new go.Binding("stroke", "color")),$$(go.Panel, "Vertical",  $$(go.Panel, "Horizontal", { stretch: go.GraphObject.Horizontal, background: "#33D3E5" },new go.Binding("background", "color"),$$("SubGraphExpanderButton", // 展开收起按钮{ alignment: go.Spot.Right, margin: 5 }),$$(go.TextBlock,{alignment: go.Spot.Left,editable: true,margin: (5,14),font: "bold 20px sans-serif",opacity: 1,  stroke: "white"},new go.Binding("text", "text").makeTwoWay())),  $$(go.Placeholder,{ padding: 5, alignment: go.Spot.TopLeft }))  );myDiagram.model.nodeDataArray = [{ key: 1, text: "算法配置", color: "#C0818B",isGroup: true },]//添加监听节点生成事件myDiagram.addDiagramListener("externalobjectsdropped",function(e) {e.subject.each(function(n){if(n.data.key.indexOf("FTPIN") != -1||n.data.key.indexOf("MQTTIN") != -1||n.data.key.indexOf("HTTPIN") != -1||n.data.key.indexOf("RTSPIN") != -1){myDiagram.model.addLinkData({ from: n.data.key, to: 1 });}if(n.data.key.indexOf("FTPOUT") != -1||n.data.key.indexOf("MQTTOUT") != -1||n.data.key.indexOf("HTTPOUT") != -1){myDiagram.model.addLinkData({ from:1 , to: n.data.key });}});});//初始化页面左侧的调色板myPalette =$$(go.Palette, "myPaletteDiv",{nodeTemplateMap: myDiagram.nodeTemplateMap, model: new go.GraphLinksModel([  //指定调色板的内容{ category: "Title", text: "输入",background:"#70D4FF" },{ category: "ExpandePanel", key:"FTPIN",background:"#95DDFF",fields: [{ name: "username", info: "data"},{ name: "pwd", info: "data"},{ name: "localDir", info: "data"},{ name: "ipaddress", info: "data"},{ name: "port", info: "data"},{ name: "ftpDir", info: "data"},{ name: "inout", info: "in"},]},{ category: "ExpandePanel", key:"MQTTIN",background:"#95DDFF",fields: [{ name: "username", info: "data"},{ name: "pwd", info: "data"},{ name: "localDir", info: "data"},{ name: "host", info: "data"},{ name: "port", info: "data"},{ name: "inout", info: "data"}]},{ category: "ExpandePanel", key:"HTTPIN",background:"#95DDFF",fields: [{ name: "username", info: "data"},{ name: "pwd", info: "data"},{ name: "urlapi", info: "data"},{ name: "host", info: "data"},{ name: "port", info: "data"},{ name: "inout", info: "data"}]},{ category: "ExpandePanel", key:"RTSPIN",background:"#95DDFF",fields: [{ name: "url", info: "data"},{ name: "uuid", info: "data"},{ name: "modelFunction", info: "data"},{ name: "x", info: "data"},{ name: "y", info: "data"},{ name: "w", info: "data"},{ name: "h", info: "data"},]},{ category: "Title", text: "模型" ,background:"#FFBE51"},{ category: "ExpandePanel", key:"MODEL",background:"#FFEDD0",fields: [{ name: "mainModel", info: "data"},{ name: "detectNum", info: "data"},{ name: "label", info: "data"},{ name: "percentage", info: "data"}]},{ category: "ExpandePanel", key:"TCPNPU",background:"#FFEDD0",fields: [{ name: "ip", info: "data"},{ name: "mainModel", info: "data"},{ name: "detectNum", info: "data"},{ name: "label", info: "data"},{ name: "percentage", info: "data"}]},{ category: "Title", text: "输出" ,background:"#72C2C2"},{ category: "ExpandePanel", key:"FTPOUT",background:"#9AD3D3",fields: [{ name: "username", info: "data"},{ name: "pwd", info: "data"},{ name: "localDir", info: "data"},{ name: "ipaddress", info: "data"},{ name: "port", info: "data"},{ name: "ftpDir", info: "data"},{ name: "inout", info: "out"},]},{ category: "ExpandePanel", key:"MQTTOUT",background:"#9AD3D3",fields: [{ name: "username", info: "data"},{ name: "pwd", info: "data"},{ name: "localDir", info: "data"},{ name: "host", info: "data"},{ name: "port", info: "data"},{ name: "inout", info: "data"}]},{ category: "ExpandePanel", key:"HTTPOUT",background:"#9AD3D3",fields: [{ name: "username", info: "data"},{ name: "pwd", info: "data"},{ name: "urlapi", info: "data"},{ name: "host", info: "data"},{ name: "port", info: "data"},{ name: "inout", info: "data"}]},{ category: "Button", text: "保存" },{category: "getButton", text: "加载"}])});}</script></body>
</html>

代码有点乱,有些方法没用到,还有表格添加删除行功能也可以加进去,暂时就酱~

使用gojs展示设备配置过程相关推荐

  1. 全方位说明从输入URL到页面展示的过程

    大概的流程: 第一部分是加载一个资源的过程: 1.  浏览器根据DNS服务器得到域名的IP地址 2.  向这个IP的机器发送http请求 3.  服务器收到.处理并返回http请求 4.  浏览器的到 ...

  2. 制作食物官网及网页展示的过程

    一开始我对网页的制作一无所知,直到老师布置了一个作业,让我们在网上找二十张食物类型的网页,然后我就开始找网页,找得一头雾水,而且找的网页也不怎么好看,基本都是网店类型的网页.找网页的作业做完了,老师就 ...

  3. 输入一个url到浏览器页面展示都经历了哪些过程

    在日常的浏览器访问过程中,我们肯定会访问n多页面,但是我们输入一个网址后是如何变成一个页面展示在我们面前,从一个url到页面的展示这个过程中,我们的浏览器都经历了一些什么? 步骤 → 1- 输入网址 ...

  4. 100内奇数之和流程图_IATF 16949体系资料之过程流程图,收藏备用!

    如果你不需要一键查遍国家.地方.行业标准,也不需要一个更好的工作机会,那拜托千万不要点击这个链接!!!下面为大家整理和展示了过程逻辑图和18个典型的一级过程流程图,包括流程的输入.输出,过程活动及操作 ...

  5. 5G的风头盖过了AI,英特尔展示未来四大应用场景 | MWC2018

    来源:36Kr 摘要:英特尔公司网络平台事业部副总裁Alex Quach在接受采访时表示,5G已经从实验室带到了实时现场.事实上,在MWC2018现场,英特尔则直接展示了5G网络未来可以落地的场景. ...

  6. linearregression_机器学习-TensorFlow建模过程 Linear Regression线性拟合应用

    TensorFlow是咱们机器学习领域非常常用的一个组件,它在数据处理,模型建立,模型验证等等关于机器学习方面的领域都有很好的表现,前面的一节我已经简单介绍了一下TensorFlow里面基础的数据结构 ...

  7. mapreduce shuffle过程问答

    通过hadoop权威指南学习hadoop,对shuffle过程一直很疑惑,经过查看网上多个帖子,最终 完成此篇问答总结. 1.什么叫shuffle 从map任务输出到reducer任务输入之间的过程就 ...

  8. Java递归一个四十万的树结构_java递归展示树形图代码实现以及遇到的问题

    我最近写到了一个项目中用到了树形图,不得不说这个树形图是真的扯淡: 我用到的是layui中的树形图,再展示数据过程中遇到了很多的问题,废话不多说,直接贴代码. 一.调用排序接口,对数据进行排序. 二. ...

  9. 原生js循环展示dom_为什么说JS的DOM操作很耗性能

    想问这样的问题,其实是自己心中没有个谱,一直用 js 计算性能来衡量 浏览器dom 操作性能.js性能和浏览器性能其实是两码事. 这个问题很抽象,它里面涉及挺多个小的知识点. 重申一点,js 操作 D ...

最新文章

  1. 区块链将带来怎样的应用?
  2. c++采集声卡输出_舒尔 Shure RMCE-LTG Lightning-MMCX接口耳机线[线型声卡]测评报告 [Soomal]...
  3. 【转】python删除小记
  4. [云炬Mysql数据库笔记] 第3章 数据定义
  5. ubuntu python3.6_在 Ubuntu 16.04 LTS 系统上安装 Python 3.6
  6. CoolQ/DingTalk 实现CI/CD消息推送到群
  7. 什么时候考虑使用神经网络
  8. mysql 6.17_2020 6/17 mysql数据的增删改查
  9. php获取外部URL,使用PHP从外部API / URL获取信息
  10. windows下手动安装composer并配置环境变量
  11. input type=file accept中可以限制的文件类型
  12. sql 常见查询代码操作
  13. 浅谈关于Java中map这个类衍生的类
  14. 【STC单片机】STC15单片机读取MPU6050模块数据并串口输出
  15. 机器学习——sklearn实现决策树(隐形眼镜预测和鸢尾花分类)
  16. 腾讯云CDN加速产品介绍第二章-CDN系统架构
  17. 2021-08-26小白笔记
  18. [生存志] 第136节 相如辞赋神来之笔
  19. android中文字体加粗,android TextView设置中文字体加粗实现方法
  20. Gradle-SpringCloud聚合项目配置

热门文章

  1. linux多线程编程实验报告,Linux多线程编程
  2. [ Term ] 你真的了解 UTC 时间吗?它和 GMT 时间的区别是什么?
  3. npm包前的@ 是什么意思
  4. jinja2-模板过滤器
  5. Android常用英文词汇(仅限自己收藏)
  6. node安装步骤以及环境配置
  7. 做短视频必备配音神器|最近超火的AI配音制作工具分享
  8. 二十四节气-立春海报、文案分享~万物起始 岁月向荣
  9. 计算机毕业设计之高校科研信息管理系统
  10. 01背包问题(当有的背包重量是非整数时)的递归(优化成动态规划+再用滚动数组优化)解法+一些动态规划(递归,搜索)的高级技巧