D3 Universal Diagrams

Documentation for Developers

Universal D3 Diagrams System

The Universal D3 Diagrams system provides a flexible, reusable way to create interactive diagrams from simple JSON data. This system can handle any type of network diagram, from architecture diagrams to organizational charts.

🚀 Quick Start

Basic Usage in Angular Components

import { D3UniversalDiagramComponent } from './shared/d3-universal-diagram/d3-universal-diagram.component';

// In your component
export class MyComponent {
  diagramData = {
    nodes: [
      { id: 'node1', name: 'Frontend', category: 'ui' },
      { id: 'node2', name: 'Backend', category: 'api' },
      { id: 'node3', name: 'Database', category: 'storage' }
    ],
    links: [
      { source: 'node1', target: 'node2' },
      { source: 'node2', target: 'node3' }
    ],
    categories: {
      ui: { color: '#3B82F6', label: 'User Interface' },
      api: { color: '#10B981', label: 'API Layer' },
      storage: { color: '#F59E0B', label: 'Data Storage' }
    }
  };
}
<app-d3-universal-diagram 
  [data]="diagramData"
  title="System Architecture"
  [width]="1000"
  [height]="600"
  [showLegend]="true"
  [showControls]="true">
</app-d3-universal-diagram>

📊 Data Structure

Basic Structure

{
  "title": "My Diagram",
  "nodes": [
    {
      "id": "unique-id",
      "name": "Display Name",
      "category": "optional-category",
      "color": "#optional-color",
      "size": 50,
      "description": "Optional description"
    }
  ],
  "links": [
    {
      "from": "source-node-id",
      "to": "target-node-id",
      "weight": 1,
      "color": "#optional-color"
    }
  ],
  "categories": {
    "category-name": {
      "color": "#3B82F6",
      "label": "Display Label"
    }
  },
  "settings": {
    "nodeSize": 50,
    "linkDistance": 120,
    "chargeStrength": -800,
    "showLegend": true,
    "allowDrag": true,
    "allowZoom": true
  }
}

🎨 Examples

1. Simple Network Diagram

{
  "title": "Simple Network",
  "nodes": [
    { "id": "server", "name": "Web Server", "category": "infrastructure" },
    { "id": "db", "name": "Database", "category": "storage" },
    { "id": "cache", "name": "Cache", "category": "storage" }
  ],
  "links": [
    { "from": "server", "to": "db" },
    { "from": "server", "to": "cache" }
  ],
  "categories": {
    "infrastructure": { "color": "#3B82F6", "label": "Infrastructure" },
    "storage": { "color": "#10B981", "label": "Storage" }
  }
}

2. Team Organization Chart

{
  "title": "Team Structure",
  "nodes": [
    { "id": "pm", "name": "Project Manager", "category": "management" },
    { "id": "lead", "name": "Tech Lead", "category": "management" },
    { "id": "dev1", "name": "Frontend Dev", "category": "developer" },
    { "id": "dev2", "name": "Backend Dev", "category": "developer" },
    { "id": "qa", "name": "QA Engineer", "category": "quality" }
  ],
  "links": [
    { "from": "pm", "to": "lead" },
    { "from": "lead", "to": "dev1" },
    { "from": "lead", "to": "dev2" },
    { "from": "lead", "to": "qa" }
  ],
  "categories": {
    "management": { "color": "#EF4444", "label": "Management" },
    "developer": { "color": "#3B82F6", "label": "Developers" },
    "quality": { "color": "#10B981", "label": "Quality" }
  }
}

3. Data Flow Process

