In this guide, we'll walk through the steps to build a minimal but powerful JavaScript diagramming application from scratch. Here's a sneak peek at what you'll create:
Our finished app will use the MindFusion JavaScript Diagram library to allow users to:
- Create flowchart shapes with drag-and-drop.
- Customize node and link colors in real-time.
- Edit text directly within diagram elements.
- Save the current diagram to a file and load it back.
Ready? Let's dive in!
Setting Up the Project
To save time, we'll build upon a ready-made starter project from MindFusion. It provides a solid foundation with a pre-configured vanilla JavaScript environment.
First, clone the project from GitHub and start the development server:
# Clone the repository
git clone https://github.com/MindFusionComponents/diagram-starter-vanilla
# Navigate into the project directory
cd diagram-starter-vanilla
# Install dependencies
npm install
# Start the local server
npm start
Once running, you'll see the basic starter application, which includes a diagram canvas, an overview panel, a shape palette, and zoom controls.
The backend is a simple Express server (server.js) that serves the static files. Our main focus will be on the frontend in index.html and index.js.
Initializing the Diagram Components
The diagram and its related UI components are initialized in index.js. Each component is tied to an HTML element (a <canvas> or <div>) in index.html.
For example, the main DiagramView is created by associating it with a <canvas> element with the ID "diagram":
// create a DiagramView component that wraps the "diagram" canvas
var diagramView = MindFusion.Diagramming.DiagramView.create(document.getElementById("diagram"));
var diagram = diagramView.diagram;
Similarly, the Overview and Palette components are linked to their respective elements:
// create an Overview component
var overview = MindFusion.Diagramming.Overview.create(document.getElementById("overview"));
overview.diagramView = diagramView;
// The Palette component lets users create shapes via drag-and-drop
var palette = MindFusion.Diagramming.Controls.Palette.create(document.getElementById("palette"));
We can easily add predefined shapes to the palette. The code below adds a "Flowchart Shapes" category and populates it with common shapes like Start, Input, Process, and Decision.
palette.addCategory("Flowchart Shapes");
var shapes = ["Start", "Input", "Process", "Decision"];
for (var i = 0; i < shapes.length; ++i) {
var node = new MindFusion.Diagramming.ShapeNode();
node.shape = shapes[i];
palette.addItem(node, "Flowchart Shapes", shapes[i]);
}
Implementing Save and Load
The library makes saving and loading straightforward with the toJson() and fromJson() methods. The onSaveClick function serializes the diagram content to a JSON string and prompts the user to save it as a file.
The function cleverly handles both modern browsers that support the File System API (window.showSaveFilePicker) and older ones by creating a temporary download link.
async function onSaveClick() {
try {
const json = diagram.toJson();
// For modern browsers with File System API
if (window.showSaveFileFilePicker) {
const handle = await window.showSaveFilePicker({
suggestedName: 'diagram.json',
types: [{
description: 'JSON Files',
accept: { 'application/json': ['.json'] },
}],
});
const writable = await handle.createWritable();
await writable.write(json);
await writable.close();
} else {
// Fallback for older browsers
const blob = new Blob([json], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'diagram.json';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
} catch (err) {
console.error(err.name, err.message);
}
}
When loading, you simply read the JSON file's content and pass the string directly to diagram.fromJson().
Real-Time Node and Link Styling
We added UI controls to index.html to handle real-time color changes. These are simple <input type="color"> elements that use the browser's built-in color picker.
We then listen for the change event on these inputs. When a new color is selected, we update a global variable and apply the new color to all currently selected nodes.
// New global variables for default styles
var defaultNodeBrushColor = '#e0e9e9';
// Get style control elements
const nodeColorPicker = document.getElementById('nodeColorPicker');
// Event listener for the node color picker
nodeColorPicker.addEventListener('change', (event) => {
defaultNodeBrushColor = event.target.value;
// Apply the new color to all selected nodes
diagram.selection.nodes.forEach(node => {
node.brush = defaultNodeBrushColor;
});
});
To ensure new nodes also use this color, we handle the nodeCreated event and assign the defaultNodeBrushColor to the newly created node.
// Handle the nodeCreated event to apply default styles
diagram.nodeCreated.addEventListener((sender, args) => {
args.node.brush = defaultNodeBrushColor;
// ... other style properties
});
A pro-tip: handle the nodeCreating event as well. This provides a live preview of the node's appearance while the user is drawing it, creating a much smoother user experience.
Customizing Link Appearance
By default, the routeLinks property is enabled, which makes links automatically create perpendicular segments to avoid crossing nodes.
We can also control the link's head shape. In our app, a checkbox determines whether links have a "Triangle" arrowhead or not. We set the headShape property to null to remove it.
var defaultLinkHeadShape = 'Triangle';
const linkHeadCheckbox = document.getElementById('linkHeadCheckbox');
// Update the default shape when the checkbox is changed
linkHeadCheckbox.addEventListener('change', (event) => {
defaultLinkHeadShape = event.target.checked ? 'Triangle' : null;
// Apply the change to all selected links
diagram.selection.links.forEach(link => {
link.headShape = defaultLinkHeadShape;
});
});
Using Anchor Patterns for Clean Connections
To enforce cleaner-looking diagrams, we can restrict where links can connect to a node. This is done using an AnchorPattern. An anchor pattern is a set of AnchorPoint objects defined in relative coordinates (from 0 to 100) on the node's surface.
This pattern allows connections only at the center of each of the four sides:
var nodeAnchorPattern = new AnchorPattern([
new AnchorPoint(50, 0, true, true), // Center Top
new AnchorPoint(100, 50, true, true), // Center Right
new AnchorPoint(50, 100, true, true), // Center Bottom
new AnchorPoint(0, 50, true, true) // Center Left
]);
// ... later, when creating a node ...
node.anchorPattern = nodeAnchorPattern;
With this pattern applied, links will snap cleanly to these connection points.
Creating the Initial Diagram
To provide a good starting point for the user, we create a simple decision diagram in code when the page first loads. We use the diagram.factory object, which simplifies the creation of nodes and links.
var startNode = diagram.factory.createShapeNode(95, 10, 30, 15);
startNode.text = "Start";
startNode.shape = 'Ellipse';
startNode.brush = "#DB3955";
startNode.textColor = "#f0f0f0";
startNode.anchorPattern = nodeAnchorPattern;
Nodes created with the factory are automatically added to the diagram's items collection.
Video Tutorial
This tutorial is also available as a video. Check it out here:
I truly hope this guide helps you kickstart your journey with interactive JavaScript diagrams! I crafted this tutorial to demystify the process and showcase how accessible powerful visualization tools can be. What kinds of diagrams are you looking to build for your projects? If you have any questions, encounter challenges, or simply want to share your thoughts, please don't hesitate to leave a comment below. I'd love to hear from you and spark some additional discussion!
Conclusion
And that's it! You've successfully built a feature-rich JavaScript diagramming application. We started with a basic template and added custom shapes, real-time styling, anchor points, and a predefined initial diagram.
You can download the final version of this project from this link: [https://mindfusion.dev/samples/javascript/diagram/diagram-starter-2026.zip]
Happy coding!
Further Resources:




Top comments (0)