react-d3-graph
Advanced tools
Comparing version 2.0.0-rc2 to 2.0.0
module.exports = { | ||
printWidth: 120, | ||
singleQuote: false, | ||
tabWidth: 4, | ||
singleQuote: true | ||
trailingComma: "es5", | ||
}; |
233
CHANGELOG.md
# Change Log | ||
## [2.0.0](https://github.com/danielcaldas/react-d3-graph/tree/2.0.0) | ||
[Full Changelog](https://github.com/danielcaldas/react-d3-graph/compare/2.0.0-rc2...2.0.0) | ||
**Fixed bugs:** | ||
- Link Colors not used when adding to graph [\#169](https://github.com/danielcaldas/react-d3-graph/issues/169) | ||
- Node id 0 not set properly [\#160](https://github.com/danielcaldas/react-d3-graph/issues/160) | ||
- Nodes added or deleted from a graph with nodes in fixed positions will cause issues [\#151](https://github.com/danielcaldas/react-d3-graph/issues/151) | ||
- Collapsible config option can cause orphaned nodes to not be displayed [\#129](https://github.com/danielcaldas/react-d3-graph/issues/129) | ||
**Closed issues:** | ||
- Reverse the direction of arrows for "directed" property [\#153](https://github.com/danielcaldas/react-d3-graph/issues/153) | ||
- viewGenerator key being dropped in config merge [\#142](https://github.com/danielcaldas/react-d3-graph/issues/142) | ||
- Links labeling [\#47](https://github.com/danielcaldas/react-d3-graph/issues/47) | ||
**Merged pull requests:** | ||
- Refactor/run lint on sandbox [\#179](https://github.com/danielcaldas/react-d3-graph/pull/179) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/labels on links [\#178](https://github.com/danielcaldas/react-d3-graph/pull/178) ([danielcaldas](https://github.com/danielcaldas)) | ||
- fix: Add link with custom color in existing graph [\#170](https://github.com/danielcaldas/react-d3-graph/pull/170) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
- More granular resolution of node and link parameters [\#166](https://github.com/danielcaldas/react-d3-graph/pull/166) ([sauln](https://github.com/sauln)) | ||
- Fix/0 number id edge case [\#161](https://github.com/danielcaldas/react-d3-graph/pull/161) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Update webpack-dev-server and react-dom [\#159](https://github.com/danielcaldas/react-d3-graph/pull/159) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Refactor/split graph helper logic [\#158](https://github.com/danielcaldas/react-d3-graph/pull/158) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Refactor/tooling upgrade [\#157](https://github.com/danielcaldas/react-d3-graph/pull/157) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/linting prettier improvements [\#156](https://github.com/danielcaldas/react-d3-graph/pull/156) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Simplified test folder file structure merging "component" and "snapshot" [\#155](https://github.com/danielcaldas/react-d3-graph/pull/155) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix/collapsible orphan nodes and last node [\#154](https://github.com/danielcaldas/react-d3-graph/pull/154) ([danielcaldas](https://github.com/danielcaldas)) | ||
## [2.0.0-rc2](https://github.com/danielcaldas/react-d3-graph/tree/2.0.0-rc2) | ||
@@ -9,33 +40,33 @@ | ||
* Allow nodes to override strokeColor [\#122](https://github.com/danielcaldas/react-d3-graph/issues/122) | ||
- Allow nodes to override strokeColor [\#122](https://github.com/danielcaldas/react-d3-graph/issues/122) | ||
**Fixed bugs:** | ||
* Custom onNodeClick handler not triggering on collapsible nodes [\#136](https://github.com/danielcaldas/react-d3-graph/issues/136) | ||
* 🐛 Global `viewGenerator` not been applied to the nodes [\#130](https://github.com/danielcaldas/react-d3-graph/issues/130) | ||
- Custom onNodeClick handler not triggering on collapsible nodes [\#136](https://github.com/danielcaldas/react-d3-graph/issues/136) | ||
- 🐛 Global `viewGenerator` not been applied to the nodes [\#130](https://github.com/danielcaldas/react-d3-graph/issues/130) | ||
**Closed issues:** | ||
* graph constantly re-rendering even when app is idle? [\#145](https://github.com/danielcaldas/react-d3-graph/issues/145) | ||
* Allow users to pass in a function in node.labelProperty [\#133](https://github.com/danielcaldas/react-d3-graph/issues/133) | ||
* Drop yarn support for development \(stick to npm only\) [\#127](https://github.com/danielcaldas/react-d3-graph/issues/127) | ||
* Link mouse cursor property [\#119](https://github.com/danielcaldas/react-d3-graph/issues/119) | ||
* Center graph on a specific node [\#102](https://github.com/danielcaldas/react-d3-graph/issues/102) | ||
* Links with directional arrow [\#88](https://github.com/danielcaldas/react-d3-graph/issues/88) | ||
- graph constantly re-rendering even when app is idle? [\#145](https://github.com/danielcaldas/react-d3-graph/issues/145) | ||
- Allow users to pass in a function in node.labelProperty [\#133](https://github.com/danielcaldas/react-d3-graph/issues/133) | ||
- Drop yarn support for development \(stick to npm only\) [\#127](https://github.com/danielcaldas/react-d3-graph/issues/127) | ||
- Link mouse cursor property [\#119](https://github.com/danielcaldas/react-d3-graph/issues/119) | ||
- Center graph on a specific node [\#102](https://github.com/danielcaldas/react-d3-graph/issues/102) | ||
- Links with directional arrow [\#88](https://github.com/danielcaldas/react-d3-graph/issues/88) | ||
**Merged pull requests:** | ||
* Fix/right clicks [\#140](https://github.com/danielcaldas/react-d3-graph/pull/140) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Refactor/clean link component [\#139](https://github.com/danielcaldas/react-d3-graph/pull/139) ([danielcaldas](https://github.com/danielcaldas)) | ||
* fix: Trigger custom click handler in collapsible nodes [\#137](https://github.com/danielcaldas/react-d3-graph/pull/137) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
* Add Support to pass a function to node.labelProperty [\#135](https://github.com/danielcaldas/react-d3-graph/pull/135) ([dgautsch](https://github.com/dgautsch)) | ||
* Support Development on Windows Machines [\#134](https://github.com/danielcaldas/react-d3-graph/pull/134) ([dgautsch](https://github.com/dgautsch)) | ||
* Feature/directional graph [\#132](https://github.com/danielcaldas/react-d3-graph/pull/132) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Global `viewGenerator` included in default config object [\#131](https://github.com/danielcaldas/react-d3-graph/pull/131) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
* Remove Yarn [\#128](https://github.com/danielcaldas/react-d3-graph/pull/128) ([sasalx](https://github.com/sasalx)) | ||
* Feature/right clicking [\#124](https://github.com/danielcaldas/react-d3-graph/pull/124) ([ghardin137](https://github.com/ghardin137)) | ||
* Allow nodes to override strokeColor [\#123](https://github.com/danielcaldas/react-d3-graph/pull/123) ([Andras-Simon](https://github.com/Andras-Simon)) | ||
* fix: \#119 Add mouseCursor prop to \<Link\> [\#120](https://github.com/danielcaldas/react-d3-graph/pull/120) ([kaungmyatlwin](https://github.com/kaungmyatlwin)) | ||
* Add onClick handler to the canvas, for use in eg. unselecting nodes [\#113](https://github.com/danielcaldas/react-d3-graph/pull/113) ([smilykoch](https://github.com/smilykoch)) | ||
* Focus view on a node [\#107](https://github.com/danielcaldas/react-d3-graph/pull/107) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
- Fix/right clicks [\#140](https://github.com/danielcaldas/react-d3-graph/pull/140) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Refactor/clean link component [\#139](https://github.com/danielcaldas/react-d3-graph/pull/139) ([danielcaldas](https://github.com/danielcaldas)) | ||
- fix: Trigger custom click handler in collapsible nodes [\#137](https://github.com/danielcaldas/react-d3-graph/pull/137) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
- Add Support to pass a function to node.labelProperty [\#135](https://github.com/danielcaldas/react-d3-graph/pull/135) ([dgautsch](https://github.com/dgautsch)) | ||
- Support Development on Windows Machines [\#134](https://github.com/danielcaldas/react-d3-graph/pull/134) ([dgautsch](https://github.com/dgautsch)) | ||
- Feature/directional graph [\#132](https://github.com/danielcaldas/react-d3-graph/pull/132) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Global `viewGenerator` included in default config object [\#131](https://github.com/danielcaldas/react-d3-graph/pull/131) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
- Remove Yarn [\#128](https://github.com/danielcaldas/react-d3-graph/pull/128) ([sasalx](https://github.com/sasalx)) | ||
- Feature/right clicking [\#124](https://github.com/danielcaldas/react-d3-graph/pull/124) ([ghardin137](https://github.com/ghardin137)) | ||
- Allow nodes to override strokeColor [\#123](https://github.com/danielcaldas/react-d3-graph/pull/123) ([Andras-Simon](https://github.com/Andras-Simon)) | ||
- fix: \#119 Add mouseCursor prop to \<Link\> [\#120](https://github.com/danielcaldas/react-d3-graph/pull/120) ([kaungmyatlwin](https://github.com/kaungmyatlwin)) | ||
- Add onClick handler to the canvas, for use in eg. unselecting nodes [\#113](https://github.com/danielcaldas/react-d3-graph/pull/113) ([smilykoch](https://github.com/smilykoch)) | ||
- Focus view on a node [\#107](https://github.com/danielcaldas/react-d3-graph/pull/107) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
@@ -48,12 +79,12 @@ ## [2.0.0-rc1](https://github.com/danielcaldas/react-d3-graph/tree/2.0.0-rc1) | ||
* i want to customise node. is it possible ? [\#90](https://github.com/danielcaldas/react-d3-graph/issues/90) | ||
- i want to customise node. is it possible ? [\#90](https://github.com/danielcaldas/react-d3-graph/issues/90) | ||
**Merged pull requests:** | ||
* Remove snapshoot structures for nodes and links [\#118](https://github.com/danielcaldas/react-d3-graph/pull/118) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Fix/Check for d3 config is updated [\#117](https://github.com/danielcaldas/react-d3-graph/pull/117) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/documentation overall improvements [\#116](https://github.com/danielcaldas/react-d3-graph/pull/116) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Fix/defensive code for curve types [\#115](https://github.com/danielcaldas/react-d3-graph/pull/115) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Fix/graph unnecessary calls to graph forces config [\#114](https://github.com/danielcaldas/react-d3-graph/pull/114) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Customize nodes with JSX views [\#103](https://github.com/danielcaldas/react-d3-graph/pull/103) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
- Remove snapshoot structures for nodes and links [\#118](https://github.com/danielcaldas/react-d3-graph/pull/118) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix/Check for d3 config is updated [\#117](https://github.com/danielcaldas/react-d3-graph/pull/117) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/documentation overall improvements [\#116](https://github.com/danielcaldas/react-d3-graph/pull/116) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix/defensive code for curve types [\#115](https://github.com/danielcaldas/react-d3-graph/pull/115) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix/graph unnecessary calls to graph forces config [\#114](https://github.com/danielcaldas/react-d3-graph/pull/114) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Customize nodes with JSX views [\#103](https://github.com/danielcaldas/react-d3-graph/pull/103) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
@@ -66,19 +97,19 @@ ## [2.0.0-rc0](https://github.com/danielcaldas/react-d3-graph/tree/2.0.0-rc0) | ||
* Directional links are placed on top of each other [\#89](https://github.com/danielcaldas/react-d3-graph/issues/89) | ||
- Directional links are placed on top of each other [\#89](https://github.com/danielcaldas/react-d3-graph/issues/89) | ||
**Fixed bugs:** | ||
* Error re-rendering Graph when no `config` prop is set [\#81](https://github.com/danielcaldas/react-d3-graph/issues/81) | ||
- Error re-rendering Graph when no `config` prop is set [\#81](https://github.com/danielcaldas/react-d3-graph/issues/81) | ||
**Merged pull requests:** | ||
* Configurable graph force strength and link length [\#104](https://github.com/danielcaldas/react-d3-graph/pull/104) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
* Fix alert message of onClickNode function in README [\#100](https://github.com/danielcaldas/react-d3-graph/pull/100) ([LucienBouletRoblin](https://github.com/LucienBouletRoblin)) | ||
* Fix/dependencies update [\#95](https://github.com/danielcaldas/react-d3-graph/pull/95) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/bump dependencies [\#92](https://github.com/danielcaldas/react-d3-graph/pull/92) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/bend links [\#91](https://github.com/danielcaldas/react-d3-graph/pull/91) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Small improvement in utils/pick [\#87](https://github.com/danielcaldas/react-d3-graph/pull/87) ([danielcaldas](https://github.com/danielcaldas)) | ||
* fix: Graph fails to render without config prop [\#84](https://github.com/danielcaldas/react-d3-graph/pull/84) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
* Node Collapse [\#83](https://github.com/danielcaldas/react-d3-graph/pull/83) ([svipatov](https://github.com/svipatov)) | ||
* Added overflow:hidden to container graph area [\#82](https://github.com/danielcaldas/react-d3-graph/pull/82) ([svipatov](https://github.com/svipatov)) | ||
- Configurable graph force strength and link length [\#104](https://github.com/danielcaldas/react-d3-graph/pull/104) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
- Fix alert message of onClickNode function in README [\#100](https://github.com/danielcaldas/react-d3-graph/pull/100) ([LucienBouletRoblin](https://github.com/LucienBouletRoblin)) | ||
- Fix/dependencies update [\#95](https://github.com/danielcaldas/react-d3-graph/pull/95) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/bump dependencies [\#92](https://github.com/danielcaldas/react-d3-graph/pull/92) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/bend links [\#91](https://github.com/danielcaldas/react-d3-graph/pull/91) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Small improvement in utils/pick [\#87](https://github.com/danielcaldas/react-d3-graph/pull/87) ([danielcaldas](https://github.com/danielcaldas)) | ||
- fix: Graph fails to render without config prop [\#84](https://github.com/danielcaldas/react-d3-graph/pull/84) ([LonelyPrincess](https://github.com/LonelyPrincess)) | ||
- Node Collapse [\#83](https://github.com/danielcaldas/react-d3-graph/pull/83) ([svipatov](https://github.com/svipatov)) | ||
- Added overflow:hidden to container graph area [\#82](https://github.com/danielcaldas/react-d3-graph/pull/82) ([svipatov](https://github.com/svipatov)) | ||
@@ -93,3 +124,3 @@ ## [1.3.0](https://github.com/danielcaldas/react-d3-graph/tree/1.3.0) (2018-06-25) | ||
* Customize color for a link [\#79](https://github.com/danielcaldas/react-d3-graph/pull/79) | ||
- Customize color for a link [\#79](https://github.com/danielcaldas/react-d3-graph/pull/79) | ||
@@ -107,17 +138,17 @@ ## [1.2.2](https://github.com/danielcaldas/react-d3-graph/tree/1.2.2) (2018-05-14) | ||
* BUG: NO LINK GETS HIGHLIGHTED WHEN NODE ID IS NON-STIRNG [\#73](https://github.com/danielcaldas/react-d3-graph/issues/73) props to @iamhosseindhv for reporting | ||
- BUG: NO LINK GETS HIGHLIGHTED WHEN NODE ID IS NON-STIRNG [\#73](https://github.com/danielcaldas/react-d3-graph/issues/73) props to @iamhosseindhv for reporting | ||
**Closed issues:** | ||
* can the graph nodes and line not stacked [\#58](https://github.com/danielcaldas/react-d3-graph/issues/58) | ||
* custom add node button [\#57](https://github.com/danielcaldas/react-d3-graph/issues/57) | ||
* labelProperty not implemented? [\#54](https://github.com/danielcaldas/react-d3-graph/issues/54) | ||
* BUG: NO LINK GETS HIGHLIGHTED WHEN NODE ID IS NON-STIRNG [\#73](https://github.com/danielcaldas/react-d3-graph/issues/73) | ||
- can the graph nodes and line not stacked [\#58](https://github.com/danielcaldas/react-d3-graph/issues/58) | ||
- custom add node button [\#57](https://github.com/danielcaldas/react-d3-graph/issues/57) | ||
- labelProperty not implemented? [\#54](https://github.com/danielcaldas/react-d3-graph/issues/54) | ||
- BUG: NO LINK GETS HIGHLIGHTED WHEN NODE ID IS NON-STIRNG [\#73](https://github.com/danielcaldas/react-d3-graph/issues/73) | ||
**Merged pull requests:** | ||
* Fix/mouse over link highlight [\#75](https://github.com/danielcaldas/react-d3-graph/pull/75) | ||
* Fix/link highlight id number [\#74](https://github.com/danielcaldas/react-d3-graph/pull/74) | ||
* Feature/move to node 8.11.0 [\#72](https://github.com/danielcaldas/react-d3-graph/pull/72) | ||
* Refactor/links build [\#69](https://github.com/danielcaldas/react-d3-graph/pull/69) | ||
- Fix/mouse over link highlight [\#75](https://github.com/danielcaldas/react-d3-graph/pull/75) | ||
- Fix/link highlight id number [\#74](https://github.com/danielcaldas/react-d3-graph/pull/74) | ||
- Feature/move to node 8.11.0 [\#72](https://github.com/danielcaldas/react-d3-graph/pull/72) | ||
- Refactor/links build [\#69](https://github.com/danielcaldas/react-d3-graph/pull/69) | ||
@@ -130,10 +161,10 @@ ## [1.2.1](https://github.com/danielcaldas/react-d3-graph/tree/1.2.1) (2018-04-22) | ||
* 100% Width/Height of parent element [\#63](https://github.com/danielcaldas/react-d3-graph/issues/63) | ||
* SVG image for node [\#36](https://github.com/danielcaldas/react-d3-graph/issues/36) | ||
- 100% Width/Height of parent element [\#63](https://github.com/danielcaldas/react-d3-graph/issues/63) | ||
- SVG image for node [\#36](https://github.com/danielcaldas/react-d3-graph/issues/36) | ||
**Merged pull requests:** | ||
* Move logic from graph component \(highlight updates\) [\#66](https://github.com/danielcaldas/react-d3-graph/pull/66) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/update dependencies [\#65](https://github.com/danielcaldas/react-d3-graph/pull/65) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Add fontColor as a configuration option for node's \<text\> fill property [\#64](https://github.com/danielcaldas/react-d3-graph/pull/64) ([dmmulroy](https://github.com/dmmulroy)) | ||
- Move logic from graph component \(highlight updates\) [\#66](https://github.com/danielcaldas/react-d3-graph/pull/66) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/update dependencies [\#65](https://github.com/danielcaldas/react-d3-graph/pull/65) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Add fontColor as a configuration option for node's \<text\> fill property [\#64](https://github.com/danielcaldas/react-d3-graph/pull/64) ([dmmulroy](https://github.com/dmmulroy)) | ||
@@ -146,15 +177,15 @@ ## [1.2.0](https://github.com/danielcaldas/react-d3-graph/tree/1.2.0) (2018-04-01) | ||
* Graph Rerendering [\#51](https://github.com/danielcaldas/react-d3-graph/issues/51) | ||
- Graph Rerendering [\#51](https://github.com/danielcaldas/react-d3-graph/issues/51) | ||
**Fixed bugs:** | ||
* Graph Rerendering [\#51](https://github.com/danielcaldas/react-d3-graph/issues/51) | ||
- Graph Rerendering [\#51](https://github.com/danielcaldas/react-d3-graph/issues/51) | ||
**Merged pull requests:** | ||
* Improve naming across rd3g codebase [\#62](https://github.com/danielcaldas/react-d3-graph/pull/62) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/update webpack [\#61](https://github.com/danielcaldas/react-d3-graph/pull/61) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/provide svg for nodes [\#60](https://github.com/danielcaldas/react-d3-graph/pull/60) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Fixing a broken link [\#55](https://github.com/danielcaldas/react-d3-graph/pull/55) ([ufo2mstar](https://github.com/ufo2mstar)) | ||
* Feature/add prettier [\#53](https://github.com/danielcaldas/react-d3-graph/pull/53) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Improve naming across rd3g codebase [\#62](https://github.com/danielcaldas/react-d3-graph/pull/62) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/update webpack [\#61](https://github.com/danielcaldas/react-d3-graph/pull/61) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/provide svg for nodes [\#60](https://github.com/danielcaldas/react-d3-graph/pull/60) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fixing a broken link [\#55](https://github.com/danielcaldas/react-d3-graph/pull/55) ([ufo2mstar](https://github.com/ufo2mstar)) | ||
- Feature/add prettier [\#53](https://github.com/danielcaldas/react-d3-graph/pull/53) ([danielcaldas](https://github.com/danielcaldas)) | ||
@@ -167,10 +198,10 @@ ## [1.0.1](https://github.com/danielcaldas/react-d3-graph/tree/1.0.1) (2018-02-18) | ||
* Click one node but another one moves [\#41](https://github.com/danielcaldas/react-d3-graph/issues/41) | ||
- Click one node but another one moves [\#41](https://github.com/danielcaldas/react-d3-graph/issues/41) | ||
**Merged pull requests:** | ||
* Fix/data updates static updates [\#52](https://github.com/danielcaldas/react-d3-graph/pull/52) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/e2e testing [\#50](https://github.com/danielcaldas/react-d3-graph/pull/50) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Refactor/separation of concerns render + logic [\#49](https://github.com/danielcaldas/react-d3-graph/pull/49) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Fix/install [\#45](https://github.com/danielcaldas/react-d3-graph/pull/45) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix/data updates static updates [\#52](https://github.com/danielcaldas/react-d3-graph/pull/52) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/e2e testing [\#50](https://github.com/danielcaldas/react-d3-graph/pull/50) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Refactor/separation of concerns render + logic [\#49](https://github.com/danielcaldas/react-d3-graph/pull/49) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix/install [\#45](https://github.com/danielcaldas/react-d3-graph/pull/45) ([danielcaldas](https://github.com/danielcaldas)) | ||
@@ -183,11 +214,11 @@ ## [1.0.0](https://github.com/danielcaldas/react-d3-graph/tree/1.0.0) (2017-12-02) | ||
* How can I get onMouseOverLink event? [\#25](https://github.com/danielcaldas/react-d3-graph/issues/25) | ||
- How can I get onMouseOverLink event? [\#25](https://github.com/danielcaldas/react-d3-graph/issues/25) | ||
**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)) | ||
- 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)) | ||
@@ -200,10 +231,10 @@ ## [0.4.0](https://github.com/danielcaldas/react-d3-graph/tree/0.4.0) (2017-11-11) | ||
* Node version [\#29](https://github.com/danielcaldas/react-d3-graph/issues/29) | ||
- Node version [\#29](https://github.com/danielcaldas/react-d3-graph/issues/29) | ||
**Merged pull requests:** | ||
* Refactor/improve code structure [\#35](https://github.com/danielcaldas/react-d3-graph/pull/35) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/highlight nodes degree [\#34](https://github.com/danielcaldas/react-d3-graph/pull/34) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Update node engine version in package.json [\#32](https://github.com/danielcaldas/react-d3-graph/pull/32) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/sandbox improvements [\#27](https://github.com/danielcaldas/react-d3-graph/pull/27) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Refactor/improve code structure [\#35](https://github.com/danielcaldas/react-d3-graph/pull/35) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/highlight nodes degree [\#34](https://github.com/danielcaldas/react-d3-graph/pull/34) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Update node engine version in package.json [\#32](https://github.com/danielcaldas/react-d3-graph/pull/32) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/sandbox improvements [\#27](https://github.com/danielcaldas/react-d3-graph/pull/27) ([danielcaldas](https://github.com/danielcaldas)) | ||
@@ -216,15 +247,15 @@ ## [0.3.0](https://github.com/danielcaldas/react-d3-graph/tree/0.3.0) (2017-10-21) | ||
* Squeezing if "staticGraph": true [\#24](https://github.com/danielcaldas/react-d3-graph/issues/24) | ||
- 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) | ||
- Squeezing if "staticGraph": true [\#24](https://github.com/danielcaldas/react-d3-graph/issues/24) | ||
**Merged pull requests:** | ||
* Fix/set initial static graph [\#26](https://github.com/danielcaldas/react-d3-graph/pull/26) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Refactor/general improvements [\#22](https://github.com/danielcaldas/react-d3-graph/pull/22) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Fix typo node.stype -\> node.symbolType [\#21](https://github.com/danielcaldas/react-d3-graph/pull/21) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Bump several dependencies to latest. New yarn.lock [\#20](https://github.com/danielcaldas/react-d3-graph/pull/20) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Refactor/documentation revisited [\#19](https://github.com/danielcaldas/react-d3-graph/pull/19) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix/set initial static graph [\#26](https://github.com/danielcaldas/react-d3-graph/pull/26) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Refactor/general improvements [\#22](https://github.com/danielcaldas/react-d3-graph/pull/22) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix typo node.stype -\> node.symbolType [\#21](https://github.com/danielcaldas/react-d3-graph/pull/21) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Bump several dependencies to latest. New yarn.lock [\#20](https://github.com/danielcaldas/react-d3-graph/pull/20) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Refactor/documentation revisited [\#19](https://github.com/danielcaldas/react-d3-graph/pull/19) ([danielcaldas](https://github.com/danielcaldas)) | ||
@@ -237,4 +268,4 @@ ## [0.2.1](https://github.com/danielcaldas/react-d3-graph/tree/0.2.1) (2017-09-17) | ||
* Fix/remove node link scu methods [\#18](https://github.com/danielcaldas/react-d3-graph/pull/18) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Calc proper value for node strokeWith when applying pan&zoom [\#17](https://github.com/danielcaldas/react-d3-graph/pull/17) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix/remove node link scu methods [\#18](https://github.com/danielcaldas/react-d3-graph/pull/18) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Calc proper value for node strokeWith when applying pan&zoom [\#17](https://github.com/danielcaldas/react-d3-graph/pull/17) ([danielcaldas](https://github.com/danielcaldas)) | ||
@@ -247,5 +278,5 @@ ## [0.2.0](https://github.com/danielcaldas/react-d3-graph/tree/0.2.0) (2017-09-16) | ||
* Refactor/d3 tree shaking [\#16](https://github.com/danielcaldas/react-d3-graph/pull/16) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Generate bundle stats with webpack visualizer [\#15](https://github.com/danielcaldas/react-d3-graph/pull/15) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/pan and zoom [\#14](https://github.com/danielcaldas/react-d3-graph/pull/14) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Refactor/d3 tree shaking [\#16](https://github.com/danielcaldas/react-d3-graph/pull/16) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Generate bundle stats with webpack visualizer [\#15](https://github.com/danielcaldas/react-d3-graph/pull/15) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/pan and zoom [\#14](https://github.com/danielcaldas/react-d3-graph/pull/14) ([danielcaldas](https://github.com/danielcaldas)) | ||
@@ -258,10 +289,10 @@ ## [0.1.0](https://github.com/danielcaldas/react-d3-graph/tree/0.1.0) (2017-08-05) | ||
* Adding nodes? [\#7](https://github.com/danielcaldas/react-d3-graph/issues/7) | ||
- Adding nodes? [\#7](https://github.com/danielcaldas/react-d3-graph/issues/7) | ||
**Merged pull requests:** | ||
* Refactor/sandbox improvements [\#12](https://github.com/danielcaldas/react-d3-graph/pull/12) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Fix/default node symbol [\#11](https://github.com/danielcaldas/react-d3-graph/pull/11) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Fix/not call graph configs inside component did update [\#10](https://github.com/danielcaldas/react-d3-graph/pull/10) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Refactor/update graph data [\#9](https://github.com/danielcaldas/react-d3-graph/pull/9) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Refactor/sandbox improvements [\#12](https://github.com/danielcaldas/react-d3-graph/pull/12) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix/default node symbol [\#11](https://github.com/danielcaldas/react-d3-graph/pull/11) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Fix/not call graph configs inside component did update [\#10](https://github.com/danielcaldas/react-d3-graph/pull/10) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Refactor/update graph data [\#9](https://github.com/danielcaldas/react-d3-graph/pull/9) ([danielcaldas](https://github.com/danielcaldas)) | ||
@@ -276,9 +307,9 @@ ## [0.0.2](https://github.com/danielcaldas/react-d3-graph/tree/0.0.2) (2017-04-25) | ||
* Feature/docs [\#6](https://github.com/danielcaldas/react-d3-graph/pull/6) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/test suite [\#5](https://github.com/danielcaldas/react-d3-graph/pull/5) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/sandbox [\#4](https://github.com/danielcaldas/react-d3-graph/pull/4) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/npm dependencies [\#3](https://github.com/danielcaldas/react-d3-graph/pull/3) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Feature/graph component decoupling [\#2](https://github.com/danielcaldas/react-d3-graph/pull/2) ([danielcaldas](https://github.com/danielcaldas)) | ||
* Graph forces [\#1](https://github.com/danielcaldas/react-d3-graph/pull/1) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/docs [\#6](https://github.com/danielcaldas/react-d3-graph/pull/6) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/test suite [\#5](https://github.com/danielcaldas/react-d3-graph/pull/5) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/sandbox [\#4](https://github.com/danielcaldas/react-d3-graph/pull/4) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/npm dependencies [\#3](https://github.com/danielcaldas/react-d3-graph/pull/3) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Feature/graph component decoupling [\#2](https://github.com/danielcaldas/react-d3-graph/pull/2) ([danielcaldas](https://github.com/danielcaldas)) | ||
- Graph forces [\#1](https://github.com/danielcaldas/react-d3-graph/pull/1) ([danielcaldas](https://github.com/danielcaldas)) | ||
\* _This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)_ |
@@ -116,3 +116,3 @@ "use strict"; | ||
* there is an object that maps adjacent nodes ids (string) and their values (number). | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Object} config - same as {@link #graphrenderer|config in renderGraph}. | ||
* @param {boolean} config.directed - tells whether linksMatrix represents a directed graph or not. | ||
@@ -151,2 +151,3 @@ * @returns {Array.<Object.<string, string>>} a list of leaf connections. | ||
* @param {string} nodeId - The id of the node to get the cardinality of | ||
* @param {Object.<string, Object>} nodes - an object containing all nodes mapped by their id. | ||
* @param {Object.<string, number>} linksMatrix - An object containing a matrix of connections of the nodes. | ||
@@ -156,3 +157,3 @@ * @returns {boolean} flag that indicates whether node should or not be displayed. | ||
*/ | ||
function isNodeVisible(nodeId, linksMatrix) { | ||
function isNodeVisible(nodeId, nodes, linksMatrix) { | ||
var _computeNodeDegree2 = computeNodeDegree(nodeId, linksMatrix), | ||
@@ -162,3 +163,5 @@ inDegree = _computeNodeDegree2.inDegree, | ||
return inDegree >= 1 || outDegree >= 1; | ||
var orphan = !!nodes[nodeId]._orphan; | ||
return inDegree > 0 || outDegree > 0 || orphan; | ||
} | ||
@@ -192,3 +195,3 @@ | ||
* @param {Array.<Object.<string, string>>} connections - connections to toggle on matrix. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Object} config - same as {@link #graphrenderer|config in renderGraph}. | ||
* @param {boolean} config.directed - tells whether linksMatrix represents a directed graph or not. | ||
@@ -195,0 +198,0 @@ * @returns {Object.<string, Object>} updated linksMatrix |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -7,3 +7,3 @@ Object.defineProperty(exports, "__esModule", { | ||
/** | ||
* <div style='text-align: right;'><i>This is certainly the only extra piece of documentation that you will ever need</i></div> | ||
* <div style="text-align: right;"><i>This is certainly the only extra piece of documentation that you will ever need</i></div> | ||
* <br/><br/> | ||
@@ -25,6 +25,6 @@ * Here you can consult a detailed description of each graph configurable property as well as the default values | ||
* { | ||
* id: 'id', | ||
* color: 'red', // only this node will be red | ||
* id: "id", | ||
* color: "red", // only this node will be red | ||
* size: 300, // only this node will have size 300 | ||
* symbolType: 'diamond' // only this node will have 'diamond' shape | ||
* symbolType: "diamond" // only this node will have "diamond" shape | ||
* } | ||
@@ -38,3 +38,2 @@ * ], | ||
* | ||
* **Index for config**<br/> | ||
* - <a href="#config-global">Graph global configurations</a> | ||
@@ -45,2 +44,4 @@ * - <a href="#config-d3">d3 level configurations</a> | ||
* | ||
* <br/> | ||
* | ||
* <h2 id="config-global"><a href="#config-global">#</a> Graph global configurations</h2> | ||
@@ -58,15 +59,2 @@ * @param {boolean} [automaticRearrangeAfterDropNode=false] - 🚅🚅🚅 when true performing a node drag and drop should automatically | ||
* <img src="https://github.com/danielcaldas/react-d3-graph/blob/master/docs/rd3g-directed.gif?raw=true" width="820" height="480"/> | ||
* @param {number} [height=400] - the height of the (svg) area where the graph will be rendered. | ||
* @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 | ||
* highlight behavior when some node is highlighted. If the value is set to **0** only the selected node will be | ||
* highlighted. If the value is set to **1** the selected node and his 1st degree connections will be highlighted. If | ||
* the value is set to **2** the selected node will be highlighted as well as the 1st and 2nd common degree connections. | ||
* @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 *nodeHighlightBehavior*). | ||
* @param {number} [maxZoom=8] - max zoom that can be performed against the graph. | ||
* @param {number} [minZoom=0.1] - min zoom that can be performed against the graph. | ||
* @param {number} [focusZoom=1] - zoom that will be applied when the graph view is focused in a node. Its value must be between | ||
@@ -81,3 +69,3 @@ * *minZoom* and *maxZoom*. If the specified *focusZoom* is out of this range, *minZoom* or *maxZoom* will be applied instead. | ||
* links: this.state.data.links, | ||
* focusedNodeId: 'nodeIdToTriggerZoomAnimation' | ||
* focusedNodeId: "nodeIdToTriggerZoomAnimation" | ||
* }; | ||
@@ -89,2 +77,15 @@ * ``` | ||
* @param {number} [focusAnimationDuration=0.75] - duration (in seconds) for the animation that takes place when focusing the graph on a node. | ||
* @param {number} [height=400] - the height of the (svg) area where the graph will be rendered. | ||
* @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 | ||
* highlight behavior when some node is highlighted. If the value is set to **0** only the selected node will be | ||
* highlighted. If the value is set to **1** the selected node and his 1st degree connections will be highlighted. If | ||
* the value is set to **2** the selected node will be highlighted as well as the 1st and 2nd common degree connections. | ||
* @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 *nodeHighlightBehavior*). | ||
* @param {number} [maxZoom=8] - max zoom that can be performed against the graph. | ||
* @param {number} [minZoom=0.1] - min zoom that can be performed against the graph. | ||
* @param {boolean} [panAndZoom=false] - 🚅🚅🚅 pan and zoom effect when performing zoom in the graph, | ||
@@ -103,3 +104,3 @@ * a similar functionality may be consulted {@link https://bl.ocks.org/mbostock/2a39a768b1d4bc00a09650edef75ad39|here}. | ||
* - 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. | ||
* - 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. | ||
@@ -110,19 +111,19 @@ * @param {number} [d3.linkStrength=1] - [see d3-force link.strength](https://github.com/d3/d3-force#link_strength) | ||
* <h2 id="config-node"><a href="#config-node">#</a> Node level configurations</h2> | ||
* @param {string} [node.color='#d3d3d3'] - 🔍🔍🔍 this is the color that will be applied to the node if no **color property** | ||
* is found inside the node itself (yes **you can pass a property 'color' inside the node and that color will override the | ||
* @param {string} [node.color="#d3d3d3"] - 🔍🔍🔍 this is the color that will be applied to the node if no **color property** | ||
* is found inside the node itself (yes **you can pass a property "color" inside the node and that color will override the | ||
* this default one**). | ||
* @param {string} [node.fontColor='black'] - 🔍🔍🔍 fill color for node's <text> svg label. | ||
* @param {number} [node.fontSize=10] - {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-size?v=control|font-size} | ||
* property for all nodes' labels. | ||
* @param {string} [node.fontWeight='normal'] - {@link https://developer.mozilla.org/en/docs/Web/CSS/font-weight?v=control|font-weight} | ||
* property for all nodes' labels. | ||
* @param {string} [node.highlightColor='SAME'] - color for all highlighted nodes (use string 'SAME' if you | ||
* @param {string} [node.fontColor="black"] - 🔍🔍🔍 fill color for node"s <text> svg label. | ||
* @param {number} [node.fontSize=8] - {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-size?v=control|font-size} | ||
* property for all nodes" labels. | ||
* @param {string} [node.fontWeight="normal"] - {@link https://developer.mozilla.org/en/docs/Web/CSS/font-weight?v=control|font-weight} | ||
* property for all nodes" labels. | ||
* @param {string} [node.highlightColor="SAME"] - color for all highlighted nodes (use string "SAME" if you | ||
* want the node to keep its color in highlighted state). | ||
* @param {number} [node.highlightFontSize=8] - fontSize in highlighted state. | ||
* @param {string} [node.highlightFontWeight='normal'] - fontWeight in highlighted state. | ||
* @param {string} [node.highlightStrokeColor='SAME'] - strokeColor in highlighted state. | ||
* @param {number} [node.highlightStrokeWidth=1.5] - strokeWidth in highlighted state. | ||
* @param {string|Function} [node.labelProperty='id'] - this is the node property that will be used in runtime to | ||
* @param {string} [node.highlightFontWeight="normal"] - fontWeight in highlighted state. | ||
* @param {string} [node.highlightStrokeColor="SAME"] - strokeColor in highlighted state. | ||
* @param {number} [node.highlightStrokeWidth="SAME"] - strokeWidth in highlighted state. | ||
* @param {string|Function} [node.labelProperty="id"] - this is the node property that will be used in runtime to | ||
* fetch the label content. You just need to add some property (e.g. firstName) to the node payload and then set | ||
* node.labelProperty to be **'firstName'**. **This can also be a function!**, if you pass a function here it will be called | ||
* node.labelProperty to be **"firstName"**. **This can also be a function!**, if you pass a function here it will be called | ||
* to obtain the `label` value on the fly, as a client you will receive all the node information that you passed down into react-d3-graph, | ||
@@ -133,3 +134,3 @@ * so the signature of the function would be: | ||
* // do stuff to get the final result... | ||
* return 'label string'; | ||
* return "label string"; | ||
* } | ||
@@ -139,23 +140,23 @@ * ``` | ||
* <br/> | ||
* @param {string} [node.mouseCursor='pointer'] - {@link https://developer.mozilla.org/en/docs/Web/CSS/cursor?v=control|cursor} | ||
* @param {string} [node.mouseCursor="pointer"] - {@link https://developer.mozilla.org/en/docs/Web/CSS/cursor?v=control|cursor} | ||
* property for when some node is mouse hovered. | ||
* @param {number} [node.opacity=1] - by default all nodes will have this opacity value. | ||
* @param {number} [node.opacity=1] 🔍🔍🔍 - by default all nodes will have this opacity value. | ||
* @param {boolean} [node.renderLabel=true] - when set to false no labels will appear along side nodes in the | ||
* graph. | ||
* @param {number} [node.size=200] - 🔍🔍🔍 defines the size of all nodes. | ||
* @param {string} [node.strokeColor='none'] - 🔍🔍🔍 this is the stroke color that will be applied to the node if no **strokeColor property** is found inside the node itself (yes **you can pass a property 'strokeColor' inside the node and that stroke color will override this default one** ). | ||
* @param {number} [node.strokeWidth=1.5] - the width of the all node strokes. | ||
* @param {string} [node.svg=''] - 🔍🔍🔍 render custom svg for nodes in alternative to **node.symbolType**. This svg can | ||
* @param {string} [node.strokeColor="none"] - 🔍🔍🔍 this is the stroke color that will be applied to the node if no **strokeColor property** is found inside the node itself (yes **you can pass a property "strokeColor" inside the node and that stroke color will override this default one** ). | ||
* @param {number} [node.strokeWidth=1.5] 🔍🔍🔍 - the width of the all node strokes. | ||
* @param {string} [node.svg=""] - 🔍🔍🔍 render custom svg for nodes in alternative to **node.symbolType**. This svg can | ||
* be provided as a string to either a remote svg resource or for a local one. | ||
* <br/> | ||
* <img src="https://github.com/danielcaldas/react-d3-graph/blob/master/docs/rd3g-custom-svg.gif?raw=true" width="820" height="480"/> | ||
* @param {string} [node.symbolType='circle'] - 🔍🔍🔍 the <span id='node-symbol-type'>shape</span> of the node. | ||
* @param {string} [node.symbolType="circle"] - 🔍🔍🔍 the <span id="node-symbol-type">shape</span> of the node. | ||
* Use the following values under a property **type** inside each node (nodes may have different types, same as colors): | ||
* - 'circle' | ||
* - 'cross' | ||
* - 'diamond' | ||
* - 'square' | ||
* - 'star' | ||
* - 'triangle' | ||
* - 'wye' | ||
* - "circle" | ||
* - "cross" | ||
* - "diamond" | ||
* - "square" | ||
* - "star" | ||
* - "triangle" | ||
* - "wye" | ||
* | ||
@@ -167,9 +168,22 @@ * **[note]** react-d3-graph will map this values to [d3 symbols](https://github.com/d3/d3-shape#symbols) | ||
* <h2 id="config-link"><a href="#config-link">#</a> Link level configurations</h2> | ||
* @param {string} [link.color='#d3d3d3'] - 🚅🚅🚅 the color for links | ||
* @param {string} [link.color="#d3d3d3"] - 🔍🔍🔍 the color for links | ||
* (from version 1.3.0 this property can be configured at link level). | ||
* @param {string} [link.highlightColor='#d3d3d3'] - links' color in highlight state. | ||
* @param {string} [link.fontColor="black"] - 🔍🔍🔍 fill color for link's <text> svg label. | ||
* @param {number} [link.fontSize=8] - {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-size?v=control|font-size} | ||
* property for all links' labels. | ||
* @param {string} [link.fontWeight="normal"] - {@link https://developer.mozilla.org/en/docs/Web/CSS/font-weight?v=control|font-weight} | ||
* property for all links' labels. | ||
* @param {string} [link.highlightColor="#d3d3d3"] - links' color in highlight state. | ||
* <img src="https://github.com/danielcaldas/react-d3-graph/blob/master/docs/rd3g-bend.gif?raw=true" width="820" height="480"/> | ||
* @param {string} [link.mouseCursor='pointer'] - {@link https://developer.mozilla.org/en/docs/Web/CSS/cursor?v=control|cursor} | ||
* @param {number} [link.highlightFontSize=8] - fontSize in highlighted state. | ||
* @param {string} [link.highlightFontWeight="normal"] - fontWeight in highlighted state. | ||
* @param {boolean} [link.labelProperty="label"] - the property that will be rendered as label within some link. Note that | ||
* this property needs to be passed along the link payload (along side with source and target). | ||
* @param {string} [link.mouseCursor="pointer"] - {@link https://developer.mozilla.org/en/docs/Web/CSS/cursor?v=control|cursor} | ||
* property for when link is mouse hovered. | ||
* @param {number} [link.opacity=1] - the default opacity value for links. | ||
* @param {number} [link.opacity=1] 🔍🔍🔍 - the default opacity value for links. | ||
* @param {boolean} [link.renderLabel=false] - when set to true labels will appear along side links in the | ||
* graph. **Note**: this will only happen of course if proper label is passed within the link, check also `link.labelProperty`. | ||
* <br/> | ||
* <img src="https://github.com/danielcaldas/react-d3-graph/blob/master/docs/rd3g-link-render-label.png?raw=true" width="820" height="480"/> | ||
* @param {boolean} [link.semanticStrokeWidth=false] - when set to true all links will have | ||
@@ -181,3 +195,3 @@ * *"semantic width"*, this means that the width of the connections will be proportional to the value of each link. | ||
* ``` | ||
* @param {number} [link.strokeWidth=1.5] - strokeWidth for all links. By default the actual value is obtain by the | ||
* @param {number} [link.strokeWidth=1.5] 🔍🔍🔍 - strokeWidth for all links. By default the actual value is obtain by the | ||
* following expression: | ||
@@ -187,3 +201,3 @@ * ```javascript | ||
* ``` | ||
* @param {string} [link.type='STRAIGHT'] - the type of line to draw, available types at this point are: | ||
* @param {string} [link.type="STRAIGHT"] - the type of line to draw, available types at this point are: | ||
* - "STRAIGHT" <small>(default)</small> - a straight line. | ||
@@ -193,2 +207,3 @@ * - "CURVE_SMOOTH" - a slight curve between two nodes | ||
* <br/> | ||
* <img src="https://github.com/danielcaldas/react-d3-graph/blob/master/docs/rd3g-bend.gif?raw=true" width="820" height="480"/> | ||
* | ||
@@ -200,12 +215,12 @@ * @example | ||
* node: { | ||
* color: 'lightgreen', | ||
* color: "lightgreen", | ||
* size: 120, | ||
* highlightStrokeColor: 'blue' | ||
* highlightStrokeColor: "blue" | ||
* }, | ||
* link: { | ||
* highlightColor: 'lightblue' | ||
* highlightColor: "lightblue" | ||
* } | ||
* }; | ||
* | ||
* // Sorry for the long config description, here's a potato 🥔. | ||
* // Sorry for the long config description, here"s a potato 🥔. | ||
*/ | ||
@@ -216,2 +231,4 @@ exports.default = { | ||
directed: false, | ||
focusAnimationDuration: 0.75, | ||
focusZoom: 1, | ||
height: 400, | ||
@@ -223,4 +240,2 @@ highlightDegree: 1, | ||
minZoom: 0.1, | ||
focusZoom: 1, | ||
focusAnimationDuration: 0.75, | ||
nodeHighlightBehavior: false, | ||
@@ -237,31 +252,38 @@ panAndZoom: false, | ||
node: { | ||
color: '#d3d3d3', | ||
fontColor: 'black', | ||
color: "#d3d3d3", | ||
fontColor: "black", | ||
fontSize: 8, | ||
fontWeight: 'normal', | ||
highlightColor: 'SAME', | ||
fontWeight: "normal", | ||
highlightColor: "SAME", | ||
highlightFontSize: 8, | ||
highlightFontWeight: 'normal', | ||
highlightStrokeColor: 'SAME', | ||
highlightStrokeWidth: 1.5, | ||
labelProperty: 'id', | ||
mouseCursor: 'pointer', | ||
highlightFontWeight: "normal", | ||
highlightStrokeColor: "SAME", | ||
highlightStrokeWidth: "SAME", | ||
labelProperty: "id", | ||
mouseCursor: "pointer", | ||
opacity: 1, | ||
renderLabel: true, | ||
size: 200, | ||
strokeColor: 'none', | ||
strokeColor: "none", | ||
strokeWidth: 1.5, | ||
svg: '', | ||
symbolType: 'circle', | ||
svg: "", | ||
symbolType: "circle", | ||
viewGenerator: null | ||
}, | ||
link: { | ||
color: '#d3d3d3', | ||
highlightColor: '#d3d3d3', | ||
mouseCursor: 'pointer', | ||
color: "#d3d3d3", | ||
fontColor: "black", | ||
fontSize: 8, | ||
fontWeight: "normal", | ||
highlightColor: "#d3d3d3", | ||
highlightFontSize: 8, | ||
highlightFontWeight: "normal", | ||
labelProperty: "label", | ||
mouseCursor: "pointer", | ||
opacity: 1, | ||
renderLabel: false, | ||
semanticStrokeWidth: false, | ||
strokeWidth: 1.5, | ||
type: 'STRAIGHT' | ||
type: "STRAIGHT" | ||
} | ||
}; |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -9,3 +9,3 @@ Object.defineProperty(exports, "__esModule", { | ||
var _const = require('../../const'); | ||
var _const = require("../../const"); | ||
@@ -17,13 +17,12 @@ var _const2 = _interopRequireDefault(_const); | ||
exports.default = _extends({ | ||
COORDS_SEPARATOR: ',', | ||
FORCE_IDEAL_STRENGTH: -100, // TODO: Expose as configurable, | ||
COORDS_SEPARATOR: ",", | ||
FORCE_X: 0.06, | ||
FORCE_Y: 0.06, | ||
GRAPH_CONTAINER_ID: 'graph-container-zoomable', | ||
GRAPH_WRAPPER_ID: 'graph-wrapper', | ||
GRAPH_CONTAINER_ID: "graph-container-zoomable", | ||
GRAPH_WRAPPER_ID: "graph-wrapper", | ||
KEYWORDS: { | ||
SAME: 'SAME' | ||
SAME: "SAME" | ||
}, | ||
LINK_CLASS_NAME: 'link', | ||
NODE_CLASS_NAME: 'node' | ||
LINK_CLASS_NAME: "link", | ||
NODE_CLASS_NAME: "node" | ||
}, _const2.default); |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -6,3 +6,3 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.getCenterAndZoomTransformation = exports.updateNodeHighlightedValue = exports.initializeGraphState = exports.checkForGraphElementsChanges = exports.checkForGraphConfigChanges = exports.buildNodeProps = exports.buildLinkProps = undefined; | ||
exports.updateNodeHighlightedValue = exports.initializeGraphState = exports.getCenterAndZoomTransformation = exports.checkForGraphElementsChanges = exports.checkForGraphConfigChanges = undefined; | ||
@@ -32,24 +32,22 @@ var _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; }; /** | ||
var _d3Force = require('d3-force'); | ||
var _d3Force = require("d3-force"); | ||
var _graph2 = require('./graph.const'); | ||
var _graph2 = require("./graph.const"); | ||
var _graph3 = _interopRequireDefault(_graph2); | ||
var _graph4 = require('./graph.config'); | ||
var _graph4 = require("./graph.config"); | ||
var _graph5 = _interopRequireDefault(_graph4); | ||
var _err = require('../../err'); | ||
var _err = require("../../err"); | ||
var _err2 = _interopRequireDefault(_err); | ||
var _utils = require('../../utils'); | ||
var _utils = require("../../utils"); | ||
var _utils2 = _interopRequireDefault(_utils); | ||
var _link = require('../link/link.helper'); | ||
var _collapse = require("./collapse.helper"); | ||
var _marker = require('../marker/marker.helper'); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -59,3 +57,4 @@ | ||
var NODE_PROPS_WHITELIST = ['id', 'highlighted', 'x', 'y', 'index', 'vy', 'vx']; | ||
var NODE_PROPS_WHITELIST = ["id", "highlighted", "x", "y", "index", "vy", "vx"]; | ||
var LINK_CUSTOM_PROPS_WHITELIST = ["color", "opacity", "strokeWidth", "label"]; | ||
@@ -78,31 +77,6 @@ /** | ||
return (0, _d3Force.forceSimulation)().force('charge', (0, _d3Force.forceManyBody)().strength(forceStrength)).force('x', frx).force('y', fry); | ||
return (0, _d3Force.forceSimulation)().force("charge", (0, _d3Force.forceManyBody)().strength(forceStrength)).force("x", frx).force("y", fry); | ||
} | ||
/** | ||
* 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 | ||
@@ -119,4 +93,4 @@ * in a lightweight matrix containing only links with source and target being strings representative of some node id | ||
return graphLinks.reduce(function (links, l) { | ||
var source = l.source.id || l.source; | ||
var target = l.target.id || l.target; | ||
var source = l.source.id !== undefined && l.source.id !== null ? l.source.id : l.source; | ||
var target = l.target.id !== undefined && l.target.id !== null ? l.target.id : l.target; | ||
@@ -161,6 +135,6 @@ if (!links[source]) { | ||
if (!node.hasOwnProperty('x')) { | ||
if (!node.hasOwnProperty("x")) { | ||
node.x = 0; | ||
} | ||
if (!node.hasOwnProperty('y')) { | ||
if (!node.hasOwnProperty("y")) { | ||
node.y = 0; | ||
@@ -182,3 +156,3 @@ } | ||
* @param {Array.<Object>} d3Links - all d3Links. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Object} config - same as {@link #graphrenderer|config in renderGraph}. | ||
* @param {Object} state - Graph component current state (same format as returned object on this function). | ||
@@ -194,13 +168,15 @@ * @returns {Object} a d3Link. | ||
var d3Link = d3Links[index]; | ||
var customProps = _utils2.default.pick(link, LINK_CUSTOM_PROPS_WHITELIST); | ||
if (d3Link) { | ||
var toggledDirected = state.config && state.config.directed && config.directed !== state.config.directed; | ||
var refinedD3Link = _extends({}, d3Link, customProps); | ||
// every time we toggle directed config all links should be visible again | ||
if (toggledDirected) { | ||
return _extends({}, d3Link, { isHidden: false }); | ||
return _extends({}, refinedD3Link, { isHidden: false }); | ||
} | ||
// every time we disable collapsible (collapsible is false) all links should be visible again | ||
return config.collapsible ? d3Link : _extends({}, d3Link, { isHidden: false }); | ||
return config.collapsible ? refinedD3Link : _extends({}, refinedD3Link, { isHidden: false }); | ||
} | ||
@@ -218,10 +194,32 @@ | ||
return { | ||
return _extends({ | ||
index: index, | ||
source: source, | ||
target: target | ||
}; | ||
}, customProps); | ||
} | ||
/** | ||
* Tags orphan nodes with a `_orphan` flag. | ||
* @param {Object.<string, Object>} nodes - nodes mapped by their id. | ||
* @param {Object.<string, Object>} linksMatrix - 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). | ||
* @returns {Object.<string, Object>} same input nodes structure with tagged orphans nodes where applicable. | ||
*/ | ||
function _tagOrphanNodes(nodes, linksMatrix) { | ||
return Object.keys(nodes).reduce(function (acc, nodeId) { | ||
var _computeNodeDegree = (0, _collapse.computeNodeDegree)(nodeId, linksMatrix), | ||
inDegree = _computeNodeDegree.inDegree, | ||
outDegree = _computeNodeDegree.outDegree; | ||
var node = nodes[nodeId]; | ||
var taggedNode = inDegree === 0 && outDegree === 0 ? _extends({}, node, { _orphan: true }) : node; | ||
acc[nodeId] = taggedNode; | ||
return acc; | ||
}, {}); | ||
} | ||
/** | ||
* Some integrity validations on links and nodes structure. If some validation fails the function will | ||
@@ -238,3 +236,3 @@ * throw an error. | ||
if (!data.nodes || !data.nodes.length) { | ||
_utils2.default.throwErr('Graph', _err2.default.INSUFFICIENT_DATA); | ||
_utils2.default.throwErr("Graph", _err2.default.INSUFFICIENT_DATA); | ||
} | ||
@@ -250,9 +248,14 @@ | ||
})) { | ||
_utils2.default.throwErr('Graph', _err2.default.INVALID_LINKS + ' - "' + l.source + '" is not a valid source node id'); | ||
_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'); | ||
_utils2.default.throwErr("Graph", _err2.default.INVALID_LINKS + " - \"" + l.target + "\" is not a valid target node id"); | ||
} | ||
if (l && l.value !== undefined && typeof l.value !== "number") { | ||
_utils2.default.throwErr("Graph", _err2.default.INVALID_LINK_VALUE + " - found in link with source \"" + l.source + "\" and target \"" + l.target + "\""); | ||
} | ||
}; | ||
@@ -265,158 +268,4 @@ | ||
/** | ||
* Build some Link properties based on given parameters. | ||
* @param {Object} link - the link object for which we will generate properties. | ||
* @param {Object.<string, Object>} nodes - same as {@link #buildGraph|nodes in buildGraph}. | ||
* @param {Object.<string, Object>} links - same as {@link #buildGraph|links in buildGraph}. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Function[]} linkCallbacks - same as {@link #buildGraph|linkCallbacks in buildGraph}. | ||
* @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. | ||
* @returns {Object} returns an object that aggregates all props for creating respective Link component instance. | ||
* @memberof Graph/helper | ||
*/ | ||
function buildLinkProps(link, nodes, links, config, linkCallbacks, highlightedNode, highlightedLink, transform) { | ||
var source = link.source, | ||
target = link.target; | ||
var x1 = nodes[source] && nodes[source].x || 0; | ||
var y1 = nodes[source] && nodes[source].y || 0; | ||
var x2 = nodes[target] && nodes[target].x || 0; | ||
var y2 = nodes[target] && nodes[target].y || 0; | ||
var d = (0, _link.buildLinkPathDefinition)({ source: { x: x1, y: y1 }, target: { x: x2, y: y2 } }, config.link.type); | ||
var mainNodeParticipates = false; | ||
switch (config.highlightDegree) { | ||
case 0: | ||
break; | ||
case 2: | ||
mainNodeParticipates = true; | ||
break; | ||
default: | ||
// 1st degree is the fallback behavior | ||
mainNodeParticipates = source === highlightedNode || target === highlightedNode; | ||
break; | ||
} | ||
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; | ||
} | ||
var stroke = link.color || config.link.color; | ||
if (highlight) { | ||
stroke = config.link.highlightColor === _graph3.default.KEYWORDS.SAME ? config.link.color : config.link.highlightColor; | ||
} | ||
var strokeWidth = config.link.strokeWidth * (1 / transform); | ||
if (config.link.semanticStrokeWidth) { | ||
var linkValue = links[source][target] || links[target][source] || 1; | ||
strokeWidth += linkValue * strokeWidth / 10; | ||
} | ||
var markerId = config.directed ? (0, _marker.getMarkerId)(highlight, transform, config) : null; | ||
return { | ||
markerId: markerId, | ||
d: d, | ||
source: source, | ||
target: target, | ||
strokeWidth: strokeWidth, | ||
stroke: stroke, | ||
mouseCursor: config.link.mouseCursor, | ||
className: _graph3.default.LINK_CLASS_NAME, | ||
opacity: opacity, | ||
onClickLink: linkCallbacks.onClickLink, | ||
onRightClickLink: linkCallbacks.onRightClickLink, | ||
onMouseOverLink: linkCallbacks.onMouseOverLink, | ||
onMouseOutLink: linkCallbacks.onMouseOutLink | ||
}; | ||
} | ||
/** | ||
* Build some Node properties based on given parameters. | ||
* @param {Object} node - the node object for whom we will generate properties. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Function[]} nodeCallbacks - same as {@link #buildGraph|nodeCallbacks in buildGraph}. | ||
* @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. | ||
* @returns {Object} returns object that contain Link props ready to be feeded to the Link component. | ||
* @memberof Graph/helper | ||
*/ | ||
function buildNodeProps(node, config) { | ||
var nodeCallbacks = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
var highlightedNode = arguments[3]; | ||
var highlightedLink = arguments[4]; | ||
var transform = arguments[5]; | ||
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 (highlight && config.node.highlightColor !== _graph3.default.KEYWORDS.SAME) { | ||
fill = config.node.highlightColor; | ||
} | ||
var stroke = node.strokeColor || config.node.strokeColor; | ||
if (highlight && config.node.highlightStrokeColor !== _graph3.default.KEYWORDS.SAME) { | ||
stroke = config.node.highlightStrokeColor; | ||
} | ||
var label = node[config.node.labelProperty] || node.id; | ||
if (typeof config.node.labelProperty === 'function') { | ||
label = config.node.labelProperty(node); | ||
} | ||
var t = 1 / transform; | ||
var nodeSize = node.size || config.node.size; | ||
var fontSize = highlight ? config.node.highlightFontSize : config.node.fontSize; | ||
var dx = fontSize * t + nodeSize / 100 + 1.5; | ||
var strokeWidth = highlight ? config.node.highlightStrokeWidth : config.node.strokeWidth; | ||
var svg = node.svg || config.node.svg; | ||
var fontColor = node.fontColor || config.node.fontColor; | ||
return _extends({}, node, { | ||
className: _graph3.default.NODE_CLASS_NAME, | ||
cursor: config.node.mouseCursor, | ||
cx: node && node.x || '0', | ||
cy: node && node.y || '0', | ||
fill: fill, | ||
fontColor: fontColor, | ||
fontSize: fontSize * t, | ||
dx: dx, | ||
fontWeight: highlight ? config.node.highlightFontWeight : config.node.fontWeight, | ||
id: node.id, | ||
label: label, | ||
onClickNode: nodeCallbacks.onClickNode, | ||
onRightClickNode: nodeCallbacks.onRightClickNode, | ||
onMouseOverNode: nodeCallbacks.onMouseOverNode, | ||
onMouseOut: nodeCallbacks.onMouseOut, | ||
opacity: opacity, | ||
renderLabel: config.node.renderLabel, | ||
size: nodeSize * t, | ||
stroke: stroke, | ||
strokeWidth: strokeWidth * t, | ||
svg: svg, | ||
type: node.symbolType || config.node.symbolType, | ||
viewGenerator: node.viewGenerator || config.node.viewGenerator, | ||
overrideGlobalViewGenerator: !node.viewGenerator && node.svg | ||
}); | ||
} | ||
// list of properties that are of no interest when it comes to nodes and links comparison | ||
var NODE_PROPERTIES_DISCARD_TO_COMPARE = ['x', 'y', 'vx', 'vy', 'index']; | ||
var NODE_PROPERTIES_DISCARD_TO_COMPARE = ["x", "y", "vx", "vy", "index"]; | ||
@@ -447,4 +296,4 @@ /** | ||
// FIXME: solve this source data inconsistency later | ||
source: l.source.id || l.source, | ||
target: l.target.id || l.target | ||
source: l.source.id !== undefined && l.source.id !== null ? l.source.id : l.source, | ||
target: l.target.id !== undefined && l.target.id !== null ? l.target.id : l.target | ||
}; | ||
@@ -486,2 +335,23 @@ }); | ||
/** | ||
* Returns the transformation to apply in order to center the graph on the | ||
* selected node. | ||
* @param {Object} d3Node - node to focus the graph view on. | ||
* @param {Object} config - same as {@link #graphrenderer|config in renderGraph}. | ||
* @returns {string} transform rule to apply. | ||
* @memberof Graph/helper | ||
*/ | ||
function getCenterAndZoomTransformation(d3Node, config) { | ||
if (!d3Node) { | ||
return; | ||
} | ||
var width = config.width, | ||
height = config.height, | ||
focusZoom = config.focusZoom; | ||
return "\n translate(" + width / 2 + ", " + height / 2 + ")\n scale(" + focusZoom + ")\n translate(" + -d3Node.x + ", " + -d3Node.y + ")\n "; | ||
} | ||
/** | ||
* Encapsulates common procedures to initialize graph. | ||
@@ -491,3 +361,3 @@ * @param {Object} props - Graph component props, object that holds data, id and config. | ||
* @param {string} props.id - the graph id. | ||
* @param {Object} props.config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Object} props.config - same as {@link #graphrenderer|config in renderGraph}. | ||
* @param {Object} state - Graph component current state (same format as returned object on this function). | ||
@@ -527,4 +397,4 @@ * @returns {Object} a fully (re)initialized graph state object. | ||
var newConfig = Object.assign({}, _utils2.default.merge(_graph5.default, config || {})); | ||
var nodes = _initializeNodes(graph.nodes); | ||
var links = _initializeLinks(graph.links, newConfig); // matrix of graph connections | ||
var nodes = _tagOrphanNodes(_initializeNodes(graph.nodes), links); | ||
var _graph = graph, | ||
@@ -534,3 +404,3 @@ d3Nodes = _graph.nodes, | ||
var formatedId = id.replace(/ /g, '_'); | ||
var formatedId = id.replace(/ /g, "_"); | ||
var simulation = _createForceSimulation(newConfig.width, newConfig.height, newConfig.d3 && newConfig.d3.gravity); | ||
@@ -556,3 +426,3 @@ | ||
d3Nodes: d3Nodes, | ||
highlightedNode: '', | ||
highlightedNode: "", | ||
simulation: simulation, | ||
@@ -579,3 +449,3 @@ newGraphElements: false, | ||
var highlightedNode = value ? id : ''; | ||
var highlightedNode = value ? id : ""; | ||
var node = Object.assign({}, nodes[id], { highlighted: value }); | ||
@@ -599,29 +469,6 @@ var updatedNodes = Object.assign({}, nodes, _defineProperty({}, id, node)); | ||
/** | ||
* Returns the transformation to apply in order to center the graph on the | ||
* selected node. | ||
* @param {Object} d3Node - node to focus the graph view on. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @returns {string} transform rule to apply. | ||
* @memberof Graph/helper | ||
*/ | ||
function getCenterAndZoomTransformation(d3Node, config) { | ||
if (!d3Node) { | ||
return; | ||
} | ||
var width = config.width, | ||
height = config.height, | ||
focusZoom = config.focusZoom; | ||
return '\n translate(' + width / 2 + ', ' + height / 2 + ')\n scale(' + focusZoom + ')\n translate(' + -d3Node.x + ', ' + -d3Node.y + ')\n '; | ||
} | ||
exports.buildLinkProps = buildLinkProps; | ||
exports.buildNodeProps = buildNodeProps; | ||
exports.checkForGraphConfigChanges = checkForGraphConfigChanges; | ||
exports.checkForGraphElementsChanges = checkForGraphElementsChanges; | ||
exports.getCenterAndZoomTransformation = getCenterAndZoomTransformation; | ||
exports.initializeGraphState = initializeGraphState; | ||
exports.updateNodeHighlightedValue = updateNodeHighlightedValue; | ||
exports.getCenterAndZoomTransformation = getCenterAndZoomTransformation; | ||
exports.updateNodeHighlightedValue = updateNodeHighlightedValue; |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -11,39 +11,39 @@ Object.defineProperty(exports, "__esModule", { | ||
var _react = require('react'); | ||
var _react = require("react"); | ||
var _react2 = _interopRequireDefault(_react); | ||
var _d3Drag = require('d3-drag'); | ||
var _d3Drag = require("d3-drag"); | ||
var _d3Force = require('d3-force'); | ||
var _d3Force = require("d3-force"); | ||
var _d3Selection = require('d3-selection'); | ||
var _d3Selection = require("d3-selection"); | ||
var _d3Zoom = require('d3-zoom'); | ||
var _d3Zoom = require("d3-zoom"); | ||
var _graph = require('./graph.const'); | ||
var _graph = require("./graph.const"); | ||
var _graph2 = _interopRequireDefault(_graph); | ||
var _graph3 = require('./graph.config'); | ||
var _graph3 = require("./graph.config"); | ||
var _graph4 = _interopRequireDefault(_graph3); | ||
var _err = require('../../err'); | ||
var _err = require("../../err"); | ||
var _err2 = _interopRequireDefault(_err); | ||
var _collapse = require('./collapse.helper'); | ||
var _collapse = require("./collapse.helper"); | ||
var collapseHelper = _interopRequireWildcard(_collapse); | ||
var _graph5 = require('./graph.helper'); | ||
var _graph5 = require("./graph.helper"); | ||
var graphHelper = _interopRequireWildcard(_graph5); | ||
var _graph6 = require('./graph.renderer'); | ||
var _graph6 = require("./graph.renderer"); | ||
var graphRenderer = _interopRequireWildcard(_graph6); | ||
var _utils = require('../../utils'); | ||
var _utils = require("../../utils"); | ||
@@ -152,4 +152,5 @@ var _utils2 = _interopRequireDefault(_utils); | ||
_createClass(Graph, [{ | ||
key: '_graphForcesConfig', | ||
key: "_graphForcesConfig", | ||
/** | ||
@@ -160,3 +161,3 @@ * 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); | ||
this.state.simulation.nodes(this.state.d3Nodes).on("tick", this._tick); | ||
@@ -169,5 +170,5 @@ var forceLink = (0, _d3Force.forceLink)(this.state.d3Links).id(function (l) { | ||
var customNodeDrag = (0, _d3Drag.drag)().on('start', this._onDragStart).on('drag', this._onDragMove).on('end', this._onDragEnd); | ||
var customNodeDrag = (0, _d3Drag.drag)().on("start", this._onDragStart).on("drag", this._onDragMove).on("end", this._onDragEnd); | ||
(0, _d3Selection.select)('#' + this.state.id + '-' + _graph2.default.GRAPH_WRAPPER_ID).selectAll('.node').call(customNodeDrag); | ||
(0, _d3Selection.select)("#" + this.state.id + "-" + _graph2.default.GRAPH_WRAPPER_ID).selectAll(".node").call(customNodeDrag); | ||
} | ||
@@ -180,3 +181,10 @@ | ||
/** | ||
* Obtain a set of properties which will be used to perform the focus and zoom animation if | ||
* required. In case there's not a focus and zoom animation in progress, it should reset the | ||
* transition duration to zero and clear transformation styles. | ||
* @returns {Object} - Focus and zoom animation properties. | ||
*/ | ||
/** | ||
@@ -230,2 +238,16 @@ * Handles d3 'drag' event. | ||
/** | ||
* Calls the callback passed to the component. | ||
* @param {Object} e - The event of onClick handler. | ||
* @returns {undefined} | ||
*/ | ||
/** | ||
* Collapses the nodes, then calls the callback passed to the component. | ||
* @param {string} clickedNodeId - The id of the node where the click was performed. | ||
* @returns {undefined} | ||
*/ | ||
/** | ||
* Handles mouse over node event. | ||
@@ -288,2 +310,25 @@ * @param {string} id - id of the node that participates in the event. | ||
_this._generateFocusAnimationProps = function () { | ||
var focusedNodeId = _this.state.focusedNodeId; | ||
// In case an older animation was still not complete, clear previous timeout to ensure the new one is not cancelled | ||
if (_this.state.enableFocusAnimation) { | ||
if (_this.focusAnimationTimeout) { | ||
clearTimeout(_this.focusAnimationTimeout); | ||
} | ||
_this.focusAnimationTimeout = setTimeout(function () { | ||
return _this.setState({ enableFocusAnimation: false }); | ||
}, _this.state.config.focusAnimationDuration * 1000); | ||
} | ||
var transitionDuration = _this.state.enableFocusAnimation ? _this.state.config.focusAnimationDuration : 0; | ||
return { | ||
style: { transitionDuration: transitionDuration + "s" }, | ||
transform: focusedNodeId ? _this.state.focusTransformation : null | ||
}; | ||
}; | ||
_this._onDragEnd = function () { | ||
@@ -304,4 +349,4 @@ return !_this.state.config.staticGraph && _this.state.config.automaticRearrangeAfterDropNode && _this.state.simulation.alphaTarget(_this.state.config.d3.alphaTarget).restart(); | ||
// set nodes fixing coords fx and fy | ||
draggedNode['fx'] = draggedNode.x; | ||
draggedNode['fy'] = draggedNode.y; | ||
draggedNode["fx"] = draggedNode.x; | ||
draggedNode["fy"] = draggedNode.y; | ||
@@ -331,3 +376,3 @@ _this._tick(); | ||
_this._zoomConfig = function () { | ||
return (0, _d3Selection.select)('#' + _this.state.id + '-' + _graph2.default.GRAPH_WRAPPER_ID).call((0, _d3Zoom.zoom)().scaleExtent([_this.state.config.minZoom, _this.state.config.maxZoom]).on('zoom', _this._zoomed)); | ||
return (0, _d3Selection.select)("#" + _this.state.id + "-" + _graph2.default.GRAPH_WRAPPER_ID).call((0, _d3Zoom.zoom)().scaleExtent([_this.state.config.minZoom, _this.state.config.maxZoom]).on("zoom", _this._zoomed)); | ||
}; | ||
@@ -338,3 +383,3 @@ | ||
(0, _d3Selection.selectAll)('#' + _this.state.id + '-' + _graph2.default.GRAPH_CONTAINER_ID).attr('transform', transform); | ||
(0, _d3Selection.selectAll)("#" + _this.state.id + "-" + _graph2.default.GRAPH_CONTAINER_ID).attr("transform", transform); | ||
@@ -344,2 +389,32 @@ _this.state.config.panAndZoom && _this.setState({ transform: transform.k }); | ||
_this.onClickGraph = function (e) { | ||
if (_this.state.enableFocusAnimation) { | ||
_this.setState({ enableFocusAnimation: false }); | ||
} | ||
// Only trigger the graph onClickHandler, if not clicked a node or link. | ||
// toUpperCase() is added as a precaution, as the documentation says tagName should always | ||
// return in UPPERCASE, but chrome returns lowercase | ||
if (e.target.tagName.toUpperCase() === "SVG" && e.target.attributes.name.value === "svg-container-" + _this.state.id) { | ||
_this.props.onClickGraph && _this.props.onClickGraph(); | ||
} | ||
}; | ||
_this.onClickNode = function (clickedNodeId) { | ||
if (_this.state.config.collapsible) { | ||
var leafConnections = collapseHelper.getTargetLeafConnections(clickedNodeId, _this.state.links, _this.state.config); | ||
var links = collapseHelper.toggleLinksMatrixConnections(_this.state.links, leafConnections, _this.state.config); | ||
var d3Links = collapseHelper.toggleLinksConnections(_this.state.d3Links, links); | ||
_this._tick({ | ||
links: links, | ||
d3Links: d3Links | ||
}, function () { | ||
return _this.props.onClickNode && _this.props.onClickNode(clickedNodeId); | ||
}); | ||
} else { | ||
_this.props.onClickNode && _this.props.onClickNode(clickedNodeId); | ||
} | ||
}; | ||
_this.onMouseOverNode = function (id) { | ||
@@ -387,4 +462,4 @@ _this.props.onMouseOverNode && _this.props.onMouseOverNode(id); | ||
if (node.fx && node.fy) { | ||
Reflect.deleteProperty(node, 'fx'); | ||
Reflect.deleteProperty(node, 'fy'); | ||
Reflect.deleteProperty(node, "fx"); | ||
Reflect.deleteProperty(node, "fy"); | ||
} | ||
@@ -403,55 +478,2 @@ } | ||
_this.onClickNode = function (clickedNodeId) { | ||
if (_this.state.config.collapsible) { | ||
var leafConnections = collapseHelper.getTargetLeafConnections(clickedNodeId, _this.state.links, _this.state.config); | ||
var links = collapseHelper.toggleLinksMatrixConnections(_this.state.links, leafConnections, _this.state.config); | ||
var d3Links = collapseHelper.toggleLinksConnections(_this.state.d3Links, links); | ||
_this._tick({ | ||
links: links, | ||
d3Links: d3Links | ||
}, function () { | ||
return _this.props.onClickNode && _this.props.onClickNode(clickedNodeId); | ||
}); | ||
} else { | ||
_this.props.onClickNode && _this.props.onClickNode(clickedNodeId); | ||
} | ||
}; | ||
_this.onClickGraph = function (e) { | ||
if (_this.state.enableFocusAnimation) { | ||
_this.setState({ enableFocusAnimation: false }); | ||
} | ||
// Only trigger the graph onClickHandler, if not clicked a node or link. | ||
// toUpperCase() is added as a precaution, as the documentation says tagName should always | ||
// return in UPPERCASE, but chrome returns lowercase | ||
if (e.target.tagName.toUpperCase() === 'SVG' && e.target.attributes.name.value === 'svg-container-' + _this.state.id) { | ||
_this.props.onClickGraph && _this.props.onClickGraph(); | ||
} | ||
}; | ||
_this._generateFocusAnimationProps = function () { | ||
var focusedNodeId = _this.state.focusedNodeId; | ||
// In case an older animation was still not complete, clear previous timeout to ensure the new one is not cancelled | ||
if (_this.state.enableFocusAnimation) { | ||
if (_this.focusAnimationTimeout) { | ||
clearTimeout(_this.focusAnimationTimeout); | ||
} | ||
_this.focusAnimationTimeout = setTimeout(function () { | ||
return _this.setState({ enableFocusAnimation: false }); | ||
}, _this.state.config.focusAnimationDuration * 1000); | ||
} | ||
var transitionDuration = _this.state.enableFocusAnimation ? _this.state.config.focusAnimationDuration : 0; | ||
return { | ||
style: { transitionDuration: transitionDuration + 's' }, | ||
transform: focusedNodeId ? _this.state.focusTransformation : null | ||
}; | ||
}; | ||
if (!_this.props.id) { | ||
@@ -479,3 +501,3 @@ _utils2.default.throwErr(_this.constructor.name, _err2.default.GRAPH_NO_ID_PROP); | ||
_createClass(Graph, [{ | ||
key: 'componentWillReceiveProps', | ||
key: "componentWillReceiveProps", | ||
value: function componentWillReceiveProps(nextProps) { | ||
@@ -502,3 +524,3 @@ var _graphHelper$checkFor = graphHelper.checkForGraphElementsChanges(nextProps, this.state), | ||
var d3FocusedNode = this.state.d3Nodes.find(function (node) { | ||
return '' + node.id === '' + focusedNodeId; | ||
return "" + node.id === "" + focusedNodeId; | ||
}); | ||
@@ -520,3 +542,3 @@ var focusTransformation = graphHelper.getCenterAndZoomTransformation(d3FocusedNode, this.state.config); | ||
}, { | ||
key: 'componentDidUpdate', | ||
key: "componentDidUpdate", | ||
value: function componentDidUpdate() { | ||
@@ -538,3 +560,3 @@ // if the property staticGraph was activated we want to stop possible ongoing simulation | ||
}, { | ||
key: 'componentDidMount', | ||
key: "componentDidMount", | ||
value: function componentDidMount() { | ||
@@ -549,32 +571,10 @@ if (!this.state.config.staticGraph) { | ||
}, { | ||
key: 'componentWillUnmount', | ||
key: "componentWillUnmount", | ||
value: function componentWillUnmount() { | ||
this.pauseSimulation(); | ||
} | ||
/** | ||
* Collapses the nodes, then calls the callback passed to the component. | ||
* @param {string} clickedNodeId - The id of the node where the click was performed. | ||
* @returns {undefined} | ||
*/ | ||
/** | ||
* Calls the callback passed to the component. | ||
* @param {Object} e - The event of onClick handler. | ||
* @returns {undefined} | ||
*/ | ||
/** | ||
* Obtain a set of properties which will be used to perform the focus and zoom animation if | ||
* required. In case there's not a focus and zoom animation in progress, it should reset the | ||
* transition duration to zero and clear transformation styles. | ||
* @returns {Object} - Focus and zoom animation properties. | ||
*/ | ||
}, { | ||
key: 'render', | ||
key: "render", | ||
value: function render() { | ||
var _graphRenderer$buildG = graphRenderer.buildGraph(this.state.nodes, { | ||
var _graphRenderer$render = graphRenderer.renderGraph(this.state.nodes, { | ||
onClickNode: this.onClickNode, | ||
@@ -590,5 +590,5 @@ onRightClickNode: this.props.onRightClickNode, | ||
}, this.state.config, this.state.highlightedNode, this.state.highlightedLink, this.state.transform), | ||
nodes = _graphRenderer$buildG.nodes, | ||
links = _graphRenderer$buildG.links, | ||
defs = _graphRenderer$buildG.defs; | ||
nodes = _graphRenderer$render.nodes, | ||
links = _graphRenderer$render.links, | ||
defs = _graphRenderer$render.defs; | ||
@@ -603,11 +603,11 @@ var svgStyle = { | ||
return _react2.default.createElement( | ||
'div', | ||
{ id: this.state.id + '-' + _graph2.default.GRAPH_WRAPPER_ID }, | ||
"div", | ||
{ id: this.state.id + "-" + _graph2.default.GRAPH_WRAPPER_ID }, | ||
_react2.default.createElement( | ||
'svg', | ||
{ name: 'svg-container-' + this.state.id, style: svgStyle, onClick: this.onClickGraph }, | ||
"svg", | ||
{ name: "svg-container-" + this.state.id, style: svgStyle, onClick: this.onClickGraph }, | ||
defs, | ||
_react2.default.createElement( | ||
'g', | ||
_extends({ id: this.state.id + '-' + _graph2.default.GRAPH_CONTAINER_ID }, containerProps), | ||
"g", | ||
_extends({ id: this.state.id + "-" + _graph2.default.GRAPH_CONTAINER_ID }, containerProps), | ||
links, | ||
@@ -614,0 +614,0 @@ nodes |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -6,3 +6,3 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
exports.buildGraph = undefined; | ||
exports.renderGraph = undefined; | ||
@@ -16,27 +16,27 @@ var _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; }; /** | ||
var _react = require('react'); | ||
var _react = require("react"); | ||
var _react2 = _interopRequireDefault(_react); | ||
var _graph = require('./graph.const'); | ||
var _graph = require("./graph.const"); | ||
var _graph2 = _interopRequireDefault(_graph); | ||
var _marker = require('../marker/marker.const'); | ||
var _marker = require("../marker/marker.const"); | ||
var _Link = require('../link/Link'); | ||
var _Link = require("../link/Link"); | ||
var _Link2 = _interopRequireDefault(_Link); | ||
var _Node = require('../node/Node'); | ||
var _Node = require("../node/Node"); | ||
var _Node2 = _interopRequireDefault(_Node); | ||
var _Marker = require('../marker/Marker'); | ||
var _Marker = require("../marker/Marker"); | ||
var _Marker2 = _interopRequireDefault(_Marker); | ||
var _graph3 = require('./graph.helper'); | ||
var _graph3 = require("./graph.builder"); | ||
var _collapse = require('./collapse.helper'); | ||
var _collapse = require("./collapse.helper"); | ||
@@ -47,14 +47,14 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
* Build Link components given a list of links. | ||
* @param {Object.<string, Object>} nodes - same as {@link #buildGraph|nodes in buildGraph}. | ||
* @param {Object.<string, Object>} nodes - same as {@link #graphrenderer|nodes in renderGraph}. | ||
* @param {Array.<Object>} links - array of links {@link #Link|Link}. | ||
* @param {Array.<Object>} linksMatrix - array of links {@link #Link|Link}. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Function[]} linkCallbacks - same as {@link #buildGraph|linkCallbacks in buildGraph}. | ||
* @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 #graphrenderer|config in renderGraph}. | ||
* @param {Function[]} linkCallbacks - same as {@link #graphrenderer|linkCallbacks in renderGraph}. | ||
* @param {string} highlightedNode - same as {@link #graphrenderer|highlightedNode in renderGraph}. | ||
* @param {Object} highlightedLink - same as {@link #graphrenderer|highlightedLink in renderGraph}. | ||
* @param {number} transform - value that indicates the amount of zoom transformation. | ||
* @returns {Array.<Object>} returns the generated array of Link components. | ||
* @memberof Graph/helper | ||
* @memberof Graph/renderer | ||
*/ | ||
function _buildLinks(nodes, links, linksMatrix, config, linkCallbacks, highlightedNode, highlightedLink, transform) { | ||
function _renderLinks(nodes, links, linksMatrix, config, linkCallbacks, highlightedNode, highlightedLink, transform) { | ||
var outLinks = links; | ||
@@ -74,8 +74,8 @@ | ||
var sourceId = source.id || source; | ||
var targetId = target.id || target; | ||
var key = '' + sourceId + _graph2.default.COORDS_SEPARATOR + targetId; | ||
var props = (0, _graph3.buildLinkProps)(_extends({}, link, { source: '' + sourceId, target: '' + targetId }), nodes, linksMatrix, config, linkCallbacks, '' + highlightedNode, highlightedLink, transform); | ||
var sourceId = source.id !== undefined && source.id !== null ? source.id : source; | ||
var targetId = target.id !== undefined && target.id !== null ? target.id : target; | ||
var key = "" + sourceId + _graph2.default.COORDS_SEPARATOR + targetId; | ||
var props = (0, _graph3.buildLinkProps)(_extends({}, link, { source: "" + sourceId, target: "" + targetId }), nodes, linksMatrix, config, linkCallbacks, "" + highlightedNode, highlightedLink, transform); | ||
return _react2.default.createElement(_Link2.default, _extends({ key: key }, props)); | ||
return _react2.default.createElement(_Link2.default, _extends({ key: key, id: key }, props)); | ||
}); | ||
@@ -96,5 +96,5 @@ } | ||
* @returns {Array.<Object>} returns the generated array of node components | ||
* @memberof Graph/helper | ||
* @memberof Graph/renderer | ||
*/ | ||
function _buildNodes(nodes, nodeCallbacks, config, highlightedNode, highlightedLink, transform, linksMatrix) { | ||
function _renderNodes(nodes, nodeCallbacks, config, highlightedNode, highlightedLink, transform, linksMatrix) { | ||
var outNodes = Object.keys(nodes); | ||
@@ -104,3 +104,3 @@ | ||
outNodes = outNodes.filter(function (nodeId) { | ||
return (0, _collapse.isNodeVisible)(nodeId, linksMatrix); | ||
return (0, _collapse.isNodeVisible)(nodeId, nodes, linksMatrix); | ||
}); | ||
@@ -110,3 +110,3 @@ } | ||
return outNodes.map(function (nodeId) { | ||
var props = (0, _graph3.buildNodeProps)(Object.assign({}, nodes[nodeId], { id: '' + nodeId }), config, nodeCallbacks, highlightedNode, highlightedLink, transform); | ||
var props = (0, _graph3.buildNodeProps)(Object.assign({}, nodes[nodeId], { id: "" + nodeId }), config, nodeCallbacks, highlightedNode, highlightedLink, transform); | ||
@@ -122,5 +122,5 @@ return _react2.default.createElement(_Node2.default, _extends({ key: nodeId }, props)); | ||
* @returns {Function} memoized build definitions function. | ||
* @memberof Graph/helper | ||
* @memberof Graph/renderer | ||
*/ | ||
function _buildDefs() { | ||
function _renderDefs() { | ||
var cachedDefs = void 0; | ||
@@ -138,3 +138,3 @@ | ||
cachedDefs = _react2.default.createElement( | ||
'defs', | ||
"defs", | ||
null, | ||
@@ -154,8 +154,8 @@ _react2.default.createElement(_Marker2.default, { id: _marker.MARKERS.MARKER_S, refX: small, fill: config.link.color }), | ||
/** | ||
* Memoized reference for _buildDefs. | ||
* Memoized reference for _renderDefs. | ||
* @param {Object} config - an object containing rd3g consumer defined configurations {@link #config config} for the graph. | ||
* @returns {Object} graph reusable objects [defs](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs). | ||
* @memberof Graph/helper | ||
* @memberof Graph/renderer | ||
*/ | ||
var _memoizedBuildDefs = _buildDefs(); | ||
var _memoizedRenderDefs = _renderDefs(); | ||
@@ -203,10 +203,10 @@ /** | ||
*/ | ||
function buildGraph(nodes, nodeCallbacks, links, linksMatrix, linkCallbacks, config, highlightedNode, highlightedLink, transform) { | ||
function renderGraph(nodes, nodeCallbacks, links, linksMatrix, linkCallbacks, config, highlightedNode, highlightedLink, transform) { | ||
return { | ||
nodes: _buildNodes(nodes, nodeCallbacks, config, highlightedNode, highlightedLink, transform, linksMatrix), | ||
links: _buildLinks(nodes, links, linksMatrix, config, linkCallbacks, highlightedNode, highlightedLink, transform), | ||
defs: _memoizedBuildDefs(config) | ||
nodes: _renderNodes(nodes, nodeCallbacks, config, highlightedNode, highlightedLink, transform, linksMatrix), | ||
links: _renderLinks(nodes, links, linksMatrix, config, linkCallbacks, highlightedNode, highlightedLink, transform), | ||
defs: _memoizedRenderDefs(config) | ||
}; | ||
} | ||
exports.buildGraph = buildGraph; | ||
exports.renderGraph = renderGraph; |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -19,7 +19,7 @@ Object.defineProperty(exports, "__esModule", { | ||
var LINE_TYPES = { | ||
STRAIGHT: 'STRAIGHT', | ||
CURVE_SMOOTH: 'CURVE_SMOOTH', | ||
CURVE_FULL: 'CURVE_FULL' | ||
STRAIGHT: "STRAIGHT", | ||
CURVE_SMOOTH: "CURVE_SMOOTH", | ||
CURVE_FULL: "CURVE_FULL" | ||
}; | ||
exports.LINE_TYPES = LINE_TYPES; |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -10,3 +10,3 @@ Object.defineProperty(exports, "__esModule", { | ||
var _link = require('./link.const'); | ||
var _link = require("./link.const"); | ||
@@ -93,5 +93,5 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } /** | ||
return 'M' + sx + ',' + sy + 'A' + radius + ',' + radius + ' 0 0,1 ' + tx + ',' + ty; | ||
return "M" + sx + "," + sy + "A" + radius + "," + radius + " 0 0,1 " + tx + "," + ty; | ||
} | ||
exports.buildLinkPathDefinition = buildLinkPathDefinition; |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -7,5 +7,7 @@ Object.defineProperty(exports, "__esModule", { | ||
var _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; }; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
var _react = require('react'); | ||
var _react = require("react"); | ||
@@ -43,10 +45,10 @@ var _react2 = _interopRequireDefault(_react); | ||
* d="M1..." | ||
* source='idSourceNode' | ||
* target='idTargetNode' | ||
* markerId='marker-small' | ||
* source="idSourceNode" | ||
* target="idTargetNode" | ||
* markerId="marker-small" | ||
* strokeWidth=1.5 | ||
* stroke='green' | ||
* className='link' | ||
* stroke="green" | ||
* className="link" | ||
* opacity=1 | ||
* mouseCursor='pointer' | ||
* mouseCursor="pointer" | ||
* onClickLink={onClickLink} | ||
@@ -107,3 +109,3 @@ * onRightClickLink={onRightClickLink} | ||
_createClass(Link, [{ | ||
key: 'render', | ||
key: "render", | ||
value: function render() { | ||
@@ -114,3 +116,3 @@ var lineStyle = { | ||
opacity: this.props.opacity, | ||
fill: 'none', | ||
fill: "none", | ||
cursor: this.props.mouseCursor | ||
@@ -130,6 +132,32 @@ }; | ||
if (this.props.markerId) { | ||
lineProps.markerEnd = 'url(#' + this.props.markerId + ')'; | ||
lineProps.markerEnd = "url(#" + this.props.markerId + ")"; | ||
} | ||
return _react2.default.createElement('path', lineProps); | ||
var _props = this.props, | ||
label = _props.label, | ||
id = _props.id; | ||
var textProps = { | ||
dy: -1, | ||
style: { | ||
fill: this.props.fontColor, | ||
fontSize: this.props.fontSize, | ||
fontWeight: this.props.fontWeight | ||
} | ||
}; | ||
return _react2.default.createElement( | ||
"svg", | ||
null, | ||
_react2.default.createElement("path", _extends({}, lineProps, { id: id })), | ||
label && _react2.default.createElement( | ||
"text", | ||
_extends({ style: { textAnchor: "middle" } }, textProps), | ||
_react2.default.createElement( | ||
"textPath", | ||
{ href: "#" + id, startOffset: "50%" }, | ||
label | ||
) | ||
) | ||
); | ||
} | ||
@@ -136,0 +164,0 @@ }]); |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -6,3 +6,3 @@ Object.defineProperty(exports, "__esModule", { | ||
}); | ||
var HIGHLIGHTED = 'H'; | ||
var HIGHLIGHTED = "H"; | ||
var MARKER_SMALL_SIZE = 16; | ||
@@ -13,14 +13,14 @@ var MARKER_MEDIUM_OFFSET = 2; | ||
var MARKERS = { | ||
MARKER_S: 'marker-small', | ||
MARKER_SH: 'marker-small-highlighted', | ||
MARKER_M: 'marker-medium', | ||
MARKER_MH: 'marker-medium-highlighted', | ||
MARKER_L: 'marker-large', | ||
MARKER_LH: 'marker-large-highlighted' | ||
MARKER_S: "marker-small", | ||
MARKER_SH: "marker-small-highlighted", | ||
MARKER_M: "marker-medium", | ||
MARKER_MH: "marker-medium-highlighted", | ||
MARKER_L: "marker-large", | ||
MARKER_LH: "marker-large-highlighted" | ||
}; | ||
// hard coded aggregation of the different sizes available for markers | ||
var SIZES = { | ||
S: 'S', | ||
M: 'M', | ||
L: 'L' | ||
S: "S", | ||
M: "M", | ||
L: "L" | ||
}; | ||
@@ -27,0 +27,0 @@ |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -8,3 +8,3 @@ Object.defineProperty(exports, "__esModule", { | ||
var _marker = require('./marker.const'); | ||
var _marker = require("./marker.const"); | ||
@@ -20,3 +20,3 @@ /** | ||
function _markerKeyBuilder(size, highlighted) { | ||
return 'MARKER_' + size + highlighted; | ||
return "MARKER_" + size + highlighted; | ||
} | ||
@@ -63,3 +63,3 @@ | ||
var size = _getMarkerSize(transform, mMax, lMax); | ||
var highlighted = highlight ? _marker.HIGHLIGHTED : ''; | ||
var highlighted = highlight ? _marker.HIGHLIGHTED : ""; | ||
var markerKey = _markerKeyBuilder(size, highlighted); | ||
@@ -84,3 +84,3 @@ | ||
var cacheKey = highlight + ';' + transform + ';' + maxZoom; | ||
var cacheKey = highlight + ";" + transform + ";" + maxZoom; | ||
@@ -87,0 +87,0 @@ if (cache[cacheKey]) { |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -9,7 +9,7 @@ Object.defineProperty(exports, "__esModule", { | ||
var _graph = require('../graph/graph.config'); | ||
var _graph = require("../graph/graph.config"); | ||
var _graph2 = _interopRequireDefault(_graph); | ||
var _const = require('../../const'); | ||
var _const = require("../../const"); | ||
@@ -26,4 +26,4 @@ var _const2 = _interopRequireDefault(_const); | ||
DEFAULT_NODE_SIZE: _graph2.default.node.size, | ||
NODE_LABEL_DX: '.90em', | ||
NODE_LABEL_DY: '.35em' | ||
NODE_LABEL_DX: ".90em", | ||
NODE_LABEL_DY: ".35em" | ||
}, _const2.default); |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -7,5 +7,5 @@ Object.defineProperty(exports, "__esModule", { | ||
var _d3Shape = require('d3-shape'); | ||
var _d3Shape = require("d3-shape"); | ||
var _node = require('./node.const'); | ||
var _node = require("./node.const"); | ||
@@ -12,0 +12,0 @@ var _node2 = _interopRequireDefault(_node); |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -11,11 +11,11 @@ Object.defineProperty(exports, "__esModule", { | ||
var _react = require('react'); | ||
var _react = require("react"); | ||
var _react2 = _interopRequireDefault(_react); | ||
var _node = require('./node.const'); | ||
var _node = require("./node.const"); | ||
var _node2 = _interopRequireDefault(_node); | ||
var _node3 = require('./node.helper'); | ||
var _node3 = require("./node.helper"); | ||
@@ -125,3 +125,3 @@ var _node4 = _interopRequireDefault(_node3); | ||
_createClass(Node, [{ | ||
key: 'render', | ||
key: "render", | ||
value: function render() { | ||
@@ -157,6 +157,6 @@ var nodeProps = { | ||
var ty = height / 2; | ||
var transform = 'translate(' + tx + ',' + ty + ')'; | ||
var transform = "translate(" + tx + "," + ty + ")"; | ||
label = _react2.default.createElement( | ||
'text', | ||
"text", | ||
_extends({}, textProps, { transform: transform }), | ||
@@ -169,10 +169,10 @@ this.props.label | ||
node = _react2.default.createElement( | ||
'svg', | ||
"svg", | ||
_extends({}, nodeProps, { width: width, height: height }), | ||
_react2.default.createElement( | ||
'foreignObject', | ||
{ x: '0', y: '0', width: '100%', height: '100%' }, | ||
"foreignObject", | ||
{ x: "0", y: "0", width: "100%", height: "100%" }, | ||
_react2.default.createElement( | ||
'section', | ||
{ style: { height: height, width: width, backgroundColor: 'transparent' } }, | ||
"section", | ||
{ style: { height: height, width: width, backgroundColor: "transparent" } }, | ||
this.props.viewGenerator(this.props) | ||
@@ -183,3 +183,3 @@ ) | ||
} else { | ||
node = _react2.default.createElement('image', _extends({}, nodeProps, { href: this.props.svg, width: width, height: height })); | ||
node = _react2.default.createElement("image", _extends({}, nodeProps, { href: this.props.svg, width: width, height: height })); | ||
} | ||
@@ -197,7 +197,7 @@ | ||
label = _react2.default.createElement( | ||
'text', | ||
"text", | ||
textProps, | ||
this.props.label | ||
); | ||
node = _react2.default.createElement('path', nodeProps); | ||
node = _react2.default.createElement("path", nodeProps); | ||
} | ||
@@ -210,7 +210,7 @@ | ||
id: this.props.id, | ||
transform: 'translate(' + gtx + ',' + gty + ')' | ||
transform: "translate(" + gtx + "," + gty + ")" | ||
}; | ||
return _react2.default.createElement( | ||
'g', | ||
"g", | ||
gProps, | ||
@@ -217,0 +217,0 @@ node, |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -13,10 +13,10 @@ Object.defineProperty(exports, "__esModule", { | ||
SYMBOLS: { | ||
CIRCLE: 'circle', | ||
CROSS: 'cross', | ||
DIAMOND: 'diamond', | ||
SQUARE: 'square', | ||
STAR: 'star', | ||
TRIANGLE: 'triangle', | ||
WYE: 'wye' | ||
CIRCLE: "circle", | ||
CROSS: "cross", | ||
DIAMOND: "diamond", | ||
SQUARE: "square", | ||
STAR: "star", | ||
TRIANGLE: "triangle", | ||
WYE: "wye" | ||
} | ||
}; |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -8,5 +8,6 @@ Object.defineProperty(exports, "__esModule", { | ||
exports.default = { | ||
GRAPH_NO_ID_PROP: 'id prop not defined! id property is mandatory and it should be unique.', | ||
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' | ||
GRAPH_NO_ID_PROP: "id prop not defined! id property is mandatory and it should be unique.", | ||
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", | ||
INVALID_LINK_VALUE: "links 'value' attribute must be of type number" | ||
}; |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -8,11 +8,11 @@ Object.defineProperty(exports, "__esModule", { | ||
var _Graph = require('./components/graph/Graph'); | ||
var _Graph = require("./components/graph/Graph"); | ||
var _Graph2 = _interopRequireDefault(_Graph); | ||
var _Node = require('./components/node/Node'); | ||
var _Node = require("./components/node/Node"); | ||
var _Node2 = _interopRequireDefault(_Node); | ||
var _Link = require('./components/link/Link'); | ||
var _Link = require("./components/link/Link"); | ||
@@ -19,0 +19,0 @@ var _Link2 = _interopRequireDefault(_Link); |
@@ -1,2 +0,2 @@ | ||
'use strict'; | ||
"use strict"; | ||
@@ -28,3 +28,3 @@ Object.defineProperty(exports, "__esModule", { | ||
function _isPropertyNestedObject(o, k) { | ||
return o.hasOwnProperty(k) && _typeof(o[k]) === 'object' && o[k] !== null && !isEmptyObject(o[k]); | ||
return !!o && o.hasOwnProperty(k) && _typeof(o[k]) === "object" && o[k] !== null && !isEmptyObject(o[k]); | ||
} | ||
@@ -108,6 +108,54 @@ | ||
function isEmptyObject(o) { | ||
return !!o && (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === 'object' && !Object.keys(o).length; | ||
return !!o && (typeof o === "undefined" ? "undefined" : _typeof(o)) === "object" && !Object.keys(o).length; | ||
} | ||
/** | ||
* Function to deep clone plain javascript objects. | ||
* @param {Object} o - the object to clone. | ||
* @param {Object} _clone - carries the cloned output throughout the | ||
* recursive calls. Parameter serves only for internal usage. | ||
* @param {number} _depth - this parameter serves only for internal usage. | ||
* @returns {Object} - the cloned object. | ||
* @memberof utils | ||
*/ | ||
function deepClone(o) { | ||
var _clone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
var _depth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; | ||
// TODO: Handle invalid input o is null, undefined, empty object | ||
var oKeys = Object.keys(o); | ||
// TODO: handle arrays | ||
var _iteratorNormalCompletion2 = true; | ||
var _didIteratorError2 = false; | ||
var _iteratorError2 = undefined; | ||
try { | ||
for (var _iterator2 = oKeys[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
var k = _step2.value; | ||
var nested = _isPropertyNestedObject(o, k); | ||
_clone[k] = nested && _depth < MAX_DEPTH ? deepClone(o[k], {}, _depth + 1) : o[k]; | ||
} | ||
} catch (err) { | ||
_didIteratorError2 = true; | ||
_iteratorError2 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion2 && _iterator2.return) { | ||
_iterator2.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError2) { | ||
throw _iteratorError2; | ||
} | ||
} | ||
} | ||
return _clone; | ||
} | ||
/** | ||
* This function merges two objects o1 and o2, where o2 properties override existent o1 properties, and | ||
@@ -134,11 +182,11 @@ * if o2 doesn't posses some o1 property the fallback will be the o1 property. | ||
var _iteratorNormalCompletion2 = true; | ||
var _didIteratorError2 = false; | ||
var _iteratorError2 = undefined; | ||
var _iteratorNormalCompletion3 = true; | ||
var _didIteratorError3 = false; | ||
var _iteratorError3 = undefined; | ||
try { | ||
for (var _iterator2 = Object.keys(o1)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
var k = _step2.value; | ||
for (var _iterator3 = Object.keys(o1)[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) { | ||
var k = _step3.value; | ||
var nestedO = !!(o2[k] && _typeof(o2[k]) === 'object' && _typeof(o1[k]) === 'object' && _depth < MAX_DEPTH); | ||
var nestedO = !!(o2[k] && _typeof(o2[k]) === "object" && _typeof(o1[k]) === "object" && _depth < MAX_DEPTH); | ||
@@ -149,3 +197,3 @@ if (nestedO) { | ||
o[k] = o1[k].hasOwnProperty('length') && o2[k].hasOwnProperty('length') ? Object.keys(r).map(function (rk) { | ||
o[k] = o1[k].hasOwnProperty("length") && o2[k].hasOwnProperty("length") ? Object.keys(r).map(function (rk) { | ||
return r[rk]; | ||
@@ -159,12 +207,12 @@ }) : r; | ||
} catch (err) { | ||
_didIteratorError2 = true; | ||
_iteratorError2 = err; | ||
_didIteratorError3 = true; | ||
_iteratorError3 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion2 && _iterator2.return) { | ||
_iterator2.return(); | ||
if (!_iteratorNormalCompletion3 && _iterator3.return) { | ||
_iterator3.return(); | ||
} | ||
} finally { | ||
if (_didIteratorError2) { | ||
throw _iteratorError2; | ||
if (_didIteratorError3) { | ||
throw _iteratorError3; | ||
} | ||
@@ -222,3 +270,3 @@ } | ||
function throwErr(component, msg) { | ||
var error = 'react-d3-graph :: ' + component + ' :: ' + msg; | ||
var error = "react-d3-graph :: " + component + " :: " + msg; | ||
@@ -231,2 +279,3 @@ throw Error(error); | ||
isEmptyObject: isEmptyObject, | ||
deepClone: deepClone, | ||
merge: merge, | ||
@@ -233,0 +282,0 @@ pick: pick, |
{ | ||
"name": "react-d3-graph", | ||
"version": "2.0.0-rc2", | ||
"version": "2.0.0", | ||
"description": "React component to build interactive and configurable graphs with d3 effortlessly", | ||
@@ -14,3 +14,3 @@ "author": "Daniel Caldas", | ||
"dist:transpile": "./node_modules/babel-cli/bin/babel.js -d lib src", | ||
"dist": "npm run check && node_modules/.bin/npm-run-all --parallel dist:*", | ||
"dist": "npm run check && npm-run-all --parallel dist:*", | ||
"docs:lint": "node_modules/documentation/bin/documentation.js lint src/**/*.js", | ||
@@ -22,4 +22,5 @@ "docs:watch": "node_modules/documentation/bin/documentation.js --config documentation.yml build src/**/*.js -f html -o gen-docs --watch", | ||
"functional": "export CYPRESS_SANDBOX_URL=http://127.0.0.1:8888 && cypress run", | ||
"lint:src": "node_modules/eslint/bin/eslint.js --config=.eslintrc.js \"src/**/*.js*\"", | ||
"lint:test": "node_modules/eslint/bin/eslint.js --config=.eslintrc.test.config.js \"test/**/*.test.js\"", | ||
"lint:fix": "node_modules/eslint/bin/eslint.js --config=.eslintrc.js --fix \"src/**/*.js*\" \"sandbox/**/*.js*\"", | ||
"lint:src": "node_modules/eslint/bin/eslint.js --config=.eslintrc.js \"src/**/*.js*\" \"sandbox/**/*.js*\"", | ||
"lint:test": "node_modules/eslint/bin/eslint.js --config=.eslintrc.test.config.js \"test/**/*.spec.js\"", | ||
"lint": "npm run lint:src && npm run lint:test && npm run docs:lint", | ||
@@ -52,10 +53,8 @@ "precommit": "lint-staged", | ||
"babel-plugin-transform-class-properties": "6.24.1", | ||
"babel-plugin-transform-decorators-legacy": "1.3.4", | ||
"babel-polyfill": "6.26.0", | ||
"babel-preset-es2015": "6.24.1", | ||
"babel-preset-es2017": "6.24.1", | ||
"babel-preset-react": "6.24.1", | ||
"babel-preset-stage-0": "6.24.1", | ||
"babel-preset-stage-2": "6.24.1", | ||
"cross-env": "^5.2.0", | ||
"css-loader": "0.28.7", | ||
"css-loader": "2.0.2", | ||
"cypress": "2.1.0", | ||
@@ -68,2 +67,3 @@ "d3": "^5.5.0", | ||
"eslint-plugin-jest": "21.18.0", | ||
"eslint-plugin-prettier": "^3.0.0", | ||
"eslint-plugin-promise": "3.7.0", | ||
@@ -78,14 +78,16 @@ "eslint-plugin-react": "7.10.0", | ||
"npm-run-all": "4.1.1", | ||
"prettier": "1.11.1", | ||
"prettier": "1.15.3", | ||
"query-string": "6.1.0", | ||
"react": "^16.4.1", | ||
"react-addons-test-utils": "15.6.2", | ||
"react-dom": "16.4.1", | ||
"react-editable-json-tree": "2.2.0", | ||
"react-dom": "^16.4.2", | ||
"react-editable-json-tree": "2.2.1", | ||
"react-jsonschema-form": "1.0.4", | ||
"react-test-renderer": "16.4.1", | ||
"style-loader": "0.18.2", | ||
"webpack": "4.2.0", | ||
"typescript": "^3.2.2", | ||
"webpack": "4.28.1", | ||
"webpack-bundle-analyzer": "^3.0.3", | ||
"webpack-cli": "2.0.12", | ||
"webpack-dev-server": "3.1.3", | ||
"webpack-dev-server": "^3.1.14", | ||
"webpack-visualizer-plugin": "0.1.11" | ||
@@ -92,0 +94,0 @@ }, |
@@ -83,3 +83,3 @@ /** | ||
..._acc, | ||
outDegree: _acc.outDegree + linksMatrix[nodeId][target] | ||
outDegree: _acc.outDegree + linksMatrix[nodeId][target], | ||
}; | ||
@@ -91,3 +91,3 @@ } | ||
..._acc, | ||
inDegree: _acc.inDegree + linksMatrix[source][nodeId] | ||
inDegree: _acc.inDegree + linksMatrix[source][nodeId], | ||
}; | ||
@@ -101,3 +101,3 @@ } | ||
inDegree: 0, | ||
outDegree: 0 | ||
outDegree: 0, | ||
} | ||
@@ -112,3 +112,3 @@ ); | ||
* there is an object that maps adjacent nodes ids (string) and their values (number). | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Object} config - same as {@link #graphrenderer|config in renderGraph}. | ||
* @param {boolean} config.directed - tells whether linksMatrix represents a directed graph or not. | ||
@@ -127,3 +127,3 @@ * @returns {Array.<Object.<string, string>>} a list of leaf connections. | ||
source: rootNodeId, | ||
target | ||
target, | ||
}); | ||
@@ -144,2 +144,3 @@ } | ||
* @param {string} nodeId - The id of the node to get the cardinality of | ||
* @param {Object.<string, Object>} nodes - an object containing all nodes mapped by their id. | ||
* @param {Object.<string, number>} linksMatrix - An object containing a matrix of connections of the nodes. | ||
@@ -149,6 +150,7 @@ * @returns {boolean} flag that indicates whether node should or not be displayed. | ||
*/ | ||
function isNodeVisible(nodeId, linksMatrix) { | ||
function isNodeVisible(nodeId, nodes, linksMatrix) { | ||
const { inDegree, outDegree } = computeNodeDegree(nodeId, linksMatrix); | ||
const orphan = !!nodes[nodeId]._orphan; | ||
return inDegree >= 1 || outDegree >= 1; | ||
return inDegree > 0 || outDegree > 0 || orphan; | ||
} | ||
@@ -180,3 +182,3 @@ | ||
* @param {Array.<Object.<string, string>>} connections - connections to toggle on matrix. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Object} config - same as {@link #graphrenderer|config in renderGraph}. | ||
* @param {boolean} config.directed - tells whether linksMatrix represents a directed graph or not. | ||
@@ -216,3 +218,3 @@ * @returns {Object.<string, Object>} updated linksMatrix | ||
toggleLinksConnections, | ||
toggleLinksMatrixConnections | ||
toggleLinksMatrixConnections, | ||
}; |
/** | ||
* <div style='text-align: right;'><i>This is certainly the only extra piece of documentation that you will ever need</i></div> | ||
* <div style="text-align: right;"><i>This is certainly the only extra piece of documentation that you will ever need</i></div> | ||
* <br/><br/> | ||
@@ -19,6 +19,6 @@ * Here you can consult a detailed description of each graph configurable property as well as the default values | ||
* { | ||
* id: 'id', | ||
* color: 'red', // only this node will be red | ||
* id: "id", | ||
* color: "red", // only this node will be red | ||
* size: 300, // only this node will have size 300 | ||
* symbolType: 'diamond' // only this node will have 'diamond' shape | ||
* symbolType: "diamond" // only this node will have "diamond" shape | ||
* } | ||
@@ -32,3 +32,2 @@ * ], | ||
* | ||
* **Index for config**<br/> | ||
* - <a href="#config-global">Graph global configurations</a> | ||
@@ -39,2 +38,4 @@ * - <a href="#config-d3">d3 level configurations</a> | ||
* | ||
* <br/> | ||
* | ||
* <h2 id="config-global"><a href="#config-global">#</a> Graph global configurations</h2> | ||
@@ -52,15 +53,2 @@ * @param {boolean} [automaticRearrangeAfterDropNode=false] - 🚅🚅🚅 when true performing a node drag and drop should automatically | ||
* <img src="https://github.com/danielcaldas/react-d3-graph/blob/master/docs/rd3g-directed.gif?raw=true" width="820" height="480"/> | ||
* @param {number} [height=400] - the height of the (svg) area where the graph will be rendered. | ||
* @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 | ||
* highlight behavior when some node is highlighted. If the value is set to **0** only the selected node will be | ||
* highlighted. If the value is set to **1** the selected node and his 1st degree connections will be highlighted. If | ||
* the value is set to **2** the selected node will be highlighted as well as the 1st and 2nd common degree connections. | ||
* @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 *nodeHighlightBehavior*). | ||
* @param {number} [maxZoom=8] - max zoom that can be performed against the graph. | ||
* @param {number} [minZoom=0.1] - min zoom that can be performed against the graph. | ||
* @param {number} [focusZoom=1] - zoom that will be applied when the graph view is focused in a node. Its value must be between | ||
@@ -75,3 +63,3 @@ * *minZoom* and *maxZoom*. If the specified *focusZoom* is out of this range, *minZoom* or *maxZoom* will be applied instead. | ||
* links: this.state.data.links, | ||
* focusedNodeId: 'nodeIdToTriggerZoomAnimation' | ||
* focusedNodeId: "nodeIdToTriggerZoomAnimation" | ||
* }; | ||
@@ -83,2 +71,15 @@ * ``` | ||
* @param {number} [focusAnimationDuration=0.75] - duration (in seconds) for the animation that takes place when focusing the graph on a node. | ||
* @param {number} [height=400] - the height of the (svg) area where the graph will be rendered. | ||
* @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 | ||
* highlight behavior when some node is highlighted. If the value is set to **0** only the selected node will be | ||
* highlighted. If the value is set to **1** the selected node and his 1st degree connections will be highlighted. If | ||
* the value is set to **2** the selected node will be highlighted as well as the 1st and 2nd common degree connections. | ||
* @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 *nodeHighlightBehavior*). | ||
* @param {number} [maxZoom=8] - max zoom that can be performed against the graph. | ||
* @param {number} [minZoom=0.1] - min zoom that can be performed against the graph. | ||
* @param {boolean} [panAndZoom=false] - 🚅🚅🚅 pan and zoom effect when performing zoom in the graph, | ||
@@ -97,3 +98,3 @@ * a similar functionality may be consulted {@link https://bl.ocks.org/mbostock/2a39a768b1d4bc00a09650edef75ad39|here}. | ||
* - 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. | ||
* - 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. | ||
@@ -104,19 +105,19 @@ * @param {number} [d3.linkStrength=1] - [see d3-force link.strength](https://github.com/d3/d3-force#link_strength) | ||
* <h2 id="config-node"><a href="#config-node">#</a> Node level configurations</h2> | ||
* @param {string} [node.color='#d3d3d3'] - 🔍🔍🔍 this is the color that will be applied to the node if no **color property** | ||
* is found inside the node itself (yes **you can pass a property 'color' inside the node and that color will override the | ||
* @param {string} [node.color="#d3d3d3"] - 🔍🔍🔍 this is the color that will be applied to the node if no **color property** | ||
* is found inside the node itself (yes **you can pass a property "color" inside the node and that color will override the | ||
* this default one**). | ||
* @param {string} [node.fontColor='black'] - 🔍🔍🔍 fill color for node's <text> svg label. | ||
* @param {number} [node.fontSize=10] - {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-size?v=control|font-size} | ||
* property for all nodes' labels. | ||
* @param {string} [node.fontWeight='normal'] - {@link https://developer.mozilla.org/en/docs/Web/CSS/font-weight?v=control|font-weight} | ||
* property for all nodes' labels. | ||
* @param {string} [node.highlightColor='SAME'] - color for all highlighted nodes (use string 'SAME' if you | ||
* @param {string} [node.fontColor="black"] - 🔍🔍🔍 fill color for node"s <text> svg label. | ||
* @param {number} [node.fontSize=8] - {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-size?v=control|font-size} | ||
* property for all nodes" labels. | ||
* @param {string} [node.fontWeight="normal"] - {@link https://developer.mozilla.org/en/docs/Web/CSS/font-weight?v=control|font-weight} | ||
* property for all nodes" labels. | ||
* @param {string} [node.highlightColor="SAME"] - color for all highlighted nodes (use string "SAME" if you | ||
* want the node to keep its color in highlighted state). | ||
* @param {number} [node.highlightFontSize=8] - fontSize in highlighted state. | ||
* @param {string} [node.highlightFontWeight='normal'] - fontWeight in highlighted state. | ||
* @param {string} [node.highlightStrokeColor='SAME'] - strokeColor in highlighted state. | ||
* @param {number} [node.highlightStrokeWidth=1.5] - strokeWidth in highlighted state. | ||
* @param {string|Function} [node.labelProperty='id'] - this is the node property that will be used in runtime to | ||
* @param {string} [node.highlightFontWeight="normal"] - fontWeight in highlighted state. | ||
* @param {string} [node.highlightStrokeColor="SAME"] - strokeColor in highlighted state. | ||
* @param {number} [node.highlightStrokeWidth="SAME"] - strokeWidth in highlighted state. | ||
* @param {string|Function} [node.labelProperty="id"] - this is the node property that will be used in runtime to | ||
* fetch the label content. You just need to add some property (e.g. firstName) to the node payload and then set | ||
* node.labelProperty to be **'firstName'**. **This can also be a function!**, if you pass a function here it will be called | ||
* node.labelProperty to be **"firstName"**. **This can also be a function!**, if you pass a function here it will be called | ||
* to obtain the `label` value on the fly, as a client you will receive all the node information that you passed down into react-d3-graph, | ||
@@ -127,3 +128,3 @@ * so the signature of the function would be: | ||
* // do stuff to get the final result... | ||
* return 'label string'; | ||
* return "label string"; | ||
* } | ||
@@ -133,23 +134,23 @@ * ``` | ||
* <br/> | ||
* @param {string} [node.mouseCursor='pointer'] - {@link https://developer.mozilla.org/en/docs/Web/CSS/cursor?v=control|cursor} | ||
* @param {string} [node.mouseCursor="pointer"] - {@link https://developer.mozilla.org/en/docs/Web/CSS/cursor?v=control|cursor} | ||
* property for when some node is mouse hovered. | ||
* @param {number} [node.opacity=1] - by default all nodes will have this opacity value. | ||
* @param {number} [node.opacity=1] 🔍🔍🔍 - by default all nodes will have this opacity value. | ||
* @param {boolean} [node.renderLabel=true] - when set to false no labels will appear along side nodes in the | ||
* graph. | ||
* @param {number} [node.size=200] - 🔍🔍🔍 defines the size of all nodes. | ||
* @param {string} [node.strokeColor='none'] - 🔍🔍🔍 this is the stroke color that will be applied to the node if no **strokeColor property** is found inside the node itself (yes **you can pass a property 'strokeColor' inside the node and that stroke color will override this default one** ). | ||
* @param {number} [node.strokeWidth=1.5] - the width of the all node strokes. | ||
* @param {string} [node.svg=''] - 🔍🔍🔍 render custom svg for nodes in alternative to **node.symbolType**. This svg can | ||
* @param {string} [node.strokeColor="none"] - 🔍🔍🔍 this is the stroke color that will be applied to the node if no **strokeColor property** is found inside the node itself (yes **you can pass a property "strokeColor" inside the node and that stroke color will override this default one** ). | ||
* @param {number} [node.strokeWidth=1.5] 🔍🔍🔍 - the width of the all node strokes. | ||
* @param {string} [node.svg=""] - 🔍🔍🔍 render custom svg for nodes in alternative to **node.symbolType**. This svg can | ||
* be provided as a string to either a remote svg resource or for a local one. | ||
* <br/> | ||
* <img src="https://github.com/danielcaldas/react-d3-graph/blob/master/docs/rd3g-custom-svg.gif?raw=true" width="820" height="480"/> | ||
* @param {string} [node.symbolType='circle'] - 🔍🔍🔍 the <span id='node-symbol-type'>shape</span> of the node. | ||
* @param {string} [node.symbolType="circle"] - 🔍🔍🔍 the <span id="node-symbol-type">shape</span> of the node. | ||
* Use the following values under a property **type** inside each node (nodes may have different types, same as colors): | ||
* - 'circle' | ||
* - 'cross' | ||
* - 'diamond' | ||
* - 'square' | ||
* - 'star' | ||
* - 'triangle' | ||
* - 'wye' | ||
* - "circle" | ||
* - "cross" | ||
* - "diamond" | ||
* - "square" | ||
* - "star" | ||
* - "triangle" | ||
* - "wye" | ||
* | ||
@@ -161,9 +162,22 @@ * **[note]** react-d3-graph will map this values to [d3 symbols](https://github.com/d3/d3-shape#symbols) | ||
* <h2 id="config-link"><a href="#config-link">#</a> Link level configurations</h2> | ||
* @param {string} [link.color='#d3d3d3'] - 🚅🚅🚅 the color for links | ||
* @param {string} [link.color="#d3d3d3"] - 🔍🔍🔍 the color for links | ||
* (from version 1.3.0 this property can be configured at link level). | ||
* @param {string} [link.highlightColor='#d3d3d3'] - links' color in highlight state. | ||
* @param {string} [link.fontColor="black"] - 🔍🔍🔍 fill color for link's <text> svg label. | ||
* @param {number} [link.fontSize=8] - {@link https://developer.mozilla.org/en-US/docs/Web/CSS/font-size?v=control|font-size} | ||
* property for all links' labels. | ||
* @param {string} [link.fontWeight="normal"] - {@link https://developer.mozilla.org/en/docs/Web/CSS/font-weight?v=control|font-weight} | ||
* property for all links' labels. | ||
* @param {string} [link.highlightColor="#d3d3d3"] - links' color in highlight state. | ||
* <img src="https://github.com/danielcaldas/react-d3-graph/blob/master/docs/rd3g-bend.gif?raw=true" width="820" height="480"/> | ||
* @param {string} [link.mouseCursor='pointer'] - {@link https://developer.mozilla.org/en/docs/Web/CSS/cursor?v=control|cursor} | ||
* @param {number} [link.highlightFontSize=8] - fontSize in highlighted state. | ||
* @param {string} [link.highlightFontWeight="normal"] - fontWeight in highlighted state. | ||
* @param {boolean} [link.labelProperty="label"] - the property that will be rendered as label within some link. Note that | ||
* this property needs to be passed along the link payload (along side with source and target). | ||
* @param {string} [link.mouseCursor="pointer"] - {@link https://developer.mozilla.org/en/docs/Web/CSS/cursor?v=control|cursor} | ||
* property for when link is mouse hovered. | ||
* @param {number} [link.opacity=1] - the default opacity value for links. | ||
* @param {number} [link.opacity=1] 🔍🔍🔍 - the default opacity value for links. | ||
* @param {boolean} [link.renderLabel=false] - when set to true labels will appear along side links in the | ||
* graph. **Note**: this will only happen of course if proper label is passed within the link, check also `link.labelProperty`. | ||
* <br/> | ||
* <img src="https://github.com/danielcaldas/react-d3-graph/blob/master/docs/rd3g-link-render-label.png?raw=true" width="820" height="480"/> | ||
* @param {boolean} [link.semanticStrokeWidth=false] - when set to true all links will have | ||
@@ -175,3 +189,3 @@ * *"semantic width"*, this means that the width of the connections will be proportional to the value of each link. | ||
* ``` | ||
* @param {number} [link.strokeWidth=1.5] - strokeWidth for all links. By default the actual value is obtain by the | ||
* @param {number} [link.strokeWidth=1.5] 🔍🔍🔍 - strokeWidth for all links. By default the actual value is obtain by the | ||
* following expression: | ||
@@ -181,3 +195,3 @@ * ```javascript | ||
* ``` | ||
* @param {string} [link.type='STRAIGHT'] - the type of line to draw, available types at this point are: | ||
* @param {string} [link.type="STRAIGHT"] - the type of line to draw, available types at this point are: | ||
* - "STRAIGHT" <small>(default)</small> - a straight line. | ||
@@ -187,2 +201,3 @@ * - "CURVE_SMOOTH" - a slight curve between two nodes | ||
* <br/> | ||
* <img src="https://github.com/danielcaldas/react-d3-graph/blob/master/docs/rd3g-bend.gif?raw=true" width="820" height="480"/> | ||
* | ||
@@ -194,12 +209,12 @@ * @example | ||
* node: { | ||
* color: 'lightgreen', | ||
* color: "lightgreen", | ||
* size: 120, | ||
* highlightStrokeColor: 'blue' | ||
* highlightStrokeColor: "blue" | ||
* }, | ||
* link: { | ||
* highlightColor: 'lightblue' | ||
* highlightColor: "lightblue" | ||
* } | ||
* }; | ||
* | ||
* // Sorry for the long config description, here's a potato 🥔. | ||
* // Sorry for the long config description, here"s a potato 🥔. | ||
*/ | ||
@@ -210,2 +225,4 @@ export default { | ||
directed: false, | ||
focusAnimationDuration: 0.75, | ||
focusZoom: 1, | ||
height: 400, | ||
@@ -217,4 +234,2 @@ highlightDegree: 1, | ||
minZoom: 0.1, | ||
focusZoom: 1, | ||
focusAnimationDuration: 0.75, | ||
nodeHighlightBehavior: false, | ||
@@ -228,34 +243,41 @@ panAndZoom: false, | ||
linkLength: 100, | ||
linkStrength: 1 | ||
linkStrength: 1, | ||
}, | ||
node: { | ||
color: '#d3d3d3', | ||
fontColor: 'black', | ||
color: "#d3d3d3", | ||
fontColor: "black", | ||
fontSize: 8, | ||
fontWeight: 'normal', | ||
highlightColor: 'SAME', | ||
fontWeight: "normal", | ||
highlightColor: "SAME", | ||
highlightFontSize: 8, | ||
highlightFontWeight: 'normal', | ||
highlightStrokeColor: 'SAME', | ||
highlightStrokeWidth: 1.5, | ||
labelProperty: 'id', | ||
mouseCursor: 'pointer', | ||
highlightFontWeight: "normal", | ||
highlightStrokeColor: "SAME", | ||
highlightStrokeWidth: "SAME", | ||
labelProperty: "id", | ||
mouseCursor: "pointer", | ||
opacity: 1, | ||
renderLabel: true, | ||
size: 200, | ||
strokeColor: 'none', | ||
strokeColor: "none", | ||
strokeWidth: 1.5, | ||
svg: '', | ||
symbolType: 'circle', | ||
viewGenerator: null | ||
svg: "", | ||
symbolType: "circle", | ||
viewGenerator: null, | ||
}, | ||
link: { | ||
color: '#d3d3d3', | ||
highlightColor: '#d3d3d3', | ||
mouseCursor: 'pointer', | ||
color: "#d3d3d3", | ||
fontColor: "black", | ||
fontSize: 8, | ||
fontWeight: "normal", | ||
highlightColor: "#d3d3d3", | ||
highlightFontSize: 8, | ||
highlightFontWeight: "normal", | ||
labelProperty: "label", | ||
mouseCursor: "pointer", | ||
opacity: 1, | ||
renderLabel: false, | ||
semanticStrokeWidth: false, | ||
strokeWidth: 1.5, | ||
type: 'STRAIGHT' | ||
} | ||
type: "STRAIGHT", | ||
}, | ||
}; |
@@ -1,16 +0,15 @@ | ||
import CONST from '../../const'; | ||
import CONST from "../../const"; | ||
export default { | ||
COORDS_SEPARATOR: ',', | ||
FORCE_IDEAL_STRENGTH: -100, // TODO: Expose as configurable, | ||
COORDS_SEPARATOR: ",", | ||
FORCE_X: 0.06, | ||
FORCE_Y: 0.06, | ||
GRAPH_CONTAINER_ID: 'graph-container-zoomable', | ||
GRAPH_WRAPPER_ID: 'graph-wrapper', | ||
GRAPH_CONTAINER_ID: "graph-container-zoomable", | ||
GRAPH_WRAPPER_ID: "graph-wrapper", | ||
KEYWORDS: { | ||
SAME: 'SAME' | ||
SAME: "SAME", | ||
}, | ||
LINK_CLASS_NAME: 'link', | ||
NODE_CLASS_NAME: 'node', | ||
...CONST | ||
LINK_CLASS_NAME: "link", | ||
NODE_CLASS_NAME: "node", | ||
...CONST, | ||
}; |
@@ -26,14 +26,14 @@ /** | ||
forceSimulation as d3ForceSimulation, | ||
forceManyBody as d3ForceManyBody | ||
} from 'd3-force'; | ||
forceManyBody as d3ForceManyBody, | ||
} from "d3-force"; | ||
import CONST from './graph.const'; | ||
import DEFAULT_CONFIG from './graph.config'; | ||
import ERRORS from '../../err'; | ||
import CONST from "./graph.const"; | ||
import DEFAULT_CONFIG from "./graph.config"; | ||
import ERRORS from "../../err"; | ||
import utils from '../../utils'; | ||
import { buildLinkPathDefinition } from '../link/link.helper'; | ||
import { getMarkerId } from '../marker/marker.helper'; | ||
import utils from "../../utils"; | ||
import { computeNodeDegree } from "./collapse.helper"; | ||
const NODE_PROPS_WHITELIST = ['id', 'highlighted', 'x', 'y', 'index', 'vy', 'vx']; | ||
const NODE_PROPS_WHITELIST = ["id", "highlighted", "x", "y", "index", "vy", "vx"]; | ||
const LINK_CUSTOM_PROPS_WHITELIST = ["color", "opacity", "strokeWidth", "label"]; | ||
@@ -57,39 +57,8 @@ /** | ||
return d3ForceSimulation() | ||
.force('charge', d3ForceManyBody().strength(forceStrength)) | ||
.force('x', frx) | ||
.force('y', fry); | ||
.force("charge", d3ForceManyBody().strength(forceStrength)) | ||
.force("x", frx) | ||
.force("y", fry); | ||
} | ||
/** | ||
* 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) { | ||
const highlight = | ||
node.highlighted || | ||
node.id === (highlightedLink && highlightedLink.source) || | ||
node.id === (highlightedLink && highlightedLink.target); | ||
const someNodeHighlighted = !!( | ||
highlightedNode || | ||
(highlightedLink && highlightedLink.source && highlightedLink.target) | ||
); | ||
let opacity; | ||
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 | ||
@@ -106,4 +75,4 @@ * in a lightweight matrix containing only links with source and target being strings representative of some node id | ||
return graphLinks.reduce((links, l) => { | ||
const source = l.source.id || l.source; | ||
const target = l.target.id || l.target; | ||
const source = l.source.id !== undefined && l.source.id !== null ? l.source.id : l.source; | ||
const target = l.target.id !== undefined && l.target.id !== null ? l.target.id : l.target; | ||
@@ -148,6 +117,6 @@ if (!links[source]) { | ||
if (!node.hasOwnProperty('x')) { | ||
if (!node.hasOwnProperty("x")) { | ||
node.x = 0; | ||
} | ||
if (!node.hasOwnProperty('y')) { | ||
if (!node.hasOwnProperty("y")) { | ||
node.y = 0; | ||
@@ -169,3 +138,3 @@ } | ||
* @param {Array.<Object>} d3Links - all d3Links. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Object} config - same as {@link #graphrenderer|config in renderGraph}. | ||
* @param {Object} state - Graph component current state (same format as returned object on this function). | ||
@@ -177,13 +146,18 @@ * @returns {Object} a d3Link. | ||
const d3Link = d3Links[index]; | ||
const customProps = utils.pick(link, LINK_CUSTOM_PROPS_WHITELIST); | ||
if (d3Link) { | ||
const toggledDirected = state.config && state.config.directed && config.directed !== state.config.directed; | ||
const refinedD3Link = { | ||
...d3Link, | ||
...customProps, | ||
}; | ||
// every time we toggle directed config all links should be visible again | ||
if (toggledDirected) { | ||
return { ...d3Link, isHidden: false }; | ||
return { ...refinedD3Link, isHidden: false }; | ||
} | ||
// every time we disable collapsible (collapsible is false) all links should be visible again | ||
return config.collapsible ? d3Link : { ...d3Link, isHidden: false }; | ||
return config.collapsible ? refinedD3Link : { ...refinedD3Link, isHidden: false }; | ||
} | ||
@@ -194,7 +168,7 @@ | ||
id: link.source, | ||
highlighted | ||
highlighted, | ||
}; | ||
const target = { | ||
id: link.target, | ||
highlighted | ||
highlighted, | ||
}; | ||
@@ -205,3 +179,4 @@ | ||
source, | ||
target | ||
target, | ||
...customProps, | ||
}; | ||
@@ -211,2 +186,22 @@ } | ||
/** | ||
* Tags orphan nodes with a `_orphan` flag. | ||
* @param {Object.<string, Object>} nodes - nodes mapped by their id. | ||
* @param {Object.<string, Object>} linksMatrix - 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). | ||
* @returns {Object.<string, Object>} same input nodes structure with tagged orphans nodes where applicable. | ||
* @memberof Graph/helper | ||
*/ | ||
function _tagOrphanNodes(nodes, linksMatrix) { | ||
return Object.keys(nodes).reduce((acc, nodeId) => { | ||
const { inDegree, outDegree } = computeNodeDegree(nodeId, linksMatrix); | ||
const node = nodes[nodeId]; | ||
const taggedNode = inDegree === 0 && outDegree === 0 ? { ...node, _orphan: true } : node; | ||
acc[nodeId] = taggedNode; | ||
return acc; | ||
}, {}); | ||
} | ||
/** | ||
* Some integrity validations on links and nodes structure. If some validation fails the function will | ||
@@ -223,3 +218,3 @@ * throw an error. | ||
if (!data.nodes || !data.nodes.length) { | ||
utils.throwErr('Graph', ERRORS.INSUFFICIENT_DATA); | ||
utils.throwErr("Graph", ERRORS.INSUFFICIENT_DATA); | ||
} | ||
@@ -233,165 +228,20 @@ | ||
if (!data.nodes.find(n => n.id === l.source)) { | ||
utils.throwErr('Graph', `${ERRORS.INVALID_LINKS} - "${l.source}" is not a valid source node id`); | ||
utils.throwErr("Graph", `${ERRORS.INVALID_LINKS} - "${l.source}" is not a valid source node id`); | ||
} | ||
if (!data.nodes.find(n => n.id === l.target)) { | ||
utils.throwErr('Graph', `${ERRORS.INVALID_LINKS} - "${l.target}" is not a valid target node id`); | ||
utils.throwErr("Graph", `${ERRORS.INVALID_LINKS} - "${l.target}" is not a valid target node id`); | ||
} | ||
} | ||
} | ||
/** | ||
* Build some Link properties based on given parameters. | ||
* @param {Object} link - the link object for which we will generate properties. | ||
* @param {Object.<string, Object>} nodes - same as {@link #buildGraph|nodes in buildGraph}. | ||
* @param {Object.<string, Object>} links - same as {@link #buildGraph|links in buildGraph}. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Function[]} linkCallbacks - same as {@link #buildGraph|linkCallbacks in buildGraph}. | ||
* @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. | ||
* @returns {Object} returns an object that aggregates all props for creating respective Link component instance. | ||
* @memberof Graph/helper | ||
*/ | ||
function buildLinkProps(link, nodes, links, config, linkCallbacks, highlightedNode, highlightedLink, transform) { | ||
const { source, target } = link; | ||
const x1 = (nodes[source] && nodes[source].x) || 0; | ||
const y1 = (nodes[source] && nodes[source].y) || 0; | ||
const x2 = (nodes[target] && nodes[target].x) || 0; | ||
const y2 = (nodes[target] && nodes[target].y) || 0; | ||
const d = buildLinkPathDefinition({ source: { x: x1, y: y1 }, target: { x: x2, y: y2 } }, config.link.type); | ||
let mainNodeParticipates = false; | ||
switch (config.highlightDegree) { | ||
case 0: | ||
break; | ||
case 2: | ||
mainNodeParticipates = true; | ||
break; | ||
default: | ||
// 1st degree is the fallback behavior | ||
mainNodeParticipates = source === highlightedNode || target === highlightedNode; | ||
break; | ||
if (l && l.value !== undefined && typeof l.value !== "number") { | ||
utils.throwErr( | ||
"Graph", | ||
`${ERRORS.INVALID_LINK_VALUE} - found in link with source "${l.source}" and target "${l.target}"` | ||
); | ||
} | ||
} | ||
const reasonNode = mainNodeParticipates && nodes[source].highlighted && nodes[target].highlighted; | ||
const reasonLink = | ||
source === (highlightedLink && highlightedLink.source) && | ||
target === (highlightedLink && highlightedLink.target); | ||
const highlight = reasonNode || reasonLink; | ||
let opacity = config.link.opacity; | ||
if (highlightedNode || (highlightedLink && highlightedLink.source)) { | ||
opacity = highlight ? config.link.opacity : config.highlightOpacity; | ||
} | ||
let stroke = link.color || config.link.color; | ||
if (highlight) { | ||
stroke = config.link.highlightColor === CONST.KEYWORDS.SAME ? config.link.color : config.link.highlightColor; | ||
} | ||
let strokeWidth = config.link.strokeWidth * (1 / transform); | ||
if (config.link.semanticStrokeWidth) { | ||
const linkValue = links[source][target] || links[target][source] || 1; | ||
strokeWidth += linkValue * strokeWidth / 10; | ||
} | ||
const markerId = config.directed ? getMarkerId(highlight, transform, config) : null; | ||
return { | ||
markerId, | ||
d, | ||
source, | ||
target, | ||
strokeWidth, | ||
stroke, | ||
mouseCursor: config.link.mouseCursor, | ||
className: CONST.LINK_CLASS_NAME, | ||
opacity, | ||
onClickLink: linkCallbacks.onClickLink, | ||
onRightClickLink: linkCallbacks.onRightClickLink, | ||
onMouseOverLink: linkCallbacks.onMouseOverLink, | ||
onMouseOutLink: linkCallbacks.onMouseOutLink | ||
}; | ||
} | ||
/** | ||
* Build some Node properties based on given parameters. | ||
* @param {Object} node - the node object for whom we will generate properties. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Function[]} nodeCallbacks - same as {@link #buildGraph|nodeCallbacks in buildGraph}. | ||
* @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. | ||
* @returns {Object} returns object that contain Link props ready to be feeded to the Link component. | ||
* @memberof Graph/helper | ||
*/ | ||
function buildNodeProps(node, config, nodeCallbacks = {}, highlightedNode, highlightedLink, transform) { | ||
const highlight = | ||
node.highlighted || | ||
(node.id === (highlightedLink && highlightedLink.source) || | ||
node.id === (highlightedLink && highlightedLink.target)); | ||
const opacity = _getNodeOpacity(node, highlightedNode, highlightedLink, config); | ||
let fill = node.color || config.node.color; | ||
if (highlight && config.node.highlightColor !== CONST.KEYWORDS.SAME) { | ||
fill = config.node.highlightColor; | ||
} | ||
let stroke = node.strokeColor || config.node.strokeColor; | ||
if (highlight && config.node.highlightStrokeColor !== CONST.KEYWORDS.SAME) { | ||
stroke = config.node.highlightStrokeColor; | ||
} | ||
let label = node[config.node.labelProperty] || node.id; | ||
if (typeof config.node.labelProperty === 'function') { | ||
label = config.node.labelProperty(node); | ||
} | ||
const t = 1 / transform; | ||
const nodeSize = node.size || config.node.size; | ||
const fontSize = highlight ? config.node.highlightFontSize : config.node.fontSize; | ||
const dx = fontSize * t + nodeSize / 100 + 1.5; | ||
const strokeWidth = highlight ? config.node.highlightStrokeWidth : config.node.strokeWidth; | ||
const svg = node.svg || config.node.svg; | ||
const fontColor = node.fontColor || config.node.fontColor; | ||
return { | ||
...node, | ||
className: CONST.NODE_CLASS_NAME, | ||
cursor: config.node.mouseCursor, | ||
cx: (node && node.x) || '0', | ||
cy: (node && node.y) || '0', | ||
fill, | ||
fontColor, | ||
fontSize: fontSize * t, | ||
dx, | ||
fontWeight: highlight ? config.node.highlightFontWeight : config.node.fontWeight, | ||
id: node.id, | ||
label, | ||
onClickNode: nodeCallbacks.onClickNode, | ||
onRightClickNode: nodeCallbacks.onRightClickNode, | ||
onMouseOverNode: nodeCallbacks.onMouseOverNode, | ||
onMouseOut: nodeCallbacks.onMouseOut, | ||
opacity, | ||
renderLabel: config.node.renderLabel, | ||
size: nodeSize * t, | ||
stroke, | ||
strokeWidth: strokeWidth * t, | ||
svg, | ||
type: node.symbolType || config.node.symbolType, | ||
viewGenerator: node.viewGenerator || config.node.viewGenerator, | ||
overrideGlobalViewGenerator: !node.viewGenerator && node.svg | ||
}; | ||
} | ||
// list of properties that are of no interest when it comes to nodes and links comparison | ||
const NODE_PROPERTIES_DISCARD_TO_COMPARE = ['x', 'y', 'vx', 'vy', 'index']; | ||
const NODE_PROPERTIES_DISCARD_TO_COMPARE = ["x", "y", "vx", "vy", "index"]; | ||
@@ -417,4 +267,4 @@ /** | ||
// FIXME: solve this source data inconsistency later | ||
source: l.source.id || l.source, | ||
target: l.target.id || l.target | ||
source: l.source.id !== undefined && l.source.id !== null ? l.source.id : l.source, | ||
target: l.target.id !== undefined && l.target.id !== null ? l.target.id : l.target, | ||
})); | ||
@@ -452,2 +302,24 @@ const graphElementsUpdated = !( | ||
/** | ||
* Returns the transformation to apply in order to center the graph on the | ||
* selected node. | ||
* @param {Object} d3Node - node to focus the graph view on. | ||
* @param {Object} config - same as {@link #graphrenderer|config in renderGraph}. | ||
* @returns {string} transform rule to apply. | ||
* @memberof Graph/helper | ||
*/ | ||
function getCenterAndZoomTransformation(d3Node, config) { | ||
if (!d3Node) { | ||
return; | ||
} | ||
const { width, height, focusZoom } = config; | ||
return ` | ||
translate(${width / 2}, ${height / 2}) | ||
scale(${focusZoom}) | ||
translate(${-d3Node.x}, ${-d3Node.y}) | ||
`; | ||
} | ||
/** | ||
* Encapsulates common procedures to initialize graph. | ||
@@ -457,3 +329,3 @@ * @param {Object} props - Graph component props, object that holds data, id and config. | ||
* @param {string} props.id - the graph id. | ||
* @param {Object} props.config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Object} props.config - same as {@link #graphrenderer|config in renderGraph}. | ||
* @param {Object} state - Graph component current state (same format as returned object on this function). | ||
@@ -470,9 +342,8 @@ * @returns {Object} a fully (re)initialized graph state object. | ||
graph = { | ||
nodes: data.nodes.map( | ||
n => | ||
state.nodes[n.id] | ||
? Object.assign({}, n, utils.pick(state.nodes[n.id], NODE_PROPS_WHITELIST)) | ||
: Object.assign({}, n) | ||
nodes: data.nodes.map(n => | ||
state.nodes[n.id] | ||
? Object.assign({}, n, utils.pick(state.nodes[n.id], NODE_PROPS_WHITELIST)) | ||
: Object.assign({}, n) | ||
), | ||
links: data.links.map((l, index) => _mapDataLinkToD3Link(l, index, state && state.d3Links, config, state)) | ||
links: data.links.map((l, index) => _mapDataLinkToD3Link(l, index, state && state.d3Links, config, state)), | ||
}; | ||
@@ -482,3 +353,3 @@ } else { | ||
nodes: data.nodes.map(n => Object.assign({}, n)), | ||
links: data.links.map(l => Object.assign({}, l)) | ||
links: data.links.map(l => Object.assign({}, l)), | ||
}; | ||
@@ -488,6 +359,6 @@ } | ||
let newConfig = Object.assign({}, utils.merge(DEFAULT_CONFIG, config || {})); | ||
let nodes = _initializeNodes(graph.nodes); | ||
let links = _initializeLinks(graph.links, newConfig); // matrix of graph connections | ||
let nodes = _tagOrphanNodes(_initializeNodes(graph.nodes), links); | ||
const { nodes: d3Nodes, links: d3Links } = graph; | ||
const formatedId = id.replace(/ /g, '_'); | ||
const formatedId = id.replace(/ /g, "_"); | ||
const simulation = _createForceSimulation(newConfig.width, newConfig.height, newConfig.d3 && newConfig.d3.gravity); | ||
@@ -510,7 +381,7 @@ | ||
d3Nodes, | ||
highlightedNode: '', | ||
highlightedNode: "", | ||
simulation, | ||
newGraphElements: false, | ||
configUpdated: false, | ||
transform: 1 | ||
transform: 1, | ||
}; | ||
@@ -531,3 +402,3 @@ } | ||
function updateNodeHighlightedValue(nodes, links, config, id, value = false) { | ||
const highlightedNode = value ? id : ''; | ||
const highlightedNode = value ? id : ""; | ||
const node = Object.assign({}, nodes[id], { highlighted: value }); | ||
@@ -547,36 +418,12 @@ let updatedNodes = Object.assign({}, nodes, { [id]: node }); | ||
nodes: updatedNodes, | ||
highlightedNode | ||
highlightedNode, | ||
}; | ||
} | ||
/** | ||
* Returns the transformation to apply in order to center the graph on the | ||
* selected node. | ||
* @param {Object} d3Node - node to focus the graph view on. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @returns {string} transform rule to apply. | ||
* @memberof Graph/helper | ||
*/ | ||
function getCenterAndZoomTransformation(d3Node, config) { | ||
if (!d3Node) { | ||
return; | ||
} | ||
const { width, height, focusZoom } = config; | ||
return ` | ||
translate(${width / 2}, ${height / 2}) | ||
scale(${focusZoom}) | ||
translate(${-d3Node.x}, ${-d3Node.y}) | ||
`; | ||
} | ||
export { | ||
buildLinkProps, | ||
buildNodeProps, | ||
checkForGraphConfigChanges, | ||
checkForGraphElementsChanges, | ||
getCenterAndZoomTransformation, | ||
initializeGraphState, | ||
updateNodeHighlightedValue, | ||
getCenterAndZoomTransformation | ||
}; |
@@ -1,16 +0,16 @@ | ||
import React from 'react'; | ||
import React from "react"; | ||
import { drag as d3Drag } from 'd3-drag'; | ||
import { forceLink as d3ForceLink } from 'd3-force'; | ||
import { select as d3Select, selectAll as d3SelectAll, event as d3Event } from 'd3-selection'; | ||
import { zoom as d3Zoom } from 'd3-zoom'; | ||
import { drag as d3Drag } from "d3-drag"; | ||
import { forceLink as d3ForceLink } from "d3-force"; | ||
import { select as d3Select, selectAll as d3SelectAll, event as d3Event } from "d3-selection"; | ||
import { zoom as d3Zoom } from "d3-zoom"; | ||
import CONST from './graph.const'; | ||
import DEFAULT_CONFIG from './graph.config'; | ||
import ERRORS from '../../err'; | ||
import CONST from "./graph.const"; | ||
import DEFAULT_CONFIG from "./graph.config"; | ||
import ERRORS from "../../err"; | ||
import * as collapseHelper from './collapse.helper'; | ||
import * as graphHelper from './graph.helper'; | ||
import * as graphRenderer from './graph.renderer'; | ||
import utils from '../../utils'; | ||
import * as collapseHelper from "./collapse.helper"; | ||
import * as graphHelper from "./graph.helper"; | ||
import * as graphRenderer from "./graph.renderer"; | ||
import utils from "../../utils"; | ||
@@ -105,2 +105,31 @@ /** | ||
/** | ||
* Obtain a set of properties which will be used to perform the focus and zoom animation if | ||
* required. In case there's not a focus and zoom animation in progress, it should reset the | ||
* transition duration to zero and clear transformation styles. | ||
* @returns {Object} - Focus and zoom animation properties. | ||
*/ | ||
_generateFocusAnimationProps = () => { | ||
const { focusedNodeId } = this.state; | ||
// In case an older animation was still not complete, clear previous timeout to ensure the new one is not cancelled | ||
if (this.state.enableFocusAnimation) { | ||
if (this.focusAnimationTimeout) { | ||
clearTimeout(this.focusAnimationTimeout); | ||
} | ||
this.focusAnimationTimeout = setTimeout( | ||
() => this.setState({ enableFocusAnimation: false }), | ||
this.state.config.focusAnimationDuration * 1000 | ||
); | ||
} | ||
const transitionDuration = this.state.enableFocusAnimation ? this.state.config.focusAnimationDuration : 0; | ||
return { | ||
style: { transitionDuration: `${transitionDuration}s` }, | ||
transform: focusedNodeId ? this.state.focusTransformation : null, | ||
}; | ||
}; | ||
/** | ||
* Sets d3 tick function and configures other d3 stuff such as forces and drag events. | ||
@@ -110,3 +139,3 @@ * @returns {undefined} | ||
_graphForcesConfig() { | ||
this.state.simulation.nodes(this.state.d3Nodes).on('tick', this._tick); | ||
this.state.simulation.nodes(this.state.d3Nodes).on("tick", this._tick); | ||
@@ -121,8 +150,8 @@ const forceLink = d3ForceLink(this.state.d3Links) | ||
const customNodeDrag = d3Drag() | ||
.on('start', this._onDragStart) | ||
.on('drag', this._onDragMove) | ||
.on('end', this._onDragEnd); | ||
.on("start", this._onDragStart) | ||
.on("drag", this._onDragMove) | ||
.on("end", this._onDragEnd); | ||
d3Select(`#${this.state.id}-${CONST.GRAPH_WRAPPER_ID}`) | ||
.selectAll('.node') | ||
.selectAll(".node") | ||
.call(customNodeDrag); | ||
@@ -160,4 +189,4 @@ } | ||
// set nodes fixing coords fx and fy | ||
draggedNode['fx'] = draggedNode.x; | ||
draggedNode['fy'] = draggedNode.y; | ||
draggedNode["fx"] = draggedNode.x; | ||
draggedNode["fy"] = draggedNode.y; | ||
@@ -208,3 +237,3 @@ this._tick(); | ||
.scaleExtent([this.state.config.minZoom, this.state.config.maxZoom]) | ||
.on('zoom', this._zoomed) | ||
.on("zoom", this._zoomed) | ||
); | ||
@@ -219,3 +248,3 @@ | ||
d3SelectAll(`#${this.state.id}-${CONST.GRAPH_CONTAINER_ID}`).attr('transform', transform); | ||
d3SelectAll(`#${this.state.id}-${CONST.GRAPH_CONTAINER_ID}`).attr("transform", transform); | ||
@@ -226,2 +255,54 @@ this.state.config.panAndZoom && this.setState({ transform: transform.k }); | ||
/** | ||
* Calls the callback passed to the component. | ||
* @param {Object} e - The event of onClick handler. | ||
* @returns {undefined} | ||
*/ | ||
onClickGraph = e => { | ||
if (this.state.enableFocusAnimation) { | ||
this.setState({ enableFocusAnimation: false }); | ||
} | ||
// Only trigger the graph onClickHandler, if not clicked a node or link. | ||
// toUpperCase() is added as a precaution, as the documentation says tagName should always | ||
// return in UPPERCASE, but chrome returns lowercase | ||
if ( | ||
e.target.tagName.toUpperCase() === "SVG" && | ||
e.target.attributes.name.value === `svg-container-${this.state.id}` | ||
) { | ||
this.props.onClickGraph && this.props.onClickGraph(); | ||
} | ||
}; | ||
/** | ||
* Collapses the nodes, then calls the callback passed to the component. | ||
* @param {string} clickedNodeId - The id of the node where the click was performed. | ||
* @returns {undefined} | ||
*/ | ||
onClickNode = clickedNodeId => { | ||
if (this.state.config.collapsible) { | ||
const leafConnections = collapseHelper.getTargetLeafConnections( | ||
clickedNodeId, | ||
this.state.links, | ||
this.state.config | ||
); | ||
const links = collapseHelper.toggleLinksMatrixConnections( | ||
this.state.links, | ||
leafConnections, | ||
this.state.config | ||
); | ||
const d3Links = collapseHelper.toggleLinksConnections(this.state.d3Links, links); | ||
this._tick( | ||
{ | ||
links, | ||
d3Links, | ||
}, | ||
() => this.props.onClickNode && this.props.onClickNode(clickedNodeId) | ||
); | ||
} else { | ||
this.props.onClickNode && this.props.onClickNode(clickedNodeId); | ||
} | ||
}; | ||
/** | ||
* Handles mouse over node event. | ||
@@ -299,4 +380,4 @@ * @param {string} id - id of the node that participates in the event. | ||
if (node.fx && node.fy) { | ||
Reflect.deleteProperty(node, 'fx'); | ||
Reflect.deleteProperty(node, 'fy'); | ||
Reflect.deleteProperty(node, "fx"); | ||
Reflect.deleteProperty(node, "fy"); | ||
} | ||
@@ -368,3 +449,3 @@ } | ||
enableFocusAnimation, | ||
focusTransformation | ||
focusTransformation, | ||
}); | ||
@@ -402,85 +483,4 @@ } | ||
/** | ||
* Collapses the nodes, then calls the callback passed to the component. | ||
* @param {string} clickedNodeId - The id of the node where the click was performed. | ||
* @returns {undefined} | ||
*/ | ||
onClickNode = clickedNodeId => { | ||
if (this.state.config.collapsible) { | ||
const leafConnections = collapseHelper.getTargetLeafConnections( | ||
clickedNodeId, | ||
this.state.links, | ||
this.state.config | ||
); | ||
const links = collapseHelper.toggleLinksMatrixConnections( | ||
this.state.links, | ||
leafConnections, | ||
this.state.config | ||
); | ||
const d3Links = collapseHelper.toggleLinksConnections(this.state.d3Links, links); | ||
this._tick( | ||
{ | ||
links, | ||
d3Links | ||
}, | ||
() => this.props.onClickNode && this.props.onClickNode(clickedNodeId) | ||
); | ||
} else { | ||
this.props.onClickNode && this.props.onClickNode(clickedNodeId); | ||
} | ||
}; | ||
/** | ||
* Calls the callback passed to the component. | ||
* @param {Object} e - The event of onClick handler. | ||
* @returns {undefined} | ||
*/ | ||
onClickGraph = e => { | ||
if (this.state.enableFocusAnimation) { | ||
this.setState({ enableFocusAnimation: false }); | ||
} | ||
// Only trigger the graph onClickHandler, if not clicked a node or link. | ||
// toUpperCase() is added as a precaution, as the documentation says tagName should always | ||
// return in UPPERCASE, but chrome returns lowercase | ||
if ( | ||
e.target.tagName.toUpperCase() === 'SVG' && | ||
e.target.attributes.name.value === `svg-container-${this.state.id}` | ||
) { | ||
this.props.onClickGraph && this.props.onClickGraph(); | ||
} | ||
}; | ||
/** | ||
* Obtain a set of properties which will be used to perform the focus and zoom animation if | ||
* required. In case there's not a focus and zoom animation in progress, it should reset the | ||
* transition duration to zero and clear transformation styles. | ||
* @returns {Object} - Focus and zoom animation properties. | ||
*/ | ||
_generateFocusAnimationProps = () => { | ||
const { focusedNodeId } = this.state; | ||
// In case an older animation was still not complete, clear previous timeout to ensure the new one is not cancelled | ||
if (this.state.enableFocusAnimation) { | ||
if (this.focusAnimationTimeout) { | ||
clearTimeout(this.focusAnimationTimeout); | ||
} | ||
this.focusAnimationTimeout = setTimeout( | ||
() => this.setState({ enableFocusAnimation: false }), | ||
this.state.config.focusAnimationDuration * 1000 | ||
); | ||
} | ||
const transitionDuration = this.state.enableFocusAnimation ? this.state.config.focusAnimationDuration : 0; | ||
return { | ||
style: { transitionDuration: `${transitionDuration}s` }, | ||
transform: focusedNodeId ? this.state.focusTransformation : null | ||
}; | ||
}; | ||
render() { | ||
const { nodes, links, defs } = graphRenderer.buildGraph( | ||
const { nodes, links, defs } = graphRenderer.renderGraph( | ||
this.state.nodes, | ||
@@ -491,3 +491,3 @@ { | ||
onMouseOverNode: this.onMouseOverNode, | ||
onMouseOut: this.onMouseOutNode | ||
onMouseOut: this.onMouseOutNode, | ||
}, | ||
@@ -500,3 +500,3 @@ this.state.d3Links, | ||
onMouseOverLink: this.onMouseOverLink, | ||
onMouseOutLink: this.onMouseOutLink | ||
onMouseOutLink: this.onMouseOutLink, | ||
}, | ||
@@ -511,3 +511,3 @@ this.state.config, | ||
height: this.state.config.height, | ||
width: this.state.config.width | ||
width: this.state.config.width, | ||
}; | ||
@@ -514,0 +514,0 @@ |
@@ -6,27 +6,27 @@ /** | ||
*/ | ||
import React from 'react'; | ||
import React from "react"; | ||
import CONST from './graph.const'; | ||
import { MARKERS, MARKER_SMALL_SIZE, MARKER_MEDIUM_OFFSET, MARKER_LARGE_OFFSET } from '../marker/marker.const'; | ||
import CONST from "./graph.const"; | ||
import { MARKERS, MARKER_SMALL_SIZE, MARKER_MEDIUM_OFFSET, MARKER_LARGE_OFFSET } from "../marker/marker.const"; | ||
import Link from '../link/Link'; | ||
import Node from '../node/Node'; | ||
import Marker from '../marker/Marker'; | ||
import { buildLinkProps, buildNodeProps } from './graph.helper'; | ||
import { isNodeVisible } from './collapse.helper'; | ||
import Link from "../link/Link"; | ||
import Node from "../node/Node"; | ||
import Marker from "../marker/Marker"; | ||
import { buildLinkProps, buildNodeProps } from "./graph.builder"; | ||
import { isNodeVisible } from "./collapse.helper"; | ||
/** | ||
* Build Link components given a list of links. | ||
* @param {Object.<string, Object>} nodes - same as {@link #buildGraph|nodes in buildGraph}. | ||
* @param {Object.<string, Object>} nodes - same as {@link #graphrenderer|nodes in renderGraph}. | ||
* @param {Array.<Object>} links - array of links {@link #Link|Link}. | ||
* @param {Array.<Object>} linksMatrix - array of links {@link #Link|Link}. | ||
* @param {Object} config - same as {@link #buildGraph|config in buildGraph}. | ||
* @param {Function[]} linkCallbacks - same as {@link #buildGraph|linkCallbacks in buildGraph}. | ||
* @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 #graphrenderer|config in renderGraph}. | ||
* @param {Function[]} linkCallbacks - same as {@link #graphrenderer|linkCallbacks in renderGraph}. | ||
* @param {string} highlightedNode - same as {@link #graphrenderer|highlightedNode in renderGraph}. | ||
* @param {Object} highlightedLink - same as {@link #graphrenderer|highlightedLink in renderGraph}. | ||
* @param {number} transform - value that indicates the amount of zoom transformation. | ||
* @returns {Array.<Object>} returns the generated array of Link components. | ||
* @memberof Graph/helper | ||
* @memberof Graph/renderer | ||
*/ | ||
function _buildLinks(nodes, links, linksMatrix, config, linkCallbacks, highlightedNode, highlightedLink, transform) { | ||
function _renderLinks(nodes, links, linksMatrix, config, linkCallbacks, highlightedNode, highlightedLink, transform) { | ||
let outLinks = links; | ||
@@ -41,4 +41,4 @@ | ||
// FIXME: solve this source data inconsistency later | ||
const sourceId = source.id || source; | ||
const targetId = target.id || target; | ||
const sourceId = source.id !== undefined && source.id !== null ? source.id : source; | ||
const targetId = target.id !== undefined && target.id !== null ? target.id : target; | ||
const key = `${sourceId}${CONST.COORDS_SEPARATOR}${targetId}`; | ||
@@ -56,3 +56,3 @@ const props = buildLinkProps( | ||
return <Link key={key} {...props} />; | ||
return <Link key={key} id={key} {...props} />; | ||
}); | ||
@@ -73,9 +73,9 @@ } | ||
* @returns {Array.<Object>} returns the generated array of node components | ||
* @memberof Graph/helper | ||
* @memberof Graph/renderer | ||
*/ | ||
function _buildNodes(nodes, nodeCallbacks, config, highlightedNode, highlightedLink, transform, linksMatrix) { | ||
function _renderNodes(nodes, nodeCallbacks, config, highlightedNode, highlightedLink, transform, linksMatrix) { | ||
let outNodes = Object.keys(nodes); | ||
if (config.collapsible) { | ||
outNodes = outNodes.filter(nodeId => isNodeVisible(nodeId, linksMatrix)); | ||
outNodes = outNodes.filter(nodeId => isNodeVisible(nodeId, nodes, linksMatrix)); | ||
} | ||
@@ -102,5 +102,5 @@ | ||
* @returns {Function} memoized build definitions function. | ||
* @memberof Graph/helper | ||
* @memberof Graph/renderer | ||
*/ | ||
function _buildDefs() { | ||
function _renderDefs() { | ||
let cachedDefs; | ||
@@ -114,4 +114,4 @@ | ||
const small = MARKER_SMALL_SIZE; | ||
const medium = small + MARKER_MEDIUM_OFFSET * config.maxZoom / 3; | ||
const large = small + MARKER_LARGE_OFFSET * config.maxZoom / 3; | ||
const medium = small + (MARKER_MEDIUM_OFFSET * config.maxZoom) / 3; | ||
const large = small + (MARKER_LARGE_OFFSET * config.maxZoom) / 3; | ||
@@ -134,8 +134,8 @@ cachedDefs = ( | ||
/** | ||
* Memoized reference for _buildDefs. | ||
* Memoized reference for _renderDefs. | ||
* @param {Object} config - an object containing rd3g consumer defined configurations {@link #config config} for the graph. | ||
* @returns {Object} graph reusable objects [defs](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs). | ||
* @memberof Graph/helper | ||
* @memberof Graph/renderer | ||
*/ | ||
const _memoizedBuildDefs = _buildDefs(); | ||
const _memoizedRenderDefs = _renderDefs(); | ||
@@ -183,3 +183,3 @@ /** | ||
*/ | ||
function buildGraph( | ||
function renderGraph( | ||
nodes, | ||
@@ -196,4 +196,4 @@ nodeCallbacks, | ||
return { | ||
nodes: _buildNodes(nodes, nodeCallbacks, config, highlightedNode, highlightedLink, transform, linksMatrix), | ||
links: _buildLinks( | ||
nodes: _renderNodes(nodes, nodeCallbacks, config, highlightedNode, highlightedLink, transform, linksMatrix), | ||
links: _renderLinks( | ||
nodes, | ||
@@ -208,6 +208,6 @@ links, | ||
), | ||
defs: _memoizedBuildDefs(config) | ||
defs: _memoizedRenderDefs(config), | ||
}; | ||
} | ||
export { buildGraph }; | ||
export { renderGraph }; |
@@ -14,7 +14,7 @@ /** | ||
const LINE_TYPES = { | ||
STRAIGHT: 'STRAIGHT', | ||
CURVE_SMOOTH: 'CURVE_SMOOTH', | ||
CURVE_FULL: 'CURVE_FULL' | ||
STRAIGHT: "STRAIGHT", | ||
CURVE_SMOOTH: "CURVE_SMOOTH", | ||
CURVE_FULL: "CURVE_FULL", | ||
}; | ||
export { LINE_TYPES }; |
@@ -6,3 +6,3 @@ /** | ||
*/ | ||
import { LINE_TYPES } from './link.const'; | ||
import { LINE_TYPES } from "./link.const"; | ||
@@ -46,3 +46,3 @@ /** | ||
[LINE_TYPES.CURVE_SMOOTH]: smoothCurveRadius, | ||
[LINE_TYPES.CURVE_FULL]: fullCurveRadius | ||
[LINE_TYPES.CURVE_FULL]: fullCurveRadius, | ||
}; | ||
@@ -49,0 +49,0 @@ |
@@ -1,2 +0,2 @@ | ||
import React from 'react'; | ||
import React from "react"; | ||
@@ -24,10 +24,10 @@ /** | ||
* d="M1..." | ||
* source='idSourceNode' | ||
* target='idTargetNode' | ||
* markerId='marker-small' | ||
* source="idSourceNode" | ||
* target="idTargetNode" | ||
* markerId="marker-small" | ||
* strokeWidth=1.5 | ||
* stroke='green' | ||
* className='link' | ||
* stroke="green" | ||
* className="link" | ||
* opacity=1 | ||
* mouseCursor='pointer' | ||
* mouseCursor="pointer" | ||
* onClickLink={onClickLink} | ||
@@ -72,4 +72,4 @@ * onRightClickLink={onRightClickLink} | ||
opacity: this.props.opacity, | ||
fill: 'none', | ||
cursor: this.props.mouseCursor | ||
fill: "none", | ||
cursor: this.props.mouseCursor, | ||
}; | ||
@@ -84,3 +84,3 @@ | ||
onMouseOver: this.handleOnMouseOverLink, | ||
style: lineStyle | ||
style: lineStyle, | ||
}; | ||
@@ -92,4 +92,25 @@ | ||
return <path {...lineProps} />; | ||
const { label, id } = this.props; | ||
const textProps = { | ||
dy: -1, | ||
style: { | ||
fill: this.props.fontColor, | ||
fontSize: this.props.fontSize, | ||
fontWeight: this.props.fontWeight, | ||
}, | ||
}; | ||
return ( | ||
<svg> | ||
<path {...lineProps} id={id} /> | ||
{label && ( | ||
<text style={{ textAnchor: "middle" }} {...textProps}> | ||
<textPath href={`#${id}`} startOffset="50%"> | ||
{label} | ||
</textPath> | ||
</text> | ||
)} | ||
</svg> | ||
); | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
const HIGHLIGHTED = 'H'; | ||
const HIGHLIGHTED = "H"; | ||
const MARKER_SMALL_SIZE = 16; | ||
@@ -7,16 +7,16 @@ const MARKER_MEDIUM_OFFSET = 2; | ||
const MARKERS = { | ||
MARKER_S: 'marker-small', | ||
MARKER_SH: 'marker-small-highlighted', | ||
MARKER_M: 'marker-medium', | ||
MARKER_MH: 'marker-medium-highlighted', | ||
MARKER_L: 'marker-large', | ||
MARKER_LH: 'marker-large-highlighted' | ||
MARKER_S: "marker-small", | ||
MARKER_SH: "marker-small-highlighted", | ||
MARKER_M: "marker-medium", | ||
MARKER_MH: "marker-medium-highlighted", | ||
MARKER_L: "marker-large", | ||
MARKER_LH: "marker-large-highlighted", | ||
}; | ||
// hard coded aggregation of the different sizes available for markers | ||
const SIZES = { | ||
S: 'S', | ||
M: 'M', | ||
L: 'L' | ||
S: "S", | ||
M: "M", | ||
L: "L", | ||
}; | ||
export { HIGHLIGHTED, MARKER_LARGE_OFFSET, MARKER_MEDIUM_OFFSET, MARKER_SMALL_SIZE, MARKERS, SIZES }; |
@@ -6,3 +6,3 @@ /** | ||
*/ | ||
import { MARKERS, SIZES, HIGHLIGHTED } from './marker.const'; | ||
import { MARKERS, SIZES, HIGHLIGHTED } from "./marker.const"; | ||
@@ -53,3 +53,3 @@ /** | ||
const size = _getMarkerSize(transform, mMax, lMax); | ||
const highlighted = highlight ? HIGHLIGHTED : ''; | ||
const highlighted = highlight ? HIGHLIGHTED : ""; | ||
const markerKey = _markerKeyBuilder(size, highlighted); | ||
@@ -56,0 +56,0 @@ |
@@ -1,2 +0,2 @@ | ||
import React from 'react'; | ||
import React from "react"; | ||
@@ -3,0 +3,0 @@ /** |
@@ -1,3 +0,3 @@ | ||
import CONFIG from '../graph/graph.config'; | ||
import CONST from '../../const'; | ||
import CONFIG from "../graph/graph.config"; | ||
import CONST from "../../const"; | ||
@@ -7,8 +7,8 @@ export default { | ||
START_ANGLE: 0, | ||
END_ANGLE: 2 * Math.PI | ||
END_ANGLE: 2 * Math.PI, | ||
}, | ||
DEFAULT_NODE_SIZE: CONFIG.node.size, | ||
NODE_LABEL_DX: '.90em', | ||
NODE_LABEL_DY: '.35em', | ||
...CONST | ||
NODE_LABEL_DX: ".90em", | ||
NODE_LABEL_DY: ".35em", | ||
...CONST, | ||
}; |
@@ -14,6 +14,6 @@ /** | ||
symbolWye as d3SymbolWye, | ||
symbol as d3Symbol | ||
} from 'd3-shape'; | ||
symbol as d3Symbol, | ||
} from "d3-shape"; | ||
import CONST from './node.const'; | ||
import CONST from "./node.const"; | ||
@@ -64,3 +64,3 @@ /** | ||
export default { | ||
buildSvgSymbol | ||
buildSvgSymbol, | ||
}; |
@@ -1,6 +0,6 @@ | ||
import React from 'react'; | ||
import React from "react"; | ||
import CONST from './node.const'; | ||
import CONST from "./node.const"; | ||
import nodeHelper from './node.helper'; | ||
import nodeHelper from "./node.helper"; | ||
@@ -83,3 +83,3 @@ /** | ||
onMouseOver: this.handleOnMouseOverNode, | ||
opacity: this.props.opacity | ||
opacity: this.props.opacity, | ||
}; | ||
@@ -93,3 +93,3 @@ | ||
fontWeight: this.props.fontWeight, | ||
opacity: this.props.opacity | ||
opacity: this.props.opacity, | ||
}; | ||
@@ -121,3 +121,3 @@ | ||
<foreignObject x="0" y="0" width="100%" height="100%"> | ||
<section style={{ height, width, backgroundColor: 'transparent' }}> | ||
<section style={{ height, width, backgroundColor: "transparent" }}> | ||
{this.props.viewGenerator(this.props)} | ||
@@ -150,3 +150,3 @@ </section> | ||
id: this.props.id, | ||
transform: `translate(${gtx},${gty})` | ||
transform: `translate(${gtx},${gty})`, | ||
}; | ||
@@ -153,0 +153,0 @@ |
@@ -8,10 +8,10 @@ /** | ||
SYMBOLS: { | ||
CIRCLE: 'circle', | ||
CROSS: 'cross', | ||
DIAMOND: 'diamond', | ||
SQUARE: 'square', | ||
STAR: 'star', | ||
TRIANGLE: 'triangle', | ||
WYE: 'wye' | ||
} | ||
CIRCLE: "circle", | ||
CROSS: "cross", | ||
DIAMOND: "diamond", | ||
SQUARE: "square", | ||
STAR: "star", | ||
TRIANGLE: "triangle", | ||
WYE: "wye", | ||
}, | ||
}; |
/*eslint max-len: ["error", 200]*/ | ||
export default { | ||
GRAPH_NO_ID_PROP: 'id prop not defined! id property is mandatory and it should be unique.', | ||
GRAPH_NO_ID_PROP: "id prop not defined! id property is mandatory and it should be unique.", | ||
INVALID_LINKS: | ||
'you provided a invalid links data structure. Links source and target attributes must point to an existent node', | ||
"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' | ||
"you have not provided enough data for react-d3-graph to render something. You need to provide at least one node", | ||
INVALID_LINK_VALUE: "links 'value' attribute must be of type number", | ||
}; |
@@ -1,5 +0,5 @@ | ||
import Graph from './components/graph/Graph'; | ||
import Node from './components/node/Node'; | ||
import Link from './components/link/Link'; | ||
import Graph from "./components/graph/Graph"; | ||
import Node from "./components/node/Node"; | ||
import Link from "./components/link/Link"; | ||
export { Graph, Node, Link }; |
@@ -20,3 +20,3 @@ /** | ||
function _isPropertyNestedObject(o, k) { | ||
return o.hasOwnProperty(k) && typeof o[k] === 'object' && o[k] !== null && !isEmptyObject(o[k]); | ||
return !!o && o.hasOwnProperty(k) && typeof o[k] === "object" && o[k] !== null && !isEmptyObject(o[k]); | ||
} | ||
@@ -77,6 +77,29 @@ | ||
function isEmptyObject(o) { | ||
return !!o && typeof o === 'object' && !Object.keys(o).length; | ||
return !!o && typeof o === "object" && !Object.keys(o).length; | ||
} | ||
/** | ||
* Function to deep clone plain javascript objects. | ||
* @param {Object} o - the object to clone. | ||
* @param {Object} _clone - carries the cloned output throughout the | ||
* recursive calls. Parameter serves only for internal usage. | ||
* @param {number} _depth - this parameter serves only for internal usage. | ||
* @returns {Object} - the cloned object. | ||
* @memberof utils | ||
*/ | ||
function deepClone(o, _clone = {}, _depth = 0) { | ||
// TODO: Handle invalid input o is null, undefined, empty object | ||
const oKeys = Object.keys(o); | ||
// TODO: handle arrays | ||
for (let k of oKeys) { | ||
const nested = _isPropertyNestedObject(o, k); | ||
_clone[k] = nested && _depth < MAX_DEPTH ? deepClone(o[k], {}, _depth + 1) : o[k]; | ||
} | ||
return _clone; | ||
} | ||
/** | ||
* This function merges two objects o1 and o2, where o2 properties override existent o1 properties, and | ||
@@ -99,3 +122,3 @@ * if o2 doesn't posses some o1 property the fallback will be the o1 property. | ||
for (let k of Object.keys(o1)) { | ||
const nestedO = !!(o2[k] && typeof o2[k] === 'object' && typeof o1[k] === 'object' && _depth < MAX_DEPTH); | ||
const nestedO = !!(o2[k] && typeof o2[k] === "object" && typeof o1[k] === "object" && _depth < MAX_DEPTH); | ||
@@ -106,3 +129,3 @@ if (nestedO) { | ||
o[k] = | ||
o1[k].hasOwnProperty('length') && o2[k].hasOwnProperty('length') ? Object.keys(r).map(rk => r[rk]) : r; | ||
o1[k].hasOwnProperty("length") && o2[k].hasOwnProperty("length") ? Object.keys(r).map(rk => r[rk]) : r; | ||
} else { | ||
@@ -163,6 +186,7 @@ o[k] = o2.hasOwnProperty(k) ? o2[k] : o1[k]; | ||
isEmptyObject, | ||
deepClone, | ||
merge, | ||
pick, | ||
antiPick, | ||
throwErr | ||
throwErr, | ||
}; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
411866
54
5274
1
46