HTML5 Javascript treemap - v0.4.2

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

Development and testing has primarily been limited to current versions of Chrome, Safari and FF. I rarely test (and fix for) MS/IE.

Example

The following example 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.

Click the 'create' button to create example treemap

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.
  • "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":[.25], 
                "color":[.39], 
                "children":[
                    {
                        "id":"ce96d31f", 
                        "size":[.25], 
                        "color":[.74]
                    },
                    {
                        "id":"91e0ea1d", 
                        "size":[.25], 
                        "color":[.98]
                    },
                    {
                        "id":"62188591", 
                        "size":[.16667], 
                        "color":[.39]
                    },
                    ...
                ]
            },
            ...
        ]
    }
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"
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
enableLabels

Boolean used to enable or disable node labelling.

Default:

    enableLabels: true

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

01-example.html

TODOs

  • Make treemap layout algorithm an option. Currently, the layout method is passed to the refresh layout routine which is sort of configurable by modifying the widget code. This is not great but it is sort of configurable. It needs to be improved.