5.0.3 • Published 1 month ago

@linkurious/ogma-react v5.0.3

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
1 month ago

@linkurious/ogma-react

logo

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

PropTypeDefaultDescription
options?Ogma.Options{}Ogma options
graph?Ogma.RawGraphnullThe graph to render
onReady?(ogma: Ogma) => voidnullCallback when the Ogma instance is ready
ref?React.Ref<Ogma>nullReference to the Ogma instance
childrenReact.ReactNodenullThe 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

PropTypeDefaultDescription
attributesOgma.NodeAttributeValue{}Attributes to apply to the node
selector?(node: Ogma.Node) => booleannullSelector to apply the attributes to the node
ref?React.Ref<Ogma.StyleRule>nullReference to the style rule

Example

<Ogma>
  <NodeStyle attributes={{ color: "red", radius: 10 }} />
</Ogma>

<EdgeStyle />

Edge style component.

Props

PropTypeDefaultDescription
attributesOgma.EdgeAttributeValue{}Attributes to apply to the edge
selector?(edge: Ogma.Edge) => booleannullSelector to apply the attributes to the edge
ref?React.Ref<Ogma.StyleRule>nullReference to the style rule

Example

<Ogma>
  <EdgeStyle attributes={{ color: "red" }} />
</Ogma>

<Popup />

Custom popup UI layer.

Props

PropTypeDefaultDescription
positionPoint \| (ogma: Ogma) => PointnullPosition of the popup
size?{ width: number \| 'auto'; height: number \| 'auto'; }{ width: 'auto', height: 'auto' }Size of the popup
childrenReact.ReactNodenullThe children of the component
isOpenbooleantrueWhether the popup is open
onClose() => voidnullCallback when the popup is closed
placement'top' \| 'bottom' \| 'right'\| 'left'Placement of the popup
ref?React.Ref<Popup>nullReference to the popup
closeOnEsc?booleantrueWhether 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

PropTypeDefaultDescription
positionPoint \| (ogma: Ogma) => PointPosition of the tooltip
size?{ width: number \| 'auto'; height: number \| 'auto'; }{ width: 'auto', height: 'auto' }Size of the tooltip
childrenReact.ReactNodenullThe children of the component
visiblebooleantrueWhether the tooltip is open
placementPlacementrightPlacement of the tooltip
ref?React.Ref<Tooltip>nullReference to the tooltip
tooltipClassstring'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

PropTypeDefaultDescription
refReact.Ref<CanvasLayer>nullReference to the canvas layer
render(ctx: CanvasRenderingContext2D) => voidnullCallback to render the canvas layer
index?number1Index of the layer
isStatic?booleanfalseWhether the layer is static
noClear?booleanfalseWhether 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

PropTypeDefaultDescription
childrenReact.ReactNodenullThe children of the layer

Example

<Ogma>
  <Layer>
    <span>Layer content here!</span>
  </Layer>
</Ogma>

<Overlay />

Generic Overlay layer, see ogma.layers.addOverlay.

Props

PropTypeDefaultDescription
childrenReact.ReactNodenullThe children of the layer
classNamestringnullClassname for the Overlay
scaledbooleantrueWether the Overlay is scaled on zoom or not
positionPoint \| (ogma: Ogma) => PointPosition 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

PropTypeDefaultDescription
selector(node: Ogma.Node) => booleannullSelector to apply the attributes to the node
groupIdFunction(node: Ogma.Node) => string \| undefinedGrouping function
ref?React.Ref<Ogma.Transformation>nullReference to the transformation
...restSee ogma.transformations.addNodeGrouping() propertiesNode 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

PropTypeDefaultDescription
selector(edge: Ogma.Edge) => booleannullSelector for the edges
groupIdFunction(edge: Ogma.Edge) => string \| undefinedGrouping function
ref?React.Ref<Ogma.Transformation>nullReference to the transformation
...restSee ogma.transformations.addEdgeGrouping() propertiesEdge 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

PropTypeDefaultDescription
...propsOgma.NodeFilterOptionsSee 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

PropTypeDefaultDescription
...propsOgma.EdgeFilterOptionsSee 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

PropTypeDefaultDescription
selector(node: Ogma.Node) => booleannullSelector
dataFunction(node: Ogma.Node) => object | undefined;Neighbor data function
ref?React.Ref<Ogma.Transformation>nullReference to the transformation
...restSee ogma.transformations.addNeighborMerging() propertiesNeighbor 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

PropTypeDefaultDescription
selector(node: Ogma.Node) => booleannullSelector
neighborIdFunction(node: Ogma.Node) => string|Array<string>|null;Neighbor data function
ref?React.Ref<Ogma.Transformation>nullReference to the transformation
...restSee ogma.transformations.addNeighborMerging() propertiesTransformation 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

PropTypeDefaultDescription
selector(node: Ogma.Node) => booleannullSelector
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>nullReference to the transformation
...restSee ogma.transformations.addNodeCollapsing() propertiesTransformation 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

PropTypeDefaultDescription
enabled?booleanfalseOn/off toggle
...restOgma.GeomModeOptionsSee 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

5.0.3

1 month ago

5.0.2

3 months ago

4.6.1

5 months ago

4.6.0

5 months ago

4.3.3

9 months ago

4.3.2

12 months ago

4.3.1

1 year ago

4.3.0

1 year ago

0.1.4

2 years ago

0.1.1

2 years ago

0.1.3

2 years ago

0.1.0

2 years ago

0.0.11

2 years ago

0.0.10

2 years ago

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago