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 2.4.1 to 2.5.0

30

CHANGELOG.md
# Change Log
## [2.5.0](https://github.com/danielcaldas/react-d3-graph/tree/2.5.0)
[Full Changelog](https://github.com/danielcaldas/react-d3-graph/compare/2.4.1...2.5.0)
**Implemented enhancements:**
- make node.size accept both height and width [\#336](https://github.com/danielcaldas/react-d3-graph/issues/336)
**Fixed bugs:**
- Passing an empty data.links array throws a warning [\#323](https://github.com/danielcaldas/react-d3-graph/issues/323)
- renderLabel params are not working for single node [\#322](https://github.com/danielcaldas/react-d3-graph/issues/322)
- The release version does not contain some fixes [\#314](https://github.com/danielcaldas/react-d3-graph/issues/314)
**Closed issues:**
- Docs missing collapsible sandbox example [\#337](https://github.com/danielcaldas/react-d3-graph/issues/337)
- Multiple Edges between 2 nodes [\#335](https://github.com/danielcaldas/react-d3-graph/issues/335)
- Ability to display node labels in different positions relative to the node center [\#299](https://github.com/danielcaldas/react-d3-graph/issues/299)
**Merged pull requests:**
- Added ability to configure a node's width and height separately [\#342](https://github.com/danielcaldas/react-d3-graph/pull/342) ([terahn](https://github.com/terahn))
- Bump websocket-extensions from 0.1.3 to 0.1.4 [\#331](https://github.com/danielcaldas/react-d3-graph/pull/331) ([dependabot[bot]](https://github.com/apps/dependabot))
- Misc improvements cleanup from previous PRs [\#327](https://github.com/danielcaldas/react-d3-graph/pull/327) ([danielcaldas](https://github.com/danielcaldas))
- Add GitHub Actions Workflow for library CI [\#326](https://github.com/danielcaldas/react-d3-graph/pull/326) ([danielcaldas](https://github.com/danielcaldas))
- Fix/misc documentation sandbox improvements [\#315](https://github.com/danielcaldas/react-d3-graph/pull/315) ([danielcaldas](https://github.com/danielcaldas))
- Feature/initial zoom [\#289](https://github.com/danielcaldas/react-d3-graph/pull/289) ([Morta1](https://github.com/Morta1))
- Reorganizing the computation of arrows and links for circle nodes [\#271](https://github.com/danielcaldas/react-d3-graph/pull/271) ([antoninklopp](https://github.com/antoninklopp))
## [2.4.1](https://github.com/danielcaldas/react-d3-graph/tree/2.4.1)

@@ -4,0 +34,0 @@

51

lib/components/graph/graph.builder.js

@@ -15,2 +15,4 @@ "use strict";

var _graph2 = require("./graph.helper");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

@@ -24,2 +26,4 @@

function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
/**

@@ -75,12 +79,2 @@ * Get the correct node opacity in order to properly make decisions based on context such as currently highlighted node.

var type = link.type || config.link.type;
var d = (0, _link.buildLinkPathDefinition)({
source: {
x: x1,
y: y1
},
target: {
x: x2,
y: y2
}
}, type);
var mainNodeParticipates = false;

@@ -143,2 +137,13 @@

var normalizedNodeCoordinates = (0, _graph2.getNormalizedNodeCoordinates)({
source: {
x: x1,
y: y1
},
target: {
x: x2,
y: y2
}
}, nodes, config, strokeWidth);
var d = (0, _link.buildLinkPathDefinition)(normalizedNodeCoordinates, type);
return {

@@ -213,6 +218,23 @@ className: _graph["default"].LINK_CLASS_NAME,

var nodeSize = node.size || config.node.size;
var offset;
var isSizeNumericValue = _typeof(nodeSize) !== "object";
if (isSizeNumericValue) {
offset = nodeSize;
} else if (labelPosition === "top" || labelPosition === "bottom") {
offset = nodeSize.height;
} else {
nodeSize.width;
}
var fontSize = highlight ? config.node.highlightFontSize : config.node.fontSize;
var dx = fontSize * t + nodeSize / 100 + 1.5;
var dx = fontSize * t + offset / 100 + 1.5;
var svg = node.svg || config.node.svg;
var fontColor = node.fontColor || config.node.fontColor;
var renderLabel = config.node.renderLabel;
if (node.renderLabel !== undefined && typeof node.renderLabel === "boolean") {
renderLabel = node.renderLabel;
}
return _objectSpread({}, node, {

@@ -233,4 +255,7 @@ className: _graph["default"].NODE_CLASS_NAME,

overrideGlobalViewGenerator: !node.viewGenerator && node.svg,
renderLabel: node.renderLabel || config.node.renderLabel,
size: nodeSize * t,
renderLabel: renderLabel,
size: isSizeNumericValue ? nodeSize * t : {
height: nodeSize.height * t,
width: nodeSize.width * t
},
stroke: stroke,

@@ -237,0 +262,0 @@ strokeWidth: strokeWidth * t,

@@ -53,3 +53,3 @@ "use strict";

* @param {boolean} [collapsible=false] - <a id="collapsible" href="#collapsible">🔗</a> 🚅🚅🚅 Allow leaf neighbors nodes to be collapsed (folded), this will allow users to clear the way out and focus on the parts of the graph that really matter.
* To see an example of this behavior you can access this sandbox link that has a specific set up to experiment this feature. <b>NOTE</b>: At this moment
* To see an example of this behavior you can access <a href="https://danielcaldas.github.io/react-d3-graph/sandbox/index.html?data=marvel" target="_blank" title="sandbox collapsible example">this sandbox link</a> that has a specific set up to experiment this feature. <b>NOTE</b>: At this moment
* nodes without connections (orphan nodes) are not rendered when this property is activated (see <a target="_blank" href="https://github.com/danielcaldas/react-d3-graph/issues/129">GitHub issue #129</a>).

@@ -89,2 +89,3 @@ * </br>

* the value the more the less highlighted nodes will be visible (related to <i>nodeHighlightBehavior</i>).
* @param {number} [initialZoom=null] - <a id="max-zoom" href="#initial-zoom">🔗</a> initial zoom that can be set on the graph.
* @param {number} [maxZoom=8] - <a id="max-zoom" href="#max-zoom">🔗</a> max zoom that can be performed against the graph.

@@ -111,3 +112,3 @@ * @param {number} [minZoom=0.1] - <a id="min-zoom" href="#min-zoom">🔗</a> min zoom that can be performed against the graph.

* @param {number} [d3.linkStrength=1] - <a id="d3-link-strength" href="#d3-link-strength">🔗</a> <a target="_blank" href="https://github.com/d3/d3-force#link_strength">see d3-force link.strength</a>
* @param {number} [d3.disableLinkForce=false] - <a id="d3-disable-link-force" href="#d3-disable-link-force">🔗</a> ⚠️🧪EXPERIMENTAL🧪⚠️ it completely disables d3 force link and simulation to re-trigger so that one can obtain
* @param {boolean} [d3.disableLinkForce=false] - <a id="d3-disable-link-force" href="#d3-disable-link-force">🔗</a> ⚠️🧪EXPERIMENTAL🧪⚠️ it completely disables d3 force link and simulation to re-trigger so that one can obtain
* precise render of node positions as described by the author <a target="_blank" href="https://github.com/antoninklopp">@antoninklopp</a> in <a target="_blank" href="https://github.com/danielcaldas/react-d3-graph/pull/278">the Pull Request description</a>.

@@ -158,3 +159,13 @@ * </br>

* graph.
* @param {number} [node.size=200] - <a id="node-size" href="#node-size">🔗</a> 🔍🔍🔍 defines the size of all nodes.
* @param {number|Object} [node.size=200] - <a id="node-size" href="#node-size">🔗</a> 🔍🔍🔍 defines the size of all nodes. When set to a number, the node will have equal height and width.</br>
* This can also be an object with a height and width property <b>when using custom nodes</b>.
* ```javascript
* size: 200
* // or
* size: {
* height: 200,
* width: 300,
* }
* ```
* The actual node dimensions (in px) rendered on screen will be the size value divided by 10. For example, a node size of 200 will result in a node with a height and width of 20px.
* @param {string} [node.strokeColor="none"] - <a id="node-stroke-color" href="#node-stroke-color">🔗</a> 🔍🔍🔍 this is the stroke color that will be applied to the node if no <b>strokeColor property</b> is found inside the node itself (yes <b>you can pass a property "strokeColor" inside the node and that stroke color will override this default one</b>).

@@ -252,2 +263,3 @@ * @param {number} [node.strokeWidth=1.5] - <a id="node-stroke-width" href="#node-stroke-width">🔗</a> 🔍🔍🔍 the width of the all node strokes.

minZoom: 0.1,
initialZoom: null,
nodeHighlightBehavior: false,

@@ -254,0 +266,0 @@ panAndZoom: false,

@@ -12,2 +12,3 @@ "use strict";

exports.updateNodeHighlightedValue = updateNodeHighlightedValue;
exports.getNormalizedNodeCoordinates = getNormalizedNodeCoordinates;

@@ -212,3 +213,3 @@ var _d3Force = require("d3-force");

* INVALID_LINKS - if links point to nonexistent nodes
* INSUFFICIENT_LINKS - if no links are provided
* INSUFFICIENT_LINKS - if no links are provided (not even empty Array)
* @returns {undefined}

@@ -224,3 +225,3 @@ * @memberof Graph/helper

if (!data.links || !data.links.length) {
if (!data.links) {
(0, _utils.logWarning)("Graph", _err["default"].INSUFFICIENT_LINKS);

@@ -493,2 +494,86 @@ data.links = [];

};
}
/**
* Computes the normalized vector from a vector.
* @param {Object} vector a 2D vector with x and y components
* @param {number} vector.x x coordinate
* @param {number} vector.y y coordinate
* @returns {Object} normalized vector
*/
function normalize(vector) {
var norm = Math.sqrt(Math.pow(vector.x, 2) + Math.pow(vector.y, 2));
return {
x: vector.x / norm,
y: vector.y / norm
};
}
/**
* Computes new node coordinates to make arrowheads point at nodes.
* Arrow configuration is only available for circles.
* @param {Object} node - the couple of nodes we need to compute new coordinates
* @param {Object} node.source - node source
* @param {Object} node.target - node target
* @param {Object.<string, Object>} nodes - same as {@link #graphrenderer|nodes in renderGraph}.
* @param {Object} config - same as {@link #graphrenderer|config in renderGraph}.
* @param {number} strokeWidth width of the link stroke
* @returns {Object} new nodes coordinates
*/
function getNormalizedNodeCoordinates(_ref2, nodes, config, strokeWidth) {
var _config$node, _config$node2;
var _ref2$source = _ref2.source,
source = _ref2$source === void 0 ? {} : _ref2$source,
_ref2$target = _ref2.target,
target = _ref2$target === void 0 ? {} : _ref2$target;
if ((_config$node = config.node) === null || _config$node === void 0 ? void 0 : _config$node.viewGenerator) {
return {
source: source,
target: target
};
}
var x1 = source.x,
y1 = source.y;
var x2 = target.x,
y2 = target.y;
switch ((_config$node2 = config.node) === null || _config$node2 === void 0 ? void 0 : _config$node2.symbolType) {
case _graph2["default"].SYMBOLS.CIRCLE:
{
var _nodes$source;
var directionVector = normalize({
x: x2 - x1,
y: y2 - y1
});
var strokeSize = strokeWidth * Math.min(config.link.markerWidth, config.link.markerHeight);
var nodeSize = (nodes === null || nodes === void 0 ? void 0 : (_nodes$source = nodes[source]) === null || _nodes$source === void 0 ? void 0 : _nodes$source.size) || config.node.size; // cause this is a circle and A = pi * r^2
// we multiply by 0.95, because if we don't the link is not melting properly
nodeSize = Math.sqrt(nodeSize / Math.PI) * 0.95; // points from the source, we move them not to begin in the circle but outside
x1 += nodeSize * directionVector.x;
y1 += nodeSize * directionVector.y; // points from the target, we move the by the size of the radius of the circle + the size of the arrow
x2 -= (nodeSize + (config.directed ? strokeSize : 0)) * directionVector.x;
y2 -= (nodeSize + (config.directed ? strokeSize : 0)) * directionVector.y;
break;
}
}
return {
source: {
x: x1,
y: y1
},
target: {
x: x2,
y: y2
}
};
}

@@ -306,3 +306,12 @@ "use strict";

_defineProperty(_assertThisInitialized(_this), "_zoomConfig", function () {
(0, _d3Selection.select)("#".concat(_this.state.id, "-").concat(_graph["default"].GRAPH_WRAPPER_ID)).call((0, _d3Zoom.zoom)().scaleExtent([_this.state.config.minZoom, _this.state.config.maxZoom]).on("zoom", _this._zoomed)).on("dblclick.zoom", null);
var selector = (0, _d3Selection.select)("#".concat(_this.state.id, "-").concat(_graph["default"].GRAPH_WRAPPER_ID));
var zoomObject = (0, _d3Zoom.zoom)().scaleExtent([_this.state.config.minZoom, _this.state.config.maxZoom]).on("zoom", _this._zoomed);
if (_this.state.config.initialZoom !== null) {
zoomObject.scaleTo(selector, _this.state.config.initialZoom);
} // avoid double click on graph to trigger zoom
// for more details consult: https://github.com/danielcaldas/react-d3-graph/pull/202
selector.call(zoomObject).on("dblclick.zoom", null);
});

@@ -309,0 +318,0 @@

@@ -26,2 +26,4 @@ "use strict";

var _marker2 = require("../marker/marker.helper");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

@@ -126,5 +128,7 @@

var small = _marker.MARKER_SMALL_SIZE;
var medium = small + _marker.MARKER_MEDIUM_OFFSET * config.maxZoom / 3;
var large = small + _marker.MARKER_LARGE_OFFSET * config.maxZoom / 3;
var _getMarkerSize = (0, _marker2.getMarkerSize)(config),
small = _getMarkerSize.small,
medium = _getMarkerSize.medium,
large = _getMarkerSize.large;
var markerProps = {

@@ -131,0 +135,0 @@ markerWidth: config.link.markerWidth,

@@ -6,2 +6,3 @@ "use strict";

});
exports.getMarkerSize = getMarkerSize;
exports.getMarkerId = void 0;

@@ -11,2 +12,6 @@

var _graph = _interopRequireDefault(require("../graph/graph.const"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
/**

@@ -114,3 +119,33 @@ * @module Marker/helper

var getMarkerId = _memoizedComputeMarkerId();
/**
* Computes the three marker sizes
* For supported shapes in {@link Graph/helper/getNormalizedNodeCoordinates}, the function should return 0,
* to be able to control more accurately nodes and arrows sizes and positions in directional graphs.
* @param {Object} config - the graph config object.
* @returns {Object} size of markers
*/
exports.getMarkerId = getMarkerId;
exports.getMarkerId = getMarkerId;
function getMarkerSize(config) {
var small = _marker.MARKER_SMALL_SIZE;
var medium = small + _marker.MARKER_MEDIUM_OFFSET * config.maxZoom / 3;
var large = small + _marker.MARKER_LARGE_OFFSET * config.maxZoom / 3;
if (config.node && !config.node.viewGenerator) {
switch (config.node.symbolType) {
case _graph["default"].SYMBOLS.CIRCLE:
small = 0;
medium = 0;
large = 0;
break;
}
}
return {
small: small,
medium: medium,
large: large
};
}

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

var _node2 = _interopRequireDefault(require("./node.const"));
var _utils = require("../../utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

@@ -144,2 +148,3 @@

var size = this.props.size;
var isSizeNumericalValue = _typeof(size) !== "object";
var gtx = this.props.cx,

@@ -151,4 +156,4 @@ gty = this.props.cy,

if (this.props.svg || this.props.viewGenerator) {
var height = size / 10;
var width = size / 10;
var height = isSizeNumericalValue ? size / 10 : size.height / 10;
var width = isSizeNumericalValue ? size / 10 : size.width / 10;
var tx = width / 2;

@@ -189,2 +194,7 @@ var ty = height / 2;

} else {
if (!isSizeNumericalValue) {
(0, _utils.logWarning)("node.size should be a number when not using custom nodes.");
size = _node2["default"].DEFAULT_NODE_SIZE;
}
nodeProps.d = _node["default"].buildSvgSymbol(size, this.props.type);

@@ -191,0 +201,0 @@ nodeProps.fill = this.props.fill;

@@ -11,3 +11,3 @@ "use strict";

GRAPH_NO_ID_PROP: "id prop not defined! id property is mandatory and it should be unique.",
INSUFFICIENT_LINKS: "you are passing invalid data to react-d3-graph. You must include a links array in the data object you're passing down to the <Graph> component.",
INSUFFICIENT_LINKS: "you are passing invalid data to react-d3-graph. You must include a links array, even if empty, in the data object you're passing down to the <Graph> component.",
INVALID_LINKS: "you provided a invalid links data structure. Links source and target attributes must point to an existent node",

@@ -14,0 +14,0 @@ INSUFFICIENT_DATA: "you have not provided enough data for react-d3-graph to render something. You need to provide at least one node",

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

@@ -5,0 +5,0 @@ "author": "Daniel Caldas",

@@ -1,3 +0,5 @@

# react-d3-graph &middot; [![Build Status](https://travis-ci.org/danielcaldas/react-d3-graph.svg?branch=master&style=flat-square)](https://travis-ci.org/danielcaldas/react-d3-graph)
# react-d3-graph &middot; [![Build Status](https://github.com/danielcaldas/react-d3-graph/workflows/react-d3-graph/badge.svg)](https://github.com/danielcaldas/react-d3-graph/workflows/react-d3-graph/badge.svg)
⚠️ __There has been some changes in the domain where I host the documentation and live examples, please use https://danielcaldas.github.io/react-d3-graph/docs instead of the old domain https://goodguydaniel.com/react-d3-graph. Sorry for any inconvenient__ ⚠️
[![npm version](https://img.shields.io/npm/v/react-d3-graph.svg?style=flat-square)](https://www.npmjs.com/package/react-d3-graph) [![npm](https://img.shields.io/npm/dw/react-d3-graph.svg?style=flat-square)](https://www.npmjs.com/package/react-d3-graph)

@@ -8,3 +10,3 @@ [![npm](https://img.shields.io/npm/dt/react-d3-graph.svg?style=flat-square)](https://www.npmjs.com/package/react-d3-graph) [![probot enabled](https://img.shields.io/badge/probot:stale-enabled-yellow.svg?longCache=true&style=flat-square)](https://probot.github.io/) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier)

:book: [documentation](https://danielcaldas.github.io/react-d3-graph/docs/index.html)
:book: [Documentation](https://danielcaldas.github.io/react-d3-graph/docs/index.html)

@@ -25,10 +27,12 @@ ### _Interactive and configurable graphs with react and d3 effortlessly_

You can also load different datasets and configurations via URL query parameter, here are the links:
You can also load different data sets and configurations via URL query parameter. Below is a table with all the data sets available in the live sandbox for you to interactively explore different kinds of integrations with the library.
- [small dataset](https://goodguydaniel.com/react-d3-graph/sandbox/index.html?data=small) - small example.
- [custom node dataset](https://goodguydaniel.com/react-d3-graph/sandbox/index.html?data=custom-node) - sample config with custom views.
- [marvel dataset](https://goodguydaniel.com/react-d3-graph/sandbox/index.html?data=marvel) - sample config with directed collapsible graph and custom svg nodes.
- [static dataset](https://goodguydaniel.com/react-d3-graph/sandbox/index.html?data=static) - small sample config statically positioned nodes.
| Name | Link | Source | Description |
| :---------- | :---------------------------------------------------------------------------------------------------- | :------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| small | [see it in action](https://danielcaldas.github.io/react-d3-graph/sandbox/index.html?data=small) | `sandbox/data/small` | This is a good example to get you started. It has only 4 nodes. It's good to discuss over integration details and it's also good to report issues that you might found in the library. It's much easier to debug over a tiny graph. |
| custom-node | [see it in action](https://danielcaldas.github.io/react-d3-graph/sandbox/index.html?data=custom-node) | `sandbox/data/custom-node` | In this example you'll be able to see the power of the feature [node.viewGenerator](https://danielcaldas.github.io/react-d3-graph/docs/#node-view-generator) to create highly customizable nodes for you graph that go beyond the simple shapes that come out of the box with the library. |
| marvel | [see it in action](https://danielcaldas.github.io/react-d3-graph/sandbox/index.html?data=marvel) | `sandbox/data/marvel` | In this thematic example you can see how several features such as: [nodeHighlightBehavior](https://danielcaldas.github.io/react-d3-graph/docs/#node-highlight-behavior), [custom SVGs for nodes](https://danielcaldas.github.io/react-d3-graph/docs/#node-svg), [collapsible](https://danielcaldas.github.io/react-d3-graph/docs/#collapsible) etc. come together on top of a directed graph that displays some characters from the Marvel Universe. |
| static | [see it in action](https://danielcaldas.github.io/react-d3-graph/sandbox/index.html?data=static) | `sandbox/data/static` | If your goal is not to have nodes dancing around with the default [d3 forces](https://danielcaldas.github.io/react-d3-graph/docs/#config-d3) that the library provides, you can opt by making your nodes static and positioned them always in the same _(x, y)_ coordinates. To achieve this you can make use of [staticGraphWithDragAndDrop](https://danielcaldas.github.io/react-d3-graph/docs/#static-graph-with-drag-and-drop) or [staticGraph](https://danielcaldas.github.io/react-d3-graph/docs/#static-graph) |
Do you want to visualize your own data set on the live sandbox? Just submit a PR! You're welcome 😁
Do you want to visualize your own data set on the live sandbox? Just submit a PR! You're welcome 😁.

@@ -68,3 +72,6 @@ ## Documentation :book:

nodes: [{ id: "Harry" }, { id: "Sally" }, { id: "Alice" }],
links: [{ source: "Harry", target: "Sally" }, { source: "Harry", target: "Alice" }],
links: [
{ source: "Harry", target: "Sally" },
{ source: "Harry", target: "Alice" },
],
};

@@ -71,0 +78,0 @@

@@ -12,11 +12,11 @@ ## Release Process

1. Update versioning in package.json
1. npm run dist
2. Update versioning in package.json
3. npm run docs
4. Small tweaks on documentation page (quicklinks)
5. Replace current files in docs for the generated ones in gen-docs
6. Generate CHANGELOG.md (github_changelog_generator -u GITHUB_USERNAME)
7. git commit -m "Release x.x.x"
8. Create release x.x.x in github
9. git pull (origin master)
10. npm publish
1. npm run docs
1. Small tweaks on documentation page (quicklinks)
1. Replace current files in docs for the generated ones in gen-docs
1. Generate CHANGELOG.md (github_changelog_generator -u GITHUB_USERNAME)
1. git commit -m "Release x.x.x"
1. Create release x.x.x in github
1. git pull (origin master)
1. npm publish

@@ -10,2 +10,3 @@ /**

import { getMarkerId } from "../marker/marker.helper";
import { getNormalizedNodeCoordinates } from "./graph.helper";

@@ -57,8 +58,8 @@ /**

const { source, target } = link;
const x1 = nodes?.[source]?.x || 0;
const y1 = nodes?.[source]?.y || 0;
const x2 = nodes?.[target]?.x || 0;
const y2 = nodes?.[target]?.y || 0;
let x1 = nodes?.[source]?.x || 0;
let y1 = nodes?.[source]?.y || 0;
let x2 = nodes?.[target]?.x || 0;
let y2 = nodes?.[target]?.y || 0;
const type = link.type || config.link.type;
const d = buildLinkPathDefinition({ source: { x: x1, y: y1 }, target: { x: x2, y: y2 } }, type);

@@ -126,2 +127,10 @@ let mainNodeParticipates = false;

const normalizedNodeCoordinates = getNormalizedNodeCoordinates(
{ source: { x: x1, y: y1 }, target: { x: x2, y: y2 } },
nodes,
config,
strokeWidth
);
const d = buildLinkPathDefinition(normalizedNodeCoordinates, type);
return {

@@ -162,4 +171,4 @@ className: CONST.LINK_CLASS_NAME,

node.highlighted ||
(node.id === (highlightedLink && highlightedLink.source) ||
node.id === (highlightedLink && highlightedLink.target));
node.id === (highlightedLink && highlightedLink.source) ||
node.id === (highlightedLink && highlightedLink.target);
const opacity = _getNodeOpacity(node, highlightedNode, highlightedLink, config);

@@ -195,7 +204,24 @@

const nodeSize = node.size || config.node.size;
let offset;
const isSizeNumericValue = typeof nodeSize !== "object";
if (isSizeNumericValue) {
offset = nodeSize;
} else if (labelPosition === "top" || labelPosition === "bottom") {
offset = nodeSize.height;
} else {
nodeSize.width;
}
const fontSize = highlight ? config.node.highlightFontSize : config.node.fontSize;
const dx = fontSize * t + nodeSize / 100 + 1.5;
const dx = fontSize * t + offset / 100 + 1.5;
const svg = node.svg || config.node.svg;
const fontColor = node.fontColor || config.node.fontColor;
let renderLabel = config.node.renderLabel;
if (node.renderLabel !== undefined && typeof node.renderLabel === "boolean") {
renderLabel = node.renderLabel;
}
return {

@@ -217,4 +243,4 @@ ...node,

overrideGlobalViewGenerator: !node.viewGenerator && node.svg,
renderLabel: node.renderLabel || config.node.renderLabel,
size: nodeSize * t,
renderLabel,
size: isSizeNumericValue ? nodeSize * t : { height: nodeSize.height * t, width: nodeSize.width * t },
stroke,

@@ -221,0 +247,0 @@ strokeWidth: strokeWidth * t,

@@ -46,3 +46,3 @@ /**

* @param {boolean} [collapsible=false] - <a id="collapsible" href="#collapsible">🔗</a> 🚅🚅🚅 Allow leaf neighbors nodes to be collapsed (folded), this will allow users to clear the way out and focus on the parts of the graph that really matter.
* To see an example of this behavior you can access this sandbox link that has a specific set up to experiment this feature. <b>NOTE</b>: At this moment
* To see an example of this behavior you can access <a href="https://danielcaldas.github.io/react-d3-graph/sandbox/index.html?data=marvel" target="_blank" title="sandbox collapsible example">this sandbox link</a> that has a specific set up to experiment this feature. <b>NOTE</b>: At this moment
* nodes without connections (orphan nodes) are not rendered when this property is activated (see <a target="_blank" href="https://github.com/danielcaldas/react-d3-graph/issues/129">GitHub issue #129</a>).

@@ -82,2 +82,3 @@ * </br>

* the value the more the less highlighted nodes will be visible (related to <i>nodeHighlightBehavior</i>).
* @param {number} [initialZoom=null] - <a id="max-zoom" href="#initial-zoom">🔗</a> initial zoom that can be set on the graph.
* @param {number} [maxZoom=8] - <a id="max-zoom" href="#max-zoom">🔗</a> max zoom that can be performed against the graph.

@@ -104,3 +105,3 @@ * @param {number} [minZoom=0.1] - <a id="min-zoom" href="#min-zoom">🔗</a> min zoom that can be performed against the graph.

* @param {number} [d3.linkStrength=1] - <a id="d3-link-strength" href="#d3-link-strength">🔗</a> <a target="_blank" href="https://github.com/d3/d3-force#link_strength">see d3-force link.strength</a>
* @param {number} [d3.disableLinkForce=false] - <a id="d3-disable-link-force" href="#d3-disable-link-force">🔗</a> ⚠️🧪EXPERIMENTAL🧪⚠️ it completely disables d3 force link and simulation to re-trigger so that one can obtain
* @param {boolean} [d3.disableLinkForce=false] - <a id="d3-disable-link-force" href="#d3-disable-link-force">🔗</a> ⚠️🧪EXPERIMENTAL🧪⚠️ it completely disables d3 force link and simulation to re-trigger so that one can obtain
* precise render of node positions as described by the author <a target="_blank" href="https://github.com/antoninklopp">@antoninklopp</a> in <a target="_blank" href="https://github.com/danielcaldas/react-d3-graph/pull/278">the Pull Request description</a>.

@@ -151,3 +152,13 @@ * </br>

* graph.
* @param {number} [node.size=200] - <a id="node-size" href="#node-size">🔗</a> 🔍🔍🔍 defines the size of all nodes.
* @param {number|Object} [node.size=200] - <a id="node-size" href="#node-size">🔗</a> 🔍🔍🔍 defines the size of all nodes. When set to a number, the node will have equal height and width.</br>
* This can also be an object with a height and width property <b>when using custom nodes</b>.
* ```javascript
* size: 200
* // or
* size: {
* height: 200,
* width: 300,
* }
* ```
* The actual node dimensions (in px) rendered on screen will be the size value divided by 10. For example, a node size of 200 will result in a node with a height and width of 20px.
* @param {string} [node.strokeColor="none"] - <a id="node-stroke-color" href="#node-stroke-color">🔗</a> 🔍🔍🔍 this is the stroke color that will be applied to the node if no <b>strokeColor property</b> is found inside the node itself (yes <b>you can pass a property "strokeColor" inside the node and that stroke color will override this default one</b>).

@@ -245,2 +256,3 @@ * @param {number} [node.strokeWidth=1.5] - <a id="node-stroke-width" href="#node-stroke-width">🔗</a> 🔍🔍🔍 the width of the all node strokes.

minZoom: 0.1,
initialZoom: null,
nodeHighlightBehavior: false,

@@ -247,0 +259,0 @@ panAndZoom: false,

@@ -211,3 +211,3 @@ /**

* INVALID_LINKS - if links point to nonexistent nodes
* INSUFFICIENT_LINKS - if no links are provided
* INSUFFICIENT_LINKS - if no links are provided (not even empty Array)
* @returns {undefined}

@@ -221,3 +221,3 @@ * @memberof Graph/helper

if (!data.links || !data.links.length) {
if (!data.links) {
logWarning("Graph", ERRORS.INSUFFICIENT_LINKS);

@@ -456,2 +456,58 @@ data.links = [];

/**
* Computes the normalized vector from a vector.
* @param {Object} vector a 2D vector with x and y components
* @param {number} vector.x x coordinate
* @param {number} vector.y y coordinate
* @returns {Object} normalized vector
* @memberof Graph/helper
*/
function normalize(vector) {
const norm = Math.sqrt(Math.pow(vector.x, 2) + Math.pow(vector.y, 2));
return { x: vector.x / norm, y: vector.y / norm };
}
/**
* Computes new node coordinates to make arrowheads point at nodes.
* Arrow configuration is only available for circles.
* @param {Object} node - the couple of nodes we need to compute new coordinates
* @param {Object} node.source - node source
* @param {Object} node.target - node target
* @param {Object.<string, Object>} nodes - same as {@link #graphrenderer|nodes in renderGraph}.
* @param {Object} config - same as {@link #graphrenderer|config in renderGraph}.
* @param {number} strokeWidth width of the link stroke
* @returns {Object} new nodes coordinates
* @memberof Graph/helper
*/
function getNormalizedNodeCoordinates({ source = {}, target = {} }, nodes, config, strokeWidth) {
if (config.node?.viewGenerator) {
return { source, target };
}
let { x: x1, y: y1 } = source;
let { x: x2, y: y2 } = target;
switch (config.node?.symbolType) {
case CONST.SYMBOLS.CIRCLE: {
const directionVector = normalize({ x: x2 - x1, y: y2 - y1 });
const strokeSize = strokeWidth * Math.min(config.link.markerWidth, config.link.markerHeight);
let nodeSize = nodes?.[source]?.size || config.node.size;
// cause this is a circle and A = pi * r^2
// we multiply by 0.95, because if we don't the link is not melting properly
nodeSize = Math.sqrt(nodeSize / Math.PI) * 0.95;
// points from the source, we move them not to begin in the circle but outside
x1 += nodeSize * directionVector.x;
y1 += nodeSize * directionVector.y;
// points from the target, we move the by the size of the radius of the circle + the size of the arrow
x2 -= (nodeSize + (config.directed ? strokeSize : 0)) * directionVector.x;
y2 -= (nodeSize + (config.directed ? strokeSize : 0)) * directionVector.y;
break;
}
}
return { source: { x: x1, y: y1 }, target: { x: x2, y: y2 } };
}
export {

@@ -464,2 +520,3 @@ checkForGraphConfigChanges,

updateNodeHighlightedValue,
getNormalizedNodeCoordinates,
};

@@ -280,9 +280,15 @@ import React from "react";

_zoomConfig = () => {
d3Select(`#${this.state.id}-${CONST.GRAPH_WRAPPER_ID}`)
.call(
d3Zoom()
.scaleExtent([this.state.config.minZoom, this.state.config.maxZoom])
.on("zoom", this._zoomed)
)
.on("dblclick.zoom", null);
const selector = d3Select(`#${this.state.id}-${CONST.GRAPH_WRAPPER_ID}`);
const zoomObject = d3Zoom()
.scaleExtent([this.state.config.minZoom, this.state.config.maxZoom])
.on("zoom", this._zoomed);
if (this.state.config.initialZoom !== null) {
zoomObject.scaleTo(selector, this.state.config.initialZoom);
}
// avoid double click on graph to trigger zoom
// for more details consult: https://github.com/danielcaldas/react-d3-graph/pull/202
selector.call(zoomObject).on("dblclick.zoom", null);
};

@@ -289,0 +295,0 @@

@@ -9,3 +9,3 @@ /**

import CONST from "./graph.const";
import { MARKERS, MARKER_SMALL_SIZE, MARKER_MEDIUM_OFFSET, MARKER_LARGE_OFFSET } from "../marker/marker.const";
import { MARKERS } from "../marker/marker.const";

@@ -18,2 +18,3 @@ import Link from "../link/Link";

import { isNodeVisible } from "./collapse.helper";
import { getMarkerSize } from "../marker/marker.helper";

@@ -110,6 +111,3 @@ /**

const small = MARKER_SMALL_SIZE;
const medium = small + (MARKER_MEDIUM_OFFSET * config.maxZoom) / 3;
const large = small + (MARKER_LARGE_OFFSET * config.maxZoom) / 3;
const { small, medium, large } = getMarkerSize(config);
const markerProps = {

@@ -116,0 +114,0 @@ markerWidth: config.link.markerWidth,

@@ -6,3 +6,11 @@ /**

*/
import { MARKERS, SIZES, HIGHLIGHTED } from "./marker.const";
import {
MARKERS,
SIZES,
HIGHLIGHTED,
MARKER_SMALL_SIZE,
MARKER_MEDIUM_OFFSET,
MARKER_LARGE_OFFSET,
} from "./marker.const";
import CONST from "../graph/graph.const";

@@ -97,2 +105,28 @@ /**

export { getMarkerId };
/**
* Computes the three marker sizes
* For supported shapes in {@link Graph/helper/getNormalizedNodeCoordinates}, the function should return 0,
* to be able to control more accurately nodes and arrows sizes and positions in directional graphs.
* @param {Object} config - the graph config object.
* @returns {Object} size of markers
* @memberof Marker/helper
*/
function getMarkerSize(config) {
let small = MARKER_SMALL_SIZE;
let medium = small + (MARKER_MEDIUM_OFFSET * config.maxZoom) / 3;
let large = small + (MARKER_LARGE_OFFSET * config.maxZoom) / 3;
if (config.node && !config.node.viewGenerator) {
switch (config.node.symbolType) {
case CONST.SYMBOLS.CIRCLE:
small = 0;
medium = 0;
large = 0;
break;
}
}
return { small, medium, large };
}
export { getMarkerId, getMarkerSize };

@@ -68,2 +68,3 @@ /**

* props to put text svg for label in correct spot. default case returns just dx and dy, without textAnchor and dominantBaseline
* @memberof Node/helper
*/

@@ -70,0 +71,0 @@ function getLabelPlacementProps(dx, labelPosition) {

import React from "react";
import nodeHelper from "./node.helper";
import CONST from "./node.const";
import { logWarning } from "../../utils";

@@ -97,3 +99,4 @@ /**

const size = this.props.size;
let size = this.props.size;
const isSizeNumericalValue = typeof size !== "object";

@@ -106,4 +109,4 @@ let gtx = this.props.cx,

if (this.props.svg || this.props.viewGenerator) {
const height = size / 10;
const width = size / 10;
const height = isSizeNumericalValue ? size / 10 : size.height / 10;
const width = isSizeNumericalValue ? size / 10 : size.width / 10;
const tx = width / 2;

@@ -138,2 +141,6 @@ const ty = height / 2;

} else {
if (!isSizeNumericalValue) {
logWarning("node.size should be a number when not using custom nodes.");
size = CONST.DEFAULT_NODE_SIZE;
}
nodeProps.d = nodeHelper.buildSvgSymbol(size, this.props.type);

@@ -140,0 +147,0 @@ nodeProps.fill = this.props.fill;

@@ -5,3 +5,3 @@ /*eslint max-len: ["error", 200]*/

INSUFFICIENT_LINKS:
"you are passing invalid data to react-d3-graph. You must include a links array in the data object you're passing down to the <Graph> component.",
"you are passing invalid data to react-d3-graph. You must include a links array, even if empty, in the data object you're passing down to the <Graph> component.",
INVALID_LINKS:

@@ -8,0 +8,0 @@ "you provided a invalid links data structure. Links source and target attributes must point to an existent node",

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