Hello,
Continuing with our goal of migrating our D3.js charts to GoJS, I am reaching out for your assistance regarding forces and collisions.
Here’s some context: We have a list of cryptocurrency holders, each possessing a different amount. The chart draws bubbles for each holder. The size of the bubble varies depending on the amount the holder owns.
Currently, we apply a magnetic force that encourages all nodes to move towards the center based on the available space. If you move a node, a collision effect occurs to “push” the nodes along the path. Again, the nodes will use the freed space to move closer to the center through a slow movement.
I invite you to visit XIDAR resource explorer and select a resource to see the effect in action.
Could you help me replicate this effect?
Here is the code I currently have with GoJS:
const $ = go.GraphObject.make; // for conciseness in defining templates
this.diagram = new go.Diagram("holders-chart", // must name or refer to the DIV HTML element
{
allowCopy: false,
initialContentAlignment: go.Spot.Center,
layout: $(go.ForceDirectedLayout),
"commandHandler.copiesTree": false,
"commandHandler.deletesTree": false,
"draggingTool.dragsTree": true,
"undoManager.isEnabled": false
});
this.diagram.nodeTemplate =
$(go.Node,
"Auto",
{
desiredSize: new go.Size(this.nodeDefaultSize, this.nodeDefaultSize),
selectionObjectName: "PANEL",
isTreeExpanded: false,
isTreeLeaf: false,
cursor: "pointer",
selectionAdorned: false,
click: (e, obj) => {
const node = obj.part;
if (node === null) return;
e.handled = true;
const data = node.data;
this.setHighlightedAddress(data.address);
}
},
new go.Binding("desiredSize", "scale", scale => {
return new go.Size(this.nodeDefaultSize * scale, this.nodeDefaultSize * scale)
}),
$(go.Picture,
{
opacity: .5,
desiredSize: new go.Size(this.nodeDefaultSize, this.nodeDefaultSize),
mouseEnter: function(e, shape) {
// @ts-ignore
shape.opacity = .8;
},
mouseLeave: function(e, shape) {
// @ts-ignore
shape.opacity = shape.part.isSelected ? .8 : .5;
}
},
new go.Binding("desiredSize", "scale", scale => {
return new go.Size(this.nodeDefaultSize * scale, this.nodeDefaultSize * scale)
}),
new go.Binding("opacity", "isSelected", sel => {
if (sel) return .8; else return .5;
}).ofObject(""),
new go.Binding("source", "address", (address) => {
return this.convertAddressToImage(self.projects.getProject(address, true));
})
)
);
this.diagram.model = new go.GraphLinksModel(this.getHoldersToShow());