Hello!
My node represents a message that contains variables represented by different shapes.
I want my node to look like this:
What is the easiest way to do this?
You’ll need to break it up into separate TextBlocks and Panels.
Here’s a simple FlowPanelLayout:
function FlowPanelLayout() {
go.PanelLayout.call(this);
this.spacing = new go.Size(2, 2);
}
go.Diagram.inherit(FlowPanelLayout, go.PanelLayout);
FlowPanelLayout.prototype.measure = function(panel, width, height, elements, union, minw, minh) {
var x = 0;
var y = 0;
var maxx = 0;
var rowh = 0;
for (var i = 0; i < elements.length; i++) {
var elem = elements[i];
this.measureElement(elem, width, height, minw, minh);
var mb = elem.measuredBounds;
if (x + this.spacing.width + mb.width > width) {
y += rowh + this.spacing.height;
x = this.spacing.width + mb.width;
rowh = mb.height;
} else {
x += this.spacing.width + mb.width;
rowh = Math.max(rowh, mb.height);
}
maxx = Math.max(maxx, x);
}
union.width = maxx;
union.height = y + rowh;
}
FlowPanelLayout.prototype.arrange = function(panel, elements, union) {
var x = 0;
var y = 0;
var rowh = 0;
for (var i = 0; i < elements.length; i++) {
var elem = elements[i];
var mb = elem.measuredBounds;
if (x + this.spacing.width + mb.width > union.width) {
x = 0;
y += rowh + this.spacing.height;
this.arrangeElement(elem, x, y, mb.width, mb.height);
x = this.spacing.width + mb.width;
rowh = mb.height;
} else {
this.arrangeElement(elem, x, y, mb.width, mb.height);
x += this.spacing.width + mb.width;
rowh = Math.max(rowh, mb.height);
}
}
}
go.Panel.definePanelLayout('Flow', new FlowPanelLayout())
Example use:
function init() {
var $ = go.GraphObject.make;
myDiagram =
$(go.Diagram, "myDiagramDiv",
{ "undoManager.isEnabled": true });
var templMap = new go.Map();
templMap.add("",
$(go.Panel,
$(go.TextBlock,
new go.Binding("text", ""))
));
templMap.add("Shape",
$(go.Panel,
$(go.Shape,
{ width: 16, height: 16, strokeWidth: 0 },
new go.Binding("figure", "fig"),
new go.Binding("fill", "color"))
));
templMap.add("Capsule",
$(go.Panel, "Auto",
$(go.Shape, "RoundedRectangle",
{ fill: "white", strokeWidth: 0, spot1: go.Spot.TopLeft, spot2: go.Spot.BottomRight }),
$(go.Panel, "Flow",
new go.Binding("itemArray", "content"),
{ itemTemplateMap: templMap }
)
));
myDiagram.nodeTemplate =
$(go.Node, "Vertical",
$(go.TextBlock, new go.Binding("text")),
$(go.Panel, "Auto",
{ portId: "" },
$(go.Shape, { fill: "lightgray" }),
$(go.Panel, "Flow",
{
margin: new go.Margin(4, 4, 3, 4),
maxSize: new go.Size(160, NaN),
itemTemplateMap: templMap
},
new go.Binding("itemArray", "items"))
)
);
myDiagram.model = new go.GraphLinksModel([
{
key: 1, text: "Alpha", items: [
"A1",
{ category: "Shape", fig: "Diamond", color: "red"},
"C1"
]
},
{
key: 2, text: "Beta", items: [
"some",
{
category: "Capsule", content: [
{ category: "Shape", fig: "Circle", color: "green" },
"inside",
{ category: "Shape", fig: "TriangleRight", color: "green" },
"text"
]
},
"more",
{ category: "Shape", fig: "TriangleUp", color: "orange" },
"stuff"
]
}
],
[
{ from: 1, to: 2 }
]);
}
produces:
The main thing lacking now is support for text baselines. And right-to-left text.