Skip to content

Palette

NgDiagram provides a comprehensive palette system that allows users to create custom drag-and-drop interfaces for adding nodes to diagrams. The palette system consists of built-in components that can be customized to create your own palette.

The core building block of the palette is the <ng-diagram-palette-item> component. It transforms any content into a draggable palette item. This wrapper provides drag-and-drop capabilities without imposing visual constraints on the content itself.

A palette item is defined by an NgDiagramPaletteItem:

interface NgDiagramPaletteItem<Data extends object = BasePaletteItemData> {
type?: string;
data: Data;
resizable?: boolean;
rotatable?: boolean;
angle?: number;
size?: Size;
autoSize?: boolean;
zOrder?: number;
}

A palette item is essentially a definition of a node. You can specify its data or other properties that will be used when the node is initialized on the diagram.

Think of it as similar to an Angular component definition:

  • The definition in the palette describes how the node should be created.
  • The instance dropped into the diagram becomes a live node.

Note: You can use your node templates directly inside the palette to represent items. However, ports will not be rendered in the palette or its preview. Ports only render within the diagram canvas context, so outside of it (e.g. palette or preview), they will not appear.

When using <ng-diagram-palette-item>, you can pass any HTML or Angular template as its content to represent the item in the palette. For example, this could be plain text, an image, or a more complex Angular component.

When dragging, a preview of the node is shown. To define the preview, wrap your content in <ng-diagram-palette-item-preview> inside <ng-diagram-palette-item>.

The preview itself can be any HTML or Angular component.

The preview can render any element, of any size. It takes no space in your layout and never shows up on the page — place <ng-diagram-palette-item-preview> anywhere inside the palette item and lay out the palette like any other panel.

During a drag, the preview is scaled to the current zoom of the diagram (up to 3x) and shown under the cursor, so the drag image matches the node that will be dropped.

In the example below, each preview renders the same shape and size as the node its item creates, so the image under the cursor is exactly what lands on the canvas.

import '@angular/compiler';
import { Component } from '@angular/core';
import {
initializeModel,
NgDiagramBackgroundComponent,
NgDiagramComponent,
provideNgDiagram,
type NgDiagramConfig,
type NgDiagramPaletteItem,
} from 'ng-diagram';
import { Palette } from './palette/palette.component';
@Component({
imports: [NgDiagramComponent, NgDiagramBackgroundComponent, Palette],
providers: [provideNgDiagram()],
template: `
<palette-container [model]="paletteModel" />
<div class="not-content diagram">
<ng-diagram [model]="model" [config]="config">
<ng-diagram-background />
</ng-diagram>
</div>
`,
styleUrls: ['./diagram.component.scss'],
})
export class DiagramComponent {
paletteModel: NgDiagramPaletteItem[] = [
{
data: { label: 'Default Node' },
resizable: true,
rotatable: true,
size: { width: 180, height: 45 },
autoSize: false,
},
{
data: { label: 'Default Group' },
resizable: true,
isGroup: true,
size: { width: 200, height: 150 },
autoSize: false,
},
];
config = {
zoom: {
zoomToFit: {
onInit: true,
padding: [150, 150, 150, 150],
},
},
} satisfies NgDiagramConfig;
model = initializeModel({
nodes: [
{ id: '1', position: { x: 100, y: 150 }, data: { label: 'Node 1' } },
],
});
}