Adding a colour slider
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.
...
var heatmap = lc.heatmap()
...
.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 scatterplot = lc.scatter()
...
.showLegend( false );
lc.xLine( "line", scatterplot )
...
.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" )
...
lc.xLine( "lines", curveFit )
...
.place( "#scatterplot" );
...
|
Show/hide full code
<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>
<table><tr>
<td id="heatmap" valign="top"></td>
<td id="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 ) {
return get_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>