npm package: @graphnizer/force-graph
Description: A powerful React force-directed graph visualization library
Author: Fadlan Fasya
Latest version: 1.0.8

# @graphnizer/force-graph

A powerful, performant React force-directed graph visualization library built with D3.js.

## Features

✨ **Force-directed layout** - Physics-based graph visualization  
🎯 **Interactive** - Drag, zoom, pan, click interactions  
🎨 **Customizable** - Full control over colors, sizes, and styles  
⚡ **Performant** - Canvas-based rendering for smooth animations  
📦 **Lightweight** - Small bundle size with tree-shaking support  
🎭 **Multiple layouts** - Force, circular, hierarchical, and grid layouts  
🔧 **TypeScript ready** - Full TypeScript definitions included

## Installation

```bash
npm install @graphnizer/force-graph
```

Or with yarn:

```bash
yarn add @graphnizer/force-graph
```

## Quick Start

```jsx
import React from "react";
import { ForceGraph } from "@graphnizer/force-graph";

function App() {
  const data = {
    nodes: [
      { id: "1", label: "Node 1", color: "#3b82f6" },
      { id: "2", label: "Node 2", color: "#ec4899" },
      { id: "3", label: "Node 3", color: "#8b5cf6" },
    ],
    links: [
      { source: "1", target: "2", label: "connects" },
      { source: "2", target: "3", label: "relates" },
    ],
  };

  return (
    <ForceGraph
      data={data}
      width={800}
      height={600}
      onNodeClick={(node) => console.log("Clicked:", node)}
    />
  );
}

export default App;
```

## API Reference

### Props

| Prop              | Type                     | Default                    | Description                      |
| ----------------- | ------------------------ | -------------------------- | -------------------------------- |
| `data`            | `Object`                 | `{ nodes: [], links: [] }` | Graph data with nodes and links  |
| `width`           | `number`                 | `800`                      | Canvas width in pixels           |
| `height`          | `number`                 | `600`                      | Canvas height in pixels          |
| `nodeColor`       | `string`                 | `'#3b82f6'`                | Default node color               |
| `linkColor`       | `string`                 | `'#94a3b8'`                | Default link color               |
| `linkWidth`       | `number`                 | `2`                        | Link stroke width                |
| `linkStyle`       | `'straight' \| 'curved'` | `'straight'`               | Link rendering style             |
| `showArrows`      | `boolean`                | `true`                     | Show directional arrows on links |
| `showNodeLabels`  | `boolean`                | `true`                     | Display node labels              |
| `showLinkLabels`  | `boolean`                | `false`                    | Display link labels              |
| `nodeShadow`      | `boolean`                | `true`                     | Add shadow effect to nodes       |
| `backgroundColor` | `string`                 | `'#ffffff'`                | Canvas background color          |
| `enableZoom`      | `boolean`                | `true`                     | Enable zoom functionality        |
| `enableDrag`      | `boolean`                | `true`                     | Enable node dragging             |
| `linkDistance`    | `number`                 | `100`                      | Force simulation link distance   |
| `chargeStrength`  | `number`                 | `-300`                     | Force simulation charge strength |
| `collisionRadius` | `number`                 | `30`                       | Collision detection radius       |
| `alphaDecay`      | `number`                 | `0.0228`                   | Simulation cooling rate          |
| `onNodeClick`     | `function`               | `() => {}`                 | Callback when node is clicked    |
| `onNodeHover`     | `function`               | `() => {}`                 | Callback when node is hovered    |
| `onLinkClick`     | `function`               | `() => {}`                 | Callback when link is clicked    |
| `className`       | `string`                 | `''`                       | Additional CSS class name        |
| `style`           | `Object`                 | `{}`                       | Additional inline styles         |

### Data Structure

#### Node Object

```typescript
{
  id: string;           // Required: unique identifier
  label?: string;       // Optional: display label
  color?: string;       // Optional: node color (hex/rgb)
  radius?: number;      // Optional: node radius in pixels
  x?: number;           // Optional: initial x position
  y?: number;           // Optional: initial y position
  fx?: number;          // Optional: fixed x position
  fy?: number;          // Optional: fixed y position
  [key: string]: any;   // Any additional custom properties
}
```

#### Link Object

```typescript
{
  source: string | Node; // Required: source node id or object
  target: string | Node; // Required: target node id or object
  label?: string;        // Optional: link label
  [key: string]: any;    // Any additional custom properties
}
```

## Advanced Usage

### Custom Node Styling

```jsx
const data = {
  nodes: [
    {
      id: "1",
      label: "Important",
      color: "#ef4444",
      radius: 30,
    },
    {
      id: "2",
      label: "Normal",
      color: "#3b82f6",
      radius: 20,
    },
  ],
  links: [{ source: "1", target: "2" }],
};

<ForceGraph data={data} />;
```

### Event Handling

```jsx
<ForceGraph
  data={data}
  onNodeClick={(node) => {
    console.log("Node clicked:", node);
    // Open modal, navigate, etc.
  }}
  onNodeHover={(node) => {
    if (node) {
      console.log("Hovering over:", node.label);
    }
  }}
/>
```

### Custom Styling

```jsx
<ForceGraph
  data={data}
  nodeColor="#10b981"
  linkColor="#6366f1"
  linkWidth={3}
  linkStyle="curved"
  showArrows={true}
  showLinkLabels={true}
  backgroundColor="#f8fafc"
  nodeShadow={true}
/>
```

### Disable Interactions

```jsx
<ForceGraph data={data} enableZoom={false} enableDrag={false} />
```

### Custom Force Parameters

```jsx
<ForceGraph
  data={data}
  linkDistance={150} // Longer links
  chargeStrength={-500} // Stronger repulsion
  collisionRadius={40} // More spacing
  alphaDecay={0.01} // Slower cooling
/>
```

## Using Layout Algorithms

```jsx
import { CircularLayout, HierarchicalLayout } from "@graphnizer/force-graph";

// Circular layout
const circularLayout = new CircularLayout();
const simulation = circularLayout.apply(nodes, links, width, height);

// Hierarchical layout
const hierarchicalLayout = new HierarchicalLayout();
const simulation = hierarchicalLayout.apply(nodes, links, width, height);
```

## Examples

### Social Network Graph

```jsx
const socialNetwork = {
  nodes: [
    { id: "user1", label: "Alice", color: "#ec4899", radius: 25 },
    { id: "user2", label: "Bob", color: "#3b82f6", radius: 25 },
    { id: "user3", label: "Charlie", color: "#8b5cf6", radius: 25 },
    { id: "user4", label: "Diana", color: "#10b981", radius: 25 },
  ],
  links: [
    { source: "user1", target: "user2", label: "follows" },
    { source: "user2", target: "user3", label: "follows" },
    { source: "user3", target: "user4", label: "follows" },
    { source: "user4", target: "user1", label: "follows" },
  ],
};

<ForceGraph
  data={socialNetwork}
  width={1000}
  height={700}
  showLinkLabels={true}
/>;
```

### Organizational Chart

```jsx
const orgChart = {
  nodes: [
    { id: "ceo", label: "CEO", color: "#ef4444", radius: 30 },
    { id: "cto", label: "CTO", color: "#f59e0b", radius: 25 },
    { id: "cfo", label: "CFO", color: "#f59e0b", radius: 25 },
    { id: "dev1", label: "Dev 1", color: "#3b82f6", radius: 20 },
    { id: "dev2", label: "Dev 2", color: "#3b82f6", radius: 20 },
  ],
  links: [
    { source: "ceo", target: "cto" },
    { source: "ceo", target: "cfo" },
    { source: "cto", target: "dev1" },
    { source: "cto", target: "dev2" },
  ],
};

<ForceGraph data={orgChart} showArrows={true} />;
```

## Performance Tips

1. **Large graphs (1000+ nodes)**: Consider reducing `alphaDecay` for faster simulation
2. **Static graphs**: Set `fx` and `fy` on nodes to skip simulation
3. **Memory**: Clear references when unmounting components
4. **Rendering**: Use `linkStyle="straight"` for better performance

## Browser Support

- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)

## Contributing

Contributions are welcome! Please open an issue or submit a pull request.

## License

MIT © Your Company

## Related

- [D3.js](https://d3js.org/)
- [React](https://reactjs.org/)

## Support

For bugs and feature requests, please [create an issue](https://github.com/yourcompany/force-graph/issues).