React 包装器

NVL 提供了 React 现成的组件,以便于与 React 集成。

您可以按照以下方式安装 NVL React 包装器

npm install @neo4j-nvl/react

基本 React 包装器

基本 React 包装器将基础库包装在 React 组件中。它将类的参数作为属性,这些属性被传递给 NVL 构造函数。任何属性的更改都会通过调用相应的方法反映在 NVL 实例中。

import { BasicNvlWrapper } from '@neo4j-nvl/react'

export default () => <BasicNvlWrapper
 nodes={[{ id: '0' }, { id: '1' }]}
 rels={[{ id: '10', from: '0', to: '1' }]}
 nvlOptions={{ initialZoom: 2 }}
 nvlCallbacks={{ onLayoutDone: () => console.log('layout done') }}
/>

等同于

import { NVL } from '@neo4j-nvl/base'

const myNvl = new NVL(
  document.getElementById('frame'),
  [{ id: '0' }, { id: '1' }],
  [{ id: '10', from: '0', to: '1' }],
  { initialZoom: 2 },
  { onLayoutDone: () => console.log('layout done') }
)

当在 React 包装器中更新节点和/或关系时,NVL 实例也会相应地更新。

import { BasicNvlWrapper } from '@neo4j-nvl/react'

const [nodes, setNodes] = useState([{ id: '0' }, { id: '1' }])

const addElements = () => {
  const newNodes = [...nodes, { id: nodes.length }]
  setNodes(newNodes)
}

export default () => (<div>
  <BasicNvlWrapper nodes={nodes} />
  <button onClick={addElements}>Add Graph Elements</button>
</div>)

等同于

import { NVL } from '@neo4j-nvl/base'

const nodes = [{ id: '0' }, { id: '1' }]
let i = nodes.length
const myNvl = new NVL(document.getElementById('frame'), nodes, [])

myButton.addEventListener('click', () => {
 myNvl.addAndUpdateElementsInGraph({ id: i.toString() }, [])
 i++
})

如果要从 React 包装器外部访问 NVL 类,可以使用对 NVL 的引用来调用其方法。

import { useRef } from 'react'
import { BasicNvlWrapper } from '@neo4j-nvl/react'

export default () => {
  const nvlRef = useRef()

  return (<div>
    <BasicNvlWrapper
      nodes={[{ id: '0' }, { id: '1' }]}
      rels={[{ from: '0', to: '1', id: '10' }]}
      ref={nvlRef}
    />
    <button onClick={() => nvlRef.current?.zoomToNodes(['0', '1'])}>Zoom to Nodes</button>
  </div>)
}

要将事件传递给 NVL 实例,请将事件作为属性传递给 React 包装器。

import { BasicNvlWrapper } from '@neo4j-nvl/react'

export default () => <BasicNvlWrapper
  nodes={[{ id: '0' }, { id: '1' }]}
  rels={[{ from: '0', to: '1', id: '10' }]}
 onClick={(event) => console.log(event)}
/>

等同于

import { NVL } from '@neo4j-nvl/base'

const myNvl = new NVL(container, [{ id: '0' }, { id: '1' }], [{ id: '10', from: '0', to: '1' }])
container.addEventListener('click', (event) => console.log(event))

交互式 React 包装器

交互式 React 包装器组件默认包含一组交互处理程序,并提供各种常见功能和回调。mouseEventCallbacks 属性接受一个对象,其中可以定义各种回调并打开或关闭行为。例如,如果将 onZoom 设置为 true/false,则会打开/关闭缩放。为 onZoom 提供回调会打开行为并在每次交互发生时调用回调。以下是如何使用它的示例。

import type { HitTargets, Node, Relationship } from '@neo4j-nvl/base'
import { InteractiveNvlWrapper } from '@neo4j-nvl/react'
import type { MouseEventCallbacks } from '@neo4j-nvl/react'
import React, { useState } from 'react'

export default () => {
  const [myNodes] = useState<Node[]>([
    { id: '0', size: 20 },
    { id: '1', size: 50 }
  ])
  const [relationships] = useState<Relationship[]>([{ id: '10', from: '0', to: '1' }])

  const mouseEventCallbacks: MouseEventCallbacks = {
    onHover: (element: Node | Relationship, hitTargets: HitTargets, evt: MouseEvent) =>
      console.log('onHover', element, hitTargets, evt),
    onRelationshipRightClick: (rel: Relationship, hitTargets: HitTargets, evt: MouseEvent) =>
      console.log('onRelationshipRightClick', rel, hitTargets, evt),
    onNodeClick: (node: Node, hitTargets: HitTargets, evt: MouseEvent) =>
      console.log('onNodeClick', node, hitTargets, evt),
    onNodeRightClick: (node: Node, hitTargets: HitTargets, evt: MouseEvent) =>
      console.log('onNodeRightClick', node, hitTargets, evt),
    onNodeDoubleClick: (node: Node, hitTargets: HitTargets, evt: MouseEvent) =>
      console.log('onNodeDoubleClick', node, hitTargets, evt),
    onRelationshipClick: (rel: Relationship, hitTargets: HitTargets, evt: MouseEvent) =>
      console.log('onRelationshipClick', rel, hitTargets, evt),
    onRelationshipDoubleClick: (rel: Relationship, hitTargets: HitTargets, evt: MouseEvent) =>
      console.log('onRelationshipDoubleClick', rel, hitTargets, evt),
    onCanvasClick: (evt: MouseEvent) => console.log('onCanvasClick', evt),
    onCanvasDoubleClick: (evt: MouseEvent) => console.log('onCanvasDoubleClick', evt),
    onCanvasRightClick: (evt: MouseEvent) => console.log('onCanvasRightClick', evt),
    onDrag: (nodes: Node[]) => console.log('onDrag', nodes),
    onPan: (evt: MouseEvent) => console.log('onPan', evt),
    onZoom: (zoomLevel: number) => console.log('onZoom', zoomLevel)
  }

  return <InteractiveNvlWrapper nodes={myNodes} rels={relationships} mouseEventCallbacks={mouseEventCallbacks} />
}