D3 Graphs

Documentation for Developers

🎨 D3.js Interactive Graphs System

Complete guide to creating and using D3.js diagrams in our documentation system


🔍 How It Works - The Magic Behind the Scenes

When you add a simple code block like this:

full

Here's exactly what happens:

1. 📖 Markdown Parsing

// In enhanced-markdown-renderer.component.ts
if (language === 'd3-architecture' || language === 'd3-nx') {
  const preset = content.includes('simplified') ? 'simplified' : 'full';
  return {
    element: {
      type: 'd3-architecture',
      d3Config: { preset, width: 1200, height: 800 }
    }
  };
}

2. 🎯 Component Selection

<!-- The renderer detects 'd3-architecture' type and renders: -->
<app-d3-architecture-diagram
  [data]="getD3DiagramData('full')"
  [title]="'Complete NX Architecture'"
  [width]="1200"
  [height]="800">
</app-d3-architecture-diagram>

3. 📊 Data Loading

// From nx-architecture.data.ts
export const NX_ARCHITECTURE_DATA = {
  nodes: [
    { id: 'core-types', name: 'core-types', layer: 'foundation' },
    { id: 'ux-framework', name: 'ux-framework', layer: 'framework' },
    // ... 16 total libraries
  ],
  links: [
    { source: 'core-types', target: 'ux-framework' },
    { source: 'shared-ui', target: 'widgets' },
    // ... actual dependency relationships
  ]
};

4. 🎨 D3 Rendering

// D3 creates the interactive visualization
const simulation = d3.forceSimulation(nodes)
  .force('link', d3.forceLink(links))
  .force('charge', d3.forceManyBody())
  .force('center', d3.forceCenter())
  .force('collision', d3.forceCollide());

🚀 Usage Guide

Basic Syntax

Full Architecture Diagram

full

Simplified Overview

simplified

Custom Configuration

full

Available Presets

Preset Description Nodes Use Case
full Complete architecture 16 libraries Detailed technical documentation
simplified High-level overview 4 layer groups Executive summaries, presentations

🛠 Creating New D3 Diagrams

Step 1: Define Your Data Structure

Create a new data file (e.g., my-diagram.data.ts):

export interface MyNode {
  id: string;
  name: string;
  category: 'backend' | 'frontend' | 'database';
  size?: number;
}

export interface MyLink {
  source: string;
  target: string;
  strength?: number;
}

export const MY_DIAGRAM_DATA = {
  nodes: [
    { id: 'api', name: 'REST API', category: 'backend' },
    { id: 'web', name: 'Web App', category: 'frontend' },
    { id: 'db', name: 'Database', category: 'database' }
  ],
  links: [
    { source: 'web', target: 'api' },
    { source: 'api', target: 'db' }
  ]
};

Step 2: Create a D3 Component

@Component({
  selector: 'app-my-diagram',
  standalone: true,
  template: `
    <div class="diagram-container">
      <svg [attr.width]="width()" [attr.height]="height()"></svg>
    </div>
  `
})
export class MyDiagramComponent {
  data = input.required<MyDiagramData>();
  width = input<number>(800);
  height = input<number>(600);
  
  // D3 rendering logic here...
}

Step 3: Register in Markdown Renderer

Add to enhanced-markdown-renderer.component.ts:

// In parseCodeBlock method
if (language === 'my-diagram') {
  return {
    element: { type: 'my-diagram', content, title }
  };
}

// In template
@case ('my-diagram') {
  <app-my-diagram [data]="getMyDiagramData()"></app-my-diagram>
}

Step 4: Use in Markdown

preset-name

🎨 Advanced Styling Techniques

Layer-Based Color Coding

private getLayerColor(layer: string): string {
  const colors = {
    foundation: '#4F46E5',  // Indigo
    framework: '#059669',   // Emerald  
    feature: '#DC2626',     // Red
    application: '#7C3AED'  // Violet
  };
  return colors[layer];
}

Interactive Hover Effects

nodeGroups
  .on('mouseover', (event, d) => {
    // Highlight connected nodes
    this.highlightConnections(d.id);
  })
  .on('mouseout', () => {
    // Reset all styles
    this.resetHighlighting();
  });

Force Simulation Configuration

const simulation = d3.forceSimulation(nodes)
  .force('link', d3.forceLink(links)
    .distance(120)        // Distance between connected nodes
    .strength(0.7))       // Link strength
  .force('charge', d3.forceManyBody()
    .strength(-1000))     // Repulsion between nodes
  .force('center', d3.forceCenter(width/2, height/2))
  .force('collision', d3.forceCollide()
    .radius(55));         // Prevent overlap

🎯 Best Practices

✅ DO:

❌ DON'T:


🔧 Troubleshooting

Common Issues:

"Diagram not rendering"

"Nodes overlapping"

// Increase collision radius
.force('collision', d3.forceCollide().radius(60))

"Text not visible"

// Ensure proper text styling
.style('fill', '#ffffff')
.style('font-size', '14px')
.style('pointer-events', 'none')

"Links not connecting"


📊 Performance Optimization

For Large Datasets (100+ nodes):

// Limit simulation iterations
simulation.alphaDecay(0.05);

// Use canvas instead of SVG for better performance
const canvas = d3.select(container).append('canvas');

// Implement viewport culling
const visibleNodes = nodes.filter(n => isInViewport(n));

Memory Management:

ngOnDestroy() {
  // Stop simulation
  this.simulation?.stop();
  
  // Clear event listeners
  this.svg?.selectAll('*').on('.drag', null);
}

🎪 Examples & Templates

Network Topology Diagram

const networkData = {
  nodes: [
    { id: 'router', name: 'Router', type: 'network' },
    { id: 'server1', name: 'Web Server', type: 'server' },
    { id: 'db', name: 'Database', type: 'storage' }
  ],
  links: [
    { source: 'router', target: 'server1' },
    { source: 'server1', target: 'db' }
  ]
};

Organizational Chart

const orgData = {
  nodes: [
    { id: 'ceo', name: 'CEO', level: 1 },
    { id: 'cto', name: 'CTO', level: 2 },
    { id: 'dev1', name: 'Developer', level: 3 }
  ],
  links: [
    { source: 'ceo', target: 'cto' },
    { source: 'cto', target: 'dev1' }
  ]
};

Process Flow Diagram

const processData = {
  nodes: [
    { id: 'start', name: 'Start', type: 'event' },
    { id: 'process1', name: 'Process Data', type: 'activity' },
    { id: 'decision', name: 'Valid?', type: 'gateway' },
    { id: 'end', name: 'End', type: 'event' }
  ],
  links: [
    { source: 'start', target: 'process1' },
    { source: 'process1', target: 'decision' },
    { source: 'decision', target: 'end' }
  ]
};

🚀 Next Steps

  1. 📖 Read the D3.js official documentation: https://d3js.org/
  2. 🎨 Explore our existing components in shared/d3-architecture-diagram/
  3. 🔧 Create your first custom diagram following the guide above
  4. 🎯 Test with real data from your domain
  5. 📱 Make it responsive for all screen sizes

Happy Diagramming! 🎉