@linkurious/ogma-react v5.0.3
@linkurious/ogma-react
Wrapper library for @linkurious/ogma
to use with React.
Getting Started
Add @linkurious/ogma
and @linkurious/ogma-react
to your project. For Ogma, you should use you NPM link from get.linkurio.us.
npm install <YOUR_LINK_WITH_API_KEY>
npm i @linkurious/ogma-react --save
Or, with yarn:
yarn i <YOUR_LINK_WITH_API_KEY>
yarn add @linkurious/ogma-react
You will need the CSS or Styled Components (see web/src/index.css
for an example). No CSS is included by default.
import { Ogma, NodeStyle, Popup } from '@linkurious/ogma-react';
import { MouseButtonEvent, Node as OgmaNode } from '@linkurious/ogma';
...
const [clickedNode, setClickedNode] = useState<OgmaNode|null>(null);
const onMouseMove = ({ target }: MouseButtonEvent) => {
setClickedNode((target && target.isNode) ? target : null);
}
<Ogma
options={...}
onReady={(ogma) => {
ogma.events.on('click', onClick);
}}
>
<NodeStyle attributes={{ color: 'red', radius: 10 }} />
<Popup
position={() => clickedNode ? clickedNode.getPosition() : null}
>
<div>Popup content here!</div>
</Popup>
</Ogma>
Usage
See the web/src/App.tsx
file for a complete example.
const graph: Ogma.RawGraph = ...;
return <Ogma options={{ backgroundColor: '#9dc5bb'}} graph={graph}>
Custom components
You can (and should) create your own components to implement different behaviors. It's easy, you just need to use the useOgma
hook to get access to the instance of Ogma.
import { useOgma } from '@linkurious/ogma-react';
export function MyComponent() {
const ogma = useOgma();
const onClick = useCallback(() => {
ogma.getNodes([1,2,3,4]).setSelected(true);
}, []);
return (
<div>
<button onClick={onClick}>Select nodes 1, 2, 3, 4</button>
</div>
);
}
How to apply the layouts
It's unintuitive to implement the layouts as a React component declaratively. We suggest using custom components and hook to ogma events to apply the layouts.
components/LayoutService.tsx
:
import { useEffect } from 'react';
import { useOgma } from '@linkurious/ogma-react';
export function LayoutService () {
const ogma = useOgma(); // hook to get the ogma instance
useEffect(() => {
const onNodesAdded = () => {
// apply your layout
}
ogma.events.on('addNodes', onNodesAdded);
// cleanup
return () => {
ogma.events.off(onNodesAdded);
};
}, []);
return null;
}
App.tsx
:
import { LayoutService } from './components/LayoutService';
export default function App() {
... // retrive the graph here
return (<Ogma options={options} graph={graph}>
<LayoutService />
</Ogma>);
}
How to load the graph
import { useState, useEffect } from 'react';
import { RawGraph } from '@linkurious/ogma';
import { Ogma } from '@linkurious/ogma-react';
export default function App () {
const [isLoading, setIsLoading] = useState(true);
const [graph, setGraph] = useState<RawGraph>();
useEffect(() => {
fetch('/graph.json')
.then(res => res.json())
.then(json => {
setGraph(json);
setIsLoading(false);
});
}, []);
if (isLoading) return (<div>Loading...</div>);
return (<Ogma graph={graph}/>);
}
Using the parsers:
import { useState, useEffect } from 'react';
import OgmaLib, { RawGraph } from '@linkurious/ogma';
import { Ogma } from '@linkurious/ogma-react';
export default function App () {
const [isLoading, setIsLoading] = useState(true);
const [graph, setGraph] = useState<RawGraph>();
// using ogma parser to parse GEXF format
useEffect(() => {
fetch('/graph.gexf')
.then(res => res.text())
.then(gexf => OgmaLib.parse.gexf(gexf))
.then(jsonGraph => {
setGraph(jsonGraph);
setIsLoading(false);
});
}, []);
if (isLoading) return (<div>Loading...</div>);
return (<Ogma graph={graph} />)
}
Components
API
<Ogma />
Main visualisation component. You can use onReady
or ref
prop to get a reference to the Ogma instance.
Props
Prop | Type | Default | Description |
---|---|---|---|
options? | Ogma.Options | {} | Ogma options |
graph? | Ogma.RawGraph | null | The graph to render |
onReady? | (ogma: Ogma) => void | null | Callback when the Ogma instance is ready |
ref? | React.Ref<Ogma> | null | Reference to the Ogma instance |
children | React.ReactNode | null | The children of the component, such as <Popup> or <Tooltip> or your custom component. Ogma instance is avalable to the children components through useOgma() hook |
<NodeStyle />
Node style component.
Props
Prop | Type | Default | Description |
---|---|---|---|
attributes | Ogma.NodeAttributeValue | {} | Attributes to apply to the node |
selector? | (node: Ogma.Node) => boolean | null | Selector to apply the attributes to the node |
ref? | React.Ref<Ogma.StyleRule> | null | Reference to the style rule |
Example
<Ogma>
<NodeStyle attributes={{ color: "red", radius: 10 }} />
</Ogma>
<EdgeStyle />
Edge style component.
Props
Prop | Type | Default | Description |
---|---|---|---|
attributes | Ogma.EdgeAttributeValue | {} | Attributes to apply to the edge |
selector? | (edge: Ogma.Edge) => boolean | null | Selector to apply the attributes to the edge |
ref? | React.Ref<Ogma.StyleRule> | null | Reference to the style rule |
Example
<Ogma>
<EdgeStyle attributes={{ color: "red" }} />
</Ogma>
<Popup />
Custom popup UI layer.
Props
Prop | Type | Default | Description |
---|---|---|---|
position | Point \| (ogma: Ogma) => Point | null | Position of the popup |
size? | { width: number \| 'auto'; height: number \| 'auto'; } | { width: 'auto', height: 'auto' } | Size of the popup |
children | React.ReactNode | null | The children of the component |
isOpen | boolean | true | Whether the popup is open |
onClose | () => void | null | Callback when the popup is closed |
placement | 'top' \| 'bottom' \| 'right'\| 'left' | Placement of the popup | |
ref? | React.Ref<Popup> | null | Reference to the popup |
closeOnEsc? | boolean | true | Whether to close the popup when the user presses the ESC key |
popupClass? | string | 'ogma-popup' | Class name to apply to the popup container |
contentClass? | string | 'ogma-popup--content' | Class name to apply to the popup content |
popupBodyClass? | string | 'ogma-popup--body' | Class name to apply to the popup body |
closePopupClass? | string | 'ogma-popup--close' | Class name to apply to the close button |
Example
<Ogma>
<Popup
position={() => (clickedNode ? clickedNode.getPosition() : null)}
size={{ width: 200, height: 200 }}
>
<div>Popup content here!</div>
</Popup>
</Ogma>
<Tooltip />
Tooltip component. Use it for cutom movable tooltips. It automatically adjusts the placement of the tooltip to conainer bounds.
Props
Prop | Type | Default | Description |
---|---|---|---|
position | Point \| (ogma: Ogma) => Point | Position of the tooltip | |
size? | { width: number \| 'auto'; height: number \| 'auto'; } | { width: 'auto', height: 'auto' } | Size of the tooltip |
children | React.ReactNode | null | The children of the component |
visible | boolean | true | Whether the tooltip is open |
placement | Placement | right | Placement of the tooltip |
ref? | React.Ref<Tooltip> | null | Reference to the tooltip |
tooltipClass | string | 'ogma-tooltip' | Class name to apply to the tooltip container |
Example
<Ogma>
<Tooltip
visible={hoveredNode}
position={() => (hoveredNode ? hoveredNode.getPosition() : null)}
size={{ width: 200, height: 200 }}
>
<div>Tooltip content here!</div>
</Tooltip>
</Ogma>
<CanvasLayer />
Custom canvas layer.
Props
Prop | Type | Default | Description |
---|---|---|---|
ref | React.Ref<CanvasLayer> | null | Reference to the canvas layer |
render | (ctx: CanvasRenderingContext2D) => void | null | Callback to render the canvas layer |
index? | number | 1 | Index of the layer |
isStatic? | boolean | false | Whether the layer is static |
noClear? | boolean | false | Whether to clear the canvas before rendering |
Example
<Ogma>
<CanvasLayer
render={(ctx) => {
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 100, 100);
}}
/>
</Ogma>
<Layer />
Generic DOM layer, see ogma.layers.addLayer
.
Props
Prop | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | null | The children of the layer |
Example
<Ogma>
<Layer>
<span>Layer content here!</span>
</Layer>
</Ogma>
<Overlay />
Generic Overlay layer, see ogma.layers.addOverlay
.
Props
Prop | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | null | The children of the layer |
className | string | null | Classname for the Overlay |
scaled | boolean | true | Wether the Overlay is scaled on zoom or not |
position | Point \| (ogma: Ogma) => Point | Position of the Overlay | |
size? | { width: number \| 'auto'; height: number \| 'auto'; } | { width: 'auto', height: 'auto' } | Size of the Overlay |
Example
<Ogma>
<Overlay position={{x: 0, y: 0}} >
<span>Layer content here!</span>
</Overlay>
</Ogma>
Transformations
All transformations have callback props, making it easy to react to events related to transformations.
| Prop | Type | Default | Description |
| ------------ | ------------------------------ | ------- | ----------- |
| onEnabled
| (t: Transformation) => void
| null
| Triggered when transformation is enabled |
| onUpdated
| (t: Transformation) => void
| null
| Triggered when transformation is refreshed |
| onDisabled
| (t: Transformation) => void
| null
| Triggered when transformation is disabled |
| onDestroyed
| (t: Transformation) => void
| null
| Triggered when transformation is destroyed |
| onSetIndex
| (t: Transformation, i: number) => void
| null
| Triggered when transformation changes index |
<NodeGrouping />
Node grouping transformation. See ogma.transformations.addNodeGrouping()
for more details.
Props
Prop | Type | Default | Description |
---|---|---|---|
selector | (node: Ogma.Node) => boolean | null | Selector to apply the attributes to the node |
groupIdFunction | (node: Ogma.Node) => string \| undefined | Grouping function | |
ref? | React.Ref<Ogma.Transformation> | null | Reference to the transformation |
...rest | See ogma.transformations.addNodeGrouping() properties | Node grouping transformation properties |
Example
<Ogma graph={...}>
<NodeGrouping
selector={node => node.getAttribute('type') === 'type1'}
groupIdFunction={node => node.getAttribute('type')}
disabled={false}
/>
</Ogma>
<EdgeGrouping />
Edge grouping transformation. See ogma.transformations.addEdgeGrouping()
for more information.
Props
Prop | Type | Default | Description |
---|---|---|---|
selector | (edge: Ogma.Edge) => boolean | null | Selector for the edges |
groupIdFunction | (edge: Ogma.Edge) => string \| undefined | Grouping function | |
ref? | React.Ref<Ogma.Transformation> | null | Reference to the transformation |
...rest | See ogma.transformations.addEdgeGrouping() properties | Edge grouping transformation properties |
Example
<Ogma graph={...}>
<EdgeGrouping
selector={edge => edge.getAttribute('type') === 'type1'}
groupIdFunction={edge => edge.getAttribute('type')}
disabled={false}
/>
</Ogma>
<NodeFilter />
Node filter transformation. See ogma.transformations.addNodeFilter()
for more information.
Props
Prop | Type | Default | Description |
---|---|---|---|
...props | Ogma.NodeFilterOptions | See ogma.transformations.addNodeFilter() for more information. |
Example
<Ogma graph={...}>
<NodeFilter
criteria={node => node.getData('age') > 22}
disabled={false}
/>
</Ogma>
<EdgeFilter />
Wrapper for the edge filter transformation. See ogma.transformations.addEdgeFilter()
for more information.
Props
Prop | Type | Default | Description |
---|---|---|---|
...props | Ogma.EdgeFilterOptions | See ogma.transformations.addEdgeFilter() for more information. |
Example
<Ogma graph={...}>
<EdgeFilter
criteria={edge => edge.getData('type') === 'important'}
disabled={false}
/>
</Ogma>
<NeighborMerging />
Neighbor merging transformation. See ogma.transformations.addNeighborMerging()
for more information.
Props
Prop | Type | Default | Description |
---|---|---|---|
selector | (node: Ogma.Node) => boolean | null | Selector |
dataFunction | (node: Ogma.Node) => object | undefined; | Neighbor data function | |
ref? | React.Ref<Ogma.Transformation> | null | Reference to the transformation |
...rest | See ogma.transformations.addNeighborMerging() properties | Neighbor merging transformation properties |
Example
<Ogma graph={...}>
<NeighborMerging
selector={node => node.getAttribute('type') === 'type1'}
dataFunction={node => ({
type: node.getAttribute('type'),
label: node.getAttribute('label'),
})}
disabled={false}
/>
</Ogma>
<NeighborGeneration />
Neighbor generation transformation. See ogma.transformations.addNeighborGeneration()
for more information.
Props
Prop | Type | Default | Description |
---|---|---|---|
selector | (node: Ogma.Node) => boolean | null | Selector |
neighborIdFunction | (node: Ogma.Node) => string|Array<string>|null; | Neighbor data function | |
ref? | React.Ref<Ogma.Transformation> | null | Reference to the transformation |
...rest | See ogma.transformations.addNeighborMerging() properties | Transformation properties |
Example
<Ogma graph={...}>
<NeighborGeneration
selector={node => node.getAttribute('type') === 'type1'}
neighborIdFunction={node => node.getAttribute('type')}
disabled={false}
/>
</Ogma>
<NodeCollapsing />
Node collapsing transformation. See ogma.transformations.addNodeCollapsing()
for more information.
Props
Prop | Type | Default | Description |
---|---|---|---|
selector | (node: Ogma.Node) => boolean | null | Selector |
edgeGenerator? | (hiddenNode: Ogma.Node, node1: Ogma.Node, node2: Ogma.Node, edges1: Ogma.EdgeList, edges2: Ogma.EdgeList): RawEdge|null) | Edge generator function | |
ref? | React.Ref<Ogma.Transformation> | null | Reference to the transformation |
...rest | See ogma.transformations.addNodeCollapsing() properties | Transformation properties |
<Geo />
Geo mode component. It's the first version of this component and we are still gathering feedback on how you can use it.
Props
Prop | Type | Default | Description |
---|---|---|---|
enabled? | boolean | false | On/off toggle |
...rest | Ogma.GeomModeOptions | See GeoModeOptions properties |
Example
<Ogma graph={...}>
<Geo
enabled={true}
tileUrlTemplate="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
longitudePath="data.lng"
latitudePath="data.lat"
/>
</Ogma>
License
Apache 2.0
1 month ago
3 months ago
5 months ago
5 months ago
9 months ago
12 months ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago