Following up on a previous question here: SO Q
The solution provided in the previous question uses JavaScript code to convert axis ticks into exponential format, but it only works for a single axis on a single plot.
When applied in a subplot() structure, it only affects the first plot and not all subplots in the final plot.
Here are the modifications I am seeking:
1: Solution should work on subplots. Attempts to call JavaScript in the build of each subplot resulted in all plots displaying without exponential formatting.
2: Make the solution work for both x and y axes. Previous attempts failed to achieve this requirement.
3: Ensure the solution does not cause issues when the axis is not numerical (as the application can also plot date columns).
4: If possible, display the exponential format as 1.23E+1 instead of 1E+1.
library(shiny)
library(plotly)
library(htmlwidgets)
ui <- fluidPage(
mainPanel(
plotlyOutput('myplotly')
)
)
server <- function(input, output, session) {
javascript <- "
function(el, x)
{
function fix_ticks()
{
ticks = Plotly.d3.selectAll('g.ytick').selectAll('text');
ticks.forEach(function(tick)
{
var num = parseInt(tick[0].innerHTML);
tick[0].innerHTML = num.toExponential();
})
}
el.on('plotly_afterplot', fix_ticks);
}"
output$myplotly <- renderPlotly({
myplots <- lapply(unique(mtcars$cyl), function(v) {
data <- mtcars[which(mtcars$cyl == v), ]
subp <- plot_ly(data = data,
x = rownames(data),
y = ~mpg,
type = "bar")
subp
})
p <- subplot(myplots, margin = 0.08)
p$elementId <- NULL ## to surpress warning of widgetid
p <- onRender(p, javascript)
p <- p %>% layout(margin =list(l = 60, r = 20, b = 160, t = 70) )
p
})
}
shinyApp(ui = ui, server = server)
UPDATE Based on the recommendations provided, I have modified the code to check for numerical values and work for each axis. However, there are still some issues with handling negative values as it results in NaN. I have tried different approaches, including using tick[0].innerHTML and the forEach loop. It seems like a complete solution is still pending.
This is the code snippet I ended up using before encountering issues with negative values:
javascriptMPP <- "
function(el, x)
{
function isNumber(n) {
return (Object.prototype.toString.call(n) === '[object Number]' || Object.prototype.toString.call(n) === '[object String]') &&!isNaN(parseFloat(n)) && isFinite(n.toString().replace(/^-/, ''));
}
function fixTicks()
{
ticks = Plotly.d3.selectAll('g.yaxislayer-above,g.xaxislayer-above').selectAll('text');
ticks.each(function(d)
{
if(parseInt(d.text) !== 0 )
{
var num = parseInt(d.text).toExponential(2);
Plotly.d3.select(this).text(num);
}
})
}
el.on('plotly_afterplot', fixTicks);
}"