MindFusion.Diagramming for JavaScript Programmer's Guide
Tutorial 3: Create a Custom Node Type

This tutorial shows how to define a custom node class that adds several new properties.

1. Create empty Tutorial3.html and Tutorial3.js files, and add DIV and CANVAS elements to the HTML page.

HTML  Copy Code
<!-- The Diagram component is bound to the canvas element below -->
<div style="width: 900px; height: 500px; overflow: auto; border: 1px solid;">

<canvas id="diagram" width="2100" height="2100">
    This page requires a browser that supports HTML 5 Canvas element.
</canvas>

</div>

2. Add script references to the Microsoft Ajax, MindFusion.Diagramming and Tutorial3 JavaScript files.

HTML  Copy Code
<script src="MicrosoftAjax.js" type="text/javascript"> </script>
<script src="MindFusion.Diagramming.js" type="text/javascript"> </script>
<script src="Tutorial3.js" type="text/javascript"> </script>

3. In Tutorial3.js, assign shorter names to the Diagram, Behavior, Font, Rect and Text classes.

JavaScript  Copy Code

var Diagram = MindFusion.Diagramming.Diagram;
var Behavior = MindFusion.Diagramming.Behavior;

var Font = MindFusion.Drawing.Font;
var Rect = MindFusion.Drawing.Rect;
var Text = MindFusion.Drawing.Text;

4. In Tutorial3.js add a new class constructor for an object called OrgChartNode. This class will inherit from ShapeNode.

JavaScript  Copy Code

var OrgChartNode = function (parent)
{
    OrgChartNode.initializeBase(this, [parent]);

    this.setShape('Rectangle');
    this.setText('node text');
    this.setBrush('#fff');
}

5. Add the property getters and setters for a custom title, full name and image to the OrgChartNode's prototype.

JavaScript  Copy Code

OrgChartNode.prototype =
{
    getTitle: function ()
    {
        return this.title;
    },

    setTitle: function (value)
    {
        if (this.title !== value)
        {
            this.title = value;
        }
    },

    getFullName: function ()
    {
        return this.fullName;
    },

    setFullName: function (value)
    {
        if (this.fullName !== value)
        {
            this.fullName = value;
        }
    },

    getNodeImageLocation: function ()
    {
        return this.nodeImageLocation;
    },

    setNodeImageLocation: function (value)
    {
        if (this.nodeImageLocation != value)
        {
            this.nodeImageLocation = value;
            if (value)
            {
                this.nodeImage = new MindFusion.Drawing.Image(new Rect(this.bounds.x, this.bounds.y + (this.bounds.height - 20) / 2, 20, 20));
                $addHandlers(this.nodeImage.image, { load: Function.createDelegate(this, this.loadNodeImage) });
                this.nodeImage.image.src = value;
            }
        }
    },

    loadNodeImage: function ()
    {
        this.nodeImage.loaded = true;
        if (this.parent)
            this.invalidate();
    }
};

6. Change the class constructor with initialization code for the newly added properties.

JavaScript  Copy Code

var OrgChartNode = function (parent)
{
    OrgChartNode.initializeBase(this, [parent]);

    this.setShape('Rectangle');
    this.setText('node text');
    this.setBrush('#fff');

    this.setTitle('title');
    this.setFullName('full name');
    this.setNodeImageLocation('icon4.png');
}

7. Add an updateCanvasElements override in OrgChartNode's prototype with the custom draw logic.

JavaScript  Copy Code

updateCanvasElements: function (node)
{
    OrgChartNode.callBaseMethod(this, 'updateCanvasElements');

    // add the node image;
    if (this.nodeImage)
    {
        this.nodeImage.setBounds(new Rect(this.bounds.x, this.bounds.y + (this.bounds.height - 20) / 2, 20, 20));
        this.graphicsContainer.content.push(this.nodeImage);
    }

    // add the title label
    var titleFont = Font.copy(this.getEffectiveFont());
    var titleLabel = new Text(this.getTitle(), new Rect(this.bounds.x + 21, this.bounds.y + 5, this.bounds.width - 22, titleFont.size));
    titleLabel.font = titleFont;
    titleLabel.font.bold = true;
    titleLabel.fitInBounds = false;
    this.graphicsContainer.content.push(titleLabel);

    // add the name label
    var nameFont = Font.copy(this.getEffectiveFont());
    var nameLabel = new Text(this.getFullName(), new Rect(this.bounds.x + 21, this.bounds.y + 5 + titleFont.size, this.bounds.width - 22, nameFont.size));
    nameLabel.font = nameFont;
    nameLabel.pen = "blue";
    nameLabel.fitInBounds = false;
    this.graphicsContainer.content.push(nameLabel);

    // adjust the text label properties
    var textFont = Font.copy(this.getEffectiveFont());
    textFont.size = 3;
    var textRect = new Rect(this.bounds.x + 21, this.bounds.y + 3 + titleFont.size + nameFont.size, this.bounds.width - 22, this.bounds.height - 2 - titleFont.size - nameFont.size);
    this.text.font = textFont;
    this.text.textAlignment = Alignment.Near;
    this.text.lineAlignment = Alignment.Near;
    this.text.margin = 0;
    this.text.setBounds(textRect, 0);
},

8. After OrgChartNode is defined, add a Sys.Application.init handler to register the newly created class.

JavaScript  Copy Code

Sys.Application.add_init(function ()
{
    OrgChartNode.registerClass("OrgChartNode", MindFusion.Diagramming.ShapeNode);
});

9. Finally, add a Sys.Application.load handler that creates a Diagram instance wrapping the HTML Canvas element. Then add two nodes of the new class and one link to the diagram.

JavaScript  Copy Code

var diagram = null;

Sys.Application.add_load(function (sender, args)
{
    // create a Diagram component that wraps the "diagram" canvas
    diagram = $create(Diagram, null, null, null, $get("diagram"));

    // enable drawing of custom nodes interactively
    diagram.setCustomNodeType(OrgChartNode);
    diagram.setBehavior(Behavior.Custom);

    var node1 = new OrgChartNode(diagram);
    node1.setBounds(new Rect(25, 15, 60, 25));
    node1.setTitle("CEO");
    node1.setFullName("John Smith");
    node1.setText("Our beloved leader. \r\nThe CEO of this great corporation.");
    node1.setNodeImageLocation("icon4.png");
    diagram.addItem(node1);

    var node2 = new OrgChartNode(diagram);
    node2.setBounds(new Rect(55, 55, 60, 25));
    node2.setTitle("CIO");
    node2.setFullName("Bob Smith");
    node2.setText("The CIO of this great corporation.");
    node2.setNodeImageLocation("icon5.png");
    diagram.addItem(node2);

    diagram.getFactory().createDiagramLink(node1, node2);
});

10. Publish MicrosoftAjax.js, MindFusion.Diagramming.js and the tutorial files using web server of your choice. Now you should see this if you open Tutorial3.html in a web browser: