Git Product home page Git Product logo

react-flow-chart's Introduction

React Flow Chart

CircleCI

  • Dragabble Nodes and Canvas
  • Create curved links between ports
  • Custom components for Canvas, Links, Ports, Nodes
  • React state container
  • Update state on Select/Hover nodes, ports and links
  • Base functionality complete
  • Stable NPM version
  • Scroll/Pinch canvas to zoom
  • Ctrl+z/Ctrl+y history
  • Read-only mode
  • Redux state container
  • Arrow heads on links
  • Docs

This project aims to build a highly customisable, declarative flow chart library. Critically, you control the state. Pick from Redux, MobX, React or any other state managment library - simply pass in the current state and hook up the callbacks.

For example:

demo

Data Stucture

The flow chart is designed as a collection of Nodes, Ports and Links. You can specify your own custom properties, making this format quite flexible. See types/chart.ts. Note, nodes, ports and links should have a unique id.

Example

export const chart: IChart = {
  offset: {
    x: 0,
    y: 0,
  },
  scale: 1,
  nodes: {
    node1: {
      id: 'node1',
      type: 'output-only',
      position: {
        x: 300,
        y: 100,
      },
      ports: {
        port1: {
          id: 'port1',
          type: 'output',
          properties: {
            value: 'yes',
          },
        },
        port2: {
          id: 'port2',
          type: 'output',
          properties: {
            value: 'no',
          },
        },
      },
    },
    node2: {
      id: 'node2',
      type: 'input-output',
      position: {
        x: 300,
        y: 300,
      },
      ports: {
        port1: {
          id: 'port1',
          type: 'input',
        },
        port2: {
          id: 'port2',
          type: 'output',
        },
      },
    },
  },
  links: {
    link1: {
      id: 'link1',
      from: {
        nodeId: 'node1',
        portId: 'port2',
      },
      to: {
        nodeId: 'node2',
        portId: 'port1',
      },
    },
  },
  selected: {},
  hovered: {},
}

This will produce a simple 2 noded chart which looks like:

Demo

Basic Usage

npm i @mrblenny/react-flow-chart

Most components/types are available as a root level export. Check the storybook demo for more examples.

import { FlowChartWithState } from "@mrblenny/react-flow-chart";

const chartSimple = {
  offset: {
    x: 0,
    y: 0
  },
  nodes: {
    node1: {
      id: "node1",
      type: "output-only",
      position: {
        x: 300,
        y: 100
      },
      ports: {
        port1: {
          id: "port1",
          type: "output",
          properties: {
            value: "yes"
          }
        },
        port2: {
          id: "port2",
          type: "output",
          properties: {
            value: "no"
          }
        }
      }
    },
    node2: {
      id: "node2",
      type: "input-output",
      position: {
        x: 300,
        y: 300
      },
      ports: {
        port1: {
          id: "port1",
          type: "input"
        },
        port2: {
          id: "port2",
          type: "output"
        }
      }
    },
  },
  links: {
    link1: {
      id: "link1",
      from: {
        nodeId: "node1",
        portId: "port2"
      },
      to: {
        nodeId: "node2",
        portId: "port1"
      },
    },
  },
  selected: {},
  hovered: {}
};

const Example = (
  <FlowChartWithState initialValue={chartSimple} />
);

With Internal State

stories/InternalReactState.tsx

With External State

stories/ExternalReactState.tsx

Readonly Mode

stories/ReadonlyMode.tsx

Other Demos

stories/ExternalReactState.tsx

Contributing

If you're interested in helping out, let me know.

In particular, would be great to get a hand with docs and redux / mobx integrations.

Development

npm install
npm run start:storybook

react-flow-chart's People

Contributors

ajuhos avatar alexkuz avatar andrewadams3 avatar crsven avatar ecarrasquero avatar fenech avatar idealsystemsmcp avatar lax1089 avatar leonzamel avatar loonyuni avatar lordi avatar lukewarlow avatar mrblenny avatar msteinmn avatar noytse avatar parasg1999 avatar pokai-chang-appier avatar svenliebig avatar yukai-w avatar yuyokk 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

react-flow-chart's Issues

BUG: "TypeError: Converting circular structure to JSON" when trying to stringify state

When using your code from this issue, and adding a single button which logs the chart in the console, I get the following error after I move node with id "node2". It only happens with snapToGrid set to false.

I believe the issue lies in the position property on the node, which holds several new values like "deltaX, deltaY, lastX, lastY, node", with the latter being a reference to the DOM node.

import React, { useState, useEffect } from 'react';
import { FlowChart } from '@mrblenny/react-flow-chart';
import * as actions from '@mrblenny/react-flow-chart/src/container/actions';
export default function ChatEditor() {
  let [chart, updateChart] = useState({
    offset: {
      x: 0,
      y: 0
    },
    nodes: {
      node1: {
        id: 'node1',
        type: 'output-only',
        position: {
          x: 0,
          y: 0
        },
        ports: {
          port1: {
            id: 'port1',
            type: 'output',
            properties: {
              value: 'yes'
            }
          },
          port2: {
            id: 'port2',
            type: 'output',
            properties: {
              value: 'no'
            }
          }
        }
      },
      node2: {
        id: 'node2',
        position: {
          x: 300,
          y: 100
        },
        type: 'input-output',
        ports: {
          port3: {
            id: 'port3',
            type: 'output'
          },
          port4: {
            id: 'port4',
            type: 'input'
          }
        }
      }
    },
    links: {},
    selected: {},
    hovered: {}
  });

  let stateActionCallbacks = Object.keys(actions).reduce((obj, key, idx) => {
    obj[key] = (...args) => {
      let action = actions[key];
      let newChartTransformer = action(...args);
      let newChart = newChartTransformer(chart);
      updateChart({ ...chart, ...newChart });
      return newChart;
    };
    return obj;
  }, {});
  return (
    <div>
      <div
        onClick={() => {
          try {
            console.log(JSON.stringify(chart.nodes['node2'].position));
          } catch (e) {
            console.log(e, chart.nodes['node2']);
          }
        }}
      >
        get state
      </div>
      <FlowChart chart={chart} callbacks={stateActionCallbacks} />
    </div>
  );
}

screenshot:

screenshot

codesandbox demo

docs?

Love the library, thank you for working on this! I have been looking all over for a declarative approach to diagram building, the other alternatives are either too imperative for my taste or just non existent.

For the life of me, I am not able to find the docs or a getting started tutorial, I tried digging into the code itself specifically in the storybook but it's a webpacked script which makes it not really readable. Any other place I should look into?

Question: How to have multiple nodes inside a container node

Just wondering the best way to do this... imagine 3 joined nodes that act as containers, in each of the container nodes are other nodes connected. Would the best practice be to call another instance of the flow chart within a custom node type of say container?

BUG: CanvasWrapper's onDrop event assumes canvas is positioned in the top left of the document.

Right now the onDrop event handler assumes determines the position to place a node when the on drop event fires based on the clientX and clientY properties of the drop event, correcting for the Chart's offset.

This works when the canvas is in the top left hand corner of the document. However, when the Canvas is positioned to the right, or down, the clientX and clientY values do not correspond to the position of a users mouse when the drop event occurred.

Proposing making the following change to the onDrop method that gets passed to ComponentInner in Canvas.wrapper.tsx

onDrop={ (e) => {
  const data = JSON.parse(e.dataTransfer.getData(REACT_FLOW_CHART))
  let elementOffset;
  if (this.ref.current){
    elementOffset = {
      x: this.ref.current.offsetLeft,
      y: this.ref.current.offsetTop
    }
  }else{
    elementOffset = {x: 0, y: 0}
  }
  onCanvasDrop({ data, position: {
    x: e.clientX - (position.x + elementOffset.x),
    y: e.clientY - (position.y + elementOffset.y),
  }})
} }

this would get the actual offset of the HTML element on the page and include this when calculating where the node should drop.

Does anyone see any issues with this? Should I make a PR?

Some additions you might find useful

I created a fork with a number of fixes and some additions you might find useful. I am looking for some input on whether you'd like me to create a PR. The additions are summarized like that:

  • Allow nodes to be React components and not just styled divs
  • Adjust for chart offset origin different than 0,0 and scrolling
  • Added a resize observer to detect node size changes and re-render ports and links
  • Node size now adjusts properly, re-rendering ports and links on node size change
  • Allow nodes to be rotated with ports rotating accordingly. New prop orientation on the node defines the angle of rotation of the node (ports rotate automatically, the node needs to be given specific css to rotate it)
  • Exported actions so that it can be used with the FlowChart component
  • Added a validation function (needs some more work) for new links
  • Added nodeProps prop to Flowchart so that data can be sent to e.g. autocomplete menu options inside nodes (spread to Node and InnerNode)
  • Added boolean snap prop to Flowchart to enable snap to grid for node placements

