Skip to content

Model Initialization

Model initialization and reinitialization are crucial concepts in ngDiagram that determine when and how your diagram data is set up and when it’s safe to perform operations on the model. Understanding these mechanisms is essential for building robust applications that handle dynamic data loading and model switching.

There are various scenarios when and how to initialize a model, depending on your application’s requirements and data flow. For comprehensive information about state management patterns and model operations, see State Management.

The initializeModel function is the primary way to create a model for use in ngDiagram. It creates a model instance that wraps your diagram data and provides reactive state management.

import { initializeModel } from 'ng-diagram';
// Create a model with default values (empty nodes, edges, and default metadata)
const model = initializeModel();
// Create a model with initial data
const model = initializeModel({
nodes: [
{
id: '1',
position: { x: 100, y: 150 },
data: { label: 'Node 1' },
},
{
id: '2',
position: { x: 400, y: 150 },
data: { label: 'Node 2' },
},
],
edges: [
{
id: 'edge-1',
source: '1',
target: '2',
sourcePort: 'port-right',
targetPort: 'port-left',
data: {},
},
],
metadata: {
viewport: { x: 0, y: 0, scale: 1 },
},
});

Sometimes you need to replace the entire model with new data. This commonly happens when:

  • Loading data asynchronously - Fetching diagram data from an API
  • Switching between different diagrams - User selects a different model from a list
  • Resetting the diagram - Clearing all data and starting fresh
export class MyComponent {
private readonly injector = inject(Injector);
model = initializeModel();
async loadDiagramFromAPI(diagramId: string) {
// Fetch data asynchronously
const diagramData = await this.dataService.getDiagramData(diagramId);
// Reinitialize model with new data
this.model = initializeModel(diagramData, this.injector);
}
switchToDiagram(diagramData: Partial<Model>) {
// Switch to a different diagram
this.model = initializeModel(diagramData, this.injector);
}
resetDiagram() {
// Reset to empty diagram
this.model = initializeModel({}, this.injector);
}
}

When a model is reinitialized, the diagram goes through a complete initialization process. All nodes and edges need to be measured and positioned before the diagram is fully ready. You need to wait for this process to complete before performing operations on the model.

The initialization process involves several steps:

  1. Model Assignment – A new model is assigned to the diagram component.
  2. Logic Recreation – The internal core logic is destroyed and recreated. Because the logic is recreated, the isInitialized signal has its default value (false).
  3. Element Measurement – All nodes, edges, and their internal parts are measured.
  4. Layout Calculation – Positions and sizes are calculated.
  5. Event Emission & Signal Update – The diagramInit event is emitted when everything is ready, and the isInitialized signal is set to true.

There are three main ways to detect when the diagram is fully initialized:

The most convenient way is to listen for the diagramInit event from the ng-diagram component:

export class MyComponent {
model = initializeModel();
private injector = inject(Injector);
onDiagramInit(event: DiagramInitEvent): void {
console.log('Diagram is fully initialized');
console.log('Nodes:', event.nodes);
console.log('Edges:', event.edges);
console.log('Viewport:', event.viewport);
// Now it's safe to perform operations
this.performPostInitializationLogic();
}
private performPostInitializationLogic() {
// Your logic here - diagram is fully ready
this.modelService.addNodes([...]);
this.modelService.updateNodeData('node-1', { ... });
}
}
<ng-diagram [model]="model" (diagramInit)="onDiagramInit($event)"> </ng-diagram>

You can also check the isInitialized signal from NgDiagramService:

export class MyComponent {
private ngDiagramService = inject(NgDiagramService);
private modelService = inject(NgDiagramModelService);
constructor() {
effect(() => {
if (this.ngDiagramService.isInitialized()) {
this.performPostInitializationLogic();
}
});
}
}

For more advanced scenarios, you can register event listeners programmatically:

export class MyComponent {
private ngDiagramService = inject(NgDiagramService);
private modelService = inject(NgDiagramModelService);
ngOnInit() {
// Register a one-time listener for diagram initialization.
// Alternatively, you can use addEventListener, but make sure to
// unregister it when no longer needed to avoid memory leaks.
this.ngDiagramService.addEventListenerOnce('diagramInit', (event) => {
console.log('Diagram initialized via event listener');
this.performPostInitializationLogic(event);
});
}
private performPostInitializationLogic(event: DiagramInitEvent) {
// Your logic here — at this stage you can safely read the measured
// nodes, edges and their internal parts (positions, sizes, points, etc.).
}
}
// ❌ Don't do this - operations may fail or be ignored
this.model = initializeModel(newData, this.injector);
this.modelService.addNodes([...]); // This might not work!
// ✅ Do this instead
this.model = initializeModel(newData, this.injector);
// Wait for onDiagramInit() to be called, then perform operations

When performing multiple operations after initialization, wrap them in a transaction:

onDiagramInit(event: DiagramInitEvent): void {
this.ngDiagramService.transaction(() => {
this.modelService.addNodes([...]);
this.modelService.addEdges([...]);
this.modelService.updateMetadata({ ... });
});
}

When switching between models frequently, be aware of memory usage:

export class MemoryConsciousComponent {
model = initializeModel();
private injector = inject(Injector);
private currentDiagramId: string | null = null;
async switchToDiagram(diagramId: string) {
// Avoid unnecessary reinitializations
if (this.currentDiagramId === diagramId) {
return;
}
this.currentDiagramId = diagramId;
const diagramData = await this.diagramAPI.getDiagram(diagramId);
this.model = initializeModel(diagramData, this.injector);
}
}

Operations not working after model reinitialization:

  • Ensure you’re waiting for the diagramInit event
  • Check that you’re using the model service, not the model directly

Initialization events not firing:

  • Verify that the diagram component is properly rendered
  • Check that the model is actually changing (not the same reference)

Understanding model initialization and reinitialization is key to building robust ngDiagram applications that can handle dynamic data loading and model switching while maintaining proper timing and state management.