Giter VIP home page Giter VIP logo

react-digraph's Introduction

react-digraph

Demo

Overview

A React component which makes it easy to create a directed graph editor without implementing any of the SVG drawing or event handling logic.

Important v8.0.0 Information

Version 8.0.0 introduces multi-select nodes and edges using Ctrl-Shift-Mouse events (Cmd-Shift-mouse for Mac). This requires a breaking change. Instead of onSelectNode/Edge, you'll only provide one onSelect function callback and a selected object with { nodes: Map, and edges: Map } as the parameter format. The typings folder has the exact type definition for these attributes. When either edges or nodes are selected the onSelect function will fire with the object. You will have to handle all nodes and edges selected, or if there is only one then you will have to determine if it's a node or edge within the onSelect function.

To disable multi-select you can set allowMultiselect to false, which disables the Ctrl-Shift-mouse event, but we will still use the onSelect function. Both onSelectNode and onSelectEdge are deprecated.

Breaking changes:

  • onPasteSelected now accepts a SelectionT object for the first parameter
  • onPasteSelected now accepts an IPoint instead of a XYCoords array for the second parameter.
  • onDeleteSelected is added which takes a SelectionT parameter.
  • onSelect is added, which accepts SelectionT and Event parameters.
  • onUpdateNode accepts a Map of updated nodes in the second parameter (for example, if multiple nodes are moved).
  • selected is a new property to track selected nodes and edges. It is a SelectionT type.
  • canDeleteSelected takes the place of canDeleteNode and canDeleteEdge. It accepts a SelectionT type as a parameter.
  • onDeleteNode is removed
  • onDeleteEdge is removed
  • selectedNode is removed
  • selectedEdge is removed
  • canDeleteNode is removed
  • canDeleteEdge is removed
  • selectedNodes is removed
  • selectedEdges is removed

Installation

npm install --save react-digraph

If you don't have the following peerDependenies, make sure to install them:

npm install --save react react-dom

Usage

The default export is a component called GraphView; it provides a multitude of hooks for various graph editing operations and a set of controls for zooming. Typically, it should be wrapped in a higher order component that supplies various callbacks (onCreateNode, onCreateEdge etc...).

GraphView expects several properties to exist on your nodes and edges. If these types conflict with existing properties on your data, you must transform your data to re-key these properties under different names and to add the expected properties. All nodes and edges can have a type attribute set - nodes also support a subtype attribute. For a full description of node and edge properties, see the sections for INode and IEdge below.

Configuration for nodes and edges can be passed to GraphView via the nodeTypes, nodeSubtypes, and edgeTypes props. Custom SVG elements can be defined here for the node's type/subtype and the edge's type.

It is often convenient to combine these types into a configuration object that can be referred to elsewhere in the application and used to associate events fired from nodes/edges in the GraphView with other actions in the application. Here is an abbreviated example:

import {
  GraphView, // required
  Edge, // optional
  type IEdge, // optional
  Node, // optional
  type INode, // optional
  type LayoutEngineType, // required to change the layoutEngineType, otherwise optional
  BwdlTransformer, // optional, Example JSON transformer
  GraphUtils // optional, useful utility functions
} from 'react-digraph';

const GraphConfig =  {
  NodeTypes: {
    empty: { // required to show empty nodes
      typeText: "None",
      shapeId: "#empty", // relates to the type property of a node
      shape: (
        <symbol viewBox="0 0 100 100" id="empty" key="0">
          <circle cx="50" cy="50" r="45"></circle>
        </symbol>
      )
    },
    custom: { // required to show empty nodes
      typeText: "Custom",
      shapeId: "#custom", // relates to the type property of a node
      shape: (
        <symbol viewBox="0 0 50 25" id="custom" key="0">
          <ellipse cx="50" cy="25" rx="50" ry="25"></ellipse>
        </symbol>
      )
    }
  },
  NodeSubtypes: {},
  EdgeTypes: {
    emptyEdge: {  // required to show empty edges
      shapeId: "#emptyEdge",
      shape: (
        <symbol viewBox="0 0 50 50" id="emptyEdge" key="0">
          <circle cx="25" cy="25" r="8" fill="currentColor"> </circle>
        </symbol>
      )
    }
  }
}

const NODE_KEY = "id"       // Allows D3 to correctly update DOM

class Graph extends Component {

  constructor(props) {
    super(props);

    this.state = {
      graph: sample,
      selected: {}
    }
  }

  /* Define custom graph editing methods here */

  render() {
    const nodes = this.state.graph.nodes;
    const edges = this.state.graph.edges;
    const selected = this.state.selected;

    const NodeTypes = GraphConfig.NodeTypes;
    const NodeSubtypes = GraphConfig.NodeSubtypes;
    const EdgeTypes = GraphConfig.EdgeTypes;

    return (
      <div id='graph' style={styles.graph}>

        <GraphView  ref='GraphView'
                    nodeKey={NODE_KEY}
                    nodes={nodes}
                    edges={edges}
                    selected={selected}
                    nodeTypes={NodeTypes}
                    nodeSubtypes={NodeSubtypes}
                    edgeTypes={EdgeTypes}
                    allowMultiselect={true} // true by default, set to false to disable multi select.
                    onSelect={this.onSelect}
                    onCreateNode={this.onCreateNode}
                    onUpdateNode={this.onUpdateNode}
                    onDeleteNode={this.onDeleteNode}
                    onCreateEdge={this.onCreateEdge}
                    onSwapEdge={this.onSwapEdge}
                    onDeleteEdge={this.onDeleteEdge}/>
      </div>
    );
  }

}

A typical graph that would be stored in the Graph component's state looks something like this:

{
  "nodes": [
    {
      "id": 1,
      "title": "Node A",
      "x": 258.3976135253906,
      "y": 331.9783248901367,
      "type": "empty"
    },
    {
      "id": 2,
      "title": "Node B",
      "x": 593.9393920898438,
      "y": 260.6060791015625,
      "type": "empty"
    },
    {
      "id": 3,
      "title": "Node C",
      "x": 237.5757598876953,
      "y": 61.81818389892578,
      "type": "custom"
    },
    {
      "id": 4,
      "title": "Node C",
      "x": 600.5757598876953,
      "y": 600.81818389892578,
      "type": "custom"
    }
  ],
  "edges": [
    {
      "source": 1,
      "target": 2,
      "type": "emptyEdge"
    },
    {
      "source": 2,
      "target": 4,
      "type": "emptyEdge"
    }
  ]
}

For a detailed example, check out src/examples/graph.js. To run the example:

npm install
npm run example

A webpage will open in your default browser automatically.

  • To add nodes, hold shift and click on the grid.
  • To add edges, hold shift and click/drag to between nodes.
  • To delete a node or edge, click on it and press delete.
  • Click and drag nodes to change their position.
  • To select multiple nodes, press Ctrl+Shift then click and drag the mouse.
  • You may copy and paste selected nodes and edges with Ctrl+C and Ctrl+V
  • Note: On Mac computers, use Cmd instead of Ctrl.

All props are detailed below.

Props

