New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

react-d3-graph

Package Overview
Dependencies
Maintainers
1
Versions
26
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-d3-graph - npm Package Compare versions

Comparing version 0.4.0 to 1.0.0

.vscode/launch.json

28

CHANGELOG.md
# Change Log
## [1.0.0](https://github.com/danielcaldas/react-d3-graph/tree/1.0.0) (2017-12-02)
[Full Changelog](https://github.com/danielcaldas/react-d3-graph/compare/0.4.0...1.0.0)
**Closed issues:**
- How can I get onMouseOverLink event? [\#25](https://github.com/danielcaldas/react-d3-graph/issues/25)
**Fixed bugs:**
- Click one node but another one moves [\#41](https://github.com/danielcaldas/react-d3-graph/issues/41)
**Merged pull requests:**
- Fix/tests coverage [\#44](https://github.com/danielcaldas/react-d3-graph/pull/44) ([danielcaldas](https://github.com/danielcaldas))
- Fix/on drag node handler [\#42](https://github.com/danielcaldas/react-d3-graph/pull/42) ([danielcaldas](https://github.com/danielcaldas))
- Feature/on mouse over and out link [\#40](https://github.com/danielcaldas/react-d3-graph/pull/40) ([danielcaldas](https://github.com/danielcaldas))
- Set proper defaults for Graph component config [\#39](https://github.com/danielcaldas/react-d3-graph/pull/39) ([danielcaldas](https://github.com/danielcaldas))
- Fix semantics mouse over methods in Graph component [\#38](https://github.com/danielcaldas/react-d3-graph/pull/38) ([danielcaldas](https://github.com/danielcaldas))
## [0.4.0](https://github.com/danielcaldas/react-d3-graph/tree/0.4.0) (2017-11-11)

@@ -20,6 +38,10 @@ [Full Changelog](https://github.com/danielcaldas/react-d3-graph/compare/0.3.0...0.4.0)

**Implemented enhancements and Fixed bugs:**
**Implemented enhancements:**
- Squeezing if "staticGraph": true [\#24](https://github.com/danielcaldas/react-d3-graph/issues/24), props to [scoutrul](https://github.com/scoutrul) for reporting this issue.
- Squeezing if "staticGraph": true [\#24](https://github.com/danielcaldas/react-d3-graph/issues/24)
**Fixed bugs:**
- Squeezing if "staticGraph": true [\#24](https://github.com/danielcaldas/react-d3-graph/issues/24)
**Merged pull requests:**

@@ -79,2 +101,2 @@

\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*

29

lib/components/graph/config.js

@@ -15,3 +15,3 @@ 'use strict';

* These properties are marked with 🚅🚅🚅.<br/>
* ⭐ **tip** *to achieve smoother interactions you may want to set **staticGraph** to **true** *<br/>
* ⭐ **tip** *to achieve smoother interactions you may want to provide a toggle to set **staticGraph** to **true** *<br/>
* <br/>

@@ -39,4 +39,6 @@ * **Note about granularity**<br/>

* @param {number} [height=400] - the height of the (svg) area where the graph will be rendered.
* @param {boolean} [highlightBehavior=false] - 🚅🚅🚅 when user mouse hovers a node that node and adjacent common
* connections will be highlighted. All the remaining nodes and links assume opacity value equal to **highlightOpacity**.
* @param {boolean} [nodeHighlightBehavior=false] - 🚅🚅🚅 when user mouse hovers a node that node and adjacent common
* connections will be highlighted (depending on the *highlightDegree* value). All the remaining nodes and links assume opacity value equal to **highlightOpacity**.
* @param {boolean} [linkHighlightBehavior=false] - 🚅🚅🚅 when the user mouse hovers some link that link and the correspondent nodes will be highlighted, this is a similar behavior
* to *nodeHighlightBehavior* but for links <small>(just for historical reference this property was introduced in **v1.0.0**)</small>.
* @param {number} [highlightDegree=1] - **Possible values: 0, 1 or 2**. This value represents the range of the

@@ -47,3 +49,3 @@ * highlight behavior when some node is highlighted. If the value is set to **0** only the selected node will be

* @param {number} [highlightOpacity=1] - this value is used to highlight nodes in the network. The lower
* the value the more the less highlighted nodes will be visible (related to *highlightBehavior*).
* the value the more the less highlighted nodes will be visible (related to *nodeHighlightBehavior*).
* @param {number} [maxZoom=8] - max zoom that can be performed against the graph.

@@ -92,3 +94,3 @@ * @param {number} [minZoom=0.1] - min zoom that can be performed against the graph.

* want the node to keep its color in highlighted state).
* @param {number} [node.highlightFontSize=10] - fontSize in highlighted state.
* @param {number} [node.highlightFontSize=8] - fontSize in highlighted state.
* @param {string} [node.highlightFontWeight='normal'] - fontWeight in highlighted state.

@@ -108,3 +110,7 @@ * @param {string} [node.highlightStrokeColor='SAME'] - strokeColor in highlighted state.

* ```
* @param {number} [link.strokeWidth=1.5] - strokeWidth for all links.
* @param {number} [link.strokeWidth=1.5] - strokeWidth for all links. By default the actual value is obtain by the
* following expression:
* ```javascript
* link.strokeWidth * (1 / transform); // transform is a zoom delta Δ value
* ```
* @param {string} [link.highlightColor='#d3d3d3'] - links' color in highlight state.

@@ -115,3 +121,3 @@ *

* const myConfig = {
* highlightBehavior: true,
* nodeHighlightBehavior: true,
* node: {

@@ -132,7 +138,8 @@ * color: 'lightgreen',

height: 400,
highlightBehavior: true,
highlightDegree: 1,
highlightOpacity: 0.1,
highlightOpacity: 1,
linkHighlightBehavior: false,
maxZoom: 8,
minZoom: 0.5,
minZoom: 0.1,
nodeHighlightBehavior: false,
panAndZoom: false,

@@ -149,3 +156,3 @@ staticGraph: false,

renderLabel: true,
size: 80,
size: 200,
strokeColor: 'none',

@@ -152,0 +159,0 @@ strokeWidth: 1.5,

@@ -66,2 +66,3 @@ 'use strict';

* @param {string} highlightedNode - same as {@link #buildGraph|highlightedNode in buildGraph}.
* @param {Object} highlightedLink - same as {@link #buildGraph|highlightedLink in buildGraph}.
* @param {number} transform - value that indicates the amount of zoom transformation.

@@ -71,3 +72,3 @@ * @returns {Object} returns an object that aggregates all props for creating respective Link component instance.

*/
function _buildLinkProps(source, target, nodes, links, config, linkCallbacks, highlightedNode, transform) {
function _buildLinkProps(source, target, nodes, links, config, linkCallbacks, highlightedNode, highlightedLink, transform) {
var x1 = nodes[source] && nodes[source].x || 0;

@@ -78,4 +79,3 @@ var y1 = nodes[source] && nodes[source].y || 0;

var opacity = config.link.opacity;
var mainNodeParticipates = void 0;
var mainNodeParticipates = false;

@@ -94,4 +94,10 @@ switch (config.highlightDegree) {

if (highlightedNode) {
opacity = mainNodeParticipates && nodes[source].highlighted && nodes[target].highlighted ? config.link.opacity : config.highlightOpacity;
var reasonNode = mainNodeParticipates && nodes[source].highlighted && nodes[target].highlighted;
var reasonLink = source === (highlightedLink && highlightedLink.source) && target === (highlightedLink && highlightedLink.target);
var highlight = reasonNode || reasonLink;
var opacity = config.link.opacity;
if (highlightedNode || highlightedLink && highlightedLink.source) {
opacity = highlight ? config.link.opacity : config.highlightOpacity;
}

@@ -101,11 +107,11 @@

if (mainNodeParticipates && nodes[source].highlighted && nodes[target].highlighted) {
if (highlight) {
stroke = config.link.highlightColor === _const2.default.KEYWORDS.SAME ? config.link.color : config.link.highlightColor;
}
var linkValue = links[source][target] || links[target][source] || 1;
var strokeWidth = config.link.strokeWidth * (1 / transform);
if (config.link.semanticStrokeWidth) {
var linkValue = links[source][target] || links[target][source] || 1;
strokeWidth += linkValue * strokeWidth / 10;

@@ -125,3 +131,5 @@ }

opacity: opacity,
onClickLink: linkCallbacks.onClickLink
onClickLink: linkCallbacks.onClickLink,
onMouseOverLink: linkCallbacks.onMouseOverLink,
onMouseOutLink: linkCallbacks.onMouseOutLink
};

@@ -138,2 +146,3 @@ }

* @param {string} highlightedNode - same as {@link #buildGraph|highlightedNode in buildGraph}.
* @param {Object} highlightedLink - same as {@link #buildGraph|highlightedLink in buildGraph}.
* @param {number} transform - value that indicates the amount of zoom transformation.

@@ -143,3 +152,3 @@ * @returns {Object[]} returns the generated array of Link components.

*/
function _buildNodeLinks(nodeId, nodes, links, config, linkCallbacks, highlightedNode, transform) {
function _buildNodeLinks(nodeId, nodes, links, config, linkCallbacks, highlightedNode, highlightedLink, transform) {
var linksComponents = [];

@@ -157,3 +166,3 @@

var key = '' + nodeId + _const2.default.COORDS_SEPARATOR + target;
var props = _buildLinkProps(source, target, nodes, links, config, linkCallbacks, highlightedNode, transform);
var props = _buildLinkProps(source, target, nodes, links, config, linkCallbacks, highlightedNode, highlightedLink, transform);

@@ -169,24 +178,2 @@ linksComponents.push(_react2.default.createElement(_link2.default, _extends({ key: key }, props)));

/**
* Get the correct node opacity in order to properly make decisions based on context such as currently highlited node.
* @param {Object} node - the node object for whom we will generate properties.
* @param {string} highlightedNode - same as {@link #buildGraph|highlightedNode in buildGraph}.
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}.
* @returns {number} the opacity value for the given node.
* @memberof Graph/helper
*/
function _getNodeOpacity(node, highlightedNode, config) {
var opacity = void 0;
if (highlightedNode && config.highlightDegree === 0) {
opacity = node.id === highlightedNode && node.highlighted ? config.node.opacity : config.highlightOpacity;
} else if (highlightedNode) {
opacity = node.highlighted ? config.node.opacity : config.highlightOpacity;
} else {
opacity = config.node.opacity;
}
return opacity;
}
/**
* Build some Node properties based on given parameters.

@@ -197,2 +184,3 @@ * @param {Object} node - the node object for whom we will generate properties.

* @param {string} highlightedNode - same as {@link #buildGraph|highlightedNode in buildGraph}.
* @param {Object} highlightedLink - same as {@link #buildGraph|highlightedLink in buildGraph}.
* @param {number} transform - value that indicates the amount of zoom transformation.

@@ -202,8 +190,8 @@ * @returns {Object} returns object that contain Link props ready to be feeded to the Link component.

*/
function _buildNodeProps(node, config, nodeCallbacks, highlightedNode, transform) {
var opacity = _getNodeOpacity(node, highlightedNode, config);
function _buildNodeProps(node, config, nodeCallbacks, highlightedNode, highlightedLink, transform) {
var highlight = node.highlighted || node.id === (highlightedLink && highlightedLink.source) || node.id === (highlightedLink && highlightedLink.target);
var opacity = _getNodeOpacity(node, highlightedNode, highlightedLink, config);
var fill = node.color || config.node.color;
if (node.highlighted && config.node.highlightColor !== _const2.default.KEYWORDS.SAME) {
if (highlight && config.node.highlightColor !== _const2.default.KEYWORDS.SAME) {
fill = config.node.highlightColor;

@@ -214,3 +202,3 @@ }

if (node.highlighted && config.node.highlightStrokeColor !== _const2.default.KEYWORDS.SAME) {
if (highlight && config.node.highlightStrokeColor !== _const2.default.KEYWORDS.SAME) {
stroke = config.node.highlightStrokeColor;

@@ -221,5 +209,5 @@ }

var nodeSize = node.size || config.node.size;
var fontSize = node.highlighted ? config.node.highlightFontSize : config.node.fontSize;
var fontSize = highlight ? config.node.highlightFontSize : config.node.fontSize;
var dx = fontSize * t + nodeSize / 100 + 1.5;
var strokeWidth = node.highlighted ? config.node.highlightStrokeWidth : config.node.strokeWidth;
var strokeWidth = highlight ? config.node.highlightStrokeWidth : config.node.strokeWidth;

@@ -234,3 +222,3 @@ return {

dx: dx,
fontWeight: node.highlighted ? config.node.highlightFontWeight : config.node.fontWeight,
fontWeight: highlight ? config.node.highlightFontWeight : config.node.fontWeight,
id: node.id,

@@ -251,2 +239,124 @@ label: node[config.node.labelProperty] || node.id,

/**
* Get the correct node opacity in order to properly make decisions based on context such as currently highlighted node.
* @param {Object} node - the node object for whom we will generate properties.
* @param {string} highlightedNode - same as {@link #buildGraph|highlightedNode in buildGraph}.
* @param {Object} highlightedLink - same as {@link #buildGraph|highlightedLink in buildGraph}.
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}.
* @returns {number} the opacity value for the given node.
* @memberof Graph/helper
*/
function _getNodeOpacity(node, highlightedNode, highlightedLink, config) {
var highlight = node.highlighted || node.id === (highlightedLink && highlightedLink.source) || node.id === (highlightedLink && highlightedLink.target);
var someNodeHighlighted = !!(highlightedNode || highlightedLink && highlightedLink.source && highlightedLink.target);
var opacity = void 0;
if (someNodeHighlighted && config.highlightDegree === 0) {
opacity = highlight ? config.node.opacity : config.highlightOpacity;
} else if (someNodeHighlighted) {
opacity = highlight ? config.node.opacity : config.highlightOpacity;
} else {
opacity = config.node.opacity;
}
return opacity;
}
/**
* Receives a matrix of the graph with the links source and target as concrete node instances and it transforms it
* in a lightweight matrix containing only links with source and target being strings representative of some node id
* and the respective link value (if non existent will default to 1).
* @param {Object[]} graphLinks - an array of all graph links but all the links contain the source and target nodes
* objects.
* @returns {Object.<string, Object>} an object containing a matrix of connections of the graph, for each nodeId,
* there is an object that maps adjacent nodes ids (string) and their values (number).
* @memberof Graph/helper
*/
function _initializeLinks(graphLinks) {
return graphLinks.reduce(function (links, l) {
var source = l.source.id || l.source;
var target = l.target.id || l.target;
if (!links[source]) {
links[source] = {};
}
if (!links[target]) {
links[target] = {};
}
// @TODO: If the graph is directed this should be adapted
links[source][target] = links[target][source] = l.value || 1;
return links;
}, {});
}
/**
* Method that initialize graph nodes provided by rd3g consumer and adds additional default mandatory properties
* that are optional for the user. Also it generates an index mapping, this maps nodes ids the their index in the array
* of nodes. This is needed because d3 callbacks such as node click and link click return the index of the node.
* @param {Object[]} graphNodes - the array of nodes provided by the rd3g consumer.
* @returns {Object} returns the nodes ready to be used within rd3g with additional properties such as x, y
* and highlighted values.
* @memberof Graph/helper
*/
function _initializeNodes(graphNodes) {
var nodes = {};
var n = graphNodes.length;
for (var i = 0; i < n; i++) {
var node = graphNodes[i];
node.highlighted = false;
if (!node.hasOwnProperty('x')) {
node['x'] = 0;
}
if (!node.hasOwnProperty('y')) {
node['y'] = 0;
}
nodes[node.id.toString()] = node;
}
return nodes;
}
/**
* Some integrity validations on links and nodes structure. If some validation fails the function will
* throw an error.
* @param {Object} data - Same as {@link #initializeGraphState|data in initializeGraphState}.
* @memberof Graph/helper
* @throws can throw the following error msg:
* INSUFFICIENT_DATA - msg if no nodes are provided
* INVALID_LINKS - if links point to nonexistent nodes
*/
function _validateGraphData(data) {
if (!data.nodes || !data.nodes.length) {
_utils2.default.throwErr('Graph', _err2.default.INSUFFICIENT_DATA);
}
var n = data.links.length;
var _loop = function _loop(i) {
var l = data.links[i];
if (!data.nodes.find(function (n) {
return n.id === l.source;
})) {
_utils2.default.throwErr('Graph', _err2.default.INVALID_LINKS + ' - "' + l.source + '" is not a valid source node id');
}
if (!data.nodes.find(function (n) {
return n.id === l.target;
})) {
_utils2.default.throwErr('Graph', _err2.default.INVALID_LINKS + ' - "' + l.target + '" is not a valid target node id');
}
};
for (var i = 0; i < n; i++) {
_loop(i);
}
}
/**
* Method that actually is exported an consumed by Graph component in order to build all Nodes and Link

@@ -282,10 +392,13 @@ * components.

* @param {Function[]} linkCallbacks - array of callbacks for used defined event handler for link interactions.
* @param {Object} config - an object containg rd3g consumer defined configurations {@link #config config} for the graph.
* @param {Object} config - an object containing rd3g consumer defined configurations {@link #config config} for the graph.
* @param {string} highlightedNode - this value contains a string that represents the some currently highlighted node.
* @param {Object} highlightedLink - this object contains a source and target property for a link that is highlighted at some point in time.
* @param {string} highlightedLink.source - id of source node for highlighted link.
* @param {string} highlightedLink.target - id of target node for highlighted link.
* @param {number} transform - value that indicates the amount of zoom transformation.
* @returns {Object} returns an object containg the generated nodes and links that form the graph. The result is
* @returns {Object} returns an object containing the generated nodes and links that form the graph. The result is
* returned in a way that can be consumed by es6 **destructuring assignment**.
* @memberof Graph/helper
*/
function buildGraph(nodes, nodeCallbacks, links, linkCallbacks, config, highlightedNode, transform) {
function buildGraph(nodes, nodeCallbacks, links, linkCallbacks, config, highlightedNode, highlightedLink, transform) {
var linksComponents = [];

@@ -297,7 +410,7 @@ var nodesComponents = [];

var props = _buildNodeProps(nodes[nodeId], config, nodeCallbacks, highlightedNode, transform);
var props = _buildNodeProps(nodes[nodeId], config, nodeCallbacks, highlightedNode, highlightedLink, transform);
nodesComponents.push(_react2.default.createElement(_node2.default, _extends({ key: nodeId }, props)));
linksComponents = linksComponents.concat(_buildNodeLinks(nodeId, nodes, links, config, linkCallbacks, highlightedNode, transform));
linksComponents = linksComponents.concat(_buildNodeLinks(nodeId, nodes, links, config, linkCallbacks, highlightedNode, highlightedLink, transform));
}

@@ -313,4 +426,5 @@

* Create d3 forceSimulation to be applied on the graph.<br/>
* <a href="https://github.com/d3/d3-force#forceSimulation" target="_blank">https://github.com/d3/d3-force#forceSimulation</a><br/>
* <a href="https://github.com/d3/d3-force#simulation_force" target="_blank">https://github.com/d3/d3-force#simulation_force</a><br/>
* {@link https://github.com/d3/d3-force#forceSimulation|d3-force#forceSimulation}<br/>
* {@link https://github.com/d3/d3-force#simulation_force|d3-force#simulation_force}<br/>
* 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.

@@ -329,3 +443,3 @@ * @param {number} height - the height of the container area of the graph.

/**
* Incapsulates common procedures to initialize graph.
* Encapsulates common procedures to initialize graph.
* @param {Object} props - Graph component props, object that holds data, id and config.

@@ -336,3 +450,3 @@ * @param {Object} props.data - Data object holds links (array of **Link**) and nodes (array of **Node**).

* @param {Object} state - Graph component current state (same format as returned object on this function).
* @returns a fully (re)initialized graph state object.
* @returns {Object} a fully (re)initialized graph state object.
* @memberof Graph/helper

@@ -347,6 +461,6 @@ */

validateGraphData(data);
_validateGraphData(data);
if (state && state.nodes && state.links && state.nodeIndexMapping) {
// absorve existent positining
if (state && state.nodes && state.links) {
// absorb existent positioning
graph = {

@@ -372,8 +486,4 @@ nodes: data.nodes.map(function (n) {

var newConfig = Object.assign({}, _utils2.default.merge(_config2.default, config || {}));
var _initializeNodes = initializeNodes(graph.nodes),
nodes = _initializeNodes.nodes,
nodeIndexMapping = _initializeNodes.nodeIndexMapping;
var links = initializeLinks(graph.links); // Matrix of graph connections
var nodes = _initializeNodes(graph.nodes);
var links = _initializeLinks(graph.links); // matrix of graph connections
var _graph = graph,

@@ -389,3 +499,2 @@ d3Nodes = _graph.nodes,

config: newConfig,
nodeIndexMapping: nodeIndexMapping,
links: links,

@@ -403,95 +512,6 @@ d3Links: d3Links,

/**
* Receives a matrix of the graph with the links source and target as concrete node instances and it transforms it
* in a lightweight matrix containing only links with source and target being strings representative of some node id
* and the respective link value (if non existant will default to 1).
* @param {Object[]} graphLinks - an array of all graph links but all the links contain the source and target nodes
* objects.
* @returns {Object.<string, Object>} an object containing a matrix of connections of the graph, for each nodeId,
* there is an object that maps adjacent nodes ids (string) and their values (number).
* @memberof Graph/helper
*/
function initializeLinks(graphLinks) {
return graphLinks.reduce(function (links, l) {
var source = l.source.id || l.source;
var target = l.target.id || l.target;
if (!links[source]) {
links[source] = {};
}
if (!links[target]) {
links[target] = {};
}
// @TODO: If the graph is directed this should be adapted
links[source][target] = links[target][source] = l.value || 1;
return links;
}, {});
}
/**
* Method that initialize graph nodes provided by rd3g consumer and adds additional default mandatory properties
* that are optional for the user. Also it generates an index mapping, this maps nodes ids the their index in the array
* of nodes. This is needed because d3 callbacks such as node click and link click return the index of the node.
* @param {Object[]} graphNodes - the array of nodes provided by the rd3g consumer.
* @returns {Object} returns the nodes ready to be used within rd3g with additional properties such as x, y
* and highlighted values. Returns also the index mapping object of type Object.<number, string>.
* @memberof Graph/helper
*/
function initializeNodes(graphNodes) {
var nodes = {};
var nodeIndexMapping = {};
var n = graphNodes.length;
for (var i = 0; i < n; i++) {
var node = graphNodes[i];
node.highlighted = false;
if (!node.hasOwnProperty('x')) {
node['x'] = 0;
}
if (!node.hasOwnProperty('y')) {
node['y'] = 0;
}
nodes[node.id.toString()] = node;
nodeIndexMapping[i] = node.id;
}
return { nodes: nodes, nodeIndexMapping: nodeIndexMapping };
}
/**
* Some integraty validations on links and nodes structure. If some validation fails the function will
* throw an error.
* @param {Object} data - Same as {@link #initializeGraphState|data in initializeGraphState}.
* @memberof Graph/helper
*/
function validateGraphData(data) {
var _this = this;
data.links.forEach(function (l) {
if (!data.nodes.find(function (n) {
return n.id === l.source;
})) {
_utils2.default.throwErr(_this.constructor.name, _err2.default.INVALID_LINKS + ' - ' + l.source + ' is not a valid node id');
}
if (!data.nodes.find(function (n) {
return n.id === l.target;
})) {
_utils2.default.throwErr(_this.constructor.name, _err2.default.INVALID_LINKS + ' - ' + l.target + ' is not a valid node id');
}
});
}
exports.default = {
buildGraph: buildGraph,
createForceSimulation: createForceSimulation,
initializeGraphState: initializeGraphState,
initializeLinks: initializeLinks,
initializeNodes: initializeNodes
initializeGraphState: initializeGraphState
};

@@ -66,3 +66,3 @@ 'use strict';

*
* // Graph payload (with minimalist structure)
* // graph payload (with minimalist structure)
* const data = {

@@ -80,5 +80,6 @@ * nodes: [

*
* // The graph configuration
* // the graph configuration, you only need to pass down properties
* // that you want to override, otherwise default ones will be used
* const myConfig = {
* highlightBehavior: true,
* nodeHighlightBehavior: true,
* node: {

@@ -94,13 +95,13 @@ * color: 'lightgreen',

*
* // Graph event callbacks
* // graph event callbacks
* const onClickNode = function(nodeId) {
* window.alert('Clicked node', nodeId);
* window.alert('Clicked node ${nodeId}');
* };
*
* const onMouseOverNode = function(nodeId) {
* window.alert('Mouse over node', nodeId);
* window.alert(`Mouse over node ${nodeId}`);
* };
*
* const onMouseOutNode = function(nodeId) {
* window.alert('Mouse out node', nodeId);
* window.alert(`Mouse out node ${nodeId}`);
* };

@@ -112,2 +113,10 @@ *

*
* const onMouseOverLink = function(source, target) {
* window.alert(`Mouse over in link between ${source} and ${target}`);
* };
*
* const onMouseOutLink = function(source, target) {
* window.alert(`Mouse out link between ${source} and ${target}`);
* };
*
* <Graph

@@ -120,3 +129,5 @@ * id='graph-id' // id is mandatory, if no id is defined rd3g will throw an error

* onMouseOverNode={onMouseOverNode}
* onMouseOutNode={onMouseOutNode} />
* onMouseOutNode={onMouseOutNode}
* onMouseOverLink={onMouseOverLink}
* onMouseOutLink={onMouseOutLink}/>
*/

@@ -130,12 +141,21 @@

/**
* Sets d3 tick function and configures other d3 stuff such as forces and drag events.
*/
value: function _graphForcesConfig() {
this.state.simulation.nodes(this.state.d3Nodes).on('tick', this._tick);
var forceLink = (0, _d3Force.forceLink)(this.state.d3Links).id(function (l) {
return l.id;
}).distance(D3_CONST.LINK_IDEAL_DISTANCE).strength(D3_CONST.FORCE_LINK_STRENGTH);
this.state.simulation.force(_const2.default.LINK_CLASS_NAME, forceLink);
var customNodeDrag = (0, _d3Drag.drag)().on('start', this._onDragStart).on('drag', this._onDragMove).on('end', this._onDragEnd);
(0, _d3Selection.select)('#' + this.state.id + '-' + _const2.default.GRAPH_WRAPPER_ID).selectAll('.node').call(customNodeDrag);
}
/**
* This method resets all nodes fixed positions by deleting the properties fx (fixed x)
* and fy (fixed y). Following this, a simulation is triggered in order to force nodes to go back
* to their original positions (or at least new positions according to the d3 force parameters).
* Handles d3 drag 'end' event.
*/

@@ -145,4 +165,9 @@

/**
* Handles mouse over node event.
* @param {number} index - index of the mouse hovered node.
* Handles d3 'drag' event.
* @param {Object} ev - if not undefined it will contain event data.
* @param {number} index - index of the node that is being dragged.
* @param {Array.<Object>} nodeList - array of d3 nodes. This list of nodes is provided by d3, each
* node contains all information that was previously fed by rd3g.
*
* {@link https://github.com/d3/d3-drag/blob/master/README.md#drag_subject|more about d3 drag}
*/

@@ -152,4 +177,3 @@

/**
* Handler for 'zoom' event within zoom config.
* @returns {Object} returns the transformed elements within the svg graph area.
* Handles d3 drag 'start' event.
*/

@@ -159,2 +183,9 @@

/**
* Sets nodes and links highlighted value.
* @param {string} id - the id of the node to highlight.
* @param {boolean} [value=false] - the highlight value to be set (true or false).
*/
/**
* The tick function simply calls React set state in order to update component and render nodes

@@ -166,25 +197,22 @@ * along time as d3 calculates new node positioning.

/**
* Handles d3 drag 'start' event.
* Configures zoom upon graph with default or user provided values.<br/>
* {@link https://github.com/d3/d3-zoom#zoom}
*/
/**
* Handles d3 drag 'end' event.
* Handler for 'zoom' event within zoom config.
* @returns {Object} returns the transformed elements within the svg graph area.
*/
value: function _graphForcesConfig() {
this.state.simulation.nodes(this.state.d3Nodes).on('tick', this._tick);
var forceLink = (0, _d3Force.forceLink)(this.state.d3Links).id(function (l) {
return l.id;
}).distance(D3_CONST.LINK_IDEAL_DISTANCE).strength(D3_CONST.FORCE_LINK_STRENGTH);
this.state.simulation.force(_const2.default.LINK_CLASS_NAME, forceLink);
/**
* Handles mouse over node event.
* @param {string} id - id of the node that participates in the event.
*/
var customNodeDrag = (0, _d3Drag.drag)().on('start', this._onDragStart).on('drag', this._onDragMove).on('end', this._onDragEnd);
(0, _d3Selection.select)('#' + this.state.id + '-' + _const2.default.GRAPH_WRAPPER_ID).selectAll('.node').call(customNodeDrag);
}
/**
* Calls d3 simulation.restart().<br/>
* {@link https://github.com/d3/d3-force#simulation_restart}
* Handles mouse out node event.
* @param {string} id - id of the node that participates in the event.
*/

@@ -194,10 +222,12 @@

/**
* Calls d3 simulation.stop().<br/>
* {@link https://github.com/d3/d3-force#simulation_stop}
*/
* Handles mouse over link event.
* @param {string} source - id of the source node that participates in the event.
* @param {string} target - id of the target node that participates in the event.
*/
/**
* Handles mouse out node event.
* @param {number} index - index of the mouse hovered node.
* Handles mouse out link event.
* @param {string} source - id of the source node that participates in the event.
* @param {string} target - id of the target node that participates in the event.
*/

@@ -207,11 +237,11 @@

/**
* Configures zoom upon graph with default or user provided values.<br/>
* {@link https://github.com/d3/d3-zoom#zoom}
*/
* Calls d3 simulation.stop().<br/>
* {@link https://github.com/d3/d3-force#simulation_stop}
*/
/**
* Sets nodes and links highlighted value.
* @param {number} index - the index of the node to highlight (and its adjacent).
* @param {boolean} value - the highlight value to be set (true or false).
* This method resets all nodes fixed positions by deleting the properties fx (fixed x)
* and fy (fixed y). Following this, a simulation is triggered in order to force nodes to go back
* to their original positions (or at least new positions according to the d3 force parameters).
*/

@@ -221,5 +251,4 @@

/**
* Handles d3 'drag' event.
* @param {Object} ev - event.
* @param {number} index - index of the node that is being dragged.
* Calls d3 simulation.restart().<br/>
* {@link https://github.com/d3/d3-force#simulation_restart}
*/

@@ -238,6 +267,8 @@

_this._onDragMove = function (ev, index) {
_this._onDragMove = function (ev, index, nodeList) {
var id = nodeList[index].id;
if (!_this.state.config.staticGraph) {
// This is where d3 and react bind
var draggedNode = _this.state.nodes[_this.state.nodeIndexMapping[index]];
// this is where d3 and react bind
var draggedNode = _this.state.nodes[id];

@@ -247,3 +278,3 @@ draggedNode.x += _d3Selection.event.dx;

// Set nodes fixing coords fx and fy
// set nodes fixing coords fx and fy
draggedNode['fx'] = draggedNode.x;

@@ -260,9 +291,11 @@ draggedNode['fy'] = draggedNode.y;

_this._setHighlighted = function (index, value) {
_this.state.highlightedNode = value ? index : '';
_this.state.nodes[index].highlighted = value;
_this._setNodeHighlightedValue = function (id) {
var value = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
_this.state.highlightedNode = value ? id : '';
_this.state.nodes[id].highlighted = value;
// when highlightDegree is 0 we want only to highlight selected node
if (_this.state.links[index] && _this.state.config.highlightDegree !== 0) {
Object.keys(_this.state.links[index]).forEach(function (k) {
if (_this.state.links[id] && _this.state.config.highlightDegree !== 0) {
Object.keys(_this.state.links[id]).forEach(function (k) {
_this.state.nodes[k].highlighted = value;

@@ -291,14 +324,34 @@ });

_this.onMouseOutNode = function (index) {
_this.props.onMouseOutNode && _this.props.onMouseOutNode(index);
_this.onMouseOverNode = function (id) {
_this.props.onMouseOverNode && _this.props.onMouseOverNode(id);
_this.state.config.highlightBehavior && _this._setHighlighted(index, false);
_this.state.config.nodeHighlightBehavior && _this._setNodeHighlightedValue(id, true);
};
_this.onMouseOverNode = function (index) {
_this.props.onMouseOverNode && _this.props.onMouseOverNode(index);
_this.onMouseOutNode = function (id) {
_this.props.onMouseOutNode && _this.props.onMouseOutNode(id);
_this.state.config.highlightBehavior && _this._setHighlighted(index, true);
_this.state.config.nodeHighlightBehavior && _this._setNodeHighlightedValue(id, false);
};
_this.onMouseOverLink = function (source, target) {
_this.props.onMouseOverLink && _this.props.onMouseOverLink(source, target);
if (_this.state.config.linkHighlightBehavior) {
_this.state.highlightedLink = { source: source, target: target };
_this._tick();
}
};
_this.onMouseOutLink = function (source, target) {
_this.props.onMouseOutLink && _this.props.onMouseOutLink(source, target);
if (_this.state.config.linkHighlightBehavior) {
_this.state.highlightedLink = undefined;
_this._tick();
}
};
_this.pauseSimulation = function () {

@@ -350,3 +403,3 @@ return !_this.state.config.staticGraph && _this.state.simulation.stop();

// In order to properly update graph data we need to pause eventual d3 ongoing animations
// in order to properly update graph data we need to pause eventual d3 ongoing animations
newGraphElements && this.pauseSimulation();

@@ -366,3 +419,3 @@

value: function componentDidUpdate() {
// If the property staticGraph was activated we want to stop possible ongoing simulation
// if the property staticGraph was activated we want to stop possible ongoing simulation
this.state.config.staticGraph && this.state.simulation.stop();

@@ -388,3 +441,3 @@

// Graph zoom and drag&drop all network
// graph zoom and drag&drop all network
this._zoomConfig();

@@ -404,3 +457,7 @@ }

onMouseOut: this.onMouseOutNode
}, this.state.links, { onClickLink: this.props.onClickLink }, this.state.config, this.state.highlightedNode, this.state.transform),
}, this.state.links, {
onClickLink: this.props.onClickLink,
onMouseOverLink: this.onMouseOverLink,
onMouseOutLink: this.onMouseOutLink
}, this.state.config, this.state.highlightedNode, this.state.highlightedLink, this.state.transform),
nodes = _graphHelper$buildGra.nodes,

@@ -407,0 +464,0 @@ links = _graphHelper$buildGra.links;

@@ -28,2 +28,10 @@ 'use strict';

*
* const onMouseOverLink = function(source, target) {
* window.alert(`Mouse over in link between ${source} and ${target}`);
* };
*
* const onMouseOutLink = function(source, target) {
* window.alert(`Mouse out link between ${source} and ${target}`);
* };
*
* <Link

@@ -40,3 +48,5 @@ * source='idSourceNode'

* opacity=1
* onClickLink={onClickLink} />
* onClickLink={onClickLink}
* onMouseOverLink={onMouseOverLink}
* onMouseOutLink={onMouseOutLink} />
*/

@@ -59,2 +69,6 @@ var Link = function (_React$Component) {

return _this.props.onClickLink && _this.props.onClickLink(_this.props.source, _this.props.target);
}, _this.handleOnMouseOverLink = function () {
return _this.props.onMouseOverLink && _this.props.onMouseOverLink(_this.props.source, _this.props.target);
}, _this.handleOnMouseOutLink = function () {
return _this.props.onMouseOutLink && _this.props.onMouseOutLink(_this.props.source, _this.props.target);
}, _temp), _possibleConstructorReturn(_this, _ret);

@@ -67,2 +81,12 @@ }

/**
* Handle mouse over link event.
*/
/**
* Handle mouse out link event.
*/
_createClass(Link, [{

@@ -80,2 +104,4 @@ key: 'render',

onClick: this.handleOnClickLink,
onMouseOut: this.handleOnMouseOutLink,
onMouseOver: this.handleOnMouseOverLink,
style: lineStyle,

@@ -82,0 +108,0 @@ x1: this.props.x1,

@@ -6,8 +6,8 @@ "use strict";

});
/*eslint max-len: ["error", 200]*/
exports.default = {
GRAPH_NO_ID_PROP: "id prop not defined! id property is mandatory and it should be unique.",
STATIC_GRAPH_DATA_UPDATE: "a static graph cannot receive new data (nodes or links).\
Make sure config.staticGraph is set to true if you want to update graph data",
INVALID_LINKS: "you provided a invalid links data structure.\
Links source and target attributes must point to an existent node"
STATIC_GRAPH_DATA_UPDATE: "a static graph cannot receive new data (nodes or links). Make sure config.staticGraph is set to true if you want to update graph data",
INVALID_LINKS: "you provided a invalid links data structure. Links source and target attributes must point to an existent node",
INSUFFICIENT_DATA: "you have not provided enough data for react-d3-graph to render something. You need to provide at least one node"
};

@@ -121,2 +121,6 @@ 'use strict';

if (Object.keys(o1 || {}).length === 0) {
return o2 && !isObjectEmpty(o2) ? o2 : {};
}
var _iteratorNormalCompletion2 = true;

@@ -123,0 +127,0 @@ var _didIteratorError2 = false;

{
"name": "react-d3-graph",
"version": "0.4.0",
"version": "1.0.0",
"description": "React component to build interactive and configurable graphs with d3 effortlessly",

@@ -22,3 +22,3 @@ "author": "Daniel Caldas",

"test:clean": "jest --no-cache --updateSnapshot --verbose --coverage",
"test:watch": "jest --verbose --watchAll"
"test:watch": "jest --verbose --coverage --watchAll"
},

@@ -49,3 +49,3 @@ "dependencies": {

"html-webpack-plugin": "2.30.1",
"jest": "21.1.0",
"jest": "21.3.0-beta.8",
"npm-run-all": "4.1.1",

@@ -52,0 +52,0 @@ "react-addons-test-utils": "15.6.0",

@@ -1,7 +0,7 @@

# react-d3-graph &middot; [![Build Status](https://travis-ci.org/danielcaldas/react-d3-graph.svg?branch=master)](https://travis-ci.org/danielcaldas/react-d3-graph) [![npm version](https://img.shields.io/badge/npm-v0.3.0-blue.svg)](https://www.npmjs.com/package/react-d3-graph) [![npm stats](https://img.shields.io/badge/downloads-700+-brightgreen.svg)](https://npm-stat.com/) [![probot enabled](https://img.shields.io/badge/probot:stale-enabled-yellow.svg)](https://probot.github.io/)
[:book:](https://danielcaldas.github.io/react-d3-graph/docs/index.html)
# react-d3-graph &middot; [![Build Status](https://travis-ci.org/danielcaldas/react-d3-graph.svg?branch=master)](https://travis-ci.org/danielcaldas/react-d3-graph) [![npm version](https://img.shields.io/badge/npm-v1.0.0-blue.svg)](https://www.npmjs.com/package/react-d3-graph) [![npm stats](https://img.shields.io/badge/downloads-1k-brightgreen.svg)](https://npm-stat.com/charts.html?package=react-d3-graph&from=2017-04-25&to=2017-12-02) [![probot enabled](https://img.shields.io/badge/probot:stale-enabled-yellow.svg)](https://probot.github.io/)
:book: [1.0.0](https://danielcaldas.github.io/react-d3-graph/docs/index.html) | [0.4.0](https://danielcaldas.github.io/react-d3-graph/docs/0.4.0.html) | [0.3.0](https://danielcaldas.github.io/react-d3-graph/docs/0.3.0.html)
### *Interactive and configurable graphs with react and d3 effortlessly*
[![react-d3-graph gif sample](https://github.com/danielcaldas/react-d3-graph/blob/master/sandbox/rd3g.gif?raw=true)](https://danielcaldas.github.io/react-d3-graph/sandbox/index.html)
[![react-d3-graph gif sample](https://github.com/danielcaldas/react-d3-graph/blob/master/sandbox/rd3g_v2.gif?raw=true)](https://danielcaldas.github.io/react-d3-graph/sandbox/index.html)

@@ -30,3 +30,3 @@ ## Playground

// Graph payload (with minimalist structure)
// graph payload (with minimalist structure)
const data = {

@@ -44,5 +44,6 @@ nodes: [

// The graph configuration
// the graph configuration, you only need to pass down properties
// that you want to override, otherwise default ones will be used
const myConfig = {
highlightBehavior: true,
nodeHighlightBehavior: true,
node: {

@@ -58,13 +59,13 @@ color: 'lightgreen',

// Graph event callbacks
// graph event callbacks
const onClickNode = function(nodeId) {
window.alert('Clicked node', nodeId);
window.alert('Clicked node ${nodeId}');
};
const onMouseOverNode = function(nodeId) {
window.alert('Mouse over node', nodeId);
window.alert(`Mouse over node ${nodeId}`);
};
const onMouseOutNode = function(nodeId) {
window.alert('Mouse out node', nodeId);
window.alert(`Mouse out node ${nodeId}`);
};

@@ -76,2 +77,10 @@

const onMouseOverLink = function(source, target) {
window.alert(`Mouse over in link between ${source} and ${target}`);
};
const onMouseOutLink = function(source, target) {
window.alert(`Mouse out link between ${source} and ${target}`);
};
<Graph

@@ -84,6 +93,12 @@ id='graph-id' // id is mandatory, if no id is defined rd3g will throw an error

onMouseOverNode={onMouseOverNode}
onMouseOutNode={onMouseOutNode} />
onMouseOutNode={onMouseOutNode}
onMouseOverLink={onMouseOverLink}
onMouseOutLink={onMouseOutLink}/>
```
## Roadmap :railway_track:
Want to know what's ahead for react-d3-graph? Or simply curious on what comes next and stuff that is under development?
Check [this trello board](https://trello.com/b/KrnmFXha/react-d3-graph) where everything related to react-d3-graph is managed.
## Contributions
Contributions are welcome fell free to submit new ideas/features.
Contributions are welcome fell free to submit new ideas/features, just open an issue or send me an email or something. If you are more a *hands on* person, just submit a pull request.

@@ -8,6 +8,6 @@ ## Release Process

2. npm run docs:lint (fix if errors)
3. npm run docs
4. Small tweaks on documentation page (quicklinks)
5. Replace current docs folder with gen-docs
6. Update versioning in package.json
3. Update versioning in package.json
4. npm run docs
5. Small tweaks on documentation page (quicklinks)
6. Replace current files in docs for the generated ones in gen-docs
7. git commit -m "Release x.x.x"

@@ -14,0 +14,0 @@ 8. Create release x.x.x in github

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc