I am trying out the 3d Force Graph in this package and I am looking for ways to influence bond strength between nodes. Either link width or length would be good, but I don't see anything in API that allows me to control or influence either. What is the correct field of Graph
to pass in link strenghts, one for each link?
Here is a modified version of this example which applies a custom distance per link:
const N = 300;
const gData = {
nodes: [...Array(N).keys()].map(i => ({ id: i })),
links: [...Array(N).keys()]
.filter(id => id)
.map(id => {
var distance = (Math.random() < 0.2) ? 75 : 250;
var width = (distance == 75) ? 4 : 0.2;
return ({
source: id,
target: Math.round(Math.random() * (id-1)),
width: width,
distance: distance
})
})
};
const Graph = ForceGraph3D()
(document.getElementById('3d-graph'))
.graphData(gData)
.linkWidth('width')
.cameraPosition({ z: 600 })
.d3Force("link", d3.forceLink().distance(d => d.distance))
.d3Force("charge", d3.forceManyBody().theta(0.5).strength(-1));
<head>
<style> body { margin: 0; } </style>
<script src="//unpkg.com/3d-force-graph"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="3d-graph"></div>
</body>
In fact, to allow users to modify links parameters, the library simply uses the d3 force API. The only difference is the name of the accessor in the 3d-force-graph library which is .d3Force()
(instead of .force()
in d3).
For instance, to modify the distance per link, we can add a distance
attribute to each link data point (in addition to source
and target
) and then modify this distance as follow in the force layout (using the d3Force
accessor):
.d3Force("link", d3.forceLink().distance(d => d.distance))
whereas in a d3 force layout we would have used:
.force("link", d3.forceLink().distance(d => d.distance))
which gives us:
const Graph = ForceGraph3D()
(document.getElementById('3d-graph'))
.graphData(gData)
.linkWidth('width')
// The link distance modification:
.d3Force("link", d3.forceLink().distance(d => d.distance))
// To make it prettier:
.d3Force("charge", d3.forceManyBody().theta(0.5).strength(-1));
The strength can be adjusted the same way, using:
.d3Force("link", d3.forceLink().strength(d => d.strength))
In the example, I have given each link a distance which is randomly either 75 or 250. And to make it clear, I have given a bigger width to links with a smaller distance. The distribution of nodes in my demo is not perfect, and might need additional tuning.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With