Dynamically adding shapes and fonts

I am working to be able to dynamically add shapes and icons, as I don’t know which icons will actually be used by other developers using the graph. The graph will essentially be a re-usable angular component.

I think some icons look better with a background shape, and some don’t. So is there a way to let another developer determine if he or she wants a background shape dynamically, behind the icon or not? Maybe something like this, and then show that background -shape if it is included in the JSON.

    { key: "MARYLAND INDUSTRY", geo2: "file"},
    { key: "CHESTFIELD HOLDING" width: 20, background-shape: true}

Here is what I have currently, you can see CHESTFIELD HOLDINGS has two default GoJS shapes, and would require a background shape, while the other nodes are using the “file” icon from IcoMoons and does not need a background:

Yes, you can do it that way.

If the background is implemented as a separate Shape, you might want there to be a Binding of the Shape.visible property to that “background-shape” data property.

If you only wanted a rectangular background color, you wouldn’t even need a background Shape. Just bind the foreground shape’s Shape.background property to the “background-shape” data property, with a conversion function converting true to some appropriate color and false to “transparent”.

Or maybe change the “background-shape” data property to be “background”, with a default value that was “transparent” and otherwise could be “#123456” or whatever, so no conversion function would be needed.

Isn’t this the syntax for the first option, I need the shape to be dynamic so that other developer can over ride the shape so that second option won’t work:

 { key: "CHESTFIELD HOLDING", width: 20, background: true},
 new go.Binding("visible", "background", function (b) {if (b) return "red"; else return "transparent";}),

It doesn’t work, and I get this error: property set error: Error: GraphObject.visible value is not an instance of boolean: “red”

Can’t find any docs on it.

Is it background or fill?

Not entirely sure what you’re intending but most likely you just need to swap the arguments because they are out of order.

The first argument to Binding is the property that the binding will set, and the second argument is the property that it looks for in the model data. So:

new go.Binding("visible", "background" ...

Sets the visible property. visible cannot be set to "red" it can only be set to true or false, which is why you are getting that error.

For example consider this binding:

new go.Binding("fill", "color")

Which works with node data like:

  { key: "Alpha", color: "lightblue" },
  { key: "Beta", color: "orange" },

the value of "color" sets the fill property.

Ok thanks, that works but it is still showing the background for every shape unless I manually go in and specify false:

{ key: "MARYLAND INDUSTRY", geo2: "file", background: false},
{ key: "CHESTFIELD HOLDING", width: 20, background: true},
new go.Binding("visible", "background", function (b) { return b ? true : false })

Is there a best way to not have a background unless only the “backgrould: true” property is added, if there is no background property then the background is false and hidden?

 { key: "HEETON HOLDING", geo2: "file"}, //no background wanted


Set the value in the template to what you want to be the default value.

Thanks Walter.

What would be the best way to allow for a background image via a shape as I have in my screen shot above, but I want to give the user the ability to change the default circle background to a different shape, or get rid of the background completely. My understanding is that setting the visible property just hides the background but it is technically still there, which looks fine visually. But I would like to style the icons differently depending on if a user has included a background shape or not, if there is a background shape, and if the icon is not selected or highlighted, then I don’t need to do anything with the icon because I am already fading out the background shape and if there is a background shape then the icon needs to be white so I can leave the icon as white. But if there is no background shape, and if the node is not selected or highlighted I want to fade out the stroke of the icon.

I have an idea on how to do all that but I need to remove the background completely so that it does not exist if specified by the user. By default the background is there. It doesn’t seem to make sense to set a binding on background for the shape that is serving as a background, so just wondering if there is a way to allow for dynamically changing the background shape but at the same time having the option to remove it completely from the DOM.

          //Background shape for icon 1. 
	graph(go.Shape, "Circle",
         {name: "ICONSHAPE1", stroke: null, fill: "#009BE1", width: 25, height: 20, alignment: go.Spot.BottomLeft, minSize: new go.Size(15, 15)},
		 new go.Binding("visible", "hasIcon1Background", function (b) { return b ? "red" : ""}),
		 new go.Binding("alignment", "alignment"),
		 new go.Binding("margin", "icon1Margin"),
		 new go.Binding("height", "height"),
		 new go.Binding("width", "width"),
		 new go.Binding("figure", "icon1Background"),
		 new go.Binding("fill", "isHighlighted", function(h) { return h ? "#388E3C" : "#388E3C"; })
		 new go.Binding("fill", "isSelected", function(h) { return h ? "#388E3C" : "#009BE1"; })
	//Shape/Icon for the node on the lower left of the node, default is the "ThinCross" shape built into GoJS
      graph(go.Shape, "ThinCross",
	    {name: "ICON1", margin:2,  stroke: "#FFF", strokeWidth: 2, alignment: go.Spot.BottomLeft, width: 15, height: 15},
        new go.Binding("geometryString", "icon1", geoFunc),
		new go.Binding("figure", "figure1"),
		new go.Binding("stroke", "icon1StrokeColor")),


Bindings cannot remove or add GraphObjects to the visual tree, but you can get that effect by changing the value of GraphObject.visible.

But changing the visibility of a shape means its technically still there, so if I do a check like this, which gets called in my “ChangedSelection” listener to see if a node is selected or highlighted, this doesn’t work because iconShape1 is there its just not visible:

 iconShape1 = indNode.findObject("ICONSHAPE1");
 icon1 = indNode.findObject("ICON1");

 // if there is an icon but not a background, then set the stroke of the icon.
 if (icon1 && !iconShape1) {
      	icon1.stroke = "rgba(183, 227, 246, 0.7)";

I get undefined when I try to do something like “iconShape1.isVisible”…is there a syntax like that available?

Just confirming that is not possible before moving on…Thanks

It’s the same property that you would be setting and/or binding: GraphObject.visible.

So iconShape1 !== null && !iconShape1.visible