@lincle/react-web-interactive v0.4.0-next.1
@lincle/react-web-interactive
generates a reactive, composable graph/diagram. @lincle/react-web-interactive
is built on @lincle/base
diagram generating capabilities adding interactive functionality.
Interactivity is provided by:
react-map-interaction
for panning and scalingreact-draggable
for moving of nodes and edges.
The nodes are moveable by default. To pull new edges, tap and hold the diagram or press and hold shift
. To select nodes, press on a node for half a second or hold ctrl
.
*Note: node selection relies on a callback function and is disabled if a callback is not provided.*
Please see the various testing demos for examples.
Installation & Setup
Install @lincle/react-web-interactive
and the peer dependencies react
, react-dom
:
npm install react react-dom @lincle/react-web-interactive
Also include the provided styles file. For example:
import '@lincle/react-web-interactive/dist/main.min.css';
Simple Example
The following example will generate this diagram:
.node {
display: flex;
align-items: center;
justify-content: center;
width: calc(100% - 2px);
height: calc(100% - 2px);
cursor: grab;
border: 1px solid black;
background-color: white;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
}
.node:active {
cursor: grabbing;
}
.node-oval {
border-radius: 50%;
}
<Graph
id='YetAnotherDiagram'
key='1'
nodeHeight={50}
nodeWidth={50}
onEdgeDrop={handleEdgeDrop}
>
<Nodes>
<Node
id={1}
key={1}
x={50}
y={50}
>
<div styleName='node'>
Node 1
</div>
</Node>
<Node
height={100}
id={2}
key={2}
line='direct'
shape='oval'
width={200}
x={100}
y={150}
>
<div styleName='node node-oval'>
Node 2
</div>
</Node>
<Node
id={3}
key={3}
line='curve'
shape='oval'
x={150}
y={350}
>
<div styleName='node node-oval'>
Node 3
</div>
</Node>
</Nodes>
<Edges>
<Edge
id={1}
key={1}
sourceId={1}
targetId={2}
>
<circle
fill='white'
r='3'
stroke='black'
strokeWidth={2}
>
<title>
Bridge
</title>
</circle>
</Edge>
<Edge
id={2}
key={2}
line='direct'
sourceId={2}
targetId={3}
/>
</Edges>
</Graph>
Component API's
* bolded parameters are required
<Graph>
Parameters | Type | Default | Description |
---|---|---|---|
id | string \| number | The unique ID of the graph | |
disableMove | boolean | false | Disable moving nodes |
disablePan | boolean | false | Disable panning the diagram |
disablePull | boolean | false | Disable connecting nodes |
disableScale | boolean | false | Disable zooming/scaling the diagram |
edgeFrequency | number | 16 (60Hz) | Frequency of edge updates during node movements (in ms) |
grid | false \| [number, number] | [16, 16] | The background grid space; false to disable. |
line | "curve" \| "direct" \| "step" | "step" | The default curve for the edges |
maxScale | number | 2 | The maximum zoom/scale of the diagram |
minScale | number | 0.5 | The minimum zoom/scale of the diagram |
mode | "move" \| "pull" | "move" | Forced interaction state of the diagram (moving nodes or pulling/connectiong them) |
nodeFrequency | number | 500 | Frequency of node movements reported (in ms, aside from edges) |
nodeHeight | number | 50 | The default height for nodes (in px) |
nodeWidth | number | 50 | The default width for nodes (in px) |
onEdgeDrop | (sourceId: string, targetId: string) => void | The default callback when an edge is dropped. | |
onMouseDown | (event: MouseEvent<HTMLDivElement>) => void | Callback passed on main diagram <div /> | |
onMouseUp | (event: MouseEvent<HTMLDivElement>) => void | Callback passed on main diagram <div /> | |
onNodeDrag | (event: DraggableEvent, nodeId: ReactText, data: DraggableData) => void | Default callback for dropping an edge | |
onNodeSelect | (nodeId: ReactText) => void | Default callback for selecting a node | |
onNodeStart | (event: DraggableEvent, nodeId: ReactText) => void | Default callback for nodes | |
onNodeStop | (event: DraggableEvent, nodeId: ReactText, data: DraggableData) => void | Default callback for nodes | |
onScale | (scale: number) => void | Callback passed on diagram scale events | |
onTouchEnd | (event: TouchEvent<HTMLDivElement>) => void | Callback passed on main diagram <div /> | |
onTouchStart | (event: TouchEvent<HTMLDivElement>) => void | Callback passed on main diagram <div /> | |
onTranslate | ({x: number, y: number}) => void | Callback passed on diagram translate events | |
scale | number | 1 | The default zoom/scale of the diagram |
shape | "oval" \| "rectangle" | "rectangle" | The default shape for nodes |
snap | boolean \| [number, number] | false | Snap nodes to grid when moved. If true nodes will snap to grid dimensions. |
xOffset | number | 0 | The initial x-axis position of the diagram |
yOffset | number | 0 | The initial y-axis position of the diagram |
<GraphContexts>
Parameters | Type | Default | Description |
---|---|---|---|
Same API as <Graph /> ommiting the mouse and touch event passthrough |
The primary purpose of <GraphContexts>
is to include additional elements in the graph that will share access to the various <Context.Providers>
- such as @lincle/minimap
.
<Nodes>
Parameters | Type | Default | Description |
---|---|---|---|
none |
<Node>
Parameters | Type | Default | Description |
---|---|---|---|
id | string | number | The unique ID of the node | |
x | number | 0 | The initial x coordinate of the node |
y | number | 0 | The initial y coordinate of the node |
The following override the defaults provided by <Graph /> | |||
disableMove | boolean | false | Disable moving this node |
disablePull | boolean | false | Disable connecting this node |
height | number | 50 | The node height |
line | 'curve' \| 'direct' \| 'step' | The connector line shape | |
mode | "move" \| "pull" | The node interactive state (moving node or pulling/connecting) | |
onDrag | (event: DraggableEvent, nodeId: ReactText, data: DraggableData) => void | Callback for node | |
onEdgeDrop | (sourceId: string, targetId: string) => void | Callback for dropping an edge | |
onSelect | (nodeId: ReactText) => void | Callback for selecting a node | |
onStart | (event: DraggableEvent, nodeId: ReactText) => void | Callback for node | |
onStop | (event: DraggableEvent, nodeId: ReactText, data: DraggableData) => void | Callback for node | |
shape | 'oval' \| 'rectangle' | The node shape | |
width | number | 50 | The node width |
<Edges>
Parameters | Type | Default | Description |
---|---|---|---|
dash | boolean \| undefined | undefined | Whether dash should be enabled. Defaults to hover only. |
<Edge>
Parameters | Type | Default | Description |
---|---|---|---|
id | string \| number | The unique ID for the edge | |
dash | boolean \| undefined | undefined | Whether dash should be enabled. Defaults to hover only. |
line | 'curve' \| 'direct' \| 'step' | The line shape (overrides default) and not applicable if custom path generator is used. | |
markerEnd | string | Passed to the default path generated <path> SVG | |
markerStart | string | Passed to the default path generated <path> SVG | |
path | path function - see below | Use to generate a custom path component. | |
sourceId | string \| number | ID for the source node | |
targetId | string \| number | ID for the target node |
*Note: The child of
<Edge />
is intended to be an element at the center of the path. The child will be inside an<SVG />
element and should be an SVG type or wrapped in a<foreignObject />
element. See examples for details.*
Path function
Instead of using the @lincle/react-web-interactive
provided edges (curve
, line
, & step
), you may opt to generate your own path component:
(
source: {
height: number,
id: string | number,
shape: 'oval' | 'rectangle',
width: number,
x: number,
y: number
},
target: {
height: number,
id: string | number,
shape: 'oval' | 'rectangle',
width: number,
x: number,
y: number
},
children?: ReactNode
) => Component<SVG type>
<Grid>
Parameters | Type | Default | Description |
---|---|---|---|
children | SVG | <circle> | The repeated SVG |
Contexts
There are several <Context>
's used that can be taken advantage of to extend the functionality of lincle
via their respective <Context.Provider>
s':
Context | Provides | Description |
---|---|---|
<GraphContext> | {diagramId: ReactText, nodePosition: NodePositions, edgeSubscriber: EdgeSubscriber, defaultSettings: DefaultSettings} | Provides the current diagramId and default settings along with classes to subscribe to <Node> and <Edge> events. |
<GridContext> | [number, number] | Provides the current grid dimensions. |
<ModeContext> | {disableMove?: boolean, disablePull?: boolean, givenMode?: 'move' \| 'pull' \| 'select', mode: 'move' \| 'pull' \| 'select', onMode?: 'move' \| 'pull' \| 'select' => void} | Provides the current graph mode, whether move and pull are enabled on nodes, an optional given override mode, and a function to change the mode. |
<ScaleContext> | {scale: number, onScale?: (scale: number) => void} | Provides the current scale and a function to change the scale. |
<SnapContext> | [number, number] | Provides the current snap dimensions. |
<TranslateContext> | {translate: {x: number, y: number}, onTranslate?: (translate: {x: number, y: number}) => void} | Provides the current graph translation (xOffset and yOffset) and a function to change the translation. |
<TransformContext> | {disablePan?: boolean, disableScale?: boolean, maxScale?: number, minScale?: number} | Provides the rest of the graphs current transform properties. |
27 days ago