Thanks for your quick response.
I paseted the code and screenshot, hope that will be helpful. Note: the code is written in typescript which is smiliar to Javascript.
The node template like below:
<span =“Apple-tab-span” style=“white-space:pre”> var $go = go.GraphObject.make;
<span =“Apple-tab-span” style=“white-space:pre”> this.diagram.nodeTemplateMap.add(“MainNode”,
$go(go.Node, go.Panel.Auto,
{ locationSpot: go.Spot.Center },
new go.Binding(“location”, “loc”, function (loc) {
return new go.Point.parse(loc) ;
}),
$go(go.Shape, "RoundedRectangle",
{
name: "SHAPE",
parameter1: 20,
fill: whiteblue,
spot1: go.Spot.TopLeft,
spot2: go.Spot.BottomRight,
strokeWidth: 2
}),
$go(go.Panel, go.Panel.Table,
{ margin: new go.Margin(30, 0) },
$go(go.TextBlock,
{ row: 0, column: 0, columnSpan: 3, font: "bold 60pt sans-serif", text: "text" },
new go.Binding("text", "name")
),
$go(go.Panel, go.Panel.Auto, {
name: "limitpanel",
row: 1,
column: 0,
columnSpan: 3,
margin: 50, //to have more space between svg and ports
}, {
click: (e, obj) => { this.onHoverOverRect(e, obj) }
}),
$go(go.Panel, go.Panel.Horizontal,
$go(go.Panel, go.Panel.Auto, {
name:"drilldown",
margin: 2,
click: clickHandler,
row: 0,
column: 0,
background: "lightgray",
desiredSize: new go.Size(40, 40) },
$go(go.Picture, {
alignment: go.Spot.TopLeft,
alignmentFocus: go.Spot.TopLeft,
source: this.applicationController.baseAppPath + "/Content/Images/Drilldown16.png"})
),
$go(go.Panel, go.Panel.Auto, {
name:"viewUnitData",
margin: 5,
click: clickHandler2,
row: 0,
column: 1,
background: "lightgray",
desiredSize: new go.Size(40, 40) },
$go(go.Picture, {
alignment: go.Spot.TopLeft,
alignmentFocus: go.Spot.TopLeft,
source: this.applicationController.baseAppPath + "/Content/Images/ViewUnitData.png"})
)),
$go(go.Panel,
{
name: "portf",
row: 2,
column: 0,
alignment: go.Spot.Left,
}),
$go(go.Panel,
{
name: "svgpanel",
row: 2,
column: 1,
// alignment: go.Spot.Center,
//columnSpan:3,
margin: 50 //to have more space between svg and ports
}),
$go(go.Panel,
{
name: "portp",
row: 2,
column: 2,
//columnSpan:100,
alignment: go.Spot.Right,
}),
$go(go.TextBlock,
{ row: 3, column: 0, columnSpan: 3, font: "48pt sans-serif" },
new go.Binding("text", "name")
)
),
{
toolTip: $go(go.Adornment, go.Panel.Auto,
$go(go.Shape, { fill: "whitesmoke", width: 190, height: 40 }),
$go(go.TextBlock, { margin: 4, font: "12pt sans-serif" }, new go.Binding("text", "name"))
)
},
{
selectionAdornmentTemplate:
$go(go.Adornment, go.Panel.Spot,
$go(go.Panel, go.Panel.Auto,
// this Adornment has a rectangular blue Shape around the selected node
$go(go.Shape, "RoundedRectangle", {
fill: null, parameter1: 20, spot1: go.Spot.TopLeft,
spot2: go.Spot.BottomRight, stroke: "dodgerblue", strokeWidth: 12 }),
$go(go.Placeholder)
)
),
},
{
mouseEnter: (e, obj, prev) =>
{ // change background brush
var shape = obj.part.findObject("SHAPE");
if (shape)
shape.fill = bluegrad;
},
mouseLeave: (e, obj, next) =>
{ // restore to original brush
var shape = obj.part.findObject("SHAPE");
if (shape)
shape.fill = whiteblue;
}
}
)
);
<span =“Apple-tab-span” style=“white-space:pre”>
And the ports of nodes are added dynamically, because the ports for each node are different. In the node template, I first define two section (portf and portp), and they will be filled when rendering each node.
<span =“Apple-tab-span” style=“white-space:pre”> addports(node)
{
<span =“Apple-tab-span” style=“white-space:pre”> // Find the node
<span =“Apple-tab-span” style=“white-space:pre”> var node = this.diagram.findNodeForKey(nodeId);
<span =“Apple-tab-span” style=“white-space:pre”>
var fPortPanel = $go(go.Panel, go.Panel.Vertical,
{ margin: 20, name: “fpanel” }
);
var pPortPanel = $go(go.Panel, go.Panel.Vertical,
{ margin: 20, name: "ppanel" }
);
Dojo.Utils.forEach(node.ports, (port) =>
{
var portPanel = this.createPortsForPort(port);
if (port.isFeed)
fPortPanel.add(portPanel);
else
pPortPanel.add(portPanel);
});
node.findObject("portf").add(fPortPanel);
node.findObject("portp").add(pPortPanel);
}
createPorts(port): any
{
var portPanel =
$go(go.Panel, go.Panel.Auto,
{
stretch: go.GraphObject.Horizontal,
defaultStretch: go.GraphObject.Horizontal
//defaultStretch is for panel elements (port)
},
$go(go.Shape,
{
"figure": "Roundedrectangle",
height: 50,
// width: 100,
portId: port.stream.id,
"fill": "transparent",
fromSpot: go.Spot.RightSide,
stroke: fillColor,
<span =“Apple-tab-span” style=“white-space:pre”> toSpot: go.Spot.LeftSide
}),
$go(go.TextBlock,
{
alignment: go.Spot.Left,
alignmentFocus: go.Spot.Left,
textAlign: “left”,
“text”: port.name,
font: “12pt sans-serif”,
margin: 5
})
);
return portPanel;
}
<span =“Apple-tab-span” style=“white-space:pre”>
The link template like below:
<span =“Apple-tab-span” style=“white-space:pre”> var $go = go.GraphObject.make;
<span =“Apple-tab-span” style=“white-space:pre”> this.diagram.linkTemplate =
$go(go.Link, // the whole link panel
{
routing: go.Link.AvoidsNodes
},
$go(go.Shape, // the link path shape
{
name:“LinkShape”,
isPanelMain: true,
stroke: “black”, strokeWidth: 1
}),
$go(go.Shape, // the arrowhead
{
toArrow: “standard”,
stroke: null, fill: “black”
}),
$go(go.Panel, go.Panel.Auto,
{
visible: false,
name: “LABEL”,
segmentIndex: 0
},
$go(go.Shape, // the link shape
{
figure: ‘RoundedRectangle’,
fill: “black”,
stroke: null
})
)
);
And sometime I need to update the nodes like below:
updatePort()
{
Dojo.Utils.forEach(nodes, (node) =>{
var node = this.diagram.findNodeForKey(node.id);
Dojo.Utils.forEach(node.ports, (port) =>
{
if (port.hasProblem)
{
var node = this.diagram.findNodeForKey(node.id);
if (port.isInport)
{
var fpanel = node.findObject("fpanel");
var panel = fpanel.findObject(port.name);
panel.findObject('portlengthtext').text = port.problem.text;
}
else
{
var ppanel = node.findObject("ppanel");
var panel = ppanel.findObject(port.name);
panel.findObject('portlengthtext').text = port.problem.text;
}
}
})
});
}<span ="Apple-tab-span" style="white-space:pre"> </span>