Node annotations in EJ2 TypeScript Diagram control

16 Dec 202417 minutes to read

Diagram allows you to customize the position and appearance of the annotation efficiently. Annotation can be aligned relative to the node boundaries. It has Margin, Offset, Horizontal, and Vertical alignment properties. It is quite tricky when all four alignments are used together but gives more control over alignments properties of the ShapeAnnotation class. Annotations of a node can be positioned using the following properties of ShapeAnnotation.

  • Offset
  • HorizontalAlignment
  • VerticalAlignment
  • Margin

Set annotation offset and size

The offset property of an annotation is used to align annotations based on fractional values. The offset can be customized by modifying the x and y values of the offset property. By default, the annotation offset is set to 0.5 on both the x and y axes.

By default, the size of the annotation is calculated based on its content. If you want to set the size externally, you can do so using the width and height properties of annotation.

The following code shows how to set offset, height and width for the annotation.

import {
    Diagram,
    NodeModel,
    ShapeAnnotationModel,
  } from '@syncfusion/ej2-diagrams';
  // A node is created and stored in nodes array.
  let node: NodeModel = {
    // Position of the node
    offsetX: 250,
    offsetY: 250,
    // Size of the node
    width: 100,
    height: 100,
    style: {
      fill: '#6BA5D7',
      strokeColor: 'white',
    },
    // Sets the annotation for the node
    annotations: [
      {
        // Sets the content for the annotation
        content: 'Annotation long annotation content',
        //Sets the offset for the content
        offset: { x: 0, y: 1 },
        height: 100,
        width: 100,
      },
    ],
  };
  // initialize diagram component
  let diagram: Diagram = new Diagram({
    width: '100%',
    height: '600px',
    // Add node
    nodes: [node],
  });
  // render initialized diagram
  diagram.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Diagram</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-diagrams/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-navigations/styles/fabric.css" rel="stylesheet" />
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

Update annotation offset at runtime

The annotation offset can be updated dynamically at runtime. To update the annotation offset, fetch the annotation you want to update and modify its offset.

import {
  Diagram,
  NodeModel,
  ShapeAnnotationModel,
} from '@syncfusion/ej2-diagrams';
// A node is created and stored in nodes array.
let node: NodeModel = {
  // Position of the node
  offsetX: 250,
  offsetY: 250,
  // Size of the node
  width: 100,
  height: 100,
  style: {
    fill: '#6BA5D7',
    strokeColor: 'white',
  },
  // Sets the annotation for the node
 annotations: [
  {
    // Sets the content for the annotation
    content: 'Annotation',
  },
],
};
// initialize diagram component
let diagram: Diagram = new Diagram({
  width: '100%',
  height: '600px',
  // Add node
  nodes: [node],
});
// render initialized diagram
diagram.appendTo('#element');

(document.getElementById('updateOffset') as HTMLInputElement).onclick = () =>{
  diagram.nodes[0].annotations[0].offset = {x:0, y:0.5};
  //To reflect the changes instantly
  diagram.dataBind();
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Diagram</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-diagrams/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-navigations/styles/fabric.css" rel="stylesheet" />
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <input type="button" value="updateOffset" id="updateOffset" />
        <div id='element'></div>
    </div>
</body>

</html>

NOTE

Call dataBind() after property change to reflect the changes instantly.

The following table shows the position of annotation with different offsets.

offset image  
  Top Left {x:0,y:0} TopLeft
  Middle left {x:0,y:0.5} MiddelLeft
  Bootom left {x:0,y:1} BottomLeft
  Middle Top {x:0.5,y:0} MiddleTop
  Center {x:0.5,y:0.5} Center
  Middle Bottom {x:0.5,y:1} MiddleBottom
  Top right {x:1,y:0} TopRight
  Middle right {x:1,y:0.5} MiddleRight
  Bottom right {x:1,y:1} BottomRight

Annotation alignment

The horizontalAlignment property of annotation is used to set how the annotation is horizontally aligned at the annotation position determined from the fraction values. The verticalAlignment property is used to set how annotation is vertically aligned at the annotation position.

The following codes illustrates how to align annotations.

import { Diagram, NodeModel, ShapeAnnotationModel } from '@syncfusion/ej2-diagrams';
// A node is created and stored in nodes array.
let node: NodeModel = {
    // Position of the node
    offsetX: 250,
    offsetY: 250,
    // Size of the node
    width: 100,
    height: 100,
    style: {
        fill: '#6BA5D7',
        strokeColor: 'white'
    },
    // Sets the annotation for the node
    annotations: [{
        content: 'Annotation',
        // Sets the horizontal alignment as left
        horizontalAlignment: 'Left',
        // Sets the vertical alignment as Top
        verticalAlignment: 'Top'
    }]
};
// initialize diagram component
let diagram: Diagram = new Diagram({
    width: '100%',
    height: '600px',
    // Add node
    nodes: [node]
});
// render initialized diagram
diagram.appendTo('#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Diagram</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-diagrams/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-navigations/styles/fabric.css" rel="stylesheet" />
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

The following tables illustrates all the possible alignments visually with ‘offset (0, 0)’.

Horizontal Alignment Vertical Alignment Output with Offset(0,0)
Left Top Left Top Label Alignment
Center Top Center Top Label Alignment
Right Top Right Top Label Alignment
Left Center Left Center Label Alignment
Center Center Center Center Label Alignment
Right Center Right Center Label Alignment
Left Bottom Left Bottom Label Alignment
Center Bottom Center Bottom Label Alignment
Right Bottom Right Bottom Label Alignment

Update annotation alignment at runtime

Annotation alignment can be updated dynamically at runtime. The following code example shows how to update annotation alignment at runtim.

import {
  Diagram,
  NodeModel,
  ShapeAnnotationModel,
} from '@syncfusion/ej2-diagrams';
// A node is created and stored in nodes array.
let node: NodeModel = {
  // Position of the node
  offsetX: 250,
  offsetY: 250,
  // Size of the node
  width: 100,
  height: 100,
  style: {
    fill: '#6BA5D7',
    strokeColor: 'white',
  },
  // Sets the annotation for the node
 annotations: [
  {
    // Sets the content for the annotation
    content: 'Annotation',
  },
],
};
// initialize diagram component
let diagram: Diagram = new Diagram({
  width: '100%',
  height: '600px',
  // Add node
  nodes: [node],
});
// render initialized diagram
diagram.appendTo('#element');

(document.getElementById('updateAlign') as HTMLInputElement).onclick = () =>{
  diagram.nodes[0].annotations[0].horizontalAlignment = 'Right';
  diagram.nodes[0].annotations[0].verticalAlignment = 'Bottom';
  //To reflect the changes instantly
  diagram.dataBind();
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Diagram</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-popups/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-splitbuttons/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-diagrams/styles/material.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-navigations/styles/fabric.css" rel="stylesheet" />
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <input type="button" value="updateAlign" id="updateAlign" />
        <div id='element'></div>
    </div>
</body>

</html>