UML diagram in React Diagram component

17 Mar 202524 minutes to read

UML Class Diagram

A class diagram visually depicts the static structure of an application and is extensively employed in modeling object-oriented systems. It holds a unique position in UML diagrams, as it directly aligns with object-oriented languages. The diagram also facilitates the automatic generation of class diagram shapes based on business logic, streamlining the translation from conceptual models to practical implementation.

Uml Class Diagram Shapes

The UML class diagram shapes are explained as follows.

Class

  • A class defines a group of objects that share common specifications, features, constraints, and semantics. To create a class object, the classifier should be defined using the class notation. This notation serves as a foundational element in object-oriented programming, encapsulating the Essential® characteristics and behavior that objects belonging to the class will exhibit.

  • Also, define the name, attributes, and methods of the class using the class property of node.

  • The attribute’s name, type, and scope properties allow you to define the name, data type, and visibility of the attribute.

  • The method’s name, parameters, type, and scope properties allow you to define the name, parameter, return type, and visibility of the methods.

  • The method parameters property allow you to define the name ,type and style of the parameter.

  • The following code example illustrates how to create a class.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
// A node is created and stored in nodes array.
let node = [{
    id: "Patient",
    style: {
      fill: '#26A0DA',
    },
    //Position of the node
    offsetX: 200,
    offsetY: 200,
    shape: {
      type: "UmlClassifier",
      //Define class object
      classShape: {
        name: "Patient",
        //Define class attributes
        attributes: [{ name: "accepted", type: "Date" }],
        //Define class methods
        methods: [{ name: "getHistory", type: "getHistory" }]
      },
      classifier: "Class"
    } 
}];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add node
    nodes={node}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent,NodeModel,UmlClassifierShapeModel} from "@syncfusion/ej2-react-diagrams";
// A node is created and stored in nodes array.
let node:NodeModel[] = [{
    id: "Patient",
    style: {
      fill: '#26A0DA',
    },
    //Position of the node
    offsetX: 200,
    offsetY: 200,
    shape: {
      type: "UmlClassifier",
      //Define class object
      classShape: {
        name: "Patient",
        //Define class attributes
        attributes: [{ name: "accepted", type: "Date" }],
        //Define class methods
        methods: [{ name: "getHistory", type: "getHistory" }]
      },
      classifier: "Class"
    } as UmlClassifierShapeModel
}];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add node
    nodes={node}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

Interface

An interface is a specific type of classifier that signifies a declaration of a cohesive set of public features and obligations. When creating an interface, involves defining the classifier property using the notation. This foundational concept in object-oriented programming outlines a contract for classes to adhere to, specifying the required methods and behaviors without delving into the implementation details.

Additionally, you can define the name, attributes, and methods of the interface using the interface property of the node.

The attributes’ name, type, and scope properties allow you to specify the name, data type, and visibility of each attribute.

Similarly, the methods’ name, parameters, type, and scope properties enable you to define the name, parameters, return type, and visibility of the methods.

The parameters object within methods allows you to specify the name and type of each parameter.

The following code example illustrates how to create an interface:

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
// A node is created and stored in nodes array.
let node = [{
    id: "Patient",
    //Position of the node
    offsetX: 200,
    offsetY: 200,
    style: {
        fill: '#26A0DA',
    },
    shape: {
        type: "UmlClassifier",
        //Define interface object
        interfaceShape: {
            name: "Patient",
            //Define interface attributes
            attributes: [{ name: "owner", type: "String[*]" }],
            //Define interface methods
            methods: [
                {
                    name: "deposit",
                    parameters: [
                        {
                            name: "amount",
                            type: "Dollars"
                        }
                    ]
                }
            ]
        },
        classifier: "Interface"
    }
}];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'}
        // Add node
        nodes={node} />);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent ,UmlClassifierShapeModel,NodeModel} from "@syncfusion/ej2-react-diagrams";
// A node is created and stored in nodes array.
let node:NodeModel[] = [{
    id: "Patient",
    //Position of the node
    offsetX: 200,
    offsetY: 200,
    style: {
      fill: '#26A0DA',
    },
    shape: {
      type: "UmlClassifier",
      //Define interface object
      interfaceShape: {
        name: "Patient",
        //Define interface attributes
        attributes: [{ name: "owner", type: "String[*]" }],
        //Define interface methods
        methods: [
          {
            name: "deposit",
            parameters: [
              {
                name: "amount",
                type: "Dollars"
              }
            ]
          }
        ]
      },
      classifier: "Interface"
     } as UmlClassifierShapeModel
}];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add node
    nodes={node}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

Enumeration

To establish an enumeration, designate the classifier property of the node as enumeration. Additionally, define the name and enumerate the members of the enumeration using the appropriate enumeration property of the node. This process encapsulates a set of distinct values within the enumeration, allowing for a clear representation of specific,and named constants within a system.

You can set a name for the enumeration members collection using the name property of members collection.

The following code example illustrates how to create an enumeration.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// A node is created and stored in nodes array.
let node = [{
        id: 'node',
        offsetX: 200,
        offsetY: 200,
        style: {
            fill: '#26A0DA',
          },
        shape: {
            type: 'UmlClassifier',
            enumerationShape: {
                name: 'AccountType',
                members: [
                    {
                        name: 'Checking Account', style: {}
                    },
                    {
                        name: 'Savings Account'
                    },
                    {
                        name: 'Credit Account'
                    }
                ]
            },
            classifier: 'Enumeration'
        }
    }];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add node
    nodes={node}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import {DiagramComponent,NodeModel,UmlClassifierShapeModel } from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
// A node is created and stored in nodes array.
let node: NodeModel[] = [{
    id: 'node',
        offsetX: 200,
        offsetY: 200,
        style: {
            fill: '#26A0DA',
          },
        shape: {
            type: 'UmlClassifier',
            enumerationShape: {
                name: 'AccountType',
                members: [
                    {
                        name: 'Checking Account', style: {}
                    },
                    {
                        name: 'Savings Account'
                    },
                    {
                        name: 'Credit Account'
                    }
                ]
            },
            classifier: 'Enumeration'
    } as UmlClassifierShapeModel
}];
// initialize Diagram component
function App() {
  return (
    <DiagramComponent
      id="container"
      width={'100%'}
      height={'600px'}
      // Add node
      nodes={node}
      // render initialized Diagram
    />
  );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

UML Class Relationships

  • A class may be involved in one or more relationships with other classes. A relationship can be one of the following types:
Shape Image
Association Association
Aggregation Aggregation
Composition Composition
Inheritance Inheritance
Dependency Dependency

Association

Association is basically a set of links that connects elements of a UML model. The type of association is as follows.

 1.Directional
 2.BiDirectional

The association property allows you to define the type of association. The default value of association is “Directional”. The following code example illustrates how to create an association.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// A node is created and stored in nodes array.
let connector = [{
        id: "connector",
        //Define connector start and end points
        sourcePoint: { x: 100, y: 100 },
        targetPoint: { x: 300, y: 300 },
        type: "Straight",
        shape: {
            type: "UmlClassifier",
            relationship: "Association",
            //Define type of association
            association: "BiDirectional"
        }
    },
    {
        id: 'connector2',
        //Define connector start and end points
        sourcePoint: { x: 200, y: 100 },
        targetPoint: { x: 400, y: 300 },
        type: 'Straight',
        shape: {
          type: 'UmlClassifier',
          relationship: 'Association',
          associationType: 'BiDirectional',
        },
      }];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add connector
    connectors={connector}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import {DiagramComponent,ConnectorModel } from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
// A node is created and stored in nodes array.
let connector: ConnectorModel[] = [{
    id: "connector",
    //Define connector start and end points
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 300 },
    type: "Straight",
    shape: {
      type: "UmlClassifier",
      relationship: "Association",
      //Define type of association
      association: "BiDirectional"
    }
},
{
  id: 'connector2',
  //Define connector start and end points
  sourcePoint: { x: 200, y: 100 },
  targetPoint: { x: 400, y: 300 },
  type: 'Straight',
  shape: {
    type: 'UmlClassifier',
    relationship: 'Association',
    associationType: 'BiDirectional',
  },
}];
// initialize Diagram component
function App() {
  return (
    <DiagramComponent
      id="container"
      width={'100%'}
      height={'600px'}
      // Add connector
      connectors={connector}
    />
  );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

Aggregation

Aggregation is a binary association between a property and one or more composite objects that group together a set of instances. Aggregation is decorated with a hollow diamond. To create an aggregation shape, define the relationship as “Aggregation”.

The following code example illustrates how to create an aggregation.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// A node is created and stored in nodes array.
let connector = [{
        id: "connector",
        //Define connector start and end points
        sourcePoint: { x: 100, y: 100 },
        targetPoint: { x: 300, y: 300 },
        type: "Straight",
        shape: {
            type: "UmlClassifier",
            //Set an relationship for connector
            relationship: "Aggregation"
        }
    }];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add connector
    connectors={connector}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
    Diagram,
    DiagramComponent,
    ConnectorModel
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
// A node is created and stored in nodes array.
let connector: ConnectorModel[] = [{
    id: "connector",
    //Define connector start and end points
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 300 },
    type: "Straight",
    shape: {
      type: "UmlClassifier",
      //Set an relationship for connector
      relationship: "Aggregation"
    }
}];
// initialize Diagram component
function App() {
  return (
    <DiagramComponent
      id="container"
      width={'100%'}
      height={'600px'}
      // Add connector
      connectors={connector}
    />
  );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

Composition

Composition is a strong form of aggregation. The composition is decorated with a black diamond. To create a composition shape, define the relationship property of the connector as “Composition”.

The following code example illustrates how to create a composition.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// A node is created and stored in nodes array.
let connector = [{
        id: "connector",
        //Define connector start and end points
        sourcePoint: { x: 100, y: 100 },
        targetPoint: { x: 300, y: 300 },
        type: "Straight",
        shape: {
            type: "UmlClassifier",
            //Set an relationship for connector
            relationship: "Composition"
        }
    }];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add connector
    connectors={connector}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
    Diagram,
    DiagramComponent,
    ConnectorModel
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
// A node is created and stored in nodes array.
let connector: ConnectorModel[] = [{
    id: "connector",
    //Define connector start and end points
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 300 },
    type: "Straight",
    shape: {
      type: "UmlClassifier",
      //Set an relationship for connector
      relationship: "Composition"
    }
}];
// initialize Diagram component
function App() {
  return (
    <DiagramComponent
      id="container"
      width={'100%'}
      height={'600px'}
      // Add connector
      connectors={connector}
    />
  );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

Inheritance

Inheritance is also called a “generalization”. Inheritance is a binary taxonomic directed relationship between a more general classifier (superclass) and a more specific classifier (subclass).Inheritance is shown as a line with a hollow triangle.

To create an inheritance, define the relationship as “inheritance”.

The following code example illustrates how to create an inheritance.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// A node is created and stored in nodes array.
let connector = [{
        id: "connector",
        //Define connector start and end points
        sourcePoint: { x: 100, y: 100 },
        targetPoint: { x: 300, y: 300 },
        type: "Straight",
        shape: {
            type: "UmlClassifier",
            //Set an relationship for connector
            relationship: "Inheritance"
        }
    }];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add connector
    connectors={connector}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
    Diagram,
    DiagramComponent,
    ConnectorModel
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
// A node is created and stored in nodes array.
let connector: ConnectorModel[] = [{
    id: "connector",
    //Define connector start and end points
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 300 },
    type: "Straight",
    shape: {
      type: "UmlClassifier",
      //Set an relationship for connector
      relationship: "Inheritance"
    }
}];
// initialize Diagram component
function App() {
  return (
    <DiagramComponent
      id="container"
      width={'100%'}
      height={'600px'}
      // Add connector
      connectors={connector}
    />
  );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

Dependency

Dependency is a directed relationship, which is used to show that some UML elements need or depend on other model elements for specifications. Dependency is shown a dashed line with an opened arrow. To create a dependency, define the relationship property of the connector as “dependency”.

The following code example illustrates how to create a dependency.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// A node is created and stored in nodes array.
let connector = [{
        id: "connector",
        //Define connector start and end points
        sourcePoint: { x: 100, y: 100 },
        targetPoint: { x: 300, y: 300 },
        type: "Straight",
        shape: {
            type: "UmlClassifier",
            //Set an relationship for connector
            relationship: "Dependency"
        }
    }];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add connector
    connectors={connector}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
    Diagram,
    DiagramComponent,
    ConnectorModel
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
// A node is created and stored in nodes array.
let connector: ConnectorModel[] = [{
    id: "connector",
    //Define connector start and end points
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 300 },
    type: "Straight",
    shape: {
      type: "UmlClassifier",
      //Set an relationship for connector
      relationship: "Dependency"
    }
}];
// initialize Diagram component
function App() {
  return (
    <DiagramComponent
      id="container"
      width={'100%'}
      height={'600px'}
      // Add connector
      connectors={connector}
    />
  );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

Multiplicity

Multiplicity is a definition of an inclusive interval of non-negative integers to specify the allowable number of instances of a described element. The type of multiplicity are as follows.

 1.OneToOne
 2.ManyToOne
 3.OneToMany
 4.ManyToMany

By default the multiplicity will be considered as “OneToOne”.

The multiplicity property in UML allows you to specify large number of elements or some collection of elements.

The shape multiplicity’s source property is used to set the source label to the connector and the target property is used to set the target label to the connector.

To set an optionality or cardinality for the connector source label, use the optional property.

The lowerBounds and upperBounds could be natural constants or constant expressions evaluated to a natural (non negative) number. The upper bound could also be specified as an asterisk ‘*’ which denotes an unlimited number of elements. The upper bound should be greater than or equal to the lower bound.

The following code example illustrates how to customize the multiplicity.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// A node is created and stored in nodes array.
let connector = [
    {
        id: 'connector1',
        //Define connector start and end points
        sourcePoint: { x: 100, y: 100 },
        targetPoint: { x: 300, y: 300 },
        type: 'Straight',
        shape: {
          type: 'UmlClassifier',
          relationship: 'Dependency',
          multiplicity: {
            //Set multiplicity type
            type: 'OneToOne',
          },
        },
      },
      {
        id: 'connector2',
        //Define connector start and end points
        sourcePoint: { x: 200, y: 100 },
        targetPoint: { x: 400, y: 300 },
        type: 'Straight',
        shape: {
          type: 'UmlClassifier',
          relationship: 'Dependency',
          multiplicity: {
            //Set multiplicity type
            type: 'ManyToOne',
            //Set source label to connector
            source: {
              optional: true,
              lowerBounds: '89',
              upperBounds: '67',
            },
            //Set target label to connector
            target: {
              optional: true,
              lowerBounds: '78',
              upperBounds: '90',
            },
          },
        },
      },
    {
        id: "connector3",
        //Define connector start and end points
        sourcePoint: { x: 300, y: 100 },
        targetPoint: { x: 500, y: 300 },
        type: "Straight",
        shape: {
            type: "UmlClassifier",
            relationship: "Dependency",
            multiplicity: {
                //Set multiplicity type
                type: "OneToMany",
                //Set source label to connector
                source: {
                    optional: true,
                    lowerBounds: 89,
                    upperBounds: 67
                },
                //Set target label to connector
                target: {
                    optional: true,
                    lowerBounds: 78,
                    upperBounds: 90
                }
            }
        }
    },
    {
        id: 'connector4',
        //Define connector start and end points
        sourcePoint: { x: 400, y: 100 },
        targetPoint: { x: 600, y: 300 },
        type: 'Straight',
        shape: {
          type: 'UmlClassifier',
          relationship: 'Dependency',
          multiplicity: {
            //Set multiplicity type
            type: 'ManyToMany',
            //Set source label to connector
            source: {
              optional: true,
              lowerBounds: '89',
              upperBounds: '67',
            },
            //Set target label to connector
            target: {
              optional: true,
              lowerBounds: '78',
              upperBounds: '90',
            },
          },
        },
      },
];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add connector
    connectors={connector}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import {DiagramComponent,ConnectorModel} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
// A node is created and stored in nodes array.
let connector: ConnectorModel[] = [
  {
    id: 'connector1',
    //Define connector start and end points
    sourcePoint: { x: 100, y: 100 },
    targetPoint: { x: 300, y: 300 },
    type: 'Straight',
    shape: {
      type: 'UmlClassifier',
      relationship: 'Dependency',
      multiplicity: {
        //Set multiplicity type
        type: 'OneToOne',
      },
    },
  },
  {
    id: 'connector2',
    //Define connector start and end points
    sourcePoint: { x: 200, y: 100 },
    targetPoint: { x: 400, y: 300 },
    type: 'Straight',
    shape: {
      type: 'UmlClassifier',
      relationship: 'Dependency',
      multiplicity: {
        //Set multiplicity type
        type: 'ManyToOne',
        //Set source label to connector
        source: {
          optional: true,
          lowerBounds: '89',
          upperBounds: '67',
        },
        //Set target label to connector
        target: {
          optional: true,
          lowerBounds: '78',
          upperBounds: '90',
        },
      },
    },
  },
{
    id: "connector3",
    //Define connector start and end points
    sourcePoint: { x: 300, y: 100 },
    targetPoint: { x: 500, y: 300 },
    type: "Straight",
    shape: {
        type: "UmlClassifier",
        relationship: "Dependency",
        multiplicity: {
            //Set multiplicity type
            type: "OneToMany",
            //Set source label to connector
            source: {
                optional: true,
                lowerBounds: 89,
                upperBounds: 67
            },
            //Set target label to connector
            target: {
                optional: true,
                lowerBounds: 78,
                upperBounds: 90
            }
        }
    }
},
{
    id: 'connector4',
    //Define connector start and end points
    sourcePoint: { x: 400, y: 100 },
    targetPoint: { x: 600, y: 300 },
    type: 'Straight',
    shape: {
      type: 'UmlClassifier',
      relationship: 'Dependency',
      multiplicity: {
        //Set multiplicity type
        type: 'ManyToMany',
        //Set source label to connector
        source: {
          optional: true,
          lowerBounds: '89',
          upperBounds: '67',
        },
        //Set target label to connector
        target: {
          optional: true,
          lowerBounds: '78',
          upperBounds: '90',
        },
      },
    },
  },

];
// initialize Diagram component
function App() {
  return (
    <DiagramComponent
      id="container"
      width={'100%'}
      height={'600px'}
      // Add connector
      connectors={connector}
    />
  );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

How to add UML child at runtime

In UML nodes, child elements such as members, methods and attributes can be added either programmatically or interactively.

Adding UML child through code

The addChildToUmlNode method is employed for dynamically adding a child to the UML node during runtime, providing flexibility in modifying the diagram structure programmatically.

The following code example illustrates how to add members, methods and attributes to UML node at rumtime.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
let diagramInstance;
// A node is created and stored in nodes array.
let nodes = [{
    id: 'node1',
    offsetX: 150,
    offsetY: 150, 
    style: {
        fill: '#26A0DA',
    },
    shape: {
        type: 'UmlClassifier',
        classShape: {
            attributes: [
                { name: 'accepted', type: 'Date', },
            ],
            methods: [{ name: 'getHistory', style: {}, parameters: [{ name: 'Date', style: {} }], type: 'History' }],
            name: 'Patient'
        },
        classifier: 'Class'
    },
},
{
    id: 'node2',
    offsetX: 400,
    offsetY: 200, 
    style: {
        fill: '#26A0DA',
    },
    shape: {
        type: 'UmlClassifier',
        enumerationShape: {
            name: 'AccountType',
            members: [
                {
                    name: 'Checking Account', 
                },
            ]
        },
        classifier: 'Enumeration'
    },
}];

const addMethod = function() {
    let node = diagramInstance.nodes[0];
    let methods = {
        name: 'getHistory',
        style: { color: 'red' },
        parameters: [{ name: 'Date', style: {} }],
        type: 'History',
    };
    diagramInstance.addChildToUmlNode(node, methods, 'Method');

}

const addAttribute = function() {
    let node = diagramInstance.nodes[0];
    let attributes = { name: 'accepted', type: 'Date', style: { color: "red", } };
    diagramInstance.addChildToUmlNode(node, attributes, "Attribute");
    
}
const addMember = function() {
    let node = diagramInstance.nodes[1];
    let members = { name: 'Checking new', style: { color: "red", }, isSeparator: true };
    diagramInstance.addChildToUmlNode(node, members, "Member");
    
}
// initialize Diagram component
function App() {
    return (<div>
        <ButtonComponent content="Add Method" onClick={addMethod}/>
        <ButtonComponent content="Add Attribute" onClick={addAttribute}/>
        <ButtonComponent content="Add Member" onClick={addMember}/>
    <DiagramComponent id="container" ref={(diagram) => (diagramInstance = diagram)} width={'100%'} height={'600px'} 
    nodes={nodes}
    /></div>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent ,NodeModel,UmlClassifierShapeModel} from "@syncfusion/ej2-react-diagrams";
import { ButtonComponent } from '@syncfusion/ej2-react-buttons';
let diagramInstance:DiagramComponent;
// A node is created and stored in nodes array.
let nodes:NodeModel[] = [{
    id: 'node1',
    offsetX: 150,
    offsetY: 150, 
    style: {
        fill: '#26A0DA',
    },
    shape: {
        type: 'UmlClassifier',
        classShape: {
            attributes: [
                { name: 'accepted', type: 'Date', },
            ],
            methods: [{ name: 'getHistory', style: {}, parameters: [{ name: 'Date', style: {} }], type: 'History' }],
            name: 'Patient'
        },
        classifier: 'Class',
    } as UmlClassifierShapeModel
},
{
    id: 'node2',
    offsetX: 400,
    offsetY: 200, 
    style: {
        fill: '#26A0DA',
    },
    shape: {
        type: 'UmlClassifier',
        enumerationShape: {
            name: 'AccountType',
            members: [
                {
                    name: 'Checking Account', 
                },
            ]
        },
        classifier: 'Enumeration',
    }as UmlClassifierShapeModel,
}];

const addMethod = function() {
    let node = diagramInstance.nodes[0];
    let methods = {
        name: 'getHistory',
        style: { color: 'red' },
        parameters: [{ name: 'Date', style: {} }],
        type: 'History',
    };
    diagramInstance.addChildToUmlNode(node, methods, 'Method');

}

const addAttribute = function() {
    let node = diagramInstance.nodes[0];
    let attributes = { name: 'accepted', type: 'Date', style: { color: "red", } };
    diagramInstance.addChildToUmlNode(node, attributes, "Attribute");
    
}
const addMember = function() {
    let node = diagramInstance.nodes[1];
    let members = { name: 'Checking new', style: { color: "red", }, isSeparator: true };
    diagramInstance.addChildToUmlNode(node, members, "Member");
    
}
// initialize Diagram component
function App() {
    return (<div>
        <ButtonComponent content="Add Method" onClick={addMethod}/>
        <ButtonComponent content="Add Attribute" onClick={addAttribute}/>
        <ButtonComponent content="Add Member" onClick={addMember}/>
    <DiagramComponent id="container" ref={(diagram) => (diagramInstance = diagram)} width={'100%'} height={'600px'} 
    nodes={nodes}
    /></div>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

Adding UML child through user interaction

To include a child, select a node, move the mouse outside it, and position the pointer near the right side. A highlighter emerges between the two child elements. Click the highlighter to add a child type to the chosen UML node seamlessly. The following gif illustrates how to add a Child through user interaction.

UML child

Adding UML Nodes in Symbol palette

UML built-in shapes are efficiently rendered in a symbol palette. The symbols property of palettes is used to define UML symbols with the necessary classes and methods. By incorporating this feature, you can seamlessly augment the palette with a curated collection of predefined UML symbols, thereby enhancing the versatility of your UML diagramming application.

The following code example showcases the rendering of UML built-in shapes in a symbol palette.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { SymbolPaletteComponent, DiagramComponent} from "@syncfusion/ej2-react-diagrams";
//Initialize the basicshapes for the symbol palette
export function getUmlShapes() {
    let umlShapes = [
        {
            id: 'class',
            style: {
                fill: '#26A0DA',
            },
            borderColor: 'white',
            shape: {
                type: 'UmlClassifier',
                classShape: {
                    attributes: [
                        { name: 'accepted', type: 'Date', style: { color: "red", fontFamily: "Arial", textDecoration: 'Underline',  italic: true },isSeparator: true },
                    ],
                    methods: [{ name: 'getHistory', style: {}, parameters: [{ name: 'Date', style: {} }], type: 'History' }],
                    name: 'Patient'
                },
                classifier: 'Class'
            },
        },
        {
            id: 'Interface',
            style: {
                fill: '#26A0DA',
            }, borderColor: 'white',
            shape: {
                type: 'UmlClassifier',
                interfaceShape: {
                    name: "Bank Account",
                },
                classifier: 'Interface'
            },
        },
        {
            id: 'Enumeration',
            style: {
                fill: '#26A0DA',
            }, borderColor: 'white',
            shape: {
                type: 'UmlClassifier',
                enumerationShape: {
                    name: 'AccountType',
                    members: [
                        {
                            name: 'Checking Account', style: {}
                        },
                    ]
                },
                classifier: 'Enumeration'
            },
        },
    ];
    return umlShapes;
}
//Initializes the symbol palette
let diagramInstance;
function App() {
    return (
        <div style={{ width: '100%' }}>
            <div id="palette-space" className="sb-mobile-palette">
            <SymbolPaletteComponent
                id="container"
                palettes={[
                {
                    id: 'uml',
                    expanded: true,
                    symbols: getUmlShapes(),
                    title: 'UML Shapes',
                },
                ]}
                symbolHeight={80}
                symbolWidth={80}
                getNodeDefaults={(symbol) => {
                symbol.width = 100;
                symbol.height = 100;
                }}
                //Sets the margin of the dragging helper relative to the mouse cursor
                symbolMargin={{
                left: 12,
                right: 12,
                top: 12,
                bottom: 12,
                }}
                getSymbolInfo={(symbol) => {
                //Defines the symbol description
                return { fit: true, description: { text: symbol.id } };
                }}
            />
            </div>
            <div id="diagram-space" className="sb-mobile-diagram">
            <DiagramComponent
                id="diagram"
                ref={(diagram) => (diagramInstance = diagram)}
                width={'100%'}
                height={'700px'}
            ></DiagramComponent>
            </div>
        </div>
    );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
  Diagram,
  NodeModel,
  SymbolPalette,
  DiagramComponent,
  SymbolInfo,
  NodeConstraints,
  SymbolPaletteComponent,
} from "@syncfusion/ej2-react-diagrams";
//Initialize the basicshapes for the symbol palette
let diagramInstance:any;
export function getUmlShapes(): NodeModel[] {
  let umlShapes: NodeModel[] = [
      {
        id: 'class',
        style: {
            fill: '#26A0DA',
        },
        borderColor: 'white',
        shape: {
            type: 'UmlClassifier',
            classShape: {
                attributes: [
                    { name: 'accepted', type: 'Date', style: { color: "red", fontFamily: "Arial", textDecoration: 'Underline',  italic: true },isSeparator: true },
                ],
                methods: [{ name: 'getHistory', style: {}, parameters: [{ name: 'Date', style: {} }], type: 'History' }],
                name: 'Patient'
            },
            classifier: 'Class'
        },
      },
      {
          id: 'Interface',
          style: {
              fill: '#26A0DA',
          }, borderColor: 'white',
          shape: {
              type: 'UmlClassifier',
              interfaceShape: {
                  name: "Bank Account",
              },
              classifier: 'Interface'
          },
      },
      {
          id: 'Enumeration',
          style: {
              fill: '#26A0DA',
          }, borderColor: 'white',
          shape: {
              type: 'UmlClassifier',
              enumerationShape: {
                  name: 'AccountType',
                  members: [
                      {
                          name: 'Checking Account', style: {}
                      },
                  ]
              },
              classifier: 'Enumeration'
          },
      },
  ];
  return umlShapes;
}

//Initializes the symbol palette
function App() {
  return (
      <div style={{ width: '100%' }}>
        <div id="palette-space" className="sb-mobile-palette">
        <SymbolPaletteComponent
            id="container"
            palettes={[
            {
                id: 'uml',
                expanded: true,
                symbols: getUmlShapes(),
                title: 'UML Shapes',
            },
            ]}
            symbolHeight={80}
            symbolWidth={80}
            //Sets the margin of the dragging helper relative to the mouse cursor
            symbolMargin={{
            left: 12,
            right: 12,
            top: 12,
            bottom: 12,
            }}
            getNodeDefaults={(symbol: NodeModel): void => {
              symbol.width = 100;
              symbol.height = 100;
            }}
            getSymbolInfo={(symbol: NodeModel): SymbolInfo => {
            //Defines the symbol description
            return { fit: true,description: { text: symbol.id, } };
          }}
        />
        </div>
        <div id="diagram-space" className="sb-mobile-diagram">
        <DiagramComponent
            id="diagram"
            ref={(diagram) => (diagramInstance = diagram)}
            width={'100%'}
            height={'700px'}
        ></DiagramComponent>
        </div>
      </div>
  );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

Editing in UML nodes

You can edit the name, attributes, and methods of the class diagram shapes just double clicking, similar to editing a node annotation.

The following image illustrates how the text editor looks in an edit mode.

Editing Class Diagram

UML Activity diagram

An Activity diagram functions as a visual flowchart, illustrating the progression from one activity to the next within a system. Each activity corresponds to a system operation, providing a clear depiction of the sequential flow in a dynamic process..

The purpose of an activity diagram can be described as follows.

1. Draw the activity flow of a system.

2. Describe the sequence from one activity to another.

3. Describe the parallel, branched, and concurrent flow of the system.

UML Activity diagram Shapes

To create a UmlActivity, define the type as “UmlActivity” and set the list of built-in shapes in the shape property as demonstrated below.

Shape Image
Action Action
Decision Decision
MergeNode MergeNode
InitialNode InitialNode
FinalNode FinalNode
ForkNode ForkNode
JoinNode JoinNode
TimeEvent TimeEvent
AcceptingEvent AcceptingEvent
SendSignal SendSignal
ReceiveSignal ReceiveSignal
StructuredNode StructuredNode
Note Note

The following code illustrates how to create a UmlActivity shapes.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// A node is created and stored in nodes array.
let node = [
    { id: 'Action', shape: { type: 'UmlActivity', shape: 'Action' },offsetX:100,offsetY:100,height:100,width:100 },
    { id: 'Decision', shape: { type: 'UmlActivity', shape: 'Decision' },offsetX:300,offsetY:100,height:100,width:100  },
    { id: 'MergeNode', shape: { type: 'UmlActivity', shape: 'MergeNode' },offsetX:500,offsetY:100,height:100,width:100  },
    { id: 'InitialNode', shape: { type: 'UmlActivity', shape: 'InitialNode' },offsetX:100,offsetY:300,height:100,width:100  },
    { id: 'FinalNode', shape: { type: 'UmlActivity', shape: 'FinalNode' },offsetX:300,offsetY:300,height:100,width:100  },
    { id: 'ForkNode', shape: { type: 'UmlActivity', shape: 'ForkNode' },offsetX:500,offsetY:300,height:100,width:100},
    { id: 'JoinNode', shape: { type: 'UmlActivity', shape: 'JoinNode' },offsetX:100,offsetY:500,height:100,width:100 },
    { id: 'TimeEvent', shape: { type: 'UmlActivity', shape: 'TimeEvent' },offsetX:300,offsetY:500,height:100,width:100 },
    { id: 'AcceptingEvent', shape: { type: 'UmlActivity', shape: 'AcceptingEvent' },offsetX:500,offsetY:500,height:100,width:100 },
    { id: 'SendSignal', shape: { type: 'UmlActivity', shape: 'SendSignal' },offsetX:100,offsetY:700,height:100,width:100 },
    { id: 'ReceiveSignal', shape: { type: 'UmlActivity', shape: 'ReceiveSignal' },offsetX:300,offsetY:700,height:100,width:100 },
    { id: 'StructuredNode', shape: { type: 'UmlActivity', shape: 'StructuredNode' },offsetX:500,offsetY:700,height:100,width:100 },
    { id: 'Note', shape: { type: 'UmlActivity', shape: 'Note' },offsetX:100,offsetY:900,height:100,width:100 }
];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add node
    nodes={node}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import {DiagramComponent,NodeModel } from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
// A node is created and stored in nodes array.
let node: NodeModel[] = [
  { id: 'Action', shape: { type: 'UmlActivity', shape: 'Action' },offsetX:100,offsetY:100,height:100,width:100 },
  { id: 'Decision', shape: { type: 'UmlActivity', shape: 'Decision' },offsetX:300,offsetY:100,height:100,width:100  },
  { id: 'MergeNode', shape: { type: 'UmlActivity', shape: 'MergeNode' },offsetX:500,offsetY:100,height:100,width:100  },
  { id: 'InitialNode', shape: { type: 'UmlActivity', shape: 'InitialNode' },offsetX:100,offsetY:300,height:100,width:100  },
  { id: 'FinalNode', shape: { type: 'UmlActivity', shape: 'FinalNode' },offsetX:300,offsetY:300,height:100,width:100  },
  { id: 'ForkNode', shape: { type: 'UmlActivity', shape: 'ForkNode' },offsetX:500,offsetY:300,height:100,width:100},
  { id: 'JoinNode', shape: { type: 'UmlActivity', shape: 'JoinNode' },offsetX:100,offsetY:500,height:100,width:100 },
  { id: 'TimeEvent', shape: { type: 'UmlActivity', shape: 'TimeEvent' },offsetX:300,offsetY:500,height:100,width:100 },
  { id: 'AcceptingEvent', shape: { type: 'UmlActivity', shape: 'AcceptingEvent' },offsetX:500,offsetY:500,height:100,width:100 },
  { id: 'SendSignal', shape: { type: 'UmlActivity', shape: 'SendSignal' },offsetX:100,offsetY:700,height:100,width:100 },
  { id: 'ReceiveSignal', shape: { type: 'UmlActivity', shape: 'ReceiveSignal' },offsetX:300,offsetY:700,height:100,width:100 },
  { id: 'StructuredNode', shape: { type: 'UmlActivity', shape: 'StructuredNode' },offsetX:500,offsetY:700,height:100,width:100 },
  { id: 'Note', shape: { type: 'UmlActivity', shape: 'Note' },offsetX:100,offsetY:900,height:100,width:100 }
];
// initialize Diagram component
function App() {
  return (
    <DiagramComponent
      id="container"
      width={'100%'}
      height={'600px'}
      // Add node
      nodes={node}
    />
  );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);

Uml Activity connector

To establish a UML Activity connector, specify the type of connector shape as “UmlActivity” and define the flow as either “Exception,” “Control,” or “Object.” This configuration delineates the nature of the connection, allowing for a precise representation of the interaction within the activity diagram.

The following code illustrates how to create a UmlActivity connector.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { DiagramComponent } from "@syncfusion/ej2-react-diagrams";
let diagramInstance;
// A node is created and stored in nodes array.
let connector = [{
        id: 'connector',
        type: 'Straight',
        //Define connector start and end points
        sourcePoint: { x: 100, y: 100 },
        targetPoint: { x: 200, y: 200 },
        shape: { type: 'UmlActivity', flow: 'Exception' }
    }];
// initialize Diagram component
function App() {
    return (<DiagramComponent id="container" width={'100%'} height={'600px'} 
    // Add connector
    connectors={connector}/>);
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);
import * as React from "react";
import * as ReactDOM from "react-dom";
import {
    Diagram,
    DiagramComponent,
    ConnectorModel
} from "@syncfusion/ej2-react-diagrams";
let diagramInstance: DiagramComponent;
// A node is created and stored in nodes array.
let connector: ConnectorModel[] = [{
     id: 'connector',
     type: 'Straight',
     //Define connector start and end points
     sourcePoint: { x: 100, y: 100 },
     targetPoint: { x: 200, y: 200 },
     shape: { type: 'UmlActivity', flow: 'Exception' }
}];
// initialize Diagram component
function App() {
  return (
    <DiagramComponent
      id="container"
      width={'100%'}
      height={'600px'}
      // Add connector
      connectors={connector}
    />
  );
}
const root = ReactDOM.createRoot(document.getElementById('diagram'));
root.render(<App />);