HTML5 Javascript treemap

Description

Utilizing the jQuery widget factory and HTML5 canvas this Javascript treemap widget presents hierarchical data using the squarified treemap layout algorithm described in "Squarified Treemaps", by Mark Bruls, Kees Huizing and Jarke J. van Wijk.

The jQuery treemap widget code and this page's HTML, CSS and Javascript are available from https://github.com/evancarey/jsTreemap. Stable tagged versions of the source can also be obtained via the jQuery plugin registry http://plugins.jquery.com/treemap/. Development and testing has primarily been limited to current versions of Chrome, Safari and FF. Please send issues, ideas and (even better) fixes to me via GitHub.

Example

The following example treemap of random data demonstrates the creation, destruction and dynamic update of some of the treemap plugin options. Using the buttons below, create and destroy the treemap. Click the other buttons to update the treemap plugin's dimensions, color gradient and the gradient applied to the treemap's leaf nodes.

Size By:
size opt 1
size opt 2
size opt 3
size opt 4

Click the 'create' button to create example treemap

Features

  • Pure Javascript - no embedded objects and browser plugins required.
  • Open architecture - easily change look and feel with your own gradient and labeller code.
  • Unbalanced Graphs OK - graph being treemapped can have branches of different depth.
  • Node highlighting, mouseover boxes and menus can be implemented as treemap event handlers in Javascript!
  • Size and color updates are simple plugin options.
  • Treemap graph and presentation data are separate.

Options

dimensions

An array of two elements the first being the width and the second is the height (in pixels) of the canvas element used to render the treemap. Example: set the width to 600 pixels and height to 400 pixels.

Default:

    dimensions: [600,400]
nodeData

A data structure containing the nodes to be presented in the treemap. Each node has the members: "id", "size", and "color". Internal nodes have the additional member "children". Root node does not require the members "size" or "color". If present they are ignored.

  • "id" is a unique identifier for the node. Identifier can be used in treemap event handlers to perform lookup into node detail data.
  • "size" is an array of float values in the range [0,1] that can be used to size a node. Size values are relative values that represent what fraction of the parent's area the child node should occupy. The element used to size the node is dependent on the value of the option "sizeOption".
  • "color" is an array of float values in the range [0,1) that are used to compute an index into the treemap's color gradient. The element used to color the node is dependent on the value of the option "colorOption".
  • "children" is an array of child nodes.
Example:

    nodeData: {
        "id":"2fc414e2", 
        "children":[
            {
                "id":"23f627dc", 
                "size":[0.25,0.349], 
                "color":[0.39,0.54], 
                "children":[
                    {
                        "id":"ce96d31f", 
                        "size":[0.25,0.64], 
                        "color":[0.74,0.10]
                    },
                    {
                        "id":"91e0ea1d", 
                        "size":[0.25,0.15], 
                        "color":[0.98,0.78]
                    },
                    {
                        "id":"62188591", 
                        "size":[0.16667,0.32], 
                        "color":[0.39,0.48]
                    },
                    ...
                ]
            },
            ...
        ]
    }
sizeOption

An index into a node's size array used to specify which size value to apply to the node.

Default:

    sizeOption: 0
colorOption

An index into a node's color array used to specify which color value to apply to the node.

Default:

    colorOption: 0
colorStops

An array of colors and values used to create a one pixel wide linear color gradient of length determined by option "colorResolution". The linear color gradient is used as color lookup table by calculating indexes into the linear gradient derived from the colorResoltion and each node's current color value.

Default:

    colorStops : [
        {"val":0,"color":"#08f"},
        {"val":0.5,"color":"#03f"},
        {"val":1,"color":"#005"}
    ]
colorResolution

An integer value which is used as the length of the treemap's linear color gradient.

Default:

    colorResolution: 1024
naColor

A hex color value used for nodes with null values for the current colorOption.

Default:

    naColor: "#000"
layoutMethod

A function that returns an array of rectangles representing the computed geometry derived from a containing rectangle and an array of (normalized) area values. The function must accept 2 arguments such that the first argument is the containing rectangle and the second argument is an array of area values.

  • "rect" is the containing rectangle with x, y, width, height. ex: [0, 0, 600, 400]
  • "vals" is an array of normalized area values to be treemapped. The sum of the values should equal 1.0. ex: [0.5, 0.25, 0.25]

Default:

    layoutMethod: TreemapUtils.squarify
innerNodeHeaderGradient

A function that returns a gradient object used as the fillStyle of inner node header rectangles. The function must accept 3 arguments: "ctx", "rect", and "rgb".

  • "ctx" is the 2d drawing context of the treemap's canvas element.
  • "rect" is a node's header rectangle generated by treemap layout algorithm.
  • "rgb" is a node's color value obtained by treemap's lookup into its current color gradient.

Default:

    innerNodeHeaderGradient: function(ctx,rect,rgb) {
        var gradient = ctx.createLinearGradient(rect[0],rect[1],rect[0],rect[1]+rect[3]);
        gradient.addColorStop(0.,"#ccc");
        gradient.addColorStop(.4,"#fff");
        gradient.addColorStop(.6,"#fff");
        gradient.addColorStop(1.,"#777");
        return gradient;
    }
leafNodeBodyGradient

A function that returns a gradient object used as the fillStyle of leaf node body rectangles. The function must accept 3 arguments: "ctx", "rect" and "rgb".

  • "ctx" is the 2d drawing context of the treemap's canvas element.
  • "rect" is a node's rectangle generated by treemap layout algorithm.
  • "rgb" is a node's color value obtained by treemap's lookup into its current color gradient.

Default:

    leafNodeBodyGradient: function(ctx,rect,rgb) {
        var r1 = Math.min(rect[2],rect[3])*0.1;
        var r2 = Math.max(rect[2],rect[3]);
        var x = rect[0]+rect[2]*0.5;
        var y = rect[1]+rect[3]*0.5;
        var gradient = ctx.createRadialGradient(x,y,r1,x,y,r2);
        gradient.addColorStop(0,TreemapUtils.lighterColor(TreemapUtils.rgb2hex(rgb),0.2));
        gradient.addColorStop(1,TreemapUtils.darkerColor(TreemapUtils.rgb2hex(rgb),0.2));
        return gradient;
    }
innerNodeHeaderLabeller

A function that renders text into inner node header rectangles. The function must accept 4 arguments: "ctx", "rect", "rgb" and "id".

  • "ctx" is the 2d drawing context of the treemap's canvas element.
  • "rect" is a node's header rectangle generated by treemap layout algorithm.
  • "rgb" is a node's color value obtained by treemap's lookup into its current color gradient.
  • "id" is the node's unique identifier.

Default:

    innerNodeHeaderLabeller: function(ctx,rect,rgb,id) {
        ctx.rect(rect[0],rect[1],rect[2],rect[3]);
        ctx.clip();
        ctx.fillStyle = '#555';
        ctx.font = '0.625em Verdana, Geneva, sans-serif';
        ctx.fillText(id,rect[0],rect[1]+10);
    }
leafNodeBodyLabeller

A function that renders text into leaf node body rectangles. The function must accept 4 arguments: "ctx", "rect", "rgb" and "id".

  • "ctx" is the 2d drawing context of the treemap's canvas element.
  • "rect" is a node's body rectangle generated by treemap layout algorithm.
  • "rgb" is a node's color value obtained by treemap's lookup into its current color gradient.
  • "id" is the node's unique identifier.

Default:

    leafNodeBodyLabeller: function(ctx,rect,rgb,id) {
        ctx.rect(rect[0],rect[1],rect[2],rect[3]);
        ctx.clip();
        if (TreemapUtils.avgRgb(rgb) <= 200) {
            ctx.fillStyle = '#fff';
        } else {
            ctx.fillStyle = '#888';
        }
        ctx.font = '0.625em Verdana, Geneva, sans-serif';
        ctx.fillText(id,rect[0],rect[1]+10);
    }
nodeBorderWidth

Number of pixels to use as spacing around internal nodes.

Default:

    nodeBorderWidth: 0
labelsEnabled

Boolean used to enable or disable node labelling.

Default:

    labelsEnabled: true
animationEnabled

Boolean flag indicating whether or not to animate size option changes.

Default:

    animationEnabled: false
animationDurationMs

Millisecond duration of size transition animation.

Default:

    animationDurationMs: 1000
animationEasing

Object containing input parameters to a Bezier curve function. Resultant curve is used to compute percent completion of animation.

Default:

    animationEasing: {} // linear easing

Example:

    animationEasing: {mX1 : 0.42, mY1 : 0.0, mX2 : 0.58, mY2 : 1.0} // ease-in-out

Easing convenience object:

    TreemapUtils.Easing = {
        "ease":        {mX1 : 0.25, mY1 : 0.1, mX2 : 0.25, mY2 : 1.0}, 
        "linear":      {mX1 : 0.00, mY1 : 0.0, mX2 : 1.00, mY2 : 1.0},
        "ease-in":     {mX1 : 0.42, mY1 : 0.0, mX2 : 1.00, mY2 : 1.0},
        "ease-out":    {mX1 : 0.00, mY1 : 0.0, mX2 : 0.58, mY2 : 1.0},
        "ease-in-out": {mX1 : 0.42, mY1 : 0.0, mX2 : 0.58, mY2 : 1.0}
    };

Easing convenience object members can be applied like so:

    $("#treemap").treemap({
        ...
        "animationEasing":TreemapUtils.Easing["ease-in-out"],
        ...
    });
    

Events

treemapmousemove

The treemapmousemove event can be used to trigger and update the presentation of a mouseover box and node highlighter(s) via a Javascript callback. The mouseover box and highlighter(s) shown in this example are optional presentation elements and can be populated, styled using HTML and CSS. The sample javascript code in this page demonstrates what information is available to the event handlers and how one might choose to highlight and/or display node details.

treemapclick

The treemapclick event can be used to trigger dynamic updates to the page's presentation via a Javascript callback. The sample javascript code in this page demonstrates what information is available to the event handler.

Examples

s3