UNPKG

@dormammuuuuu/nextjs-orgchart

Version:

A React component for rendering organization charts in Next.js applications.

211 lines (164 loc) 7.9 kB
# nextjs-orgchart `nextjs-orgchart` is a flexible and interactive organizational chart component for React and Next.js applications. It allows for dynamic, hierarchical data visualization with support for customizable nodes, drag-and-drop reordering, zooming, and exporting to PNG or PDF formats. This component is ideal for representing complex team structures, project hierarchies, and organizational trees. This is the modernization of [dabeng](https://github.com/dabeng/react-orgchart) and [mahyarmadad](https://github.com/mahyarmadad/nextjs-orgchart) orgchart. ## Features - **Hierarchy Representation**: Visualize nested relationships with expandable/collapsible child nodes. - **Drag-and-Drop Reordering**: Rearrange nodes within the chart with drag-and-drop support. - **Node Selection**: Click nodes to highlight and manage selected nodes. - **Zooming and Panning**: Easily navigate complex hierarchies with zoom and pan functionality. - **Customizable Node Templates**: Define custom templates for nodes using the `NodeTemplate` prop. - **Export Options**: Export the entire chart as PNG or PDF. - **Multiselect Support**: Enable multiple node selection. - **Configurable**: Customize behavior for pan, zoom limits, collapsibility, and more. ## Installation Install via npm or yarn: ```bash npm install @dormammuuuuu/nextjs-orgchart ``` or ```bash yarn add @dormammuuuuu/nextjs-orgchart ``` ## CSS Styling Include the provided CSS files in your project: ```javascript import '@dormammuuuuu/nextjs-orgchart/ChartContainer.css'; import '@dormammuuuuu/nextjs-orgchart/ChartNode.css'; ``` Add custom styles to the chart or nodes using the provided class names: - **Container**: `.orgchart-container` - **Chart**: `.orgchart` - **Node**: `.oc-node` - **Edges**: `.oc-edge` for top, bottom, left, and right edges ## Usage ```javascript import React from 'react'; import ChartContainer from '@dormammuuuuu/nextjs-orgchart'; import '@dormammuuuuu/nextjs-orgchart/ChartContainer.css'; import '@dormammuuuuu/nextjs-orgchart/ChartNode.css'; const data = { id: "1", name: "CEO", relationship: "00", children: [ { id: "2", name: "CTO", children: [{ id: "3", name: "Dev Lead" }] } ] }; const MyNodeTemplate = ({ nodeData }) => ( <div> <h4>{nodeData.name}</h4> </div> ); function App() { return ( <ChartContainer datasource={data} pan={true} zoom={true} NodeTemplate={MyNodeTemplate} draggable={true} collapsible={true} onClickNode={(node) => console.log("Node clicked:", node)} /> ); } export default App; ``` ## Props ### `ChartContainer` | Prop | Type | Default | Description | |-------------------|------------------------------------------|------------------|-------------| | `datasource` | `Datasource` | - | Hierarchical data for the chart, including `id`, `name`, and optional `relationship` and `children`. | | `pan` | `boolean` | `false` | Enables or disables panning (drag-to-move chart). | | `zoom` | `boolean` | `false` | Enables or disables zooming. | | `zoomoutLimit` | `number` | `0.5` | Minimum zoom scale. | | `zoominLimit` | `number` | `7` | Maximum zoom scale. | | `containerClass` | `string` | `""` | Custom class for the container. | | `chartClass` | `string` | `""` | Custom class for the chart. | | `NodeTemplate` | `React.ComponentType<{ nodeData: Datasource }>` | `-` | Custom template component for nodes. | | `draggable` | `boolean` | `false` | Enables or disables node dragging for reordering. | | `collapsible` | `boolean` | `true` | Enables or disables collapsibility of nodes. | | `multipleSelect` | `boolean` | `false` | Enables selection of multiple nodes. | | `onClickNode` | `(datasource: Datasource) => void` | `-` | Callback when a node is clicked. | | `onClickChart` | `() => void` | `-` | Callback when the chart area is clicked (outside any node). | ### `ChartNode` (Used Internally) | Prop | Type | Description | |------------------|-----------------------------------------------|-------------| | `datasource` | `Datasource` | Data for an individual node. | | `NodeTemplate` | `React.ComponentType<NodeTemplateProps>` | Custom template component for the node. | | `draggable` | `boolean` | Enables or disables drag-and-drop for the node. | | `collapsible` | `boolean` | Enables or disables collapsibility for the node. | | `multipleSelect` | `boolean` | Enables multiselect mode. | | `changeHierarchy`| `(draggedNode: Datasource, targetId: string) => void` | Handles reordering of nodes in the hierarchy. | | `onClickNode` | `(datasource: Datasource) => void` | Callback for node click events. | ## Services ### `dragNodeService` - **Purpose**: Handles drag events for nodes, including the node being dragged and clearing drag info. - **Methods**: - `sendDragInfo(id: string | number)`: Starts a drag operation for the node with the specified ID. - `clearDragInfo()`: Clears any current drag information. - `getDragInfo()`: Returns an observable with current drag info. ### `selectNodeService` - **Purpose**: Manages selection events for nodes. - **Methods**: - `sendSelectedNodeInfo(id: string | number)`: Sets the node with the specified ID as selected. - `clearSelectedNodeInfo()`: Clears any current selection info. - `getSelectedNodeInfo()`: Returns an observable with current selection info. ## Exporting the Chart Use `useImperativeHandle` ref in `ChartContainer` to access the `exportTo` function and export the chart to PNG or PDF: ```javascript import React, { useRef } from 'react'; import ChartContainer from '@dormammuuuuu/nextjs-orgchart'; const App = () => { const chartRef = useRef(); const exportChart = () => { chartRef.current.exportTo("MyOrgChart", "pdf"); }; return ( <> <button onClick={exportChart}>Export Chart</button> <ChartContainer ref={chartRef} datasource={data} /> </> ); }; export default App; ``` - `exportTo(filename: string, format: string)`: Exports the chart as `PNG` or `PDF` with the specified filename. ## Example Datasource Structure The `datasource` prop should be a hierarchical structure, as shown below: ```json { "id": "1", "name": "CEO", "relationship": "00", "children": [ { "id": "2", "name": "CTO", "children": [ { "id": "3", "name": "Dev Lead" } ] } ] } ``` ## Customizing Nodes Define a custom component and pass it to the `NodeTemplate` prop to render custom node templates: ```javascript const MyNodeTemplate = ({ nodeData }) => ( <div> <h4>{nodeData.name}</h4> <p>{nodeData.title}</p> </div> ); ``` Then pass it to `ChartContainer`: ```javascript <ChartContainer datasource={data} NodeTemplate={MyNodeTemplate} /> ``` ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ---