Browser Support

CanvasXpress works in all major browsers, Firefox, Safari, Chrome, Opera and IE. It even works in substandard browsers like Internet Explorer 6 if an additional javascript library like ExplorerCanvas or FlashCanvas is included. Older versions of many browsers like Firefox 1.5, Opera 9, Safari 3.x, Chrome 1.0, IE 6 also require additional javascript libraries, canvas-text and typeface.js to support printing of text. (Please see below).

Usage

Javascript Libraries

There are two or three JavaScript libraries that need to be included pedending on how to handle the fallback for older versions of IE.

Flash fallback for older versions of IE

<!--[if lt IE 9]><script type="text/javascript" src="./js/flashcanvas.js"></script><![endif]-->
<script type="text/javascript" src="./js/canvasXpress.min.js"></script>

or

VML fallback for older versions of IE

<!--[if IE]><script type="text/javascript" src="./js/excanvas.js"></script><![endif]-->
<!--[if IE]><script type="text/javascript" src="./js/extext.js"></script><![endif]-->
<script type="text/javascript" src="./js/canvasXpress.min.js"></script>

Make sure to include the flash binaries in the same directory where the JavaScript file is located when using FlashCanvas. Please see the documentation for FlashCanvas.


The file canvasXpress.min.js also contains the additional javascript libraries, sprintf to format numbers, canvas text libraries to support cross-browser displaying of text, date.format to nicely format dates and conrec.js to support contour plots.

How to initialize canvasXpress

There are two ways to initialize CanvasXpress:

var cX = new CanvasXpress(target, data, config, events);

or

var cX = new CanvasXpress(
  {
   renderTo: target,
   data: data,
   config: config,
   events: events
  }
);

The function takes either one or four arguments which are explained in detail below. Briefly, target is the id of the element in the DOM tree with the tag name <canvas> where the graph will be rendered to, data is a json object with the data to plot, config refers to a json object to customize the graph and events is a json object with user-defined mouse events. If the function is called with a single argument then it must consist of an object with the properties renderTo, data, config and events which are in essence the same four arguments described above. So now, let me ellaborate some more.

Arguments

The parameter target is the id of the element in the DOM with the tag name <canvas>. If it is undefined, a new element is inserted in the document body.

A json object with the data to plot. There are six different data formats. One for the genome browser, one for the networks, one for the Venn diagramas, one for the correlation plots, one for the stock market data and one for all the other graphs.

I'll start first with the last one which is used for the following graphs: Area, AreaLine, Bar, BarLine, Boxplot, Candlestick, Circular, Dotplot, DotLine, Heatmap, Line, Pie, Scatter2D, Scatter3D, ScatterBubble2D, Stacked, StackedLine, StackedPercent, StackedPercentLine and Treemap.

The data structure can be graphically represented like this:


A data set is always a series of values organized in rows and columns. In CanvasXpress, the rows are refered to variables while the columns are refered to samples. Very often we have additional discrete or continuous data that help us annotating either the samples or the variables which in statistical terms are refered to as factors. Conceptually, the data in CanvasXpress can be divided into three compartments. The (y) compartment which contains the actual numerical values, the (x) compartment which contains characteristics of the samples and the (z) compartment which contains annotations for the variables. It is not required however that all data sets must have all these attributes except for the (y) compartment. Another issue is that the (y) compartment could be multi-dimensional depending on the granularity of the data. For example rather than having the raw data, you may have the average and the standard deviation for variables measured in a particular set of samples, or for example, with stock market data you may have the open, low, high, close and volume for a stock (variable) on a given day (sample). Or in the case of a genomics experiment you may have transcrional profiling data, copy number data and mutation status for each sample. CanvasXpress supports all the complexity of any of these data sets.

In json format the data for a single series is like this:

{
  'y' : {
     'vars' : ['Variable1'],
     'smps' : ['Sample1', 'Sample2', 'Sample3', 'Sample4'],
     'data' : [[10, 20, 30, 40]]
  },
  'x' : {
     'Tissue' : ['Kidney', 'Liver', 'Lung', 'Heart'],
     'Donor' : ['D1', 'D1', 'D2', 'D2']
  },
  'z' : {
     'Symbol' : ['AAA'],
     'Pathway' : ['P1']
  }
}

or for two series is like that:

{
  'y' : {
     'vars' : ['Variable1', 'Variable2', ],
     'smps' : ['Sample1', 'Sample2', 'Sample3', 'Sample4'],
     'data' : [[10, 20, 30, 40], [20, 30, 40, 50]]
  },
  'x' : {
     'Tissue' : ['Kidney', 'Liver', 'Lung', 'Heart'],
     'Donor' : ['D1', 'D1', 'D2', 'D2']
  },
  'z' : {
     'Symbol' : ['AAA', 'BBB'],
     'Pathway' : ['P1', 'P2']
  }
}

There are additional properties that can be added to json object depending on the graph type. For example, you can add a (t) property to specify a dendrogram in newick format for both samples and variables. In cases of a line combination graph you must add an (a) property to specify the axis for each series.

{
  'y' : {
     'vars' : ['Variable1', 'Variable2', ],
     'smps' : ['Sample1', 'Sample2', 'Sample3', 'Sample4'],
     'data' : [[10, 20, 30, 40], [20, 30, 40, 50]]
  },
  'x' : {
     'Tissue' : ['Kidney', 'Liver', 'Lung', 'Heart'],
     'Donor' : ['D1', 'D1', 'D2', 'D2']
  },
  'z' : {
     'Symbol' : ['AAA', 'BBB'],
     'Pathway' : ['P1', 'P2']
  },
  't' : {
     'vars' : "('Variable1','Variable2')",
     'smps' : "((('Sample1','Sample2'),'Sample3'),'Sample4')"
  },
  'a' : {
     'xAxis' : ['Variable1'],
     'xAxis2' : ['Variable2']
  }
}

There are many more properties that can be included in this data format that can be found in each of the graph types examples.

The data format for the Correlation is as follows:

{
  'y' : {
    'smps' : ['Sample1', 'Sample2', 'Sample3', 'Sample4'],
    'cor' : [
      [1.0, 0.9, 0.8, 0.7],
      [0.9, 1.0, 0.8, 0.8],
      [0.8, 0.8, 1.0, 0.7],
      [0.7, 0.8, 0.7, 1.0]
    ]
  }
}

As you can see this is just an extension of the previous format in which the correlation between samples (in this case) is represented in a two dimensional array under the property (cor). In fact if you try to plot a correlation plot and you don't have the (cor) property, canvasXpress will do it for you as long as you provide the raw data.

The format for the data for the Venn with three groups is as follows:

{
  'venn' : {
    'data' : {
      'A' : 340,
      'B' : 562,
      'C' : 620,
      'AB' : 639,
      'AC' : 456,
      'BC' : 915,
      'ABC' : 552
    },
    'legend' : {
      'A' : 'List1',
      'B' : 'List2',
      'C' : 'List3'
    }
  }
}

This format contains the property (venn) where the data is organized. The (data) property contains the actual data and the (legend) property the different lists in the Venn diagram. The basic idea here is that in this case there are three lists, A, B and C so you just have to assign a number to each one and also to any combination of them but they must be in alphabetical order; that is, they have to be 'AB' rather than 'BA'. If you have four lists then you only have to assign numbers to A, B, C and D; if you have two list then you only have to assign numbers to A nad B.

The data format for the Network is as follows:

{
  'nodes' : [
    {
      'id' : 'Node1',
      'color' : 'rgb(255,0,0)',
      'shape' : 'circle',
      'size' : 1
    }, {
      'id' : 'Node2',
      'color' : 'rgb(0,255,0)',
      'shape' : 'square',
      'size' : 1.5
    }, {
      'id' : 'Node3',
      'color' : 'rgb(0,0,255)',
      'shape' : 'triangle',
      'size' : 2
    }
  ],
  'edges' : [
    {
      'id1' : 'Node1',
      'id2' : 'Node2',
      'color' : 'rgb(125,125,0)',
      'type' : 'line'
    }, {
      'id1' : 'Node1',
      'id2' : 'Node3',
      'color' : 'rgb(0,125,125)',
      'type' : 'squareHeadLine'
    }, {
      'id1' : 'Node2',
      'id2' : 'Node3',
      'color' : 'rgb(125,0,125)',
      'type' : 'arrowHeadLine'
    }
  ]
}

The (nodes) property contains as it name indicates the nodes in the network. Each node must have a unique (id) property. Also, (color), (shape), (rotate), (pattern), (outline), (outlineWidth) and either (size) or (width) and (height) can be specified for each node. The (color) property is specified in an rgb format compatible with the <canvas> element. The (shape) must be one of the shapes in this library (see the options section). The rotation for the shape must be expressed in degrees. The (pattern) is either 'closed' or 'open'. The (size) is a multiplier and not the actual size of the node, for example, to make a node twice as big, the size should be set to 2. If you need more control over the shape then you need to specify (width) and (height). The (edges) property as you can imagine, contains the info for the edges in the network. Each edge must contain an (id1) and an (id2) properties which must match two nodes in the network. Similarly, you can specify the (color), the (width), which is the actual width of the line, the (cap) which could be 'butt', 'round' or 'square' and the line (type) which should be one of the types in this library (see the options section). The property (legend) is an object that contains the information for the nodes and edges and additional text.

Each node may have one parent under the property 'parentNode' and it has to match a valid node id. This feature is useful if you want to group nodes together. You can assign a name and / or a label to each node. The order in which the text will be displayed is label or name or id.

The data format for the Candlestick (Market data) is as follows:

{
  'market': [
    {
      'symbol': 'BMY',
      'data': [
        [20100824, 26.26, 26.37, 25.95, 26.02, 11625900, 26.02],
        [20100823, 26.48, 26.76, 26.38, 26.48, 12146600, 26.48],
        [20100820, 26.31, 26.54, 26.08, 26.44, 18140100, 26.44],
        [20100819, 26.20, 26.29, 25.81, 26.06, 8218000, 26.06],
        [20100818, 26.53, 26.57, 26.23, 26.28, 12235800, 26.28],
        [20100817, 26.40, 26.79, 26.26, 26.59, 12325700, 26.59],
        [20100816, 26.24, 26.34, 26.04, 26.28, 10377700, 26.28],
        [20100813, 26.24, 26.46, 26.10, 26.32, 5760100, 26.32],
        [20100812, 26.01, 26.39, 26.00, 26.33, 7350500, 26.33],
        [20100811, 26.32, 26.50, 26.15, 26.25, 8808100, 26.25],
        [20100810, 26.32, 26.78, 26.30, 26.66, 7009500, 26.66],
        [20100809, 26.37, 26.54, 26.30, 26.51, 6825300, 26.51],
        [20100806, 26.29, 26.45, 26.05, 26.37, 8774900, 26.37],
        [20100805, 25.83, 26.38, 25.80, 26.38, 12264600, 26.38],
        [20100804, 25.70, 26.13, 25.61, 26.03, 10233700, 26.03],
        [20100803, 25.65, 25.85, 25.58, 25.68, 6842900, 25.68],
        [20100802, 25.33, 25.61, 25.29, 25.53, 9770900, 25.53],
        [20100730, 24.98, 25.13, 24.78, 24.92, 11435700, 24.92],
        [20100729, 25.37, 25.50, 24.85, 25.08, 9463800, 25.08],
        [20100728, 25.25, 25.36, 25.02, 25.12, 8072400, 25.12],
        [20100727, 25.09, 25.35, 24.84, 25.32, 14152600, 25.32],
        [20100726, 24.57, 25.03, 24.57, 24.97, 8817400, 24.97],
        [20100723, 24.94, 24.95, 24.26, 24.65, 13043700, 24.65],
        [20100722, 24.96, 25.22, 24.75, 24.93, 10385300, 24.93],
        [20100721, 24.92, 25.11, 24.59, 24.75, 9830000, 24.75],
        [20100720, 24.65, 25.09, 24.46, 25.02, 10655500, 25.02],
        [20100719, 25.27, 25.27, 24.78, 24.84, 11804800, 24.84],
        [20100716, 25.44, 25.47, 25.10, 25.17, 13136300, 25.17]
      ]
    }
  ]
}

I guess this is self eveident, it is the same format you download data from Yahoo except that the hyphens in the date are stripped. Also, you can add many symbols too.

And finally the last data format used for the Genome is probably the most elaborated. This is the json data structure:

{
  'tracks' : [
    {
      'name' : 'Affy Probes',
      'type': 'box',
      'connect': true,
      'fill' : 'rgb(255,255,51)',
      'line' : 'rgb(0,0,0)',
      'data' : [
        {
          'id' : '123456_at',
          'dir' : 'right',
          'data' : [[100,120], [123,132], [141,160]]
        },{
          'id' : '234567_at',
          'dir' : 'left',
          'data': [[181,200], [211,230], [251,270]]
        },{
          'id' : '345678_at',
          'dir' : 'right',
          'data' : [[281,300], [311,330], [351,370]]
        }
      ]
    }, {
      'hide' : true,
      'type' : 'bar',
      'height' : 20,
      'fill' : ['rgb(255,0,0)', 'rgb(0,0,255)', 'rgb(255,255,0)'],
      'line' : ['rgb(255,0,0)', 'rgb(0,0,255)', 'rgb(255,255,0)'],
      'data' : [
        {
          'id': '123456_at',
          'data': [100,25,35,46]
        }, {
          'id' : '234567_at',
          'data' : [181,80,45,10]
        }, {
          'id' : '345678_at',
          'data' : [281,65,46,29]
        }
      ]
    }, {
      'name': 'Tissue Distribution (Heart, Liver, Kidney)',
      'hide': false,
      'type': 'heatmap',
      'autowidth': true,
      'height': 20,
      'line': 'rgb(0,0,0)',
      'smps': ['Heart', 'Kidney', 'Liver'],
      'data': [
        {
          'id': '123456_at',
          'data': [100,25,35,46]
        }, {
          'id' : '234567_at',
          'data' : [181,80,45,10]
        }, {
          'id' : '345678_at',
          'data' : [281,65,46,29]
        }
      ]
    }, {
      'name' : 'SNP',
      'type' : 'triangle',
      'fill' : 'rgb(100,0,0)',
      'line' : 'rgb(0,0,0)',
      'data' : [
        {
          'id' : 'SNP123',
          'data' : 123
        }, {
          'id' : 'SNP234',
          'data' : 145
        }, {
          'id' : 'SNP789',
          'data' : 220
        }
      ]
    }, {
      'name' : 'SNP',
      'type' : 'line',
      'line' : 'rgb(0,255,0)',
      'data' : [
        {
          'id' : 'SNP123',
          'data' : 123
        }, {
          'id' : 'SNP234',
          'data' : 145
        }, {
          'id' : 'SNP789',
          'data' : 220
        }
      ]
    }, {
      'type' : 'sequence',
      'subtype' : 'DNA',
      'hide' : true,
      'line' : 'rgb(255,255,255)',
      'data' : [
        {
          'id' : 'SNP123',
          'data' : [119,'AGCT[TA]CGAG']
        }, {
          'id' : 'SNP234',
          'data' : [141,'ATCG[TG]AATA']
        },{
          'id': 'SNP789',
          'data': [216, 'GCCC[CT]AGGG']
        }
      ]
    }
  ]
}