Prop Type Required Notes
nodeKey string true Key for D3 to update nodes(typ. UUID).
nodes Array<INode> true Array of graph nodes.
edges Array<IEdge> true Array of graph edges.
allowCopyEdges boolean false (default false) Allow onCopySelected to be called when an edge is selected without any nodes.
allowMultiselect boolean false (default true) Use Ctrl-Shift-LeftMouse to draw a multiple selection box.
selected object true The currently selected graph entity.
nodeTypes object true Config object of available node types.
nodeSubtypes object true Config object of available node subtypes.
edgeTypes object true Config object of available edge types.
onSelect func false Called when nodes are selected when allowMultiselect is true. Is passed an object with nodes and edges included.
onCreateNode func true Called when a node is created.
onContextMenu func true Called when contextmenu event triggered.
onUpdateNode func true Called when a node is moved.
onCreateEdge func true Called when an edge is created.
onSwapEdge func true Called when an edge 'target' is swapped.
onBackgroundClick func false Called when the background is clicked.
onArrowClicked func false Called when the arrow head is clicked.
onUndo func false A function called when Ctrl-Z is activated. React-digraph does not keep track of actions, this must be implemented in the client website.
onCopySelected func false A function called when Ctrl-C is activated. React-digraph does not keep track of copied nodes or edges, the this must be implemented in the client website.
onPasteSelected func false A function called when Ctrl-V is activated. React-digraph does not keep track of copied nodes or edges, the this must be implemented in the client website.
canDeleteSelected func false takes the place of canDeleteNode and canDeleteEdge. It accepts a SelectionT type as a parameter. It is called before a node or edge is deleted. The function should return a boolean.
canCreateEdge func false Called before an edge is created.
canSwapEdge func false Called before an edge 'target' is swapped.
afterRenderEdge func false Called after an edge is rendered.
renderNode func false Called to render node geometry.
renderNodeText func false Called to render the node text
renderDefs func false Called to render SVG definitions.
renderBackground func false Called to render SVG background.
readOnly bool false Disables all graph editing interactions.
disableBackspace bool false Disables using backspace to delete the selected node.
maxTitleChars number false Truncates node title characters.
gridSize number false Overall grid size.
gridSpacing number false Grid spacing.
gridDotSize number false Grid dot size.
minZoom number false Minimum zoom percentage.
maxZoom number false Maximum zoom percentage.
nodeSize number false Node bbox size.
edgeHandleSize number false Edge handle size.
edgeArrowSize number false Edge arrow size in pixels. Default 8. Set to 0 to hide arrow.
zoomDelay number false Delay before zoom occurs.
zoomDur number false Duration of zoom transition.
showGraphControls boolean false Whether to show zoom controls.
layoutEngineType typeof LayoutEngineType false Uses a pre-programmed layout engine, such as 'SnapToGrid'
rotateEdgeHandle boolean false Whether to rotate edge handle with edge when a node is moved
centerNodeOnMove boolean false Whether the node should be centered on cursor when moving a node
initialBBox typeof IBBox false If specified, initial render graph using the given bounding box
graphConfig object false dagre graph setting configuration, which will override layout engine graph configuration - only apply to 'HorizontalTree'
nodeSizeOverridesAllowed boolean false Flag to toggle sizeOverride in nodes - only apply to 'HorizontalTree'
nodeLocationOverrides object false Nodes location overrides object - only apply to 'HorizontalTree'

onCreateNode

You have access to d3 mouse event in onCreateNode function.

  onCreateNode = (x, y, mouseEvent) => {
    // we can get the exact mouse position when click happens with this line
    const {pageX, pageY} = mouseEvent;
    // rest of the code for adding a new node ...
  };

Prop Types:

See prop types in the typings folder.

INode

Prop Type Required Notes
anyIDKey string true An id or key for nodes, same as the nodeKey prop
title string true Used in edges and to render the node text.
x number false X coordinate of the node.
y number false Y coordinate of the node.
type string false Node type, for displaying a custom SVG shape.
subtype string false Node subtype, for displaying a custom SVG shape.

title

The title attribute is used for the IDs in the SVG nodes in the graph.

IEdge

Prop Type Required Notes
source string true The title of the parent node.
target string true The title of the child node.
type string false Edge type, for displaying a custom SVG shape.
handleText string false Text to render on the edge.
handleTooltipText string false Used to render the SVG title element.
label_from string false Text to render along the edge with label_to.
label_to string false Text to render along the edge with label_from.

Imperative API

You can call these methods on the GraphView class using a ref.

Method Type Notes
panToNode (id: string, zoom?: boolean) => void Center the node given by id within the viewport, optionally zoom in to fit it.
panToEdge (source: string, target: string, zoom?: boolean) => void Center the edge between source and target node IDs within the viewport, optionally zoom in to fit it.

Deprecation Notes

Prop Type Required Notes
emptyType string true 'Default' node type.
getViewNode func true Node getter.
renderEdge func false Called to render edge geometry.
enableFocus bool false Adds a 'focus' toggle state to GraphView.
transitionTime number false Fade-in/Fade-out time.
primary string false Primary color.
light string false Light color.
dark string false Dark color.
style object false Style prop for wrapper.
gridDot number false Grid dot size.
graphControls boolean true Whether to show zoom controls.

react-digraph's People

Contributors

9renpoto avatar adriannesoike avatar ajbogh avatar amilajack avatar chenyunw-uber avatar chiayenhung avatar christensena avatar djazouli avatar iamsoorena avatar jasonli468 avatar johnvf avatar josh-degraw avatar justinlmeyer avatar justpilz avatar kfern avatar ksnyder9801 avatar mac-s-g avatar maekawataiki avatar malikx-alee avatar namefilip avatar pakitosec avatar rbernard avatar rickyp-uber avatar rileyhilliard avatar rohitb4 avatar thinkty avatar vampiro avatar vikr01 avatar wfriebel avatar zanettin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-digraph's Issues

There's a error or a forgotten recommendation?

./~/react-digraph/dist/components/graph-view.js
Module not found: Error: Cannot resolve module 'd3' in /Users/micheldiz/test/node_modules/react-digraph/dist/components
 @ ./~/react-digraph/dist/components/graph-view.js 42:9-22

These dependencies were not found:

* d3 in ./~/react-digraph/dist/components/graph-view.js
* radium in ./~/react-digraph/dist/components/graph-view.js, ./~/react-digraph/dist/components/graph-controls.js
* react-icons/lib/fa/expand in ./~/react-digraph/dist/components/graph-controls.js
* react-icons/lib/fa/info-circle in ./~/react-digraph/dist/components/graph-controls.js

Node selection problem on Firefox 64.0

Describe the bug
I'm running demo example. When I click on the node (in the area where is no text) then the node is selected. But when I click on node title the node is not selected. I observe this bug on Firefox 64.0 and Ubuntu 16.04. It is working as expected on Chrome 69.

To Reproduce

  1. Clone the repo and run demo example.
  2. Click on any node (in the area with no text) the node is selected.
  3. Click on any node (in the area with text) the node is not selected.

Expected behavior
The node should be selected no matter if we click on area with text or not.

Desktop:

  • OS: Ubuntu 16.04
  • Browser Firefox
  • Version 64.0

Additional context
The bug is not observed on Chrome 69.

Disable shortcut keys

Is there any way to disable the default shortcut keys? Additionally, I could not find any way to add a node programmatically, is it possible?

Development with live reload

Is your feature request related to a problem? Please describe.
Currently when I'm working to add features to this library I have a hard time.
Why?
Because dev mode has some issues.
I think the current development is designed to use with example project on the contrary I think developer should be able to use npm link and develop while working on their own project.

Describe the solution you'd like
Fix dev mode.(It currently does not update on code change while using with npm link.

As an alternative I use wml to watch for file changes and update my project's node_modules/react-digraph, also I set project entry to src and I add some extra configurations to my webpack to be able to have live code update, configs to compile flow, arrow funcitons ...

Since these configs are somehow opinionated, I didn't send a PR. I want to know what's your idea too.

Shift+click doesn't make new Node in v4.1.7

I just installed latest version and checked the examples in example folder. and noticed that shift+click doesn't work.

testing-digraph

I just changed some of graph-config.js colors to check which is which.

Add async option for onCreateNode and onCreateEdge

Is your feature request related to a problem? Please describe.
Currently, onCreateNode function does not return any promise.
Consider the case when I want to be able to add a node only when a promise is resolved from my side.
For example I want to add a node only when user provided an input for it's name.
what should I do?
I don't think It's possible now.
I was able to make this thing work in version 4 forking the repo, but this feature is not available not in v4 neither in v5.

Describe the solution you'd like
I think we can add a separate prop named onCreateNodeAsync and check out It's availability in handleSvgClicked function.

Upgrade dependencies to remove vulnerabilities notice

Describe the bug
npm issues a vulnerability notice. Use npm audit to identify the issues and upgrade packages that are able to be upgraded.

To Reproduce
Steps to reproduce the behavior:

  1. In terminal type npm audit

Expected behavior
Should have a low number or near zero vulnerabilities.

Desktop (please complete the following information):

  • Version: v5.3.2

Integrate with electron-react-boilerplate?

Is anyone using react-digraph in the electron-react-boilerplate project? What steps did you take, and can you give some debugging tips?
I can get it to run in dev mode, but I haven't had complete success running in production mode. I keep getting Uncaught ReferenceError: Graph is not defined. Some noob-style fiddling around with lint and flow gave me a graph, but with no functionality and Uncaught TypeError: Cannot read property 'getBBox' in the Javascript console.

foreignObject on renderNode method not catching onClick event

Is your feature request related to a problem? Please describe.
I'm trying to personalize my node interface with some HTML on a ReactJS context, and I'm trying to make this HTML trigger some events (e.g. onClick). To this end, I've overridden the renderNode method and inserted the code for all the interface I wanted, including a foreignObject with the HTML I needed (with the event listeners and everything). However, none of the listeners are triggered when the event is fired.
I've created this question with a little more detail and snippets, feel free to check it.

Describe the solution you'd like
Well, it's pretty obvious, I guess: I just needed the events to be thrown and the listeners to be triggered.

Describe alternatives you've considered
on my Stack Overflow post there are a few more details, but I tried adding references to each node and adding event listeners manually. This also didn't work, but I managed to be able to throw the correct event - even though I wasn't able to control it...

Additional context
I'm using:

    "react": "^16.6.1",
    "react-digraph": "^6.0.0",
    Google Chrome Version 72.0.3626.119 (Official Build) (64-bit)

Edit:
I am aware that this isn't specifically a library feature as it is a potential problem with my usage of the SVG library. However, since it is rather counterintuitive to implement this method, I'm not fully aware where the problem lies. Maybe you guys can help me get there.

Thanks.

Edit2:
My main objective was to achieve this type of interface to both the nodes and the edges. The problem I presented was specifically for the nodes, but I'm feeling that applying this logic to the edges will also pose a problem.
Perhaps this should indeed be considered a feature request, as it would make sense to include a way for the user to achieve the usual functionalities (delete, insert, edit nodes/edges) using the visual interface and the mouse.

Thank you.

Getting error with radium

radium/lib/components/style.js is expecting radium be wrapped in a higher order style component which is not available. Can someone look into this issue?

style.js:93 Uncaught TypeError: Cannot read property 'object' of undefined
at Object. (style.js:93)
at webpack_require (bootstrap d709286bfc7382baba41:555)
at fn (bootstrap d709286bfc7382baba41:86)
at Object. (index.js:15)
at webpack_require (bootstrap d709286bfc7382baba41:555)
at fn (bootstrap d709286bfc7382baba41:86)
at Object. (graph-view.js:46)
at webpack_require (bootstrap d709286bfc7382baba41:555)
at fn (bootstrap d709286bfc7382baba41:86)
at Object. (index.js:23)

double-click node handler

Is it possible to add a double-click node handler? It would be useful to update some data on the fly, among other things

Option to disable graph controls

We're using this in a bounded box rather than full screen and the graph controls are fixed in a position down the bottom left overtop some other content.

Suggested solutions:

  1. Provide an alternative way of positioning them
  2. Provide an option to turn off the controls altogether. This is probably quickest and probably good enough for our purposes as we don't tend to use them.

Can't delete selected edge

I suppose handleDocumentClick fires when an edge is selected. So state.focused becomes false and delete doesn't work.

Project Development is Slow

I think because of few number of people working on this project development is somehow slow.
I want to know what you think about future of this project?
Do you want to add other maintainers?
Do you want to make a discussion forum for this project?
I see a lot of potential and want to help anyway I can.

Getting child_process error

I'm getting the following error while running a simple digraph code. After a thorough analysis, it seems the issue is with d3 package. Do you have a digraph version which runs with an older D3 version?

Error in ./~/xmlhttprequest/lib/XMLHttpRequest.js
Module not found: 'child_process' in C:\apps\uber-digraoh\node_modules\xmlhttpre
quest\lib

@ ./~/xmlhttprequest/lib/XMLHttpRequest.js 15:12-36

Add webpack-bundle-analyzer to help with understanding build output

Is your feature request related to a problem? Please describe.
The output of react-digraph is massive, far larger than it needs to be. There are some really easy things that can be done to cut down the size and boost performance.

Describe the solution you'd like
The first step in understanding the bloat of an application and where fat can be trimmed is by visualizing the problem. webpack-bundle-analyzer allows you to see what is included in your final prod build so you can start identifying modules that are heavier than you expect.

Describe alternatives you've considered
None

Additional context
screen shot 2019-02-21 at 5 00 03 am

The screenshot above is what you're able to visualize within this repo when using webpack-bundle-analyzer. One of the first things that stand out is the use of react-icons. This one module alone accounts for over 50% of the entire asset size of the react-digraph production build. I also noticed that this module is only used for the expand icon, so one single icon is costing 374k gzipped.
I've already done the work in adding webpack-bundle-analyzer to this repo, I am only opening this issue so I can make a PR to it.

Optimize CSS

Is your feature request related to a problem? Please describe.
screen shot 2019-02-25 at 8 25 27 am
☝️The CSS selector depth is much deeper than it needs to be. This makes it hard for consuming applications to override default styles, since overrides would need to be more specific than .view-wrapper .node .shape > use.node. Additionally extremely specific CSS selectors can have an impact on CSS performance, especially in large scale applications with large CSS outputs. I was also able to identify several dead lines of CSS that do not need to be declared.

Describe the solution you'd like
CSS should strive to achieve the desired results with as minimal CSS selector depth as possible and should not contain dead code. When CSS is optimal, performance is maintained and extensibility of consuming applications is easy. This issue is only opened as a tracker. I plan to submit a fix for this myself.

Describe alternatives you've considered
None

Only import icons that are used

Describe the bug
This is part II of issue #106
react-digraph is importing all of react-icons, but it is only using one icon from font awesome.

To Reproduce
Steps to reproduce the behavior:

  1. Checkout (or merge) #107
  2. yarn && yarn analyze-bundle
  3. look at the dependency output

Expected behavior
react-digraph should only need to output the one icon that is being used in the final production build. Optimizing this is fairly straight forward, and will reduce the prod build of react-digraph by about 60%.

Screenshots
screen shot 2019-02-21 at 5 00 03 am

Desktop (please complete the following information):

  • OS: N/A
  • Browser N/A
  • Version N/A

Additional context
I plan on fixing this myself. This issue is only for tracking purposes.

Uncaught TypeError: nodesSelection.exit(...).transition is not a function

We're getting this error on v4.1.5:

graph-view.js:693 Uncaught TypeError: nodesSelection.exit(...).transition is not a function
    at RadiumEnhancer.GraphView._this.renderNodes (graph-view.js:693)
    at RadiumEnhancer.GraphView._this.renderView (graph-view.js:790)
    at RadiumEnhancer.render (graph-view.js:929)
    at RadiumEnhancer.render (enhancer.js:265)
    at finishClassComponent (react-dom.development.js:13085)
    at updateClassComponent (react-dom.development.js:13047)
    at beginWork (react-dom.development.js:13715)
    at performUnitOfWork (react-dom.development.js:15741)
    at workLoop (react-dom.development.js:15780)
    at HTMLUnknownElement.callCallback (react-dom.development.js:100)

This does not happen on this commit of the fork: https://github.com/vicapow/react-digraph/tree/d3-as-direct-dependency-dist

Port support

Is there any plan to support input and output ports?

Add ability for custom node contents

We have a use-case where we'd like to have three text fields that one could edit independently by clicking the node and then editing them in a separate text box. Looking at the readme gif this looked possible but in looking at the code it seems that it's only possible to set a subtype with a hardcoded look and feel.

Example of what we're trying to make: (This is all one node)

 --------------- 
|   First line  |   <- Editable text
|--------------
|   Second line |   <- Editable text
|-------------- 
|   Third line  |   <- Editable text
 ---------------

If this is possible now - how could we accomplish this?
If not - is this something you're interested in adding?

Node creation rendering bug

Steps to reproduce:

  1. create a project based on example
  2. Shift + Click somewhere

Expected behaviour:
New node created and rendered

Actual behaviour:
Nothing happens visually, until I drag something.

I figured out the way to fix it by myself, but it's seems to be inefficient:
https://github.com/uber/react-digraph/blob/master/src/components/graph-view.js#L884
calling renderViews() twice in a row fixes the problem.

I think better solution would imply either:

  1. some kind of proper data update before render() is called
  2. calling renderViews() on node creation callback (inside of graph-view.js of cource)

Shape Component vs Shape SVG

Really nice work! Very pretty project. I was wondering if it is possible out of the box to have a node shape to be a React component in the sense that it is still rendering a SVG shape but the props (name etc...) is being passed into the shape.

Thanks!

Uncaught TypeError: Cannot read property 'target' of undefined

Version information

Attempted to upgrade from React 16.4.2 to 16.5.2 and I seem to be getting a new error:

Uncaught TypeError: Cannot read property 'target' of undefined
 - GraphView.arrowClicked
and
Uncaught TypeError: Cannot read property 'which' of undefined
 - GraphView.handleNodeMouseLeave

Here is the useful parts of the package.lock file.

    "react": "^16.5.2",
    "react-digraph": "^4.1.0",
    "react-dom": "^16.5.2",

Initial rendering of nodes messed up

Hello everyone

I'm not sure this is a bug as I only encountered it while trying to integrate the Graph component inside my React Application. I followed the steps in the README, but somehow the rendering of my Graph seems to be completely messed up.

My component was integrated like this:

          <div id='graph'>
                   <GraphView edges={this.props.drawingBoardState.graphViewState.graphInput.edges}
                              edgeTypes={GraphConfig.EdgeTypes}
                              nodeKey={this.props.drawingBoardState.graphViewState.nodeKey}
                              nodes={this.props.drawingBoardState.graphViewState.graphInput.nodes}
                              nodeSubtypes={GraphConfig.NodeSubtypes}
                              nodeTypes={GraphConfig.NodeTypes}
                              selected={this.props.drawingBoardState.graphViewState.selected}
                              onCreateEdge={this.onCreateEdge}
                              onCreateNode={this.onCreateNode}
                              onDeleteEdge={this.onDeleteEdge}
                              onDeleteNode={this.onDeleteNode}
                              onSelectEdge={this.onSelectEdge}
                              onSelectNode={this.onSelectNode}
                              onSwapEdge={this.onSwapEdge}
                              onUpdateNode={this.onUpdateNode}
                              />
               </div>

I added the four nodes provided in the example on the README, but somehow only Node D is rendered (actually only the last one in the array). Looking into the DOM structure, it appears that the id is "undefined" (i.e. "node-undefined"). I think this could be related with the wrong rendering.

Has anyone an idea why this happens? Thanks a lot for the efforts!

Screenshot 2019-03-12 at 19 09 34

Use nws instead of python for example

Not everybody has python installed on their machine, so relying on SimpleHTTPServer won't work everywhere. I suggest using nws, which is a node module that does the same thing. Would a PR for this be welcome?

Add types to DefinitelyTyped

Add Typescript types to the DefinitelyTyped repo so that imports use the correct types instead of requiring a type stub.

Clicking on the path section of the edge does not select the edge

Repro steps:

  1. Run the example in this repository (npm run example)
  2. On the edge between Node A and Node B, click on the path section between the midpoint (the diamond) and the arrow head.

Expected: The edge to be selected
Actual: The edge is selected for a split second and then it becomes not selected

Create more tests

Tests currently check if the GraphView is exported correctly and whether the graph renders a set of nodes and edges. More complete testing is needed to avoid regressions in the future.

  • Custom node rendering callback spy
  • Various other callback spies (onCreateNode, onDeleteNode, etc.)
  • Dragging nodes (determine if edges follow)
  • Zoom
  • Pan
  • Shift-clicking to create a node
  • Creating edges
  • Changing edge connections (endpoint to new node, start point to new node, reverse start and end)
  • Creating a node in props after initial render to see if the new node is created in the graph
  • Deleting a node in props after initial render
  • Moving a node in props after initial render
  • Selecting a node in props
  • Select node by click (ensure callbacks are only called once)
  • etc.

Arrows on circles and paths are not horizontal.

Describe the bug
Arrows aren't exactly horizontal on round and path-based nodes.

To Reproduce
Steps to reproduce the behavior:

  1. Open the example site.
  2. Add some nodes (using add nodes button)
  3. Notice arrows pointed at circles and paths are slightly offset from the center.

Expected behavior
Arrows should be horizontal.

Desktop (please complete the following information):

  • OS: iOS
  • Browser: Chrome
  • Version: 5.2.3

D3 directly manipulates given props

Steps to reporoduce:

  1. Start example
  2. Set a breakpoint in onUpdateNode()
  3. Drag a node somewhere

Expected behaviour:
graph.nodes[i] === viewNode should evaluate to false
so that I have previous state and a new one to apply

Actual behaviour:
graph.nodes[i] === viewNode is true
which means, that D3 directly changed some parts of the state

First of all: this is discouraged by React documentation:
https://facebook.github.io/react/docs/react-component.html#state

Never mutate this.state directly, as calling setState() afterwards may replace the mutation you made. Treat this.state as if it were immutable.

And it actually means, that it's impossible to track changes history to provide Undo/Redo functionality.
Because there is no previous state available.

The easiest possible solution would be to just make a copy of state before passing it to the GraphView.
But it will break selection functionality. :(

build is failing

here is the output from npm run test after running npm install --save-dev on a clean master branch:

~/dev/git/personal/react-digraph$ npm run test

> [email protected] test /home/mac/dev/git/personal/react-digraph
> NODE_ENV=test npm run lint && npm run fast-test


> [email protected] lint /home/mac/dev/git/personal/react-digraph
> eslint src


/home/mac/dev/git/personal/react-digraph/src/components/graph-view.js
   978:15  error  Component definition is missing display name           react/display-name
   985:23  error  'nodeTypes' is missing in props validation             react/prop-types
   987:53  error  'nodeTypes' is missing in props validation             react/prop-types
   987:69  error  'nodeTypes[].shape' is missing in props validation     react/prop-types
   990:23  error  'nodeSubtypes' is missing in props validation          react/prop-types
   992:53  error  'nodeSubtypes' is missing in props validation          react/prop-types
   992:72  error  'nodeSubtypes[].shape' is missing in props validation  react/prop-types
   995:23  error  'edgeTypes' is missing in props validation             react/prop-types
   997:53  error  'edgeTypes' is missing in props validation             react/prop-types
   997:69  error  'edgeTypes[].shape' is missing in props validation     react/prop-types
  1006:38  error  'edgeArrowSize' is missing in props validation         react/prop-types
  1018:32  error  'gridSpacing' is missing in props validation           react/prop-types
  1023:28  error  'gridDot' is missing in props validation               react/prop-types
  1043:21  error  Component definition is missing display name           react/display-name

/home/mac/dev/git/personal/react-digraph/src/examples/graph.js
  125:15  error  Parsing error: Unexpected token =

✖ 15 problems (15 errors, 0 warnings)

v5: Letting go of shift key when drawing an edge will move the node

Version: 5.0.4

Reproduction steps:

  • Create 2 nodes
  • Hold shift to draw an edge from one node to another
  • Before connecting the edge to the second node, let go of the shift key
  • Move the mouse slightly toward the second node

What should occur: The edge should continue to draw even though the shift key is not pressed as long as the edge was started and the mouse was not released.

What actually occurs: The edge stops rendering and is not removed, so it's left floating in place and the node moves with the mouse.

[Question] How to decrease space in between in Vertical Layout

In the example provided in the project bwdl the digraph uses VerticalTree to layout, however the nodes has way too much space in between each other.

I tried to decrease it by having smaller shapes for nodes and edges but it doens't seem to work.

Is there a way of having fewer space in between nodes with the VerticalTree layout? or perhaps a way of passing parameters to the layout strategy? or a way of passing a new function to calculate it?

thanks for the project, seems to work like a charm.

Can't use in project without babel

The package distributed on NPM includes a non-bundled index.js which uses ES6 statements such as import.

Without Babel in the parent's project, this library can not be used. Or am I missing something?

Creating large graphs bogs down the browser

Describe the bug
Using the example site, creating a large graph will block the browser as the rendering processes many nodes.

To Reproduce
Steps to reproduce the behavior:

  1. Go to example site
  2. Type in 1000 nodes
  3. Tab out of input box or click Add Nodes button
  4. Attempt to zoom, select, or move nodes as they are being rendered
  5. Notice that zooming, selecting, and moving nodes essentially stops later on during the rendering cycle.

Expected behavior
Node selection, zoom, and moving may be slower than normal but it shouldn't stop completely.

Desktop (please complete the following information):

  • Version: 5.2.3

Add edge labels in v5

Is your feature request related to a problem? Please describe.
I want to add edge labels in version 5
like this:
image

Describe the solution you'd like
I think It will be helpful to have renderEdge back.

Describe alternatives you've considered
I think we can have a separate renderEdgeLabel function for this.

Can't run build

After npm i, can't run script "build": "rm -rf dist && babel src -d dist --copy-files -s", as there is no way npm recognizes rm. Any help?

Can't set up

I cloned the repo and installed. This is the error I get:

'rm' is not recognized as an internal or external command,
operable program or batch file.

my npm version is 5.7.1

Bug: Edges with a target node equaling the source node should display as a loopback edge which can be selected

Describe the bug
When an edge's sourceNode and targetNode are the same, currently the edge is rendered as a point with an arrow hanging off it. This point is not selectable, so the edge cannot be deleted.

To Reproduce
Steps to reproduce the behavior:

  1. Using the data, create an edge that has the same source and target node.
  2. Attempt to delete it.

Expected behavior
The edge should be allowed to exist (although there should be no way to create one in react-digraph)

Instead of rendering the edge as a point, make it a line that exits the source node and then returns to the source node in a different position (exit at right, return at top). Provide enough space to allow the user to select the edge for deletion.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.