Creating a new visualization

The canvasXpress object in instantiated by calling the new constructor function. This function takes either four arguments: targetId, data, configuration and events or a single argument in which these four arguments are packed in a JSON object. The four arguments are disscused below.

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

or:

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

Arguments

targetId is the DOM id of the <canvas> element included in the <body> element of the web page where the graph will be rendered.

data is either a json object or an URL that point either to a png, svg, json, text delimited, gpml or xml file containing the data to plot. The are many formats which depend on the visualization. One for the genome browser, one for the networks, one for the Venn diagramas, one for the correlation plots and one for all the other graphs.

config is a json object to customize the graph and includes a very large number of properties.

events is a json object with user-defined mouse events.

DOM - targetId and and the <canvas> element

The targetId is the DOM id of the <canvas> element inside the <body> element of the web page. The width and height attributes are used to set the initial size of the canvasXpress visualization. It may include a responsive attribute so the visualization is automatically resized to fully occupied its parentNode container. Furthermore, an aspectRatio attribute can be used to mantain the aspect ratio of the visualization. These attributes are very usefull if canvasXpress is used with other libraries like Bootstrap in any mobile or desktop devices. The <canvas> element SHOULD NOT be programatically changed in anyway to avoid cross-interactions with the canvasXpress library. Here is an example where the graph is responsive and the aspect ratio is maintained:

<div class="row">
  <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
    <canvas id='bar1' width='290' height='540' aspectRatio='1:1' responsive='true'></canvas>
  </div>
</div>

Data

The data argument can be either a json object, a function or a URL that point to a file containing the data. Here as some examples where the data points to a URL:

CSV file:

var cX = new CanvasXpress(
  {
   "renderTo": "canvasId",
   "data": "https://raw.githubusercontent.com/neuhausi/Rdatasets/master/csv/datasets/ToothGrowth.csv",
   "config": {
     "title": "Tooth Growth",
     "smpLabelRotate": 90,
     "graphType": "Boxplot",
     "graphOrientation": "vertical",
     "metaData": {
       "dose": true
     },
     "groupingFactors": [ "dose" ]
   },
   "events": false
  }
);


PNG file:

var cX = new CanvasXpress(
  {
   "renderTo": "canvasId",
   "data": "https://www.canvasxpress.org/assets/images/Ex-bar-1.png",
   "config": false,
   "events": false
  }
);


JSON file:

var cX = new CanvasXpress(
  {
   "renderTo": "canvasId",
   "data": "https://raw.githubusercontent.com/neuhausi/Rdatasets/master/json/datasets/AirPassengers.json",
   "config": false,
   "events": false
  }
);


Additional examples can be found in the Remote Graphs. Be aware that the URLs need to be in the same domain as that one serving the canvasXpress JavaScript files. Alternatively, a Cross-Origin Resource Sharing (CORS) mechanism needs to be enabled in the domain serving the data URLs.

As noted above. You can also specify the data as a JavaScript function which is very convenient when using synthetic datasets. Here are is an example:

Data as a JavaScript function:

var data = function () {
  var d = {
    "y"  :  {
      "vars"  :  [],
      "smps"  :  [],
      "data"  :  []
    }
  }
  var v = [];
  d.y.vars.push("Var1");
  for (var i = 0; i < 4; i++) {
    v.push(11 * (i + 1));
    d.y.smps.push("Smp" + i);
  }
  d.y.data.push(v);
  return d;
}

var config = {
  "graphOrientation" : "vertical",
  "graphType" : "Bar",
  "theme" : "CanvasXpress",
  "title" : "Bar Graph Title"
}

new CanvasXpress("canvasFunc", data, config);


The data structure when specified as a json object varies depending on the visualization. Most numerical visualizations which include: Area, AreaLine, Bar, BarLine, Boxplot, Bubble, Chord, Circular, Contour, Dashboard, Density, Donnut, DotLine, Dotplot, Facet, Fish, Functions, Gantt, Heatmap, Histogram, Kaplan-Meier, Line, Lollipop, Map, Meter, ParallelCoordinates, Pie, Radar, SPLOM, Sankey, Scatter2D, Scatter3D, ScatterBubble2D, Stacked, StackedLine, StackedPercent, StackedPercentLine, Streamgraph, Sunburst, TCGA, TagCloud, Tree, Treemap, UpSet, Violin, Waterfall have an "L" shaped structure with three containers, x, y and z that can be represented like this:



Each of these containers are data frames. That is, a data structure representing cases (rows or variables), each of which consists of a number of observations or measurements (columns or samples).

The y container holds the numerical data that will be used for plotting. This container has three named arrays. The vars is an array containing the names of the variables (similar to the rownames in R). The smps is an array containing the names of the samples (similar to the colnames in R). The data is an two dimensional array containing the data values for each combination of row and column. Missing values are specified as a null value. A simple data set for one series and three samples looks like this:

{
  "y: {
    "vars": [ "Variable1" ],
    "smps": [ "Sample1", "Sample2", "Sample3" ],
    "data": [ [ 10, 20, 30 ] ]
  }
}

The x container holds the meta data or annotation for the samples (columns in the y container) which could be either numerical or categorical. The container is organized as a collection of associative arrays (or named lists). The key of each list is the annotation name and the value is an array with the corresponding values for each sample in the data set. The length of each array must be the same length of that of the smps array in the y container. Similarily, The z container holds the meta data or annotation for the variables (rows in the y container) which could be either numerical or categorical. The container is organized as a collection of associative arrays (or named lists). The key of each list is the annotation name and the value is an array with the corresponding values for each variable in the data set. The length of each array must be the same length of that of the vars array in the y container. An example data set for a single series of three samples containing two annotations for samples and two annotations for variables looks like this:

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

A similar data set with two series looks like this:

{
  "y": {
    "vars": [ "Variable1", "Variable2" ],
    "smps": [ "Sample1", "Sample2", "Sample3" ],
    "data": [ [ 10, 20, 30 ],
            [ 35, 25, 15 ] ]
  },
  "x": {
    "Tissue": [ "Kidney", "Lung", "Heart" ],
    "Donor": [ "D1", "D1", "D2" ]
  },
  "z": {
    "Symbol": [ "AAA", "BBB" ],
    "Pathway": [ "P1", "P2" ]
  }
}

The data format for the correlation plot 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 data format 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 Networks 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)"
    }, {
      "id1": "Node1",
      "id2": "Node3",
      "color": "rgb(0,125,125)"
    }, {
      "id1": "Node2",
      "id2": "Node3",
      "color": "rgb(125,0,125)"
    }
  ]
}

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.

And finally the last data format used for the Genome is as follows:

{
  "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 values.

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].

Configuration

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:

3D Attributes, Animations and Visualization Transitions, Area Graphs, Aspect Ratio, Space and width, Axis, Bar Graphs, Bin Plots, Bins, Boxplot Graphs, Circular Graphs, Citations or References, Clustering, Colors, Combination Plots, Contours, Correlation Graphs, DOE, Data, Data Customizer, Data Filters, Data Point Attributes, Data Selection, Data Table, Data Table/Filter, Data sorting, Debug, Decorations, Dendrograms, Density Plots, Dotplot Graphs, Effect, Error Bars and Confidence Intervals, Events, Fish Graphs, Foreground and Background, Gantt Charts, General, General Attributes, Genome Browser, Gradients, Heatmap Graphs, Hierarchy, Histograms, Images, Legends, Line Graphs, Lines, Loess, Maps, Margins, Meter Graphs, Missing Data, Motion Charts, Network Algorithm Parameters, Network Communities, Network Graphs, Network Node and Edge Attributes, Oncoprint Graphs, Overlays, Pie Charts, Plot area, Quantile Regression Plots, R, R-Axis, Random, Remote Procedures, Ridgeline Plots, Samples, Sankey Diagrams, Scatter Plot Matrix, Scatter Plots, Shadows, Shapes, Tag Cloud, Text, Time Series, Titles and Subtitles, Treemap Graphs, Trees, Variables, Venn Diagrams, X-Axis, Y-Axis, Z-Axis, Zooming, Panning and Resizing, cxplot.

Events

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 ...
    }
  }
}

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.

Here is a simple snipet that illustrate how it works.

<html>

  <head>

    <link rel="stylesheet" href="path-to-canvasXpress.css" type="text/css"/>
    <script type="text/javascript" src="path-to-canvasXpress.min.js"></script>

  </head>

  <body>

    <canvas  id="canvasId" width="540" height="540"></canvas>

    <script>

      var data = {
        "y": {
          "vars": ["Gene1"],
          "smps": ["Smp1", "Smp2", "Smp3"],
          "data": [[10, 35, 88]]
        }
      };

      var conf = {
        "graphType": "Bar"
      };

      var evts = {
        "mousemove": function(o, e, t) {
          t.showInfoSpan(e, '<pre>' + t.prettyJSON(o) + '</pre>');
        },
        "mouseout": function(o, e, t) {

        },
        "click": function(o, e, t) {
          var s = 'click on var ' + o.y.vars[0] + ' and smp ' + o.y.smps[0];
          t.showInfoSpan(e, s);
        },
        "dblclick": function(o, e, t) {
          var s = 'dblclick on var ' + o.y.vars[0] + ' and smp ' + o.y.smps[0];
          t.showInfoSpan(e, s);
        }
      };

      var cX = new CanvasXpress("canvasId", data, conf, evts);

    </script>

  </body>

</html>


Accessing CanvasXpress Instances in the DOM

CanvasXpress instances in the web page can be retrieved and accessed at any time using its targetId as follows:

var cX = CanvasXpress.$(targetId);

Similarily, any CanvasXpress instance in the web page can be destroyed programatically. This is very important if there is a need to remove the CanvasXpress instance since there are many events that are created at the time of the initialization and this is the only way to cleanly remove all of them. This can be done using its targetId as follows:

CanvasXpress.destroy(targetId);

or using the instance itself:

CanvasXpress.$(targetId).destroy();

Initialization

Include a script that call the CanvasXpress function.

There are many convenient ways to initialize the CanvasXpress objects in a web page with previously saved data in either images or JSON, or by including the data in a regular table and add the class 'CanvasXpress'. CanvasXpress configuration parameters can be embedded in the data attributes of the DOM object making sure the camel case pattern is followed according to the HTML definitions.

Here is the HTML code with where the data is embedded in a canvas object of a class 'CanvasXpress', containing a 'data-src' attribute pointing to a JSON file in a URL:

<html>

  <head>

    <!-- The CanvasXpress library -->
    <link rel="stylesheet" href="path-to-canvasXpress.css" type="text/css"/>
    <script type="text/javascript" src="path-to-canvasXpress.min.js"></script>

  </head>

  <body>

    <!-- canvas element with a "data-src attribute" -->
    <canvas id="canvasId" class="CanvasXpress" width="540" height="540" data-graph-type="Scatter2D" data-src="https://raw.githubusercontent.com/neuhausi/Rdatasets/master/json/datasets/AirPassengers.json"></canvas>

    <!-- Initialization script -->
    <script>
      // Init all canvas elements in web page of class CanvasXpress
      CanvasXpress.initCanvas();
    </script>

  </body>

</html>


Here is the HTML code with the data embedded in an img object of a class 'CanvasXpress' where the 'src' attribute points to a PNG file in a URL:

<html>

  <head>

    <!-- The CanvasXpress library -->
    <link rel="stylesheet" href="path-to-canvasXpress.css" type="text/css"/>
    <script type="text/javascript" src="path-to-canvasXpress.min.js"></script>

  </head>

  <body>

    <!-- img element -->
    <img id="canvasId" class="CanvasXpress" width="540" height="540" src="https://www.canvasxpress.org/assets/images/Ex-bar-9.png" title="CanvasXpress Bar Graph">

    <!-- Initialization script -->
    <script>
      // Init all img elements in web page of class CanvasXpress
      CanvasXpress.initImage();
    </script>

  </body>

</html>


Here is the HTML code where the data is in a regular table of the class 'CanvasXpress':

<html>

  <head>

    <!-- The CanvasXpress library -->
    <link rel="stylesheet" href="path-to-canvasXpress.css" type="text/css"/>
    <script type="text/javascript" src="path-to-canvasXpress.min.js"></script>

  </head>

  <body>

    <!-- table element -->
    <table id="canvasTable" class="CanvasXpress" data-width="540" data-height="540" data-graph-type="Bar" data-graph-orientation="vertical">
      <tr>
        <td></td>
        <td>Smp1</td>
        <td>Smp2</td>
        <td>Smp3</td>
      </tr>
      <tr>
        <td>Gene1</td>
        <td>10</td>
        <td>35</td>
        <td>88</td>
      </tr>
    </table>

    <!-- Initialization script -->
    <script>
      // Init all table elements in web page of class CanvasXpress
      CanvasXpress.initTable();
    </script>

  </body>

</html>

Smp1 Smp2 Smp3
Gene1 10 35 88

Check out the initialization scripts in this page to see an example of every way to initialize a CanvasXpress object.