-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Configurable graph force strength and link length #104
Configurable graph force strength and link length #104
Conversation
The length of the links can be now configured via the config object. The specified length will include not only the visible segment of the link, but also the part hidden beneath the nodes it connects, which equals the half of each node' size.
Now it's posible to customize the graph force strength, which will allow the developer to define the gravity between the nodes. The longer the value, the closer they will be. If, on the contrary, a big negative value is set, the nodes will be far from each other.
Good initiative, linking Trello card that corresponds to this PR, will review asap. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one, still I think we should make a few small changes before merging this. Thanks!
src/components/graph/graph.config.js
Outdated
@@ -97,6 +97,9 @@ | |||
* | |||
* **[note]** react-d3-graph will map this values to [d3 symbols](https://github.com/d3/d3-shape#symbols) | |||
* <br/> | |||
* @param {number} [node.gravity=-100] - this will define how close nodes are to each other. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to see this values isolated in the scope of a d3
object property, can you please move this to:
...
d3: {
gravity: -100,
linkSize: 100
},
...
src/components/graph/Graph.jsx
Outdated
@@ -101,7 +101,7 @@ export default class Graph extends React.Component { | |||
|
|||
const forceLink = d3ForceLink(this.state.d3Links) | |||
.id(l => l.id) | |||
.distance(D3_CONST.LINK_IDEAL_DISTANCE) | |||
.distance(this.state.config.link.size || D3_CONST.LINK_IDEAL_DISTANCE) | |||
.strength(D3_CONST.FORCE_LINK_STRENGTH); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think of also having this constants configurable:
// Some d3 constant values
const D3_CONST = {
FORCE_LINK_STRENGTH: 1,
LINK_IDEAL_DISTANCE: 100,
SIMULATION_ALPHA_TARGET: 0.05
};
They are on the top of this file
src/components/graph/graph.helper.js
Outdated
const simulation = _createForceSimulation( | ||
newConfig.width, | ||
newConfig.height, | ||
newConfig.node && newConfig.node.gravity |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need for node.gravity
check this prop will always exist
The D3_CONST object has been removed, and all of the properties it had inside are now configurable via the config object of the `Graph` component. All of these d3 related values are now wrapped in a new `d3` section inside of the config object.
Thanks for the feedback, @danielcaldas ! I've just uploaded another commit with the changes you proposed. Now both Since they're no longer constants, I removed the whole If there's something else you'd like me to change, don't hesitate to let me know. 😃 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only some small additional comments
src/components/graph/graph.helper.js
Outdated
@@ -360,7 +362,7 @@ function initializeGraphState({ data, id, config }, state) { | |||
let links = _initializeLinks(graph.links); // matrix of graph connections | |||
const { nodes: d3Nodes, links: d3Links } = graph; | |||
const formatedId = id.replace(/ /g, '_'); | |||
const simulation = _createForceSimulation(newConfig.width, newConfig.height); | |||
const simulation = _createForceSimulation(newConfig.width, newConfig.height, newConfig.d3.gravity); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please check whether some is wrong with this line? Tests for graph.helper
are breaking in this property fetch, it seems that newConfig.d3
is undefined. Check this link for more detail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been taking a look at this and it seems that there are some tests in graph.helper.test.js
where config
is assigned a string instead of an actual config object. This is what's causing the error to occurr in some of them.
{ config: 'config' }
Since config is not an object at all in this case, newConfig.d3
is undefined
, and the same happens with the other two parameters passed down to _createForceSimulation
.
Fixing the issue is as simple as checking if newConfig.d3
before trying to access the gravity
property.
const simulation = _createForceSimulation(newConfig.width, newConfig.height, newConfig.d3 && newConfig.d3.gravity);
I'll submit a commit with the change in a bit, but I'm curious... Is there any reason why config
is taking a string value in these tests? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, so in those particular unit tests I was checking for API compatibility I wasn't particularly interested in checking whether config
was a string or other data type.
The two following parameters can be now be customized through the
config
object:link.size
(the length of the link)node.gravity
(defines how close nodes are from each other in the graph)Until now these two values were set as constants (
FORCE_IDEAL_STRENGTH
andLINK_IDEAL_DISTANCE
), but the predefined values could present visual issues for bigger node sizes.In some scenarios, the links wouldn't even appear on screen, as they would be completely hidden beneath the nodes. Also, it could happen that many of the nodes happened to overlap, making it impossible to view all of them without dragging them to isolated locations.
Having these properties as configurable values will make it easier for the developers to customize the distance between nodes depending on their size, and so ensure the graph looks good regardless of their choice.