Wrapper library for @linkurious/ogma
to use with React.
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>
See the web/src/App.tsx
file for a complete example.
const graph: Ogma.RawGraph = ...;
return <Ogma options={{ backgroundColor: '#9dc5bb'}} graph={graph}>
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>
);
}
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>);
}
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} />)
}
Main visualisation component. You can use onReady
or ref
prop to get a reference to the Ogma instance.
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 |
Node style component.
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 |
<Ogma>
<NodeStyle attributes={{ color: "red", radius: 10 }} />
</Ogma>
Edge style component.
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 |
<Ogma>
<EdgeStyle attributes={{ color: "red" }} />
</Ogma>
Custom popup UI layer.
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 |
<Ogma>
<Popup
position={() => (clickedNode ? clickedNode.getPosition() : null)}
size={{ width: 200, height: 200 }}
>
<div>Popup content here!</div>
</Popup>
</Ogma>
Tooltip component. Use it for cutom movable tooltips. It automatically adjusts the placement of the tooltip to conainer bounds.
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 |
<Ogma>
<Tooltip
visible={hoveredNode}
position={() => (hoveredNode ? hoveredNode.getPosition() : null)}
size={{ width: 200, height: 200 }}
>
<div>Tooltip content here!</div>
</Tooltip>
</Ogma>
Custom canvas layer.
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 |
<Ogma>
<CanvasLayer
render={(ctx) => {
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 100, 100);
}}
/>
</Ogma>
Generic DOM layer, see ogma.layers.addLayer
.
Prop | Type | Default | Description |
---|---|---|---|
children |
React.ReactNode |
null |
The children of the layer |
<Ogma>
<Layer>
<span>Layer content here!</span>
</Layer>
</Ogma>
Generic Overlay layer, see ogma.layers.addOverlay
.
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 |
<Ogma>
<Overlay position={{x: 0, y: 0}} >
<span>Layer content here!</span>
</Overlay>
</Ogma>
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 |
Node grouping transformation. See ogma.transformations.addNodeGrouping()
for more details.
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 |
<Ogma graph={...}>
<NodeGrouping
selector={node => node.getAttribute('type') === 'type1'}
groupIdFunction={node => node.getAttribute('type')}
disabled={false}
/>
</Ogma>
Edge grouping transformation. See ogma.transformations.addEdgeGrouping()
for more information.
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 |
<Ogma graph={...}>
<EdgeGrouping
selector={edge => edge.getAttribute('type') === 'type1'}
groupIdFunction={edge => edge.getAttribute('type')}
disabled={false}
/>
</Ogma>
Node filter transformation. See ogma.transformations.addNodeFilter()
for more information.
Prop | Type | Default | Description |
---|---|---|---|
...props |
Ogma.NodeFilterOptions |
See ogma.transformations.addNodeFilter() for more information. |
<Ogma graph={...}>
<NodeFilter
criteria={node => node.getData('age') > 22}
disabled={false}
/>
</Ogma>
Wrapper for the edge filter transformation. See ogma.transformations.addEdgeFilter()
for more information.
Prop | Type | Default | Description |
---|---|---|---|
...props |
Ogma.EdgeFilterOptions |
See ogma.transformations.addEdgeFilter() for more information. |
<Ogma graph={...}>
<EdgeFilter
criteria={edge => edge.getData('type') === 'important'}
disabled={false}
/>
</Ogma>
Neighbor merging transformation. See ogma.transformations.addNeighborMerging()
for more information.
Prop | Type | Default | Description |
---|---|---|---|
selector |
(node: Ogma.Node) => boolean |
null |
Selector |
dataFunction |
`(node: Ogma.Node) => object | undefined;` | |
ref? |
React.Ref<Ogma.Transformation> |
null |
Reference to the transformation |
...rest |
See ogma.transformations.addNeighborMerging() properties |
Neighbor merging transformation properties |
<Ogma graph={...}>
<NeighborMerging
selector={node => node.getAttribute('type') === 'type1'}
dataFunction={node => ({
type: node.getAttribute('type'),
label: node.getAttribute('label'),
})}
disabled={false}
/>
</Ogma>
Neighbor generation transformation. See ogma.transformations.addNeighborGeneration()
for more information.
Prop | Type | Default | Description |
---|---|---|---|
selector |
(node: Ogma.Node) => boolean |
null |
Selector |
neighborIdFunction |
`(node: Ogma.Node) => string | Array | null;` |
ref? |
React.Ref<Ogma.Transformation> |
null |
Reference to the transformation |
...rest |
See ogma.transformations.addNeighborMerging() properties |
Transformation properties |
<Ogma graph={...}>
<NeighborGeneration
selector={node => node.getAttribute('type') === 'type1'}
neighborIdFunction={node => node.getAttribute('type')}
disabled={false}
/>
</Ogma>
Node collapsing transformation. See ogma.transformations.addNodeCollapsing()
for more information.
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)` | |
ref? |
React.Ref<Ogma.Transformation> |
null |
Reference to the transformation |
...rest |
See ogma.transformations.addNodeCollapsing() properties |
Transformation properties |
Geo mode component. It's the first version of this component and we are still gathering feedback on how you can use it.
Prop | Type | Default | Description |
---|---|---|---|
enabled? |
boolean |
false |
On/off toggle |
...rest |
Ogma.GeomModeOptions |
See GeoModeOptions properties |
<Ogma graph={...}>
<Geo
enabled={true}
tileUrlTemplate="https://{s}.tile.osm.org/{z}/{x}/{y}.png"
longitudePath="data.lng"
latitudePath="data.lat"
/>
</Ogma>
Apache 2.0