{
  "title": "Data Processing Workflow",
  "nodes": [
    { "id": "input", "name": "User Input", "category": "input", "size": 40 },
    { "id": "validate", "name": "Validation", "category": "process" },
    { "id": "transform", "name": "Transform", "category": "process" },
    { "id": "store", "name": "Store Data", "category": "storage" },
    { "id": "output", "name": "Response", "category": "output", "size": 40 }
  ],
  "links": [
    { "from": "input", "to": "validate", "weight": 2 },
    { "from": "validate", "to": "transform" },
    { "from": "transform", "to": "store" },
    { "from": "store", "to": "output", "weight": 2 }
  ],
  "categories": {
    "input": { "color": "#10B981", "label": "Input" },
    "process": { "color": "#F59E0B", "label": "Process" },
    "storage": { "color": "#3B82F6", "label": "Storage" },
    "output": { "color": "#8B5CF6", "label": "Output" }
  },
  "settings": {
    "nodeSize": 45,
    "linkDistance": 100,
    "chargeStrength": -600
  }
}

🛠️ Using the JSON Loader Service

Loading from JSON String

import { JsonDiagramLoaderService } from './shared/d3-universal-diagram/json-diagram-loader.service';

export class MyComponent {
  constructor(private diagramLoader: JsonDiagramLoaderService) {}

  loadDiagramFromJson(jsonString: string) {
    const diagramData = this.diagramLoader.fromJsonString(jsonString);
    this.currentDiagram = diagramData;
  }

  loadDiagramFromUrl(url: string) {
    this.diagramLoader.fromUrl(url).then(data => {
      this.currentDiagram = data;
    });
  }

  generateTemplate() {
    const template = this.diagramLoader.generateTemplate();
    console.log(JSON.stringify(template, null, 2));
  }
}

Validation

const validationResult = this.diagramLoader.validateDiagramData(myData);
if (!validationResult.valid) {
  console.error('Validation errors:', validationResult.errors);
}

🎛️ Configuration Options

Node Properties

Link Properties

Global Settings

🎨 Visual Customization

Color Categories

Define reusable color schemes:

{
  "categories": {
    "frontend": { "color": "#3B82F6", "label": "Frontend" },
    "backend": { "color": "#10B981", "label": "Backend" },
    "database": { "color": "#F59E0B", "label": "Database" },
    "external": { "color": "#EF4444", "label": "External" }
  }
}

Node Sizes

Control visual hierarchy:

{
  "nodes": [
    { "id": "main", "name": "Main Server", "size": 80 },
    { "id": "worker", "name": "Worker", "size": 40 },
    { "id": "monitor", "name": "Monitor", "size": 30 }
  ]
}

Link Weights

Show relationship strength:

{
  "links": [
    { "from": "api", "to": "db", "weight": 3 },
    { "from": "api", "to": "cache", "weight": 1 }
  ]
}

🔧 Advanced Usage

Dynamic Data Loading

export class DiagramComponent {
  diagramData$ = this.http.get<any>('/api/diagram-data').pipe(
    map(data => this.diagramLoader.fromSimpleJson(data))
  );
}

Interactive Features

The component automatically includes:

Controls

Three built-in control buttons:

📱 Responsive Design

The component includes responsive breakpoints:

🚀 Performance Tips

  1. Large Datasets: For 100+ nodes, consider:

    • Reducing chargeStrength (less negative)
    • Increasing linkDistance
    • Disabling animations temporarily
  2. Memory Management:

    • Clear old diagram data when switching
    • Use OnPush change detection
    • Destroy subscriptions properly
  3. Optimization:

    • Pre-calculate node positions for static diagrams
    • Use trackBy functions in templates
    • Implement virtual scrolling for very large datasets

🎯 Use Cases

Perfect for visualizing:

🔄 Migration from Architecture Diagram

If you're currently using the architecture-specific component:

// Old way
<app-d3-architecture-diagram [data]="nxData">

// New way  
<app-d3-universal-diagram [data]="universalData">

The universal system is backward compatible and more flexible!

🆘 Troubleshooting

Common Issues

  1. Nodes not appearing: Check that all node IDs are unique
  2. Links not connecting: Verify source/target IDs match node IDs exactly
  3. Colors not showing: Ensure category names in nodes match category definitions
  4. Performance issues: Reduce node count or adjust force simulation parameters

Debug Mode

Add console logging to track issues:

const validationResult = this.diagramLoader.validateDiagramData(data);
console.log('Validation:', validationResult);

Ready to create amazing interactive diagrams! 🎉