@lautaro450/react-knowledge-chart
v1.0.11
Published
A React component for creating interactive knowledge organization charts with drag-and-drop capabilities
Maintainers
Readme
React Knowledge Chart
A React component for creating interactive knowledge organization charts with drag-and-drop capabilities.
Features
- Interactive knowledge organization charts
- Drag and drop statements between topics
- Expandable/collapsible nodes
- Smooth animations and transitions
- Customizable styling
- Search functionality for filtering nodes and statements
- Title validation to prevent duplicates
- Topic filtering with zoom-to-node capability
Installation
npm install react-knowledge-chartUsage
import { KnowledgeChart, KnowledgeChartRef } from 'react-knowledge-chart';
import { useState, useRef, useMemo } from 'react';
const initialData = {
title: "Professional Knowledge Framework",
subtitle: "Comprehensive career development competencies",
statements: [],
children: [
{
title: "Leadership Development",
statements: [
{
author: "John Smith",
date: "March 15, 2025",
content: "Effective leaders must demonstrate emotional intelligence"
}
],
background: "bg-blue-50"
}
]
};
// Helper function to get all topics from the data
const getAllTopics = (node) => {
const topics = node.children ? node.children.map(child => child.title) : [];
if (node.children) {
node.children.forEach(child => {
topics.push(...getAllTopics(child));
});
}
return topics;
};
// Helper function to find node by title
const findNodeByTitle = (node, title) => {
if (node.title === title) return node;
if (node.children) {
for (const child of node.children) {
const found = findNodeByTitle(child, title);
if (found) return found;
}
}
return null;
};
function App() {
const [data, setData] = useState(initialData);
const [searchTerm, setSearchTerm] = useState('');
const [selectedTopic, setSelectedTopic] = useState(null);
const chartRef = useRef(null);
// Get all topics for navigation
const topics = useMemo(() => getAllTopics(data), [data]);
// Filter data based on selected topic and search
const filteredData = useMemo(() => {
let result = data;
// Apply topic filter if selected
if (selectedTopic) {
const selectedNode = findNodeByTitle(data, selectedTopic);
if (selectedNode) {
result = {
...data,
children: [selectedNode]
};
}
}
// Apply search filter
if (searchTerm.trim()) {
const searchResult = searchNode(result, searchTerm.trim());
return searchResult || { ...result, statements: [], children: [] };
}
return result;
}, [data, searchTerm, selectedTopic]);
const handleNodeClick = (nodeTitle) => {
setSelectedTopic(nodeTitle);
// Allow time for filtering to take effect
setTimeout(() => {
chartRef.current?.zoomToNode(nodeTitle);
}, 100);
};
const clearSelection = () => {
setSelectedTopic(null);
};
return (
<div className="h-screen flex flex-col">
<div className="p-4 bg-white shadow-sm space-y-4">
<div className="flex items-center gap-4">
<input
type="text"
placeholder="Search..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
{selectedTopic && (
<button onClick={clearSelection}>
Clear Selection
</button>
)}
</div>
<div className="flex flex-wrap gap-2">
{topics.map((topic) => (
<button
key={topic}
onClick={() => handleNodeClick(topic)}
className={selectedTopic === topic ? 'active' : ''}
>
{topic}
</button>
))}
</div>
</div>
<div className="flex-1">
<KnowledgeChart
data={filteredData}
onNodeClick={handleNodeClick}
ref={chartRef}
/>
</div>
</div>
);
}Props
data: The knowledge chart data structureonNodeAdd: Callback when a new node is requested to be addedonStatementMove: Callback when a statement is moved between nodesonValidationError: Callback when a validation error occurs (e.g., duplicate titles)onNodeClick: Callback when a node is clicked (used for zoom functionality)ref: Reference to access chart methods like zoomToNode
Data Structure
interface Statement {
author: string;
date: string;
content: string;
}
interface KnowledgeNode {
title: string;
subtitle?: string;
statements: Statement[];
children?: KnowledgeNode[];
background?: string;
}
interface ValidationError {
message: string;
code: 'DUPLICATE_TITLE' | 'INVALID_TITLE';
}
interface KnowledgeChartRef {
zoomToNode: (nodeTitle: string) => void;
}Topic Filtering and Zoom Feature
The component supports filtering to specific topics and zooming to nodes:
Topic Selection:
- Use the
onNodeClickprop to handle node selection - Filter the data to show only the selected topic
- The chart will automatically adjust to show the filtered view
- Use the
Zoom Navigation:
- Use the
ref.zoomToNode(nodeTitle)method to programmatically zoom to a specific node - The zoom animation includes scaling and centering the selected node
- The node will automatically expand to show its statements
- Use the
Reset View:
- Clear the topic selection to return to the full chart view
- The chart will smoothly animate back to show all nodes
When implementing topic navigation:
- Create clickable cards/buttons for each topic
- Handle selection state and filtering
- Use the
ref.zoomToNode()method for smooth transitions - Consider adding a clear selection button to reset the view
Search Functionality
The component supports searching through nodes and statements. The search is case-insensitive and matches:
- Node titles
- Statement content
- Statement authors
When searching:
- Nodes with matching titles will show all their statements
- Nodes without matching titles will only show matching statements
- The hierarchy is preserved for matching nodes and their children
License
MIT
