Adding layers

In this and some futher examples we provide more insight in the possibilities of the linked-charts library and show how to use it. We will use the same set of charts, but gradually make them more and more complicated and nice looking.

Some types of charts (for example, chart with axes) support layer system, where each layer has its own set of properties that are defined independently from other layers' properties. This is a simple example of creating a chart with two layers. Generally, one should use layers to put several types of charts on one plot (for example lines and dots), but here both layers are scatters. In futher examples we will generate the same plot with only one layer.

The data used here are generated in a drug-screening experiment. 50 drugs at 5 different concentrations were tested against 21 pancreatic cancer cell lines. The heatmap shows drug-drug correlation. Like in the previous example, a click on a cell of the heatmap reveals the underlying statistics by demonstrating on the scatter plot (right upper corner) the values of avarage inhibition for all tested cell lines and the two selected drugs. By clicking on a data point one can select a cell line, and thus change the third plot (right bottom corner) that demonstrates individual inhibition percent values for the two selected drugs and the selected cell line.

The code for the example

A user of our framework can create apps with very little code. Bellow we show the part of the code that hasn't been explained in previous examples. You can find the complete code at the bottom of the page.

<script src="linked-charts.min.js"></script> 
<link rel="stylesheet" type="text/css" href="linked-charts.css"> 

<script>
  inputData = [{"CellLine":"Pa16C","Drug":"Galunisertib","minConc":1, ...}, ... ];
</script>

...

<script>
inputData = lc.separateBy(inputData, ["screen", "Drug", "CellLine"]);
var drugs = Object.keys(inputData.RTG),
  cellLines = Object.keys(inputData.RTG[drugs[0]]);

var selDrugs = [drugs[0], drugs[1]],
  selCellLine = cellLines[0];

var heatmap = lc.heatmap()
  .rowIds( drugs )
  .colIds( drugs )
  .value( function( rowId, colId ) {
    var rowValues = cellLines.map(function(e) {
        return inputData.RTG[rowId][e].avInh;
      }),
      colValues = cellLines.map(function(e) {
        return inputData.RTG[colId][e].avInh;
      });
    return lc.pearsonCorr( rowValues, colValues );
   })
  .cluster("Row")
  .cluster("Col")
  .margins({top: 50, left: 50, right: 100, bottom: 100})
...
  .place( "#heatmap");

var scatterplot = lc.scatter()
  .elementIds( cellLines )
...
  .place( "#scatterplot" );

var curveFit = lc.scatter("drug1")
...
  .nelements( 5 )
  .x( function( k ) {return k;} )
  .y( function( k ) {
    return inputData.RTG[selDrugs[0]][selCellLine]["D" + (k + 1)];
  })
  .colour( "blue" );
lc.scatter("drug2", curveFit)
  .nelements( 5 )
  .x( function( k ) {return k} )
  .y( function( k ) {
    return inputData.RTG[selDrugs[1]][selCellLine]["D" + (k + 1)];
  })
  .colour("red")
  .place( "#scatterplot" );
</script>

Click on all the yellow bubbles (), going from top to bottom, to see explanations of the code.


Here we load the linked-charts library and its stylesheet. It comes bundled with d3, d3-beeswarm plugin and FileSaver.js

There are various ways to load the data. Here, we demonstrate the simplest way: just inline it into the page.

The data was originally an R matrix. We used the toJSON function of R's 'jsonlite' package to write out the data in a form that can be read in JavaScript, and copied and pasted this here.

More about data input you can find here

This is the actual user script to use the linked-charts library.

The linked-charts library often requires to access a specific row of the data table. For example, here we will often want to get a value of avarage inhibition for a specific drug tested against a specific cell line measured using RealTime-Glo assay. To avoid excessive filtering one can assign a unique ID to each sample, as it was done in the previous example. Another way to address this problem is demonstrated here

Function separateBy(dataset, properties) is a part of the linked-charts library. It takes the data in a form of an array or object and converts it into hierarchical, tree-like form, consequently separating the data by the values of provided properties.

The figure bellow illustrates the transformation of inputData made by this function.

It can be more convenient to keep lists of all tested drugs and cell lines in separate variables. In the previous example we got such lists as a part of the input, here we save them manually to the drugs and cellLines variables.

These global variables provide the link between plots on this page:

selDrugs stores names of the two drugs user selects by clicking on a heatmap cell, selCellLine stores the name of the cell line user selects by clicking on a point of the correlation scatter plot.

Here, we use the firt two drugs and the first cell line as default values.

Here, we instantiate the first chart, namely the heatmap on the left. The heatmap is one of the standard chart types provided by the linked-charts library.

Instead of setting the number of points (rows and colums for the heatmap) one can use an array of IDs of all displayed points (rows and columns). By default, the IDs are also used as row and column labels, but this can be changed by user. If these properties are not set by the user, each point (row and column) gets a consequent number as an ID.

Here, for a correlation heatmap we use names of all the drugs as both row and column names. On the scatter plot each dot corresponds to a cell line, so we use the list of all the cell lines as IDs.

As it was described in the previous example, the value property is used to get the value that the cell given its row and column IDs.

Here, the function looks more complicated due to different form of the data. First, we need to store avarage inhibition values for each cell line in two separate variables (rowValues and colValues) and only after can we calculate Pearson correlation.

To cluster rows or columns of a heatmap one can use cluster method. By default, the Eucledian metric is used, but other metrics can be provided via clusterRowMetric and clusterColMetric functions.

Note, that the clustering is performed immediately when the method is called. Therefore, one needs to ensure that the essential properties has already been set.

Each chart has top, bottom, left and right margins, which are used to place axes, titles, legengds. Margins can be set by defining an object that has these four fields.

By default, a heatmap has large left and top margins to store row and column labels and small right and bottom ones. But when the rows or columns are clustered and a dendogram is added to the heatmap, the labels are moved to the right or to the bottom respectively. So here, we want to make this margins large enough to fit the labels.

The place function inserts the object into the web page. The argument is a CSS selector, here selecting the table elements that were marked with id attributes as the places to take up the charts.

Here, we initialize a scatter object. This is one of the standard chart types provided by our linked-charts library.

In the following lines, we set the object's properties

Here, we initialize a plot with two layers (both are scatter plots). Layers are created by the same function we used to make a single-layer scatter plot. scatter function has two optional arguments. The first one sets the ID of the new layer. If not defined, the ID for the layer will be automatically set to layerN, where N is a number of the layer starting from 0. The second argument is a chart to which the new layer should be added. If not defined a new chart is initialized.

Here, we are creating a new chart that contains one layer, which is a scatter plot and has ID drug1

If elementIds property is not set, scatter tries to estimate the number of points automatically, but in some cases that is not possible due to the specific dataset structure. If this is the case, then one should define the number of points manualy by setting the nelements property.

Here, each drug was tested at five different concentrations, so the number of points is fixed for all cases.

Linked-charts uses call-back functions to access the data: These two functions are called for each data point, being passed the number of the data point as argument. x values are just numbers from 0 to 4 - each corresponds to one of the concentrations. y value is the inhibition value that for each drug is stored as [D1, D2, ..., D5].

The global variables defined above are consulted, so that the scatter plot uses the data for the one of the drugs and the cell line that the user selected by clicking on the heatmap and the scatter plot.

Axes and scaling is automatically adjusted to the value range (but this can be overridden).

Here, we define points colour. There is no callback functions, so the value of this property will be applied to all the points of the layer.

Show/hide full code