Custom Palette

I’m quite new in the use of GoJs, but I love it.

I need to do a custom palette where items shoul be represented as treeview (or something similar just to let user know the hierarchy of items) and allow only leaf to be dragged into diagram.

Could anyone please tell me where to start or just tell me some hints to simplify this work?

Many thanks in advance!


Take a look at the TreeView sample. You’ll want to set Node.copyable = false on the inner nodes and .copyable = true on the leaf nodes. I haven’t tried this, but maybe you could get that effect by binding this way in your Node template:

new go.Binding("copyable", "isTreeLeaf").ofObject()

Wait – I just tried this, and it doesn’t work because Node.isTreeLeaf is not a settable property. But you can do it programmatically by:

myDiagram.addDiagramListener("LayoutCompleted", function(e) { for (var it = myDiagram.nodes.iterator;; ) { var node = it.value; node.copyable = node.isTreeLeaf; } });

The target Diagram will need Diagram.allowDrop = true. Remember that the templates that you use can be different between the two Diagrams, because you are dragging model data, not Nodes. And you’ll probably want them to be different, if you are using the Binding shown above.

Double wait – I don’t know why it didn’t seem to work for me when I tried it the first time, but now I find that the Binding:

new go.Binding("copyable", "isTreeLeaf").ofObject()

works fine after all. So that Diagram listener isn’t needed.

I added:

and: myTarget = $(go.Diagram, "myTarget", { allowDrop: true });

I modified myDiagram to be a Palette:
myDiagram =
$(go.Palette, “myDiagram”,
{ allowHorizontalScroll: false });

And I added that Binding to the Node template:
myDiagram.nodeTemplate =
new go.Binding(“copyable”, “isTreeLeaf”).ofObject(),
. . .

That’s all I did to modify the TreeView sample, and it worked as I think you are asking for.

It worked great. At the moment the only problem is that the expander button doesn’t work.
Here is my code:

myPalette.nodeTemplate =
{ selectionAdorned: false },
new go.Binding(“copyable”, “isTreeLeaf”).ofObject(),
width: 14,
“ButtonIcon.stroke”: “blue”,
“ButtonBorder.fill”: “yellow”
G(go.Panel, “Horizontal”,
{ position: new go.Point(16, 0) },
new go.Binding(“background”, “isSelected”, function (s) { return (s ? “lightblue” : “white”); }).ofObject(""),
width: 14, height: 14,
margin: new go.Margin(0, 4, 0, 0),
imageStretch: go.GraphObject.Uniform,
source: imageUrl
new go.Binding(“text”, “name”))
) // end Horizontal Panel
); // end Node

myPalette.linkTemplate = G(go.Link);

myPalette.layout =
alignment: go.TreeLayout.AlignmentStart,
angle: 0,
compaction: go.TreeLayout.CompactionNone,
layerSpacing: 16,
layerSpacingParentOverlap: 1,
nodeIndent: 2,
nodeIndentPastParent: 0.88,
nodeSpacing: 0,
setsPortSpot: false,
setsChildPortSpot: false
var paletteList = new Array(
{ ‘key’ : ‘I4’,‘parent’ : ‘2’, ‘name’ : ‘pippo’, ‘isTreeLeaf’: true},
{ ‘key’ : ‘I5’,‘parent’ : ‘2’, ‘name’ : ‘pippo2’, ‘isTreeLeaf’: true},
{ ‘key’ : ‘I6’,‘parent’ : ‘2’, ‘name’ : ‘rrrrr’, ‘isTreeLeaf’: true},
{ ‘key’ : ‘I7’,‘parent’ : ‘2’, ‘name’ : ‘oiuy’, ‘isTreeLeaf’: true},
{ ‘key’ : ‘I8’,‘parent’ : ‘2’, ‘name’ : ‘pippopopo’, ‘isTreeLeaf’: true},
{ ‘key’ : ‘2’, ‘name’ : ‘Test’, ‘isTreeLeaf’: false})

myPalette.model = new go.TreeModel(paletteList);

Can you help me?
Many thanks in advance

That’s because Palette.isReadOnly is true. You can either set isReadOnly to false and then set other permissions appropriately for your purposes, or you can override CommandHandler.canCollapseTree and .canExpandTree to ignore the Diagram.isReadOnly property.

BTW, setting ‘isTreeLeaf’: true in your node data is completely superfluous. It’s not referenced by anything, unless maybe you have some other code that uses it for unrelated reasons.

Great, thank you very much.
At the moment I have only a strange thing, that is when I have just one element in he node model array, with the value of isTreeLeaf set to false, the element is still copyable.
Here is my node:

{key : “2”,name : “TEST”,isTreeLeaf : false}

the js code is the same posted yesterday.

Thanks in advance

As I just said, setting ‘isTreeLeaf’ in your node data has no effect – nothing depends on that property.

If I select the only Node in a Diagram, myDiagram.selection.first().isTreeLeaf returns true, as it should. The Binding would then cause the Node to be copyable.

Sorry if I boring you, you helped me a lot.

Just to clear my mind, I have the binding in my palette.nodeTemplate:
new go.Binding(“copyable”, “isTreeLeaf”).ofObject()

With your last post are you telling me that the binding doesn’t bind the “copyable” property to the value of isTreeLeaf present in my node?


The property you are binding to is Node.isTreeLeaf. You are not binding to data.isTreeLeaf.

If you take away the call to Binding.ofObject, then the Binding would be to the “isTreeLeaf” property on the data. With the call to ofObject(), the Binding is to a GraphObject property, in this case the Node.isTreeLeaf property.

Many thanks.
I removed the .ofObject and it worked perfectly.