https://github.com/SteamFab/react-flow-chart/commits/PortPositionChange
branch PortPositionChange, specific changes are separated by commit

Discussion: Immutable chart actions

Currently the actions are changing the chart object.

From my experience in react it's better to clone the state object than change the object itself for various reasons (for react to know when to update the DOM without deep comparison with previous state)

For example: in actions.ts:

if (chart.selected.id !== nodeId || chart.selected.type !== 'node') {
  chart.selected = {
    type: 'node',
    id: nodeId,
  }
}
return chart

Would be immutable as:

 if (chart.selected.id !== nodeId || chart.selected.type !== "node") {
   return {
     ...chart,
     selected: {
       type: "node",
       id: nodeId
     }
   };
 }
 else return chart;

@MrBlenny What do you think?

API: nodes object vs nodes array

I get that using object for nodes, ports etc. is more convenient (and effective) for lookup, but from user's perspective array seems more natural in this case (arrays are easier to build and there's no need to "duplicate" node id as property name). Object (or Map) could be an internal implementation in this case. What do you think on that?
(obviously I can make a wrapper for that - which I will do for now - but maybe it's worth changing API)

Failed to compile

I tried to import this lib in a new create-react-app --typescript project but failed. I thought that may be something incompatible with create-react-app 2.1.8, so I clone the project and run start:storybook after yarn installed. It still failed with error Type 'TouchEvent' is not assignable to type 'MouseEvent'.

ERROR in /Users/windrunner/workspace/react-flow-chart/src/components/Canvas/Canvas.wrapper.tsx
./src/components/Canvas/Canvas.wrapper.tsx
[tsl] ERROR in /Users/windrunner/workspace/react-flow-chart/src/components/Canvas/Canvas.wrapper.tsx(40,49)
      TS2345: Argument of type 'DraggableEvent' is not assignable to parameter of type 'MouseEvent'.
  Type 'TouchEvent' is not assignable to type 'MouseEvent'.

ERROR in /Users/windrunner/workspace/react-flow-chart/src/components/Node/Node.wrapper.tsx
./src/components/Node/Node.wrapper.tsx
[tsl] ERROR in /Users/windrunner/workspace/react-flow-chart/src/components/Node/Node.wrapper.tsx(33,43)
      TS2345: Argument of type 'DraggableEvent' is not assignable to parameter of type 'MouseEvent'.
  Type 'TouchEvent' is missing the following properties from type 'MouseEvent': button, buttons, clientX, clientY, and 18 more.
ℹ 「wdm」: Failed to compile.

BTW, how can I use this in an existing non-TS project? It always failed to import @mrblenny/react-flow-chart. Can you provide a simple example on codesandbox or something like that?

Add support for "smart" link routing

Are there any plans to implement a "smart" link routing prop, where instead of taking the shortest path between two ports, links will avoid collision with other nodes to give the chart a neater appearance? Example attached
nodes

onLinkComplete action

I've been playing about with this package and spotted that here it compares the fromNodeId and toPortId to determine whether or not to persist the link.

Surely this will always be true? Would this be the expected behaviour?

If not, I'm happy to put up a PR to fix it.

BUG: Links don't update when node size changes

When using custom node components with a variable width or height, the start and end points of links will not update when the node size changes.

The ports and the link start match up at first

The ports and the link start match up at first

But then go out of sync when the node size changes

But then go out of sync when the node size changes

Should the position props on ports update when the nodeSize changes? Where is their position initially set?

Exporting diagams into json

Curious to know if you've developed the functionality for diagrams to be exportable into json?
Example: If I create a diagram. I'd like to export it into json via a file or an open post call for a server to consume.

TypeScript definition of ILink

currently:

export interface ILink {
id: string
from: {
nodeId: string
portId: string,
}
to: {
nodeId?: string
portId?: string
/** System Temp */
position?: IPosition,
}
properties?: any
}

I believe the to property will be more accurate like this:

  to: {
    explicit_destination: true
    nodeId: string
    portId: string
  } | {
    explicit_destination: false
    position: IPosition,
  }

Link positioned incorrectly

When creating a new link from a port it is mis-aligned based on how far away the flow-chart is from the page corner.

E.G. if you add 20 pixels of margin to the App class in the CodePen example and you start dragging a new link it'll be positioned 20 pixels too far to the bottom right.

Checking the parentElement's bounding position and then using that in the onMove handler might fix this. Just running a quick test with this seems to fix this issue:

const mouseMoveHandler = (e: MouseEvent) => {
  const element = document.querySelector('.react-draggable')
  let parentModifier: any = { x: 0, y: 0 }
   if (element) {
    const parentElement = element.parentElement
     if (parentElement) {
      const parentBoundingRect = parentElement.getBoundingClientRect()
       parentModifier = parentBoundingRect
    }
  }
   onLinkMove({
    linkId, startEvent, fromNodeId, fromPortId,
    toPosition: {
      x: e.clientX - chart.offset.x - parentModifier.x,
      y: e.clientY - chart.offset.y - parentModifier.y,
   },
  })
}

Is it possible to add/edit label on links?

Hi,
I have some questions.
Is it possible to add/edit label on links?
is it possible to rename the node(box)
does it work it on IE11?

This library looks good so I am considering to use it, however those above functions are needed to me. So could you please answer about it? Thank you

onNodeSizeChange does not return value for callback

The callback onNodeSizeChange defined in actions.ts
does not return a value, which means you need to manually override it when trying to create state hooks for the chart component.

For example, I only want to override some event handlers so I import the already defined handlers:

import * as callbacks from '@mrblenny/react-flow-chart/src/container/actions';

// define the correct handler (return the chart)
export const onNodeSizeChange = ({ nodeId, size }) => (chart) => {
  chart.nodes[nodeId] = {
    ...chart.nodes[nodeId],
    size,
  };
  return chart
};
// overwrite the existing handler with our patched version
callbacks.onNodeSizeChange = onNodeSizeChange;

// utility to allow partial override of callbacks
export const configureChart = (setChart, overrides = {}) => (
  Object.keys(callbacks).reduce((reducer, key) => {
    const callback = overrides && typeof overrides[key] !== 'undefined' ? overrides[key] : callbacks[key];
    reducer[key] = (...args) => setChart(callback(...args));
    return reducer;
  }, {})
);

I can then define a component with my custom overrides, while preserving the other default handlers:

 const [chart, setChart] = useState(initialChart);
  const callbacks = configureChart(setChart, {
    onDeleteKey, // some custom handler
    onNodeClick, // another custom handler
  });

I can open a PR, essentially all that is required is to return the updated chart from the handler.

Right angle links between nodes

I wrote a function to generate straight line links between nodes, but hit a limitation:

right angle links between nodes

I used the same logic as in generateCurvePath to determine whether the link was "horizontal" (i.e. width > height) to switch between the two link shapes, but I think that it makes more sense to base the behaviour on which edge of the node the link enters/exits. That is, a link from the top/bottom of a node should start vertical, whereas a link from the left/right should start horizontal.

Would it make sense to add the chart state to the list of props passed to the <Link> component, to make it possible to look up the port and make this decision within the component?

I guess that in order to implement #54, it would also be necessary to look at the whole chart state in order to decide where to put each line.

Linking continues on mouse release

When I link two nodes through clicking on the ports, it doesn't stop dragging and create the link but instead allows continuous dragging onto other ports. Not sure if this is intended.

Some feature suggestions

Hi, I'm going to update our internal tools that use a similar component and yours looks like a promising replacement. However, I'll need some improvements to match current functionality, like:

  • customizable node connections;
  • automatic port positioning:
  • rendering only nodes in view - for performance, react-window-style

Are you up for PRs? Pleas let me know if any of this is out of scope for your lib. Thanks!

Callbacks events not working in JSX

My callback actions are not working in JSX.

const StateActions={
			onDragNode:onDragNode,
			onDragCanvas:function(event, data){alert("dragged")}
		}


Automatic layout

It would be nice to have an automatic layout feature.

Here is my example using dagre:

Chart data

const chart = {
  nodes: {
    node1: {
      id: "node1",
      ports: // ...
      // there is no need for `position` key in the node
     }
  edges: // ...
}

Initialize dagre

import dagre from 'dagre'

const g = new dagre.graphlib.Graph()
g.setGraph({})
g.setDefaultEdgeLabel(function() { return {}; })

Calculate layout:

for (let nodeId in chart.nodes) {
  // you need to know dimension of every node
  g.setNode(nodeId, { width: 200, height: 100 });
}

for (let k in chart.links) {
  g.setEdge(chart.links[k].from.nodeId, chart.links[k].to.nodeId);
}

dagre.layout(g);

Save it to the chart variable:

for (let nodeId in chart.nodes) {
  chart.nodes[nodeId].position = {
    x: g.node(nodeId).x - 200 / 2, // dagre gives position from the center of node
    y: g.node(nodeId).y - 100 / 2
  }
}

Downside of calculating it before rendering is that we may don't know sizes of nodes.

Custom Node Links bug after upgrade to 0.0.7

Hello after upgrading the package to the new version, i am getting the linked lines visually incorrect like the following image:

flowchart-bug

I am using the following component to draw the custom node:

import * as React from 'react'
import styled from 'styled-components'

const Start = styled.div`
  position: absolute;
  width: 200px;
  height: 55px;
  padding: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-image: linear-gradient(45deg,#23bcbb,#45e994);
  color: #fff;
  border-radius:5px;
  -webkit-box-shadow: 0px 1px 5px -1px rgba(0,0,0,0.62);
-moz-box-shadow: 0px 1px 5px -1px rgba(0,0,0,0.62);
box-shadow: 0px 1px 5px -1px rgba(0,0,0,0.62);
`

const End = styled.div`
  position: absolute;
  width: 200px;
  height: 60px;
  padding: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  background-image: linear-gradient(45deg,#ee0979,#ff6a00);
  color: #fff;
  border-radius:5px;
  -webkit-box-shadow: 0px 1px 5px -1px rgba(0,0,0,0.62);
-moz-box-shadow: 0px 1px 5px -1px rgba(0,0,0,0.62);
box-shadow: 0px 1px 5px -1px rgba(0,0,0,0.62);
`

const InputDiv = styled.div`
  position: absolute;
  width: 200px;
  height: 135px;
  padding: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  background: #fff;
  border-radius:5px;
  -webkit-box-shadow: 0px 1px 5px -1px rgba(0,0,0,0.62);
-moz-box-shadow: 0px 1px 5px -1px rgba(0,0,0,0.62);
box-shadow: 0px 1px 5px -1px rgba(0,0,0,0.62);
`


const Node = ({ node, children, ...otherProps }) => {
  if(node.type === 'output-only') {
    return (
      <Start {...otherProps}>
        {children}
      </Start>
    )
  } else if(node.type === 'input-only') {
    return (
      <End {...otherProps}>
        {children}
      </End>
    )
  } else {
    return (
      <InputDiv {...otherProps}>
        {children}
      </InputDiv>
    )
  }
}

const NodeFlowchart = React.forwardRef((props, ref) => (
  <Node {...props} innerRef={ref} />
));


export { NodeFlowchart }

Any ideas why it´s not working properly?

Thank you,
cheers.

use in a Parcel.js project shows warnings of 'Could not load source file "..." in source map of "..."'

Here is a discussion on why this occurs:
parcel-bundler/parcel#2356
parcel-bundler/parcel#2346

It's not a huge issue because it builds fine. It's just disconcerting when one first imports the library to get a terminal full of warnings so I just thought I'd bring it to attention. Thanks!

Here is the output when I build:

⚠️ Could not load source file "../../src/index.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/index.js". ⚠️ Could not load source file "../../src/constants.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/constants.js". ⚠️ Could not load source file "../../../src/components/index.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/index.js". ⚠️ Could not load source file "../../../src/container/index.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/container/index.js". ⚠️ Could not load source file "../../../src/container/FlowChartWithState.tsx" in source map of "../node_modules/@mrblenny/react-flow-chart/src/container/FlowChartWithState.js". ⚠️ Could not load source file "../../../src/container/actions.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/container/actions.js". ⚠️ Could not load source file "../../../../src/components/NodeInner/index.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/NodeInner/index.js". ⚠️ Could not load source file "../../../../src/components/PortsGroup/index.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/PortsGroup/index.js". ⚠️ Could not load source file "../../../../src/components/Node/index.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/Node/index.js". ⚠️ Could not load source file "../../../../src/components/Link/index.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/Link/index.js". ⚠️ Could not load source file "../../../../src/components/Port/index.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/Port/index.js". ⚠️ Could not load source file "../../../../src/components/FlowChart/index.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/FlowChart/index.js". ⚠️ Could not load source file "../../../../src/container/utils/mapValues.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/container/utils/mapValues.js". ⚠️ Could not load source file "../../../../src/container/utils/rotate.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/container/utils/rotate.js". ⚠️ Could not load source file "../../../../src/components/Ports/index.ts" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/Ports/index.js". ⚠️ Could not load source file "../../../../src/components/Canvas/index.tsx" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/Canvas/index.js". ⚠️ Could not load source file "../../../../src/components/NodeInner/NodeInner.default.tsx" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/NodeInner/NodeInner.default.js". ⚠️ Could not load source file "../../../../src/components/Node/Node.wrapper.tsx" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/Node/Node.wrapper.js". ⚠️ Could not load source file "../../../../src/components/Node/Node.default.tsx" in source map of "../node_modules/@mrblenny/react-flow-chart/src/components/Node/Node.default.js".

How to align the whole graph inside a div?

How can I keep the nodes (grouped together) aligned in the center? So if I resize the graph container in width the nodes stay aligned to the center rather than left side of the container?

Implementing zoom

Hi! Thanks so much for your work on react-flow-chart so far - Using it for a personal project and it's worked perfectly.

I'm implementing zoom at the moment. Trying to figure out the best way to go about this - Since the container is just a plain div, is the best way to zoom in/out to just adjust the zoom property? I'm not sure I can think of another way to implement this functionality.

Thanks!

Node sticky and non-deletable properties

It would be great to have two additional node properties - to set nodes be sticky (not able to move) and to make them non-deletable. Non-deletable links is good to have too.

onCanvasDrag change offset in state

Normally offset in state is {x:number, y:number}. However, after I dragged the canvas. the offset will set to be like
offset:{
deltaX: -1
deltaY: 0
lastX: 32
lastY: -78
node: div.sc-bdVaJa.doHFhw.react-draggable.react-draggable-dragged
x: 31
y: -7
}
is this expected? I thought offset will stay like {x:number, y:number}

Multiple selection

Hi, it'll be good if it'll be possible to select multiple items (nodes & links). :)
I guess, I'll implement it and make a PR, but let me know if you're already working on it

[Question] Is there any way to read-only certain nodes or certain links?

I know we can overwrite the flow chat config to set the whole flow chat read-only like the:

export const ReadonlyMode = () => {
  return (
    <Page>
      <FlowChartWithState config={{ readonly: true }} initialValue={chartSimple}/>
    </Page>
  )
}

but I want to set certain nodes or certain links read-only and cannot drag

Is there any methods?

License

Hey there. This is looking pretty interesting and would love to investigate further, but alas no license. Any chance this could be added? The package.json says MIT but there is nothing in the repo.

Keep up the good work :)

Provide listeners with FlowChartWithState

I want to listen when a node is selected by the user. For some reason, I was not able to import the functions declared in container/actions.ts. So I copied the source code into a local file and then imported it.


export const onNodeSizeChange: IOnNodeSizeChange = ({ nodeId, size }) => (chart: IChart) => {
  chart.nodes[nodeId] = {
    ...chart.nodes[nodeId],
    size,
  }
}

For some reason the chart is null. This brings the app to an halt. Which goes to say, I was not able to setup the FlowChart with my own state because of the above mentioned reasons.

I'm using the FlowChartWithState right now. It would be nice if the state and event callbacks were separated. The FlowChartWithState class does not expose any listener callbacks. Alternatively, I tried using the onClick callback on a custom NodeInner to listen for events. Looks like the event propagation is being blocked.

In short, I'm not able to listen to events using the FlowChartWithState class. Please provide an update for this issue as soon as possible (the flow chart is the primary component in my project). I'm willing to contribute the project if it helps.

Linking continues on mouse release

When I link two nodes through clicking on the ports, it doesn't stop dragging and create the link but instead allows continuous dragging onto other ports. Not sure if this is intended.
image

Delete selected edge

When an edge is selected and I press the Esc button I expect it to be removed

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.