If you are not in the biology field please skip this data format since I will assume a general understanding of some terms. If you are stubborn enough to continue reading or you do have the biology background then look at the genome example so you can figure out how to format the data. The property (tracks) is an array with the tracks you want to represent in a region of the genome. They can be of six different (type)s, box, bar, heatmap, triangle, line and sequence. The sequence type can be of (subtype) 'DNA' or 'Protein'. You may specify the color of the shapes with the property (fill) for the inside of the shape and (line) for the edge of the shape. Only in the track type 'bar', the (fill) and the (line) properties are represented as an array of colors so you can assign each bar different colors. The (tracks) may have a (name) which will be used as the title for the track but you can use the property (hide) to prevent displaying it. This is useful in some cases to save landscape as well as to make closer elements in adjacent tracks. You may also specify the height of the track with the property (height) but if you do not, it will take the default value (see the options section). Finally you can add as many propertys as you please in each track if you need to access them for a click or mouseover event (see the event section).

First, the 'box' type can have many features specified in its (data) property as an array and each one of them may have many segments specified in its corresponding (data) property as a nested array. The segments can be displayed connected or not with the property (connect) which is boolean and is specified at the track level. That is, if it is true all the segments in each of the features in the track will be connected using a slanted line with their apexes in the middle between the adjacent segments. Also, each feature must have a unique (id) in the track, that is, it is not necessary to have a unique id among all the tracks, and it may have an orientation represented as an arrow which can be specified with the property (dir) which could be right or left. As I mentioned, the segments in each feature are an array with the first element representing the coordinate for the starting point and the second element with the coordinates for the ending point in the genome. Similar you can add many more propertys as you please if you need to make use of them for mouse events (see the event section).

The 'bar' and the 'heatmap' types, similarily, may have many features specified in its (data) property represented as an array. Each feature identified with a unique (id) may have many values identified in its corresponding (data) property also represented as an array. The first element of the array is the coordinates for the feature in the genome, the rest of the elements will be y values for the bar graphs or for the heatmap. In the case of the type 'bar', you may specify a (width) for the 'bar' at the track level or you may specify (autowidth) and in that case the width of the bar will be a unit of the base pair in the genome. That is, if you have three bars the width of each bar is going to be a third of a base pair. The only difference for the 'heatmap' type is that the bars will be stacked and the colors will be automatically assigned according to the y alues.

The 'triangle' and the line types are also very similar except that each feature will have a property data to identify the coordinates for it in the genome.

Finally, the 'sequence' type may also have many features. The only difference in the structure of the data is that in each feature's data structure, the first element represent the coordinates in the genome and the second element is the actual sequence. If there are multiple alleles at a given position then the sequence is represented in square brackets, for example, [AG].

Pretty much everything in this library is customazible. The configuration parameters are divided in major sections. Each parameter in a section contains a link to an example (in the name of the parameter) followed by the type of the value (in italic letters). There is also a description, a default, the options if approprieate and links to related parameters and graphs. Some of the parameters are private to CanvasXpress and are denoted with the work private in red. These are the major categories for the parameters:


The parameter events is a json object with the user defined events. By default I assign the four events that canvasXpress supports which are mousemove, mouseout, click and dblclick. The events can also handle scope as shown below. In json format the events is like this:

{
  'mousemove' : function(o, e, t) {
    // Do something ...
  },
  'mouseout' : function(o, e, t) {
    // Do something more...
  },
  'click' : function(o, e, t) {
    // Do something else ...
  },
  'dblclick' : function(o, e, t) {
    // Do even more stuff
  }
}

or

{
  'scope' : myScope,
  'handler' : {
    'mousemove' : function(o, e, t) {
      // Do something ...
    },
    'mouseout' : function(o, e, t) {
      // Do something ...
    },
    'click': function(o, e, t) {
      // Do something else ...
    }
  }
}

I hope it is not too complicated. The parameter (o) passed to the user defined callback has the same format as that one you passed in the data parameter. the (e) is the event that triggered the action and (t) is the full CanvasXpress object. Just go ahead and mouseover and/or click in any element in the graphs and see what I mean. It is up to you to include additional code to handle the events of course.

The default mouseover event in canvasXpress is to show the data value for most of the graphs or the feature/node/edge name for the Genome and Network graphs.

This is how the events object should look like:

{
  'click': function(o) {
    DumperAlert(o);
  }
}

Oh, I almost forgot the event names are normalized so don't worry if you use IE or Firefox.

Functionalities

Zooming and Panning

Zooming graphs can be done by dragging the mouse over an area while pressing the left mouse button or by clicking close to the axis after the axis resizer appears. You can adjust the maximum and minimum value and / or drag an interval across the range. You can select samples by dragging the mouse over the samples you want to see while you pressing the left mouse button and the 'shift' key. Also, networks and haetmaps can be zoom in and out with the help of the mouse wheel or with the help.

Panning can be done also in networks and heatmaps by either dragging the mouse or with the help of the the arrow keys.

Selecting data points or nodes

You can select data points in the scatter plots or in the networks by simultanously pressing the 'shift' key and dragging the mouse over the data points or nodes. You can also select individual items by simultaneously pressing the 'ctrl' key and clicking with the left mouse button on the individual item. Once selected, you can press simultaneously the 'ctrl' and the 'delete' keys to hide them or the 'ctrl' and the 'insert' keys to show them again. You can reset the selecting by pressing the 'esc' key.

Canvas Resizing

You can resize the canvas image using the handle that appears when you mouse over the south and east sides of the canvas.

Animations

You can use the arrow keys to rotate the 3D-Scatter plot or cycle over the axes in the 2D-Scatter plots (including the paging keys too). Of course you have to simultaneously press any of those keys and the 'ctrl' key.

Reseting the canvas

In order to reset the canvas just press the 'esc' key.

Printing the canvas

To print the canvas you need to simultaneously click the 'ctrl' and the 'p' keys.

Additional Methods

There are a few more methods to create lines, shapes and text in any plot. In order, to use these methods you just need to save the canvasXpress in a variable and use the methods like this:

var cX = new CanvasXpress(target, data, config, events);
.....
cx.drawLine('dashed', 18, 18, 613, 613, 'rgb(255,0,0)', 2, 'butt');
.....
cx.drawShape('roundrect', 36, 36, 10, 49, 'rgb(255,0,0)', 'rgb(0,0,0)', 'closed', 3.14 / 2, '1');
.....
cx.drawText('This is kewl', 50, 50, 'Verdana, sans-serif 12pt', 'rgb(0,0,0)', 'center', 'middle', 3.14 / 4);
.....

drawLine

It takes the following parameters: type (string), a valid type of line (see the documentation above); x0 (int), initial X coordinate; y0 (int), initial Y coordinate; x1 (int), final X coordinate; y1 (int), final Y coordinate; color (color), an rgb string of a valid color according to the HTML 5 canvas specification; width (int), the line width for the line; cap (string), the cap style for the line which could be 'butt', 'round' or 'square'.

drawShape

It takes the following parameters: type (string), a valid type of shape (see the documentation above); x (int), center X coordinate; y (int), center Y coordinate; width (int), width of the shape; height (int), height of the shape; fill (color), an rgb string of a valid color according to the HTML 5 canvas specification for the fill of the shape; outline (color), an rgb string of a valid color according to the HTML 5 canvas specification for the outline of the shape; pattern (string), a pattern for the shape which could be either 'closed' or 'open'; rotation (int), a rotation in degrees for the shape; outline-width (int), the line width for the outline of the shape. If the first parameter (shape) is either 'polygon' or 'path' then the second and third parameter must be arrays with integers.

drawText

It takes the following parameters: string, the text you want to print; int, X coordinate; int, Y coordinate; color, an rgb string of a valid color according to the HTML 5 canvas specification; string, a valid align position according to the HTML 5 canvas specification; string, a valid baseline position according to the HTML 5 canvas specification; float, a rotation in radians for the text.

Ext-JS

This library can be used with EXT JS. Actually, the Ext.canvasXpress component has been extended tremendously thanks to Mingyi Liu. He has added a large number of features for playing with the networks. Please go to the example and right click anywhere and you'll see what I mean.