To achieve this effect, which layout do I need?
Horizontal and longitudinal alignment and connection lines are not bent
Thanks
I have moved your post to start a new topic, because it seems to be about a completely different kind of diagram.
You are doing new development, so you should be using the latest version of GoJS, not some ancient version.
The general answer to your question about link routing is that you want the default routing without any fromSpot or toSpot. Note that TreeLayout by default does set Link.fromSpot and Link.toSpot, but you can turn that off both at the parent and at the child.
Regarding an automatic layout for achieving that result, the overall layout can easily be achieved by customizing TreeLayout to alternate the angle at which those branches should go. Although it isn’t clear to me right now how to decide which path is the “main” one that you want to be straight, and which path(s) should go off at a right angle.
I’m not sure about an automatic way to position those third and fourth branches from those red circles. If you are not too particular about exactly where those branches should go, it might not be too difficult.
If you can provide a minimal data model, I could try to create a sample for you.
nodeDataArray:
[
{
"category": "pole",
"layerName": "lineChart",
"key": "SBID000000B4D4E3CC433A45CAA58D600FEE09C899",
"text": "母线",
"type": "31100000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "T000004",
"text": "VirtualDots",
"type": null
},
{
"category": "tran2",
"layerName": "lineChart",
"key": "120000008904",
"text": "T1",
"type": "11000000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "SBID000000303A39A19A2946699389B035CFD069E2",
"text": "母线",
"type": "31100000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "T000003",
"text": "VirtualDots",
"type": null
},
{
"category": "tran2",
"layerName": "lineChart",
"key": "120000010337",
"text": "1",
"type": "11000000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "SBID00000075CD4E0711704248964B81D80AB96097",
"text": "母线",
"type": "31100000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "T000001",
"text": "VirtualDots",
"type": null
},
{
"category": "tran2",
"layerName": "lineChart",
"key": "120000514050",
"text": "T1",
"type": "11000000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00010",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "fe387b59908a06deec55b3b54c0155fe37bd48001b",
"text": "母线",
"type": "31100000"
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "14000343560238",
"text": "F213ADS",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000012",
"text": "VirtualDots",
"type": null
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "14000344049242",
"text": "F213AADS1环",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000011",
"text": "VirtualDots",
"type": null
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "14000344049264",
"text": "F214意中纺织",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00002",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "df304780-c056-4226-be9c-3e6b201852fa",
"text": "10kVADS1#柜(三遥) 母线",
"type": "31100000"
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "1669a80c-cd7e-4b0a-8353-550e1204ad98",
"text": "ADS",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "station",
"layerName": "lineChart",
"key": "aaaa",
"text": "万安变母线",
"type": "31100000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00001",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000001",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000003",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00003",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000005",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00005",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000007",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "SBID00000063552060DC9F45F78204D86D52C4FB14",
"text": "母线",
"type": "31100000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00007",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000009",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00009",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000010",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00011",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00012",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "T000002",
"text": "VirtualDots",
"type": null
},
{
"category": "tran2",
"layerName": "lineChart",
"key": "300005380820",
"text": "T1",
"type": "11000000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000002",
"text": "VirtualDots",
"type": null
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "86797c5d-b69f-453a-9165-36a935a97fa9",
"text": "10kV查镇线124联络开关",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "9017d7d6-1d52-4c43-b134-d309c9c6c605",
"text": "10kVADS1#柜(三遥) 213A1开关",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "9200000033189",
"text": "液压102264(三遥+分支)",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "9200000125856",
"text": "1082113KG06(二遥)",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "9200000139115",
"text": "1082113KG05(二遥)",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "9200000156270",
"text": "1082113KG03(二遥)",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "e9fbd2fc-65b9-4ff3-a618-3e8ba0ca4fa6",
"text": "10kvADS113开关",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
}
]
linkDataArray:
[
{
"from": "SBID000000B4D4E3CC433A45CAA58D600FEE09C899",
"to": "120000008904",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "port",
"toPort": "input"
},
{
"from": "120000008904",
"to": "T000004",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "out",
"toPort": "port"
},
{
"from": "SBID000000303A39A19A2946699389B035CFD069E2",
"to": "120000010337",
"category": "variable",
"layerName": "pointChart",
"text": "1",
"fromPort": "port",
"toPort": "input"
},
{
"from": "120000010337",
"to": "T000003",
"category": "variable",
"layerName": "pointChart",
"text": "1",
"fromPort": "out",
"toPort": "port"
},
{
"from": "SBID00000075CD4E0711704248964B81D80AB96097",
"to": "120000514050",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "port",
"toPort": "input"
},
{
"from": "120000514050",
"to": "T000001",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00010",
"to": "14000343560238",
"category": "variable",
"layerName": "pointChart",
"text": "F213ADS",
"fromPort": "port",
"toPort": "input"
},
{
"from": "14000343560238",
"to": "fe387b59908a06deec55b3b54c0155fe37bd48001b",
"category": "variable",
"layerName": "pointChart",
"text": "F213ADS",
"fromPort": "out",
"toPort": "port"
},
{
"from": "fe387b59908a06deec55b3b54c0155fe37bd48001b",
"to": "14000344049242",
"category": "variable",
"layerName": "pointChart",
"text": "F213AADS1环",
"fromPort": "port",
"toPort": "input"
},
{
"from": "14000344049242",
"to": "X000012",
"category": "variable",
"layerName": "pointChart",
"text": "F213AADS1环",
"fromPort": "out",
"toPort": "port"
},
{
"from": "fe387b59908a06deec55b3b54c0155fe37bd48001b",
"to": "14000344049264",
"category": "variable",
"layerName": "pointChart",
"text": "F214意中纺织",
"fromPort": "port",
"toPort": "input"
},
{
"from": "14000344049264",
"to": "X000011",
"category": "variable",
"layerName": "pointChart",
"text": "F214意中纺织",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00002",
"to": "1669a80c-cd7e-4b0a-8353-550e1204ad98",
"category": "variable",
"layerName": "pointChart",
"text": "ADS",
"fromPort": "port",
"toPort": "input"
},
{
"from": "1669a80c-cd7e-4b0a-8353-550e1204ad98",
"to": "df304780-c056-4226-be9c-3e6b201852fa",
"category": "variable",
"layerName": "pointChart",
"text": "ADS",
"fromPort": "out",
"toPort": "port"
},
{
"from": "aaaa",
"to": "XL00001",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000001",
"to": "XL00002",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000003",
"to": "XL00003",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000005",
"to": "SBID00000075CD4E0711704248964B81D80AB96097",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "XL00003",
"to": "XL00005",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000007",
"to": "SBID00000063552060DC9F45F78204D86D52C4FB14",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "XL00005",
"to": "XL00007",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000009",
"to": "SBID000000303A39A19A2946699389B035CFD069E2",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "XL00007",
"to": "XL00009",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000010",
"to": "XL00010",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000011",
"to": "SBID000000B4D4E3CC433A45CAA58D600FEE09C899",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000012",
"to": "XL00011",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000012",
"to": "XL00012",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "SBID00000063552060DC9F45F78204D86D52C4FB14",
"to": "300005380820",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "port",
"toPort": "input"
},
{
"from": "300005380820",
"to": "T000002",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "out",
"toPort": "port"
},
{
"from": "df304780-c056-4226-be9c-3e6b201852fa",
"to": "86797c5d-b69f-453a-9165-36a935a97fa9",
"category": "variable",
"layerName": "pointChart",
"text": "10kBFC124联络开关",
"fromPort": "port",
"toPort": "input"
},
{
"from": "86797c5d-b69f-453a-9165-36a935a97fa9",
"to": "X000002",
"category": "variable",
"layerName": "pointChart",
"text": "10kBFC124联络开关",
"fromPort": "out",
"toPort": "port"
},
{
"from": "df304780-c056-4226-be9c-3e6b201852fa",
"to": "9017d7d6-1d52-4c43-b134-d309c9c6c605",
"category": "variable",
"layerName": "pointChart",
"text": "10kVADS1#柜(三遥) 213A1开关",
"fromPort": "port",
"toPort": "input"
},
{
"from": "9017d7d6-1d52-4c43-b134-d309c9c6c605",
"to": "X000003",
"category": "variable",
"layerName": "pointChart",
"text": "10kVADS1#柜(三遥) 213A1开关",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00009",
"to": "9200000033189",
"category": "variable",
"layerName": "pointChart",
"text": "液压102264(三遥+分支)",
"fromPort": "port",
"toPort": "input"
},
{
"from": "9200000033189",
"to": "X000010",
"category": "variable",
"layerName": "pointChart",
"text": "液压102264(三遥+分支)",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00005",
"to": "9200000125856",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG06(二遥)",
"fromPort": "port",
"toPort": "input"
},
{
"from": "9200000125856",
"to": "X000007",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG06(二遥)",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00003",
"to": "9200000139115",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG05(二遥)",
"fromPort": "port",
"toPort": "input"
},
{
"from": "9200000139115",
"to": "X000005",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG05(二遥)",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00007",
"to": "9200000156270",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG03(二遥)",
"fromPort": "port",
"toPort": "input"
},
{
"from": "9200000156270",
"to": "X000009",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG03(二遥)",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00001",
"to": "e9fbd2fc-65b9-4ff3-a618-3e8ba0ca4fa6",
"category": "variable",
"layerName": "pointChart",
"text": "10kvADS113开关",
"fromPort": "port",
"toPort": "input"
},
{
"from": "e9fbd2fc-65b9-4ff3-a618-3e8ba0ca4fa6",
"to": "X000001",
"category": "variable",
"layerName": "pointChart",
"text": "10kvADS113开关",
"fromPort": "out",
"toPort": "port"
}
]
station Template:
export const station = ($, callback, myContextMenu) => {
return $(go.Node, "Spot", nodeStyle(),
new go.Binding("layerName", "layerName"),
{
locationSpot: go.Spot.Center, contextMenu: myContextMenu, click: (e, obj) => {
callback(e, obj);
}
},
$(go.Panel, "Vertical", { name: "TABLE", alignment: go.Spot.TopRight, alignmentFocus: new go.Spot(1, 1, -15, 0) },
$(go.TextBlock,
{ name: "TABLEText", text: '', stroke: "#000", font: "10px 微软雅黑, Arial, sans-serif", wrap: go.TextBlock.WrapFit, margin: new go.Margin(5, 15, 0, 15),
alignment: go.Spot.TopRight, alignmentFocus: new go.Spot(1, 1, -15, 0)
}
),
),
$(go.Picture, { desiredSize: new go.Size(30, 30), cursor: 'pointer',name: "ICON" }, { source: require("@/assets/images/station.svg") }),
$(go.Shape,
{
width: 2, height: 2, portId: "port", toSpot: go.Spot.Center, fill: 'black', stroke: 'black', strokeWidth: 1.5,
toMaxLinks: 1, fromLinkable: true, toLinkable: false
}),
$(go.TextBlock, {
alignment: go.Spot.Bottom, alignmentFocus: go.Spot.Top, stroke: "black" , margin: new go.Margin(40, 0, 0, 0)
},
new go.Binding("text"),
// new go.Binding("stroke"),
// new go.Binding("fill")
)
);
}
pole template:
export const pole = ($, callback, myContextMenu) => {
return $(go.Node, "Spot", nodeStyle(), new go.Binding("layerName", "layerName"), {
locationSpot: go.Spot.Center,
locationObjectName: 'BODY',
selectionObjectName: 'BODY',
contextMenu: myContextMenu, click: (e, obj) => {
callback(e, obj);
}
},
$(go.TextBlock,
{ name: "TABLEText", text: '', stroke: "#000", font: "10px 微软雅黑, Arial, sans-serif",
alignment: go.Spot.TopRight, alignmentFocus: new go.Spot(1, 1, -15, 0)
}
),
$(go.Shape, "Circle",
{
width: 8, height: 8, cursor: 'pointer', portId: "port", alignment: go.Spot.Center, fill: "rgba(0,0,0,0)", stroke: 'black', strokeWidth: 0.5,
fromLinkable: true, toLinkable: true,
}),
{
toolTip: // define a tooltip for each node
$(go.Adornment, "Spot", // that has several labels around it
{ background: "transparent" }, // avoid hiding tooltip when mouse moves
$(go.Placeholder, { padding: 5 }),
$(go.TextBlock,
{ alignment: go.Spot.Bottom, alignmentFocus: go.Spot.Top, stroke: "black" },
new go.Binding("text", "text", function (s) { return s; }))
) // end Adornment
}
);
}
breaker template:
export const breaker = ($, style, callback, myContextMenu) => {
var angle = 0;
if (style) angle = style.angle;
return $(go.Node, "Spot", new go.Binding("layerName", "layerName"),
{ locationSpot: go.Spot.Center, contextMenu: myContextMenu , click: (e, obj) => {
callback(e, obj);
}}, new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Picture, {
desiredSize: new go.Size(35, 45), cursor: 'pointer', angle: angle,name: "ICON"
},
new go.Binding("source", "imagePath", function (path) {
return require(`@/assets/images/${path}`);
})),
$(go.TextBlock,
{ name: "TABLEText", text: '', stroke: "#000", font: "10px 微软雅黑, Arial, sans-serif" }
),
$(go.Shape, portStyle(true),
{
portId: "input", alignment: go.Spot.LeftCenter, toMaxLinks: 1, width: 0.5, height: 0.5, click: (e, obj) => {
callback(e, obj);
}
}
),
$(go.Shape, portStyle(false),
{
portId: "out", alignment: go.Spot.RightCenter, toMaxLinks: 1, width: 0.5, height: 0.5, click: (e, obj) => {
callback(e, obj);
}
}), {
toolTip: // define a tooltip for each node
$(go.Adornment, "Spot", // that has several labels around it
{ background: "transparent" }, // avoid hiding tooltip when mouse moves
$(go.Placeholder, { padding: 5 }),
$(go.TextBlock,
{ alignment: go.Spot.Bottom, alignmentFocus: go.Spot.Top, stroke: "black" },
new go.Binding("text", "text", function (s) { return s; }))
) // end Adornment
}
);
}
tran2 template:
export const tran2 = ($, style, callback, myContextMenu) => {
var angle = 0;
if (style) angle = style.angle;
return $(go.Node, "Spot", new go.Binding("layerName", "layerName"),
{
locationSpot: go.Spot.Center, contextMenu: myContextMenu,selectionObjectName: "ICON" , click: (e, obj) => {
callback(e, obj);
}
}, new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Picture, { desiredSize: new go.Size(40, 40), cursor: 'pointer' }, { source: require("@/assets/images/tran2.svg"), angle: angle }),
$(go.Shape, portStyle(true),
{ portId: "input", alignment: go.Spot.Top, width: 1, height: 1, fromLinkable: true, toMaxLinks: 1 }
),
$(go.Shape, portStyle(false),
{
portId: "out", alignment: go.Spot.Bottom, width: 1, height: 1, toLinkable: true, toMaxLinks: 1, click: (e, obj) => {
callback(e, obj);
}
}), $(go.TextBlock, new go.Binding("text", "text"), { alignment: go.Spot.Bottom, alignmentFocus: go.Spot.Top, stroke: "black" })
);
}
The following picture is a rendering of visjs, but the animation is not very good, and needs to be replaced with gojs, and these data are consistent
Thank you very much, for helping me a lot, sorry for the trouble!
Thanks for providing the model, but you didn’t answer this important question:
I don’t see any information in the model that would help distinguish which branches should go towards the right and which ones should go downward.
I took the liberty of adding a “dir” property to the blue rectangle nodes to indicate whether that subtree should grown downwards or upwards. I also changed one of those subtrees to grow upwards, just to make sure that worked.
The following code produces:
The code requires GoJS version 3.
<!DOCTYPE html>
<html>
<head>
<title>Minimal GoJS Sample</title>
<!-- Copyright 1998-2024 by Northwoods Software Corporation. -->
</head>
<body>
<div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:400px"></div>
<textarea id="mySavedModel" style="width:100%;height:250px"></textarea>
<script src="https://cdn.jsdelivr.net/npm/gojs/release/go-debug.js"></script>
<script id="code">
class CustomTreeLayout extends go.TreeLayout {
constructor() {
super();
this.setsPortSpot = false;
this.setsChildPortSpot = false;
this._branches = null;
}
makeNetwork(coll) {
const net = super.makeNetwork(coll);
// for each vertex with children with a data.dir direction value,
// collect all of the tree parts going in that direction.
const branches = new go.Map();
net.vertexes.each(v => {
if (v.node && v.node.data.dir) {
const upward = v.node.data.dir === "up";
const parentv = v.sourceVertexes.first();
let dirs = branches.get(parentv);
if (!dirs) {
branches.set(parentv, dirs = [new go.Set(), new go.Set()]);
}
// assume just two directions, "upward" and not-"upward"
const dir = dirs[upward ? 1 : 0];
const subtree = v.node.findTreeParts();
// remove all of the subtree parts from the overall LayoutNetwork
subtree.each(part => {
if (part instanceof go.Link) {
net.deleteLink(part);
} else {
const shp = part.findObject("SHAPE");
if (shp) shp.angle = 90;
net.deleteNode(part);
}
});
// then add all of those parts to be laid out in the given direction
dir.addAll(subtree);
}
});
// now do double TreeLayouts for all downward and upward subtrees
branches.each(({ key, value }) => {
const vertex = key;
const parent = vertex.node;
parent.location = new go.Point(0, 0);
const arr = value;
const down = arr[0];
const up = arr[1];
// add common root for each subtree, for double tree layout
down.copy().each(part => {
if (part instanceof go.Node) {
if (part.findTreeParentNode() === parent) {
down.add(part.findTreeParentLink());
}
}
})
down.add(parent);
up.copy().each(part => {
if (part instanceof go.Node) {
if (part.findTreeParentNode() === parent) {
up.add(part.findTreeParentLink());
}
}
})
up.add(parent);
new go.TreeLayout({ angle: 90, arrangement: go.TreeArrangement.FixedRoots, setsPortSpot: false, setsChildPortSpot: false }).doLayout(down);
new go.TreeLayout({ angle: 270, arrangement: go.TreeArrangement.FixedRoots, setsPortSpot: false, setsChildPortSpot: false }).doLayout(up);
const downbnds = this.diagram.computePartsBounds(down);
const upbnds = this.diagram.computePartsBounds(up);
const totalbnds = downbnds.copy().unionRect(upbnds);
vertex.width = totalbnds.width;
vertex.focusX = parent.actualBounds.centerX - totalbnds.x;
vertex.height = totalbnds.height;
vertex.focusY = parent.actualBounds.centerY - totalbnds.y;
down.remove(parent);
down.removeAll(parent.findTreeChildrenLinks());
up.remove(parent);
up.removeAll(parent.findTreeChildrenLinks());
});
this._branches = branches;
return net;
}
commitNodes() {
super.commitNodes();
this._branches.each(({ key, value }) => {
const vert = key;
const parent = vert.node;
const arr = value;
const down = arr[0];
const downbnds = this.diagram.computePartsBounds(down);
this.diagram.moveParts(down, new go.Point(parent.location.x - downbnds.centerX, parent.location.y - downbnds.top + this.layerSpacing));
const up = arr[1];
const upbnds = this.diagram.computePartsBounds(up);
this.diagram.moveParts(up, new go.Point(parent.location.x - upbnds.centerX, parent.location.y - upbnds.bottom - this.layerSpacing * 1.5));
});
this._branches = null;
}
}
const myDiagram =
new go.Diagram("myDiagramDiv", {
layout: new CustomTreeLayout(),
initialAutoScale: go.AutoScale.UniformToFill,
"undoManager.isEnabled": true,
"ModelChanged": e => { // just for demonstration purposes,
if (e.isTransactionFinished) { // show the model data in the page's TextArea
document.getElementById("mySavedModel").textContent = e.model.toJson();
}
}
});
myDiagram.nodeTemplateMap.add("station",
new go.Node("Vertical", { locationObjectName: "SHAPE", locationSpot: go.Spot.Center })
.add(
new go.TextBlock()
.bind("text"),
new go.Shape("Circle", { name: "SHAPE", width: 30, height: 30, fill: "cyan", portId: "" })
)
)
myDiagram.nodeTemplateMap.add("pole",
new go.Node("Vertical", { locationObjectName: "SHAPE", locationSpot: go.Spot.Center })
.add(
new go.TextBlock()
.bind("text"),
new go.Shape("Circle", { name: "SHAPE", width: 15, height: 15, fill: "brown", strokeWidth: 0, portId: "" })
)
)
myDiagram.nodeTemplateMap.add("breaker",
new go.Node("Vertical", { locationObjectName: "SHAPE", locationSpot: go.Spot.Center })
.add(
new go.TextBlock()
.bind("text"),
new go.Shape({ name: "SHAPE", width: 40, height: 20, fill: "blue", portId: "" })
)
)
myDiagram.model = new go.GraphLinksModel(
[
{
"category": "pole",
"layerName": "lineChart",
"key": "SBID000000B4D4E3CC433A45CAA58D600FEE09C899",
"text": "母线",
"type": "31100000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "T000004",
"text": "VirtualDots",
"type": null
},
{
"category": "tran2",
"layerName": "lineChart",
"key": "120000008904",
"text": "T1",
"type": "11000000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "SBID000000303A39A19A2946699389B035CFD069E2",
"text": "母线",
"type": "31100000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "T000003",
"text": "VirtualDots",
"type": null
},
{
"category": "tran2",
"layerName": "lineChart",
"key": "120000010337",
"text": "1",
"type": "11000000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "SBID00000075CD4E0711704248964B81D80AB96097",
"text": "母线",
"type": "31100000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "T000001",
"text": "VirtualDots",
"type": null
},
{
"category": "tran2",
"layerName": "lineChart",
"key": "120000514050",
"text": "T1",
"type": "11000000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00010",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "fe387b59908a06deec55b3b54c0155fe37bd48001b",
"text": "母线",
"type": "31100000"
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "14000343560238",
"text": "F213ADS",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000012",
"text": "VirtualDots",
"type": null
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "14000344049242",
"text": "F213AADS1环",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000011",
"text": "VirtualDots",
"type": null
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "14000344049264",
"text": "F214意中纺织",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1,
"dir": "down"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00002",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "df304780-c056-4226-be9c-3e6b201852fa",
"text": "10kVADS1#柜(三遥) 母线",
"type": "31100000"
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "1669a80c-cd7e-4b0a-8353-550e1204ad98",
"text": "ADS",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "station",
"layerName": "lineChart",
"key": "aaaa",
"text": "万安变母线",
"type": "31100000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00001",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000001",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000003",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00003",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000005",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00005",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000007",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "SBID00000063552060DC9F45F78204D86D52C4FB14",
"text": "母线",
"type": "31100000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00007",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000009",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00009",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000010",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00011",
"text": "VirtualDots",
"type": null
},
{
"category": "pole",
"layerName": "lineChart",
"key": "XL00012",
"text": "VirtualDots",
"type": null,
"dir": "down"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "T000002",
"text": "VirtualDots",
"type": null
},
{
"category": "tran2",
"layerName": "lineChart",
"key": "300005380820",
"text": "T1",
"type": "11000000"
},
{
"category": "pole",
"layerName": "lineChart",
"key": "X000002",
"text": "VirtualDots",
"type": null
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "86797c5d-b69f-453a-9165-36a935a97fa9",
"text": "10kV查镇线124联络开关",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1,
"dir": "down"
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "9017d7d6-1d52-4c43-b134-d309c9c6c605",
"text": "10kVADS1#柜(三遥) 213A1开关",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "9200000033189",
"text": "液压102264(三遥+分支)",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "9200000125856",
"text": "1082113KG06(二遥)",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1,
"dir": "up"
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "9200000139115",
"text": "1082113KG05(二遥)",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1,
"dir": "down"
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "9200000156270",
"text": "1082113KG03(二遥)",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1,
"dir": "down"
},
{
"category": "breaker",
"layerName": "pointChart",
"key": "e9fbd2fc-65b9-4ff3-a618-3e8ba0ca4fa6",
"text": "10kvADS113开关",
"type": "30500000",
"imagePath": "zsglkg_1.svg",
"nodeState": 1
}
],
[
{
"from": "SBID000000B4D4E3CC433A45CAA58D600FEE09C899",
"to": "120000008904",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "port",
"toPort": "input"
},
{
"from": "120000008904",
"to": "T000004",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "out",
"toPort": "port"
},
{
"from": "SBID000000303A39A19A2946699389B035CFD069E2",
"to": "120000010337",
"category": "variable",
"layerName": "pointChart",
"text": "1",
"fromPort": "port",
"toPort": "input"
},
{
"from": "120000010337",
"to": "T000003",
"category": "variable",
"layerName": "pointChart",
"text": "1",
"fromPort": "out",
"toPort": "port"
},
{
"from": "SBID00000075CD4E0711704248964B81D80AB96097",
"to": "120000514050",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "port",
"toPort": "input"
},
{
"from": "120000514050",
"to": "T000001",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00010",
"to": "14000343560238",
"category": "variable",
"layerName": "pointChart",
"text": "F213ADS",
"fromPort": "port",
"toPort": "input"
},
{
"from": "14000343560238",
"to": "fe387b59908a06deec55b3b54c0155fe37bd48001b",
"category": "variable",
"layerName": "pointChart",
"text": "F213ADS",
"fromPort": "out",
"toPort": "port"
},
{
"from": "fe387b59908a06deec55b3b54c0155fe37bd48001b",
"to": "14000344049242",
"category": "variable",
"layerName": "pointChart",
"text": "F213AADS1环",
"fromPort": "port",
"toPort": "input"
},
{
"from": "14000344049242",
"to": "X000012",
"category": "variable",
"layerName": "pointChart",
"text": "F213AADS1环",
"fromPort": "out",
"toPort": "port"
},
{
"from": "fe387b59908a06deec55b3b54c0155fe37bd48001b",
"to": "14000344049264",
"category": "variable",
"layerName": "pointChart",
"text": "F214意中纺织",
"fromPort": "port",
"toPort": "input"
},
{
"from": "14000344049264",
"to": "X000011",
"category": "variable",
"layerName": "pointChart",
"text": "F214意中纺织",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00002",
"to": "1669a80c-cd7e-4b0a-8353-550e1204ad98",
"category": "variable",
"layerName": "pointChart",
"text": "ADS",
"fromPort": "port",
"toPort": "input"
},
{
"from": "1669a80c-cd7e-4b0a-8353-550e1204ad98",
"to": "df304780-c056-4226-be9c-3e6b201852fa",
"category": "variable",
"layerName": "pointChart",
"text": "ADS",
"fromPort": "out",
"toPort": "port"
},
{
"from": "aaaa",
"to": "XL00001",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000001",
"to": "XL00002",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000003",
"to": "XL00003",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000005",
"to": "SBID00000075CD4E0711704248964B81D80AB96097",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "XL00003",
"to": "XL00005",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000007",
"to": "SBID00000063552060DC9F45F78204D86D52C4FB14",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "XL00005",
"to": "XL00007",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000009",
"to": "SBID000000303A39A19A2946699389B035CFD069E2",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "XL00007",
"to": "XL00009",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000010",
"to": "XL00010",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000011",
"to": "SBID000000B4D4E3CC433A45CAA58D600FEE09C899",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000012",
"to": "XL00011",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "X000012",
"to": "XL00012",
"category": "variable",
"layerName": "pointChart",
"text": "cable",
"fromPort": "port",
"toPort": "port"
},
{
"from": "SBID00000063552060DC9F45F78204D86D52C4FB14",
"to": "300005380820",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "port",
"toPort": "input"
},
{
"from": "300005380820",
"to": "T000002",
"category": "variable",
"layerName": "pointChart",
"text": "T1",
"fromPort": "out",
"toPort": "port"
},
{
"from": "86797c5d-b69f-453a-9165-36a935a97fa9",
"to": "X000002",
"category": "variable",
"layerName": "pointChart",
"text": "10kBFC124联络开关",
"fromPort": "out",
"toPort": "port"
},
{
"from": "df304780-c056-4226-be9c-3e6b201852fa",
"to": "9017d7d6-1d52-4c43-b134-d309c9c6c605",
"category": "variable",
"layerName": "pointChart",
"text": "10kVADS1#柜(三遥) 213A1开关",
"fromPort": "port",
"toPort": "input"
},
{
"from": "df304780-c056-4226-be9c-3e6b201852fa",
"to": "86797c5d-b69f-453a-9165-36a935a97fa9",
"category": "variable",
"layerName": "pointChart",
"text": "10kBFC124联络开关",
"fromPort": "port",
"toPort": "input"
},
{
"from": "9017d7d6-1d52-4c43-b134-d309c9c6c605",
"to": "X000003",
"category": "variable",
"layerName": "pointChart",
"text": "10kVADS1#柜(三遥) 213A1开关",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00009",
"to": "9200000033189",
"category": "variable",
"layerName": "pointChart",
"text": "液压102264(三遥+分支)",
"fromPort": "port",
"toPort": "input"
},
{
"from": "9200000033189",
"to": "X000010",
"category": "variable",
"layerName": "pointChart",
"text": "液压102264(三遥+分支)",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00005",
"to": "9200000125856",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG06(二遥)",
"fromPort": "port",
"toPort": "input"
},
{
"from": "9200000125856",
"to": "X000007",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG06(二遥)",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00003",
"to": "9200000139115",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG05(二遥)",
"fromPort": "port",
"toPort": "input"
},
{
"from": "9200000139115",
"to": "X000005",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG05(二遥)",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00007",
"to": "9200000156270",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG03(二遥)",
"fromPort": "port",
"toPort": "input"
},
{
"from": "9200000156270",
"to": "X000009",
"category": "variable",
"layerName": "pointChart",
"text": "1082113KG03(二遥)",
"fromPort": "out",
"toPort": "port"
},
{
"from": "XL00001",
"to": "e9fbd2fc-65b9-4ff3-a618-3e8ba0ca4fa6",
"category": "variable",
"layerName": "pointChart",
"text": "10kvADS113开关",
"fromPort": "port",
"toPort": "input"
},
{
"from": "e9fbd2fc-65b9-4ff3-a618-3e8ba0ca4fa6",
"to": "X000001",
"category": "variable",
"layerName": "pointChart",
"text": "10kvADS113开关",
"fromPort": "out",
"toPort": "port"
}
]);
</script>
</body>
</html>
Thank you, I’ve adjusted it, and the effect is the same as yours, thank you for your help
The main path is the longest node of the path, which forms a horizontal line, the upward extension with more branches, and the downward extension with fewer than 3 branches