I was wondering if we could do this in R Shiny example
# using styleColorBar
datatable(df) %>% formatStyle(names(df),
background = styleColorBar(range(df), 'lightblue'),
backgroundSize = '98% 88%',
backgroundRepeat = 'no-repeat',
backgroundPosition = 'center')
But with two colors for positive and negative values and moreover if we can do so the negative values are taken as absolute values for the length of the bar
Ty and have a good day !
You can do it manually using rowCallback
as you can see
sss=datatable(df) %>% formatStyle(names(df),
background = styleColorBar(range(df), 'lightblue'),
backgroundSize = '98% 88%',
backgroundRepeat = 'no-repeat',
backgroundPosition = 'center')
sss$x$options$rowCallback
Generate for each column :
function(row, data) { var value=data[ 1]; if (value!==null) $(this.api().cell(row, 1).node()).css({'background':isNaN(parseFloat(value)) || value <= -1.311 ? '' : 'linear-gradient(90deg, transparent ' + (2.199 - value)/3.51 * 100 + '%, lightblue ' + (2.199 - value)/3.51 * 100 + '%)','background-size':'98% 88%','background-repeat':'no-repeat','background-position':'center'});
So :
1) You need to calc range variables:
rr=range(df)[2]-range(df)[1]
r1=range(df)[2]
r0=range(df)[1]
2) Than use it in rowCallback
datatable(
df,
options = list(
rowCallback=JS(paste0("function(row, data) {",
paste(lapply(1:ncol(df),function(i){
paste0("var value=data[",i,"];
if (value!==null){
if(value<0){
$(this.api().cell(row,",i,").node()).css({'background':isNaN(parseFloat(value)) || value <=",r0," ? '' : 'linear-gradient(90deg, transparent ' + (",r1," - value)/",rr," * 100 + '%, red ' + (",r1," - value)/",rr," * 100 + '%)','background-size':'98% 88%','background-repeat':'no-repeat','background-position':'center'});
}else{
$(this.api().cell(row,",i,").node()).css({'background':isNaN(parseFloat(value)) || value <=",r0," ? '' : 'linear-gradient(90deg, transparent ' + (",r1," - value)/",rr," * 100 + '%, lightblue ' + (",r1," - value)/",rr," * 100 + '%)','background-size':'98% 88%','background-repeat':'no-repeat','background-position':'center'});
}
} ")
}),collapse="\n"),
"}"))
)
)
Here I hard coded colors (red and lightblue)
Result
If you want different length for positive and negative you need different range variable or using abs
\ Math.abs
- for absolute value (for var in JS and for ranges)
Numeration for columns in JS started from 0 so if you havent rownames you need 0:(ncol(df)-1)
in lapply
for right result
Range -1 :1 and color scale for abs value
df = as.data.frame(cbind(matrix(round(runif(50, -1, 1), 3), 10), sample(0:1, 10, TRUE)))
rr=range(abs(df))[2]-range(abs(df))[1]
r1=range(abs(df))[2]
r0=range(abs(df))[1]
datatable(
df,
options = list(
rowCallback=JS(paste0("function(row, data) {",
paste(lapply(1:ncol(df),function(i){
paste0("var value=Math.abs(data[",i,"]);
var value2=data[",i,"];
if (value!==null){
if(value2<0){
$(this.api().cell(row,",i,").node()).css({'background':isNaN(parseFloat(value)) || value <=",r0," ? '' : 'linear-gradient(90deg, transparent ' + (",r1," - value)/",rr," * 100 + '%, red ' + (",r1," - value)/",rr," * 100 + '%)','background-size':'98% 88%','background-repeat':'no-repeat','background-position':'center'});
}else{
$(this.api().cell(row,",i,").node()).css({'background':isNaN(parseFloat(value)) || value <=",r0," ? '' : 'linear-gradient(90deg, transparent ' + (",r1," - value)/",rr," * 100 + '%, lightblue ' + (",r1," - value)/",rr," * 100 + '%)','background-size':'98% 88%','background-repeat':'no-repeat','background-position':'center'});
}
} ")
}),collapse="\n"),
"}"))
)
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With