1.0.11 • Published 1 year ago

@lautaro450/react-knowledge-chart v1.0.11

Weekly downloads
-
License
MIT
Repository
github
Last release
1 year ago

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-chart

Usage

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

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

1.0.11

1 year ago

1.0.10

1 year ago

1.0.9

1 year ago

1.0.8

1 year ago

1.0.7

1 year ago

1.0.6

1 year ago

1.0.5

1 year ago

1.0.4

1 year ago

1.0.3

1 year ago

1.0.1

1 year ago

1.0.0

1 year ago