Just a click away...

The example shows how to implement a custom port to provide a fast configuration option.
It is not always necessary to implement full blown dialogs or property panes. Sometimes the tiny smart
way ist the best way. Just a mouse click away.

  • hidden if a connection is present
  • the user can stick the label to provide a default value for the port
  • the default value can be changed with a context menu
  • mouse over for quick access the label

Custom router rendering example for version 5.3.1

The version 5.3.1 contains a custom router example with a not so serious rendering. It is a rubber band.

FlexGridLayout for version 5.3.0

The HorizontalLayout and VerticalLayout gets reinforcement with the new FlexGridLayout in the upcoming version 5.3.0.
More Examples and Documentations comes with the upcoming release.


var PredefinedProcess = draw2d.shape.layout.FlexGridLayout.extend({

     *     10px       grow         10px
     *    -----+------------------+-----
     *    |    |  [LABEL]         |    |
     *    |    |                  |    |
     *    |    |                  |    |    grow
     *    |    |                  |    |
     *    |    |                  |    |
     *    -----+------------------+-----
     * @param attr
    init : function(attr, setter, getter)
            columns:"10px, grow, 10px",
            rows:   "grow",
        this.label = new draw2d.shape.basic.Label({text:"Process Name", resizeable:true, stroke:2});
        this.label.installEditor(new draw2d.ui.LabelInplaceEditor());

        // add the label to the row:0, col:1 
        this.add(this.label, {row:0, col:1});

Collapsible Shapes in version 5.2.0

one additional feature for the upcoming version 5.2.0 is a demo of an CollapsibleShape. blogEntryTopper

Custome ResizeHandles

with the upcoming version 5.2.0 Draw2D allows to replace or override the default appearance and behavior or the ResizeHandles

    // Override the standard ResizeHandle and add some fancy filter to the SVG element
    // We need the fraphael.js lib to apply the filter 
    var filter = null;
    draw2d.Configuration.factory.createResizeHandle= function(forShape, type){
        var handle= new draw2d.ResizeHandle(forShape, type);

        handle._origShow = handle.show;
        // override the standard "show" method to apply the shadow filter to the raphael element 
        handle.show= function(canvas){
                filter = canvas.paper.createFilter();
                filter.element.setAttribute("x", "-55%");
                filter.element.setAttribute("y", "-55%");
                filter.element.setAttribute("width", "400%");
                filter.element.setAttribute("height", "400%");
        return handle;


Draw2D touch version 5.1.1 supports AngularJS


Version 5.1.1 provides a boilerplate example for the famous AngularJS lib.

This isn't designed to be completely general purpose, but it will be a good basis if you need a diagramming
solution and you are willing to work with AngularJS.

What is in:
  • two way data binding
  • FileOpen dialog made with AngluarUI
  • drag&drop of elements from an DIV into the canvas
  • property pane of selected figure

Copy during Drag&Drop operation

New example in the next release 5.0.4 for Drag&Copy of figures


Draw2D touch now supports group/ungroup of figures

A group is a figure that acts as a transparent container for other figures. A group is a StrongComposite node that controls a set of child figures. The bounding rectangle of a group is the union of the bounds of its children. Child nodes cannot be selected or manipulated individually.

The grouping of nodes can be performed using ready-made API.

Either by using an edit policy for the canvas and using Ctrl+G for group/ungrouping
canvas.installEditPolicy(new draw2d.policy.canvas.ExtendedKeyboardPolicy());

or binding an event to a button and call the API (with undo/redo support):
canvas.getCommandStack().execute(new draw2d.command.CommandGroup(canvas, canvas.getSelection()));

without undo/redo support:
new draw2d.command.CommandGroup(canvas, canvas.getSelection())).execute();


First implementation of a composite figure: Raft

draw2d.shape.composite.Raft figures are shapes, which aggregate multiple figures. It works like a real raft. Aboard figures are moved if the raft figures moves. Draw2D differs between WeakComposite and StrongComposite. A raft figure is a weak composite and therefore the raft didn’t receive any notifications about drag&drop nor knowns the a boards figures anything about the parent composite figure.


New Locator for labels attached on Connections

Draw2D 4.4.4 also includes the ability to place text or labels along the connections between ports. This is down by the usage of the draw2d.layout.locator.ParallelMidpointLocator.

Sample code for usage

var LabelConnection= draw2d.Connection.extend({
      // Create any Draw2D figure as decoration for the connection
      this.label = new draw2d.shape.basic.Label("I'm a Label");
      // use no special router - direct connection

      // add the new decoration to the connection with a position locator.
      this.addFigure(this.label, new draw2d.layout.locator.ParallelMidpointLocator(this));



New figure in the draw2d family "draw2d.shape.basic.Text"

How do you get words to wrap inside a box in RaphaelJS? Or in browser-based SVG in general? Text-wrapping is not built into Raphael or the SVG spec. Period.

Coming from the HTML world, I found the absence of text wrapping pretty shocking. I implement a very first version of an word wrap element in draw2d.
Available in the new test version of draw2d 4.2.3.

code snippet from the implementation if anybody thinks this part is useful for a plain raphaelJS project.

    wrappedTextAttr: function(text, width) {
        if(this.canvas ===null){
            return {text:text, width:width, height:20};
            var abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            // generate a raphaelJS node and set font, font-size,...
            var svgText = this.canvas.paper.text(0, 0, "").attr($.extend({},this.calculateTextAttr(),{text:abc}));
            // get a good estimation of a letter width...not correct but this 
            // is working for the very first draft implementation
            var letterWidth = svgText.getBBox().width / abc.length;
            var words = this.text.split(" ");
            var x = 0, s = [];
            for ( var i = 0; i < words.length; i++) {
                var l = words[i].length;
                if (x + (l * letterWidth) > width) {
                    x = 0;
                x += l * letterWidth;
                s.push(words[i] + " ");
            var bbox = svgText.getBBox();
            this.cachedWrappedAttr= {text: s.join(""), width:bbox.width), height: bbox.height)};
        return this.cachedWrappedAttr;


New kind of router available

The new interactive routing tools have been added for better handling of crossings and routing conflict. You can install the router as default router for all new generated connections with the code snipped below.

// Override the default implementation of connection creation with your own method
draw2d.Connection.createConnection=function(sourcePort, targetPort, callback, dropTarget){
    var conn= new draw2d.Connection();
    conn.setRouter(new draw2d.layout.connection.InteractiveManhattanConnectionRouter());
    return conn;


Style your connection since version 4.3.0

Since the version 4.3.0 it is possible to style your connection with a outline color and stroke. Additional the ‚radius‘ attribute is applied to a connection as well. Looks very smooth..

The code below override the standard method of draw2d for connection creation for this.

// Override the default implementation of connection creation with your own method
draw2d.Connection.createConnection=function(sourcePort, targetPort, callback, dropTarget){
    var conn= new draw2d.Connection();
    conn.setRouter(new draw2d.layout.connection.InteractiveManhattanConnectionRouter());
    return conn;