JavaScript/jQuery Diagram - Getting Started

jQuery
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.
Angular
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.
Vue
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.
React
NOTE
Before you start the tutorial, ensure DevExtreme is installed in your application.

Diagram is a UI component for creating and editing diagrams.

This tutorial shows how to add a Diagram component to your application and configure the component.

Each section in this tutorial describes one configuration step. You can also find full source code in the GitHub repository.

View on GitHub

Add the Diagram Component to a Page

jQuery

Add DevExtreme to your jQuery application and add Diagram resources (scripts and styles) to the page:

index.js
index.html
$(function() {
    $("#diagram").dxDiagram({ });
});
<html>
    <head>
        <!-- ... -->
        <script type="text/javascript" src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        <script src="https://cdn3.devexpress.com/jslib/24.1.7/js/dx-diagram.min.js"></script>
        <link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/24.1.7/css/dx-diagram.min.css">
        <link rel="stylesheet" href="https://cdn3.devexpress.com/jslib/24.1.7/css/dx.light.css">
        <script type="text/javascript" src="https://cdn3.devexpress.com/jslib/24.1.7/js/dx.all.js"></script>
        <script type="text/javascript" src="index.js"></script>
        <script type="text/javascript" src="data.js"></script>
    </head>
    <body>
        <div id="diagram"></div>
    </body>
</html>
Angular

Add DevExtreme to your Angular application, then install devexpress-diagram (npm i devexpress-diagram), and add Diagram resources (scripts and styles) to the page:

app.component.html
app.module.ts
angular.json
<dx-diagram></dx-diagram>
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';

import { DxDiagramModule } from 'devextreme-angular';

@NgModule({
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        DxDiagramModule
    ],
    providers: [ ],
    bootstrap: [AppComponent]
})
export class AppModule { }
// ...
"styles": [
    // ...
    "node_modules/devexpress-diagram/dist/dx-diagram.min.css",
],
Vue

Add DevExtreme to your Vue application and add Diagram resources (scripts and styles) to the page:

App.vue
<template>
    <DxDiagram>
    </DxDiagram>
</template>

<script setup>
import 'devextreme/dist/css/dx.light.css';
import 'devexpress-diagram/dist/dx-diagram.min.css';
import { DxDiagram } from 'devextreme-vue/diagram';
</script>
React

Add DevExtreme to your React application and use the following code snippet to create a Diagram component:

App.js
import React from 'react';

import 'devextreme/dist/css/dx.light.css';
import 'devexpress-diagram/dist/dx-diagram.min.css';

import { Diagram } from 'devextreme-react/diagram';

function App() {
    return (
        <Diagram>
        </Diagram>
    );
}

export default App;

Bind Diagram to Data

Use the nodes.dataSource property to bind Diagram to a list of nodes. This tutorial uses a linear array of nodes as the data source for the initial Diagram. In this case, the required properties to specify are nodes.keyExpr and nodes.parentKeyExpr. The tutorial also includes nodes.textExpr.

For details about different ways to bind Diagram data, refer to the following help topic: Data Binding.

jQuery
index.js
data.js
$(function() {
    $("#diagram").dxDiagram({
        nodes: {
            dataSource: new DevExpress.data.ArrayStore({
                key: 'ID',
                data: projectTasks,
            }),
            keyExpr: "ID",
            parentKeyExpr: "Parent_ID",
            textExpr: "Task_Name",
        },
    });
});
const projectTasks = [
    {
        "ID": 1,
        "Task_Name": "Project Planning",
        "Description": "Define project scope and goals",
    },
    {
        "ID": 2,
        "Parent_ID": 1,
        "Task_Name": "Requirement Analysis",
        "Description": "Gather and document requirements",
    },
    {
        "ID": 3,
        "Parent_ID": 1,
        "Task_Name": "Resource Allocation",
        "Description": "Assign team and resources",
    },
    {
        "ID": 4,
        "Parent_ID": 2,
        "Task_Name": "Design Specifications",
        "Description": "Outline system design",
    },
    {
        "ID": 5,
        "Parent_ID": 3,
        "Task_Name": "Task Scheduling",
        "Description": "Develop project timeline",
    },
    {
        "ID": 6,
        "Parent_ID": 2,
        "Task_Name": "Risk Assessment",
        "Description": "Identify potential risks",
    },
    {
        "ID": 7,
        "Parent_ID": 1,
        "Task_Name": "Kick-off Meeting",
        "Description": "Launch project with stakeholders",
    }
];
Angular
app.component.html
app.component.ts
app.service.ts
<dx-diagram>
    <dxo-nodes
        [dataSource]="dataSource"
        keyExpr="ID"
        parentKeyExpr="Parent_ID"
        textExpr="Task_Name"
    >
    </dxo-nodes>
</dx-diagram>
import { Component } from '@angular/core';
import ArrayStore from "devextreme/data/array_store";
import { Service, Task } from "./app.service";

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css'],
    providers: [Service]
})

export class AppComponent {
    projectTasks: Task[];
    dataSource: ArrayStore;
    constructor(service: AppService) {
        this.projectTasks = service.getTasks();
        this.dataSource = new ArrayStore({
            key: 'ID',
            data: service.getTasks(),
        });
    }
}
import { Injectable } from '@angular/core';

export class Task {
    "ID": number;
    "Parent_ID"?: number;
    "Task_Name": string;
    "Description": string;
}

const projectTasks: Task[] = [
    {
        "ID": 1,
        "Task_Name": "Project Planning",
        "Description": "Define project scope and goals",
    },
    {
        "ID": 2,
        "Parent_ID": 1,
        "Task_Name": "Requirement Analysis",
        "Description": "Gather and document requirements",
    },
    {
        "ID": 3,
        "Parent_ID": 1,
        "Task_Name": "Resource Allocation",
        "Description": "Assign team and resources",
    },
    {
        "ID": 4,
        "Parent_ID": 2,
        "Task_Name": "Design Specifications",
        "Description": "Outline system design",
    },
    {
        "ID": 5,
        "Parent_ID": 3,
        "Task_Name": "Task Scheduling",
        "Description": "Develop project timeline",
    },
    {
        "ID": 6,
        "Parent_ID": 2,
        "Task_Name": "Risk Assessment",
        "Description": "Identify potential risks",
    },
    {
        "ID": 7,
        "Parent_ID": 1,
        "Task_Name": "Kick-off Meeting",
        "Description": "Launch project with stakeholders",
    }
];

@Injectable({
    providedIn: 'root'
})
export class AppService {
    getTasks() {
        return projectTasks;
    }
}
Vue
App.vue
data.js
<template>
<DxDiagram>
    <DxNodes
        :data-source="dataSource"
        :key-expr="'ID'"
        :text-expr="'Task_Name'"
        :parent-key-expr="'Parent_ID'"
    />
</DxDiagram>
</template>

<script setup>
import {
    DxDiagram, DxNodes
} from 'devextreme-vue/diagram';
import ArrayStore from 'devextreme/data/array_store';
import service from './data.js';

const dataSource = new ArrayStore({
    key: 'ID',
    data: service.getTasks(),
});
</script>
const projectTasks = [
    {
        "ID": 1,
        "Task_Name": "Project Planning",
        "Description": "Define project scope and goals",
    },
    {
        "ID": 2,
        "Parent_ID": 1,
        "Task_Name": "Requirement Analysis",
        "Description": "Gather and document requirements",
    },
    {
        "ID": 3,
        "Parent_ID": 1,
        "Task_Name": "Resource Allocation",
        "Description": "Assign team and resources",
    },
    {
        "ID": 4,
        "Parent_ID": 2,
        "Task_Name": "Design Specifications",
        "Description": "Outline system design",
    },
    {
        "ID": 5,
        "Parent_ID": 3,
        "Task_Name": "Task Scheduling",
        "Description": "Develop project timeline",
    },
    {
        "ID": 6,
        "Parent_ID": 2,
        "Task_Name": "Risk Assessment",
        "Description": "Identify potential risks",
    },
    {
        "ID": 7,
        "Parent_ID": 1,
        "Task_Name": "Kick-off Meeting",
        "Description": "Launch project with stakeholders",
    }
];

export default {
    getTasks() {
        return projectTasks;
    }
}
React
App.js
data.js
import React from "react";
import Diagram, { Nodes } from "devextreme-react/diagram";
import ArrayStore from "devextreme/data/array_store";
import service from "./data.js";

const dataSource = new ArrayStore({
    key: 'ID',
    data: service.getTasks(),
});

const App = () => {
    return (
        <Diagram>
        <Nodes 
            dataSource={dataSource} 
            keyExpr="ID" 
            textExpr="Task_Name" 
            parentKeyExpr="Parent_ID"
        />
        </Diagram>
    );
};

export default App;
const projectTasks = [
    {
        "ID": 1,
        "Task_Name": "Project Planning",
        "Description": "Define project scope and goals",
    },
    {
        "ID": 2,
        "Parent_ID": 1,
        "Task_Name": "Requirement Analysis",
        "Description": "Gather and document requirements",
    },
    {
        "ID": 3,
        "Parent_ID": 1,
        "Task_Name": "Resource Allocation",
        "Description": "Assign team and resources",
    },
    {
        "ID": 4,
        "Parent_ID": 2,
        "Task_Name": "Design Specifications",
        "Description": "Outline system design",
    },
    {
        "ID": 5,
        "Parent_ID": 3,
        "Task_Name": "Task Scheduling",
        "Description": "Develop project timeline",
    },
    {
        "ID": 6,
        "Parent_ID": 2,
        "Task_Name": "Risk Assessment",
        "Description": "Identify potential risks",
    },
    {
        "ID": 7,
        "Parent_ID": 1,
        "Task_Name": "Kick-off Meeting",
        "Description": "Launch project with stakeholders",
    }
];

export default {
    getTasks() {
        return projectTasks;
    }
}

Configure Tools and Customize

To customize the Diagram component and its elements, use the following properties:

  • simpleView
    Activates a mode where the content uses all available space.

  • pageColor
    Specifies the Diagram page's color.

  • defaultItemProperties
    Defines initial properties for new items. In this tutorial, the different font is applied to the items.

Diagram UI customization tools include:

  • propertiesPanel
    Configures the properties panel settings. This tutorial adds a custom group that allows users to change the item appearance.

  • toolbox
    The toolbox contains groups of shapes. In this tutorial, we use this configuration object to disable search and limit the shapes in the general category.

jQuery
index.js
$(function() {
    $("#diagram").dxDiagram({
        simpleView: true,
        pageColor: "#f0f0f0",
        defaultItemProperties: {
            textStyle: "font-family: 'Courier New', monospace;"
        },
        propertiesPanel: {
            tabs: [
                {
                    groups: [{ title: 'Object Properties', commands: ['lineStyle', 'lineColor', 'fillColor'] }],
                },
            ],
        },
        toolbox: {
            showSearch: false,
            groups: [{
                category: 'general',
                shapes: ['text', 'rectangle'],
            }]
        },
    });
});
Angular
app.component.html
<dx-diagram
    [simpleView]="true"
    pageColor="#f0f0f0"
>
    <dxo-default-item-properties 
        textStyle="font-family: 'Courier New', monospace;">
    </dxo-default-item-properties>
    <dxo-properties-panel>
        <dxi-tab>
            <dxi-group
                title="Object Properties"
                [commands]="['lineStyle', 'lineColor', 'fillColor']"
            ></dxi-group>
        </dxi-tab>
    </dxo-properties-panel>
    <dxo-toolbox [showSearch]="false">
        <dxi-group category="general" [shapes]="['text', 'rectangle']"></dxi-group>
    </dxo-toolbox>
</dx-diagram>
Vue
App.vue
<template>
<DxDiagram
    :simple-view="true"
    page-color="#f0f0f0"
>
    <DxDefaultItemProperties :text-style="'font-family: "Courier New", monospace;'"/>
    <DxPropertiesPanel>
        <DxTab>
            <DxGroup
                :title="'Object Properties'"
                :commands="['lineStyle', 'lineColor', 'fillColor']"
            />
        </DxTab>
    </DxPropertiesPanel>
    <DxToolbox :show-search="false">
        <DxGroup
            :category="'general'"
            :shapes="['text', 'rectangle']"
        />
    </DxToolbox>
</DxDiagram>
</template>

<script setup>
import {
    DxDiagram, DxDefaultItemProperties, DxPropertiesPanel, DxTab, DxGroup
} from 'devextreme-vue/diagram';
// ...
</script>
React
App.js
import React from "react";
import Diagram, { DefaultItemProperties, Toolbox, PropertiesPanel, Tab, Group } from 'devextreme-react/diagram';
// ...

const objectCommands = ['lineStyle', 'lineColor', 'fillColor'];
const toolboxShapes = ['text', 'rectangle'];

const App = () => {
    return (
        <Diagram
            simpleView={true}
            pageColor="#f0f0f0"
        >
            <DefaultItemProperties  
                textStyle="font-family: 'Courier New', monospace;"
            />
            <PropertiesPanel>
                <Tab>
                    <Group
                        title="Object Properties"
                        commands={objectCommands}
                    />
                </Tab>
            </PropertiesPanel>
            <Toolbox showSearch={false} >
                <Group
                    category="general"
                    shapes={toolboxShapes}
                />
            </Toolbox>
        </Diagram>
    );
};

export default App;