echarty
echarty copied to clipboard
Changing result based on legend selection
This is an interesting question by @ddrogen asked here. Specifically, how to change some series data live just by toggling legend items ? Since the need is to update a chart in real time without Shiny, then obviously some Javascript code has to be written. Here is one solution which relies on additional data preparation and ECharts event handling.
set.seed(222) # make the chart reproducible
library(dplyr)
data2 <- data.frame(zipcode= as.factor(round(rnorm(10, 87965, 50),0)), program_1 = rnorm(10, 200, 20), program_2 = rnorm(10, 700, 100), program_3 = rnorm(10, 500, 50))
data1 <- data2 %>%
mutate(total = rowSums(across(where(is.numeric)))) %>%
mutate(A= round(100*program_1/total,1)) %>%
mutate(B= round(100*program_2/total,1)) %>%
mutate(C= round(100*program_3/total,1)) %>%
# additional data to cover all combinations
mutate(AB= round(100*(program_1+program_2)/total,1)) %>%
mutate(AC= round(100*(program_1+program_3)/total,1)) %>%
mutate(BC= round(100*(program_2+program_3)/total,1)) %>%
mutate("per_total"= 100*total/sum(total)) %>%
arrange(desc(total)) %>%
mutate(ABC = round(cumsum(per_total),1)) # renamed from 'cum_sum_total'
library(echarty)
p <- data1 |> ec.init(elementId='cid',
legend= list(show=TRUE),
xAxis= list(name = "Zip Code",
nameLocation = "middle", nameGap=50,
nameTextStyle = list(color = "#87786B", fontSize = 15),
axisLabel = list(fontFamily="Arial",
interval = 0, rotate = 30,
fontSize=12, color="#87786B")),
yAxis= list(
list(name="n° of visits", index = 0, show = TRUE,
nameLocation ="middle",
nameGap=70, align="right",
nameTextStyle = list(
color = "#87786B",
fontSize = 12),
axisLabel = list(fontSize=12, color="#87786B")),
list(name= '%') ),
series= list(
list(name='A', type='bar', encode=list(x='zipcode', y='program_1'), stack='g'),
list(name='B', type='bar', encode=list(x='zipcode', y='program_2'), stack='g'),
list(name='C', type='bar', encode=list(x='zipcode', y='program_3'), stack='g'),
list(name = "Cumulative %", type='line', encode=list(x='zipcode', y='ABC'),
yAxisIndex= 1, emphasis= list(focus= "series"),
label= list(
show= TRUE,
textStyle = list(fontFamily = "Arial", fontSize = 10))) ),
tooltip= list(formatter = htmlwidgets::JS("function(params) {
col = 'ABC'.indexOf(params.seriesName) +1;
return(params.marker + params.seriesName +
'<br> Total: ' + params.value[col].toFixed(2) + ' (' +
params.value[col+4] + '%)');}"),
textStyle= list(fontFamily="Arial", fontSize=12)),
animationDuration= 1500,
toolbox= list(show =TRUE, top=0, right= 10, itemSize=10,
emphasis= list(iconStyle= list(textFill= "#6C2C4E")),
feature = list(restore=list(show=TRUE), saveAsImage=list(show=TRUE)) )
) |>
ec.theme('t1', code='{"color": ["#F8AD3B", "#D15425", "#9CAC3B", "#6C2C4E"]}')
p$x$on <- list(list(event= 'legendselectchanged',
handler= htmlwidgets::JS("function(v) {
sel = v.selected;
chart = get_e_charts('cid');
opt = chart.getOption();
vals = Object.values(sel).slice(0,3);
nams = Object.keys(sel).slice(0,3);
col= ''; i= 0;
vals.map(x => {if (x) col= col + nams[i]; i++;});
if (col != '')
opt.series[3].encode.y = col; // A or AC or ABC etc.
chart.setOption(opt, true); // replace chart
}")
))
p
https://user-images.githubusercontent.com/13038071/187005714-ce02a9aa-787a-40d4-ae68-9652bf32c648.mp4
Note: if you like this solution, please consider granting a Github star ⭐ to echarty.