This is one of the series of examples, where we step by step introduce new chart properties for the
same set of charts.
Here, we replace the default static legend with an interactive one. A colourSlider
is a special type of chart that transforms any given colour scale with a sigmoind function, alloeing the user to change its slope and midpoint. As a result, it allows to change contrast,
domain and the midpoint of the colour scale.
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.
Click on all the yellow bubbles
(),
going from top to bottom, to see explanations of the code.
Some lines of code, that have been already described in the previous examples, were omitted
for the sake of simplicity. At the bottom of the page you can find the complete code.
In this example all of the charts are defined almost the same way as in the previous example.
So here, we concentrate on the colour sliders, and omit most of the properties of all other charts. The full code you can find at the bottom of the page.
Since we are going to use colour slider instead of the default legend, we would like to not to have both. The default
legend can be turned off by setting showLegend property to false.
A colourSlider is another type of basic types of charts implemented in the linked-charts library.
It's not a selfsuficient chart, but it can be linked to any continuous colour scale of any of the plots to allow an easy and
interactive way of changing the contrast and the midpoint of the scale.
Here, we intialize and place colour sliders that will be linked to both of our colour scales - of the heatmap and of the scatter plot.
Here, we define the colour scale that a colour slider will then modify. In both cases here, we use the default colour scales
that were internaly initialized for the plots from user-set palette and colourDomain properties.
In such a case any change of these properties will also affect the slider. The default scales are
stored as colourScale for all the plots and layers. Another option
is to use here
any other unrelated colour scale, since the colours for the plot will be in any case picked from a transformed by the
colourSlider scale.
By setting the on_change property the user defines, what should happen if one of the pointers of a colour slider has been
moved. Here, we would like to have colours of all the cells or points (or other elements) changed. The most obvious way for that
to use the update function. But in this case we know for sure that it's only the colour that can change. So we
don't need all the chart elements to be recalculated and rerendered, since with larger charts this may take a considerable amount of
time. Here, we use the updateCellColour method for the heatmap and the updateElementStyle method for the scatter plot.
Here, we connect our plots with colour sliders by resetting the colour property. By default, the colour is defined
using the colourScale, but in this case we want to use the transformed by the colourSlider scale. So here we redefine
the colour property, using another colour scale instead. This step can't be done before the colourSlider is defined
(and we can't set the straightColourScale property of the colourSlider before the corresponding chart is defined),
so we need to make this change of property after the chart is already initialised.
Here, we save the first layer of the scatterplot as a separate variable for
the easy access to its properties and methods in the next few lines.
Here, we change size and margins of the colour slider to make it fit nicely in the layout.
As other charts, the colourSlider has the title property that
allows to set the main title.
Show/hide full code
Show/hide full code<scriptsrc="linked-charts.min.js"></script><linkrel="stylesheet"type="text/css"href="linked-charts.css"><script> inputData =[{"CellLine":"Pa16C","Drug":"Galunisertib","minConc":1,...},...];</script><table><tr><tdid="heatmap"valign="top"></td><tdid="scatterplot"valign="top"></td></tr></table><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 ).title("Drug-drug correlation").colourDomain([-1,1]).margins({top:50, left:50, right:100, bottom:100}).palette(function( val ){return d3.interpolateRdBu(1- val );}).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 );}).on_click(function( rowId, colId ){ selDrugs =[rowId, colId] scatterplot.update(); curveFit.update();}).cluster("Row").cluster("Col").showLegend(false).place("#heatmap");var heatmapSlider = lc.colourSlider().straightColourScale( heatmap.colourScale ).on_change(function(){ heatmap.updateCellColour();}).place("#heatmap");heatmap.colour(function( val ){return heatmapSlider.colourScale( val );});var get_curve =function( drug, cellLine, x ){var max = inputData.RTG[drug][cellLine].max, min = inputData.RTG[drug][cellLine].min, IC50 = inputData.RTG[drug][cellLine].IC50, slope = inputData.RTG[drug][cellLine].Slope, minConc = inputData.RTG[drug][cellLine].minConc;return min +( max - min )/(1+ Math.pow(10,-( x - Math.log10( IC50/minConc ))* slope));}var scatterplot = lc.scatter().width(300).height(300).elementIds( cellLines ).x(function( k ){return inputData.RTG[selDrugs[0]][k].avInh }).y(function( k ){return inputData.RTG[selDrugs[1]][k].avInh }).axisTitleX(function(){return selDrugs[0]}).axisTitleY(function(){return selDrugs[1]}).title("Average inhibition").domainX([-10,50]).domainY([-10,50]).palette(["green","yellow","red"]).colourValue(function( k ){var res =0;for(var x =0; x <5; x++)for(var l =0; l <2; l++) res += Math.pow(get_curve( selDrugs[l], k, x )- inputData.RTG[selDrugs[l]][k]["D"+(x +1)],2); res = Math.sqrt( res );return res;}).colourDomain([0,30]).on_click(function( k ){ selCellLine = k; curveFit.update();}).showLegend(false);lc.xLine("line", scatterplot ).lineFun(function( x ){return x;}).place("#scatterplot");var layer = scatterplot.get_layer("layer0");var scatterSlider = lc.colourSlider().width(300).height(110).set_margins({top:50}).title("Total curvefitting error").straightColourScale( layer.colourScale ).on_change(function(){ layer.updateElementStyle();}).place("#scatterplot");layer.colour(function( id ){return scatterSlider.colourScale( layer.get_colourValue( id ));});var curveFit = lc.scatter("points").width(300).height(200).nelements(10).title(function(){return selCellLine;}).axisTitleX("Drug concentration").axisTitleY("Inhibition").domainY([-25,100]).ticksX(function(){var ticks =[d3.range(5), d3.range(5).map(function( e ){return inputData.RTG[selDrugs[0]][selCellLine].minConc * Math.pow(10, e )}), d3.range(5).map(function( e ){return inputData.RTG[selDrugs[1]][selCellLine].minConc * Math.pow(10, e )})]; ticks.colour =["blue","red"];return ticks;}).x(function( k ){return k %5;}).y(function( k ){var ind = Math.floor( k /5);return inputData.RTG[selDrugs[ind]][selCellLine]["D"+(k %5+1)];}).colour(function( k ){return k >4?"red":"blue";});lc.xLine("lines", curveFit ).nelements(2).lineFun(function( x, k ){returnget_curve( selDrugs[k], selCellLine, x );}).colour(function( k ){return k ==0?"blue":"red";}).place("#scatterplot");curveFit.legend.add_block(function(){return[selDrugs,["blue","red"]];},"colour","Drugs");</script>