Some basic (?) questions

Hi !

First, thanks for a great tool. Have been playing with it a little bit, and it’s really easy to get started using all the examples and docs.

There are two things however that I can’t really figure out how to do:

  1. I want to have a group that is expandable. I therefore let it contain a placeholder according to examples. However, I want this placeholder only to occupy say 50% of the containing object. As an example, it could be placed inside a rectangle but only occupy the lower half, no matter i’t size (i.e. the rectangle is always double the size of the placeholder). How can I do that?

  2. When saving to json and loading again, the objects in the diagram do not get back their original position, but instead the leftmost object is placed close to the left border (e.g. your FlowChart example). Can this be changed so that they actually get back to their exact original position?

Thanks

  1. I’m not sure you can express that declaratively in GoJS at the moment. We’ll need to investigate.

  2. You should be able to set Diagram.position to whatever you want, such as new go.Point(0, 0) or perhaps to a value that you have saved, when you initialize the diagram. That works in version 1.0.* but appears to be broken in the beta. We’ll fix that, of course. In the meantime, you can implement the functionality yourself by doing:

myDiagram.addDiagramListener("InitialLayoutCompleted", function() { myDiagram.position = new go.Point(0, 0); });

One way to implement what you want for #1 is to customize the Group.layout that your group template is using. After arranging the subgraph, it could also change the properties of other GraphObjects in the Group.

What value do you use for the Group.layout?

OK, let’s say that you define your Group template in the following manner:

myDiagram.groupTemplate = $(go.Group, go.Panel.Auto, { layout: $(GroupTreeLayout, { ... }) }, // this replaces the TreeLayout that you might be using $(go.Shape, { fill: null, stroke: "blue", strokeWidth: 2 }), // a border around the whole Group $(go.Panel, go.Panel.Table, { name: "TABLE", margin: 1 }, // this will be the top half $(go.Shape, { row: 0, fill: "white", stroke: null, stretch: go.GraphObject.Fill }), // this Placeholder will occupy the bottom half $(go.Placeholder, { row: 1, background: "whitesmoke", padding: 5 })));
Then you can define a function that sets the height of the first row to be the same as the height of the Group’s Placeholder:

function updateGroupHeight(group) { if (group === null) return; var table = group.findObject("TABLE"); if (table !== null) { table.getRowDefinition(0).height = group.placeholder.actualBounds.height; } }
Now you just need to call this function whenever the subgraph, i.e. the Placeholder, changes size. There’s no easy and general way to do this that I can think of offhand.

But the subgraph might change size because its layout is performed. So one can customize the layout in the following manner:

[code] function GroupTreeLayout() {
go.TreeLayout.call(this);
}
go.Diagram.inherit(GroupTreeLayout, go.TreeLayout);

GroupTreeLayout.prototype.commitLayout = function() {
go.TreeLayout.prototype.commitLayout.call(this);
updateGroupHeight(this.group);
};[/code]
Note that this shows you how to subclass any Layout and override one of its methods. This example was just assuming you had been using a TreeLayout. Note also how the Group template has replaced the go.TreeLayout with a GroupTreeLayout.

The Group’s subgraph might change size for other reasons too. For example, if the user moves some nodes, you’ll want to call updateGroupHeight too. That is most easily accomplished with a “SelectionMoved” DiagramEvent:

myDiagram.addDiagramListener("SelectionMoved", function() { var it = myDiagram.selection.iterator; while (it.next()) { var part = it.value; if (part.containingGroup !== null) updateGroupHeight(part.containingGroup); } });
Of course I have no idea of what might cause the subgraph of a group to change height, so I’m just guessing that customizing the Group.layout and a “SelectionMoved” DiagramEvent handler might be sufficient.

Some day we will extend the functionality of Table Panels to be able to specify fixed proportion row sizes or column sizes, and all of this code will be unnecessary.

Thank you very much ! That worked exactly as it should !

Follow up question on this one. Tried to make the whole table disappear when the group is collapsed. Tried to do it the following way:

myDiagram.groupTemplateMap.add(“ICON-EXP”,

$(go.Group, go.Panel.Auto,  
    { minSize : new go.Size(50,100)},    
    new go.Binding("location", "location", go.Point.parse).makeTwoWay(go.Point.stringify),
    $(go.Shape, { fill: null, stroke: "blue", strokeWidth: 2 }),
    $(go.Panel, go.Panel.Table,
       { name: "TABLE", margin: 0 },

new go.Binding(“visible”,“isSubGraphExpanded”).ofObject(),
// this will be the top half
$(go.Shape, { row: 0, fill: “transparent”, stroke: null, stretch: go.GraphObject.Fill }),
// this Placeholder will occupy the bottom half
$(go.Placeholder, { row: 1, background: “transparent”, padding: 5 })),
$(“SubGraphExpanderButton”,{alignment: new go.Spot(0,0)})));

It works, however the collapsed object is not possible to move around… Any ideas why?

BTW: Did you change the handling of geometry strings somehow in beta 7. Arcs are misbehaving badly for me with beta 7, but worked flawlessly before…

Sorry about that – recently there has been a lot of spam in our forums, and I must have missed this message.

Do you see the outer blue Shape OK when the group is collapsed? Are you saying that the user cannot drag the group by dragging that blue border?

Might a layout be occurring as the user is trying to drag the group? (Set a breakpoint in a “LayoutCompleted” DiagramEvent listener.)

Yes the outer blue is visible. When trying to drag it though the behaviour is the same as when dragging the background (everything moves). It seems like I’m sometimes am able to drag it though (maybe when I’m hitting exactly at the border.

Here's a complete (simplified, e.g. removed some stuff from the table, but this behaviour is still there..) example causing this behaviour. I have not tried the layout thing (not sure how to do that)
function init() {
var $ = go.GraphObject.make; // for conciseness in defining templates
myDiagram = new go.Diagram("myDiagram"); // create a Diagram for the DIV HTML element
myDiagram.groupTemplate =
$(go.Group, go.Panel.Auto,
{ minSize : new go.Size(50,100)},
new go.Binding("location", "location", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Shape, { fill: null, stroke: "blue", strokeWidth: 2 }),
$(go.Panel, go.Panel.Table,
{ name: "TABLE", margin: 0 },
new go.Binding("visible","isSubGraphExpanded").ofObject(), $(go.Placeholder, { row: 1, background: "transparent", padding: 5 })),
$("SubGraphExpanderButton",{alignment: new go.Spot(0,0)})); var nodeDataArray = [
{ key: "Alpha", color: "lightblue", group:"Gamma" },
{ key: "Beta", color: "orange" , group:"Gamma"},
{ key: "Gamma", color: "lightgreen", isGroup:true},
{ key: "Delta",color: "blue"}
];
var linkDataArray = [];
myDiagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
}

That’s because you set that Shape.fill to be null instead of “transparent”.

When a Shape’s fill is null, one cannot pick that Shape at points inside the geometry – only at points on the stroke (i.e. edges of the geometry) if the stroke is not null.