diff --git a/src/components/graph/Graph.jsx b/src/components/graph/Graph.jsx index 549df8b9c..de85007d8 100644 --- a/src/components/graph/Graph.jsx +++ b/src/components/graph/Graph.jsx @@ -13,13 +13,6 @@ import * as graphRenderer from './graph.renderer'; import * as graphHelper from './graph.helper'; import utils from '../../utils'; -// Some d3 constant values -const D3_CONST = { - FORCE_LINK_STRENGTH: 1, - LINK_IDEAL_DISTANCE: 100, - SIMULATION_ALPHA_TARGET: 0.05 -}; - /** * Graph component is the main component for react-d3-graph components, its interface allows its user * to build the graph once the user provides the data, configuration (optional) and callback interactions (also optional). @@ -101,8 +94,8 @@ export default class Graph extends React.Component { const forceLink = d3ForceLink(this.state.d3Links) .id(l => l.id) - .distance(D3_CONST.LINK_IDEAL_DISTANCE) - .strength(D3_CONST.FORCE_LINK_STRENGTH); + .distance(this.state.config.d3.linkLength) + .strength(this.state.config.d3.linkStrength); this.state.simulation.force(CONST.LINK_CLASS_NAME, forceLink); @@ -123,7 +116,7 @@ export default class Graph extends React.Component { _onDragEnd = () => !this.state.config.staticGraph && this.state.config.automaticRearrangeAfterDropNode && - this.state.simulation.alphaTarget(D3_CONST.SIMULATION_ALPHA_TARGET).restart(); + this.state.simulation.alphaTarget(this.state.config.d3.alphaTarget).restart(); /** * Handles d3 'drag' event. @@ -279,7 +272,7 @@ export default class Graph extends React.Component { } } - this.state.simulation.alphaTarget(D3_CONST.SIMULATION_ALPHA_TARGET).restart(); + this.state.simulation.alphaTarget(this.state.config.d3.alphaTarget).restart(); this._tick(); } diff --git a/src/components/graph/graph.config.js b/src/components/graph/graph.config.js index 1fcd0c3d9..b2756d55c 100644 --- a/src/components/graph/graph.config.js +++ b/src/components/graph/graph.config.js @@ -54,6 +54,14 @@ * from the given nodes positions by rd3g), no coordinates will be calculated by rd3g or subjacent d3 modules. * @param {number} [width=800] - the width of the (svg) area where the graph will be rendered. *
+ * @param {Object} d3 d3 object is explained in next section. ⬇️ + * @param {number} [d3.gravity=-100] - this will define how close nodes are to each other. + * - If value is positive, nodes will attract each other. + * - If value is negative, nodes will repel each other. Most of the times this is what we want, so nodes don't overlap. + * @param {number} [d3.linkLength=100] - the length of each link from the center of the nodes it joins. + * @param {number} [d3.linkStrength=1] + * @param {number} [d3.alphaTarget=0.05] + *
* @param {Object} node node object is explained in next section. ⬇️ *

Node level configurations

* @param {string} [node.color='#d3d3d3'] - 🔍🔍🔍 this is the color that will be applied to the node if no **color property** @@ -150,6 +158,12 @@ export default { panAndZoom: false, staticGraph: false, width: 800, + d3: { + gravity: -100, + linkLength: 100, + linkStrength: 1, + alphaTarget: 0.05 + }, node: { color: '#d3d3d3', fontColor: 'black', diff --git a/src/components/graph/graph.helper.js b/src/components/graph/graph.helper.js index 6baa29ab8..3e8c8c692 100644 --- a/src/components/graph/graph.helper.js +++ b/src/components/graph/graph.helper.js @@ -42,15 +42,17 @@ const NODE_PROPS_WHITELIST = ['id', 'highlighted', 'x', 'y', 'index', 'vy', 'vx' * Wtf is a force? {@link https://github.com/d3/d3-force#forces| here} * @param {number} width - the width of the container area of the graph. * @param {number} height - the height of the container area of the graph. + * @param {number} gravity - the force strength applied to the graph. * @returns {Object} returns the simulation instance to be consumed. * @memberof Graph/helper */ -function _createForceSimulation(width, height) { +function _createForceSimulation(width, height, gravity) { const frx = d3ForceX(width / 2).strength(CONST.FORCE_X); const fry = d3ForceY(height / 2).strength(CONST.FORCE_Y); + const forceStrength = gravity; return d3ForceSimulation() - .force('charge', d3ForceManyBody().strength(CONST.FORCE_IDEAL_STRENGTH)) + .force('charge', d3ForceManyBody().strength(forceStrength)) .force('x', frx) .force('y', fry); } @@ -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 && newConfig.d3.gravity); return { id: formatedId,