npm package: @lautaro450/react-knowledge-chart
Description: A React component for creating interactive knowledge organization charts with drag-and-drop capabilities
Author: lautaro450
Latest version: 1.0.11

# 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
```bash
npm install react-knowledge-chart
```

## Usage
```jsx
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 structure
- `onNodeAdd`: Callback when a new node is requested to be added
- `onStatementMove`: Callback when a statement is moved between nodes
- `onValidationError`: 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
```typescript
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:

1. Topic Selection:
   - Use the `onNodeClick` prop to handle node selection
   - Filter the data to show only the selected topic
   - The chart will automatically adjust to show the filtered view

2. 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

3. 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