Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Morphing possible between scatter and aggregated bar charts? #465

Open
rdatasculptor opened this issue Sep 28, 2022 · 9 comments
Open

Morphing possible between scatter and aggregated bar charts? #465

rdatasculptor opened this issue Sep 28, 2022 · 9 comments
Assignees

Comments

@rdatasculptor
Copy link
Contributor

rdatasculptor commented Sep 28, 2022

Hi @JohnCoene!

Just wondering. Do you think it is possible to use the new morph-function for a tranistion between a scatter plot and a bar plot?

This is an example of what I mean. It uses an avarage calculation function and uses it as a value in data, but I have no idea how to incoporate this in in echarts4r.

Thanks in advance!

@helgasoft
Copy link
Contributor

@rdatasculptor, calculating averages is on the data preparation stage, not related to visualization.
No need to use JS for it since R has function mean() and others to do the same job.
Just build the two data/charts and plug them into e_morph - should work.

@rdatasculptor
Copy link
Contributor Author

@helgasoft yes, I am aware of the possibilities within R itself, but with that approach there is no real morph. In the example of echarts the bars seem to be build of all the pieces of data the avarage is taken from. So the issue I am aimin at is the smoothness of the trainsition of scatter plot into the bar chart. If I have some more time I will show what I mean with an example.

@JohnCoene
Copy link
Owner

Could be integrated but evaluating R code via htmlwidgets is less than ideal, is it for shiny or Rmd?

@rdatasculptor
Copy link
Contributor Author

It's for Rmd. (I always intend to not be too dependent on shiny, and thanks too echarts4r I succeed very often :))

@rdatasculptor
Copy link
Contributor Author

rdatasculptor commented Nov 10, 2022

Hi @JohnCoene! I don't know if it is of any worth, but using e_list() is at least one way to bring @helgasoft's example of smooth transition between differenct plot types, mentioned here, to echarts4r:

library(dplyr)
library(echarts4r)
mc <- mtcars |> filter(cyl<8)
datt <- function(idx) { return(mc[mc$cyl==idx,]$hp) }
colors <- c("blue","red")

oscatter <- list(
  title= list(subtext='press button to morph'),
  xAxis= list(scale=TRUE),
  yAxis= list(scale=TRUE), color= colors,
  series=list(
    list(type='scatter', id=4, dataGroupId=4, data= datt(4),
         universalTransition= list(enabled= TRUE)),
    list(type='scatter', id=6, dataGroupId=6, data= datt(6),
         universalTransition= list(enabled=TRUE)) 
  )
)
obar <- list(
  title= list(text= 'Average'),
  xAxis= list(type= 'category', data= list('cyl4', 'cyl6')),
  yAxis= list(show= TRUE), color= colors,
  series= list(list(
    type= 'bar', id= 'average', colorBy= 'data',
    data= list(
      list(value= mean(datt(4)), groupId=4),
      list(value= mean(datt(6)), groupId=6)),
    universalTransition=list(enabled= TRUE, 
                             seriesKey=c(4, 6))
  ))
)

e1 <- e_charts() |>
  e_list(obar)
e2 <- e_charts() |>
  e_list(oscatter)

e_morph(e1, e2, callback = cb) %>% 
  htmlwidgets::prependContent(
    htmltools::tags$button("Toggle", id = "toggle")
  )

e_morph(e1, e2, callback = cb) %>% 
  htmlwidgets::prependContent(
    htmltools::tags$button("Toggle", id = "toggle")
  )

Maybe it generates new ideas? Somehow the charts should be connected by id's and dataGroupIds. I guess I can add them to the lists programmattically, but haven't succeeded yet in doing that properly (in finding a generic way)

@rdatasculptor
Copy link
Contributor Author

rdatasculptor commented Nov 12, 2022

Another attempt with an example script of my own. Obviously I overlook something or I misunderstand the docs about universal transition, but using dataGroupId should be at least one of the necassary ingredients. Th example below gives a transition but not the transition what I am looking for: bar chart breaking into smaller pieces and turning into the scatter plot.

df <- data.frame(nummer = 1:10, y1 = sample(1:100, 10), group=as.character(sample(1:2, 10, replace = TRUE)))
e1 <- df %>% 
  e_charts(nummer) %>%
  e_scatter(y1, symbol_size = 20, 
            dataGroupId =  = "data",
            universalTransition = list(enabled= TRUE, 
                                       seriesKey= "data")),
            animationDurationUpdate = 1000L)

e2 <- df %>% group_by(group) %>% summarise(y1 = sum(y1)) %>% ungroup() %>%
  e_charts(group) %>%
  e_bar(y1, 
        dataGroupId = "data",
        universalTransition = list(enabled= TRUE, 
                                   seriesKey= "data", divideShape = "clone"),
        animationDurationUpdate = 1000L)

cb <- "() => {
  let x = 0;
  document.getElementById('toggle')
    .addEventListener('click', (e) => {
      x++
      chart.setOption(opts[x % 2], true);
    });
}"

e_morph(e1, e2, callback = cb) %>% 
  htmlwidgets::prependContent(
    htmltools::tags$button("Toggle", id = "toggle")
  )

@rdatasculptor
Copy link
Contributor Author

rdatasculptor commented Nov 16, 2022

Hi @JohnCoene, sorry for bothering you again, but I kind of succeeded in making a smooth transition between a scatter plot and a bar chart. (@helgasoft put me in the right direction). I still don't know exactly what I am doing, but it works.... :)
But this approach needs some tweaks in the object structure. First I turn the echarts4r object into a list, then I do the tweaks, and finally I render the plots using e_list().
Maybe you can find a way (if you have time ofcourse...) to somehow make it possible to these kind of transitions without needing to tweak before rendering? But then again, maybe it is harder to implement such a feature than I think.

Here is a wokring example of the smooth transition:

library(echarts4r)
library(dplyr)

set.seed(2022)
df <- data.frame(nummer = 1:10, y1 = sample(1:100, 10), 
                 group=as.character(sample(1:2, 10, replace = TRUE))) %>% dplyr::group_by(group)

oscatter <- df %>%
  e_charts(nummer) %>%
  e_scatter(y1, symbol_size = 20) %>% e_inspect()
oscatter$series[[1]]$universalTransition <- list(enabled = TRUE, seriesKey = c(1))
oscatter$series[[2]]$universalTransition <- list(enabled = TRUE, seriesKey = c(2))
oscatter$series[[1]]$id <- 1
oscatter$series[[2]]$id <- 2
oscatter$series[[1]]$dataGroupId <- 1
oscatter$series[[2]]$dataGroupId <- 2
oscatter <- e_charts() %>%
  e_list(oscatter) 

obar <- df %>% summarise(y1 = sum(y1)) %>% ungroup() %>% 
  e_charts(group) %>%
  e_bar(y1, colorBy= "data", universalTransition = list(enabled= TRUE)) %>% e_inspect() 
obar$series[[1]]$data[[1]]$groupId <- 1 
obar$series[[2]]$data[[1]]$groupId <- 2
obar$series[[1]]$universalTransition <- list(enabled = TRUE, seriesKey = c(1,2))
obar <- e_charts() %>%
  e_list(obar) 

cb <- "() => {
  let x = 0;
  document.getElementById('toggle')
    .addEventListener('click', (e) => {
      x++
      chart.setOption(opts[x % 2], true);
    });
}"

e_morph(oscatter, obar, callback = cb) %>% 
  htmlwidgets::prependContent(
    htmltools::tags$button("Toggle", id = "toggle")
  )

@rdatasculptor
Copy link
Contributor Author

If someone can find a solution for not being able to morph between bar charts and scatter plots using echart4r (@munoztd0 .. :)), well, for me he earns the nobel prize ....

@munoztd0 munoztd0 self-assigned this Oct 15, 2023
@rdatasculptor
Copy link
Contributor Author

In my imagination we just give the scatterplot and the bar chart that should be morphed into one another the same "morph id". Under the hood echarts4r takes care of all the necessary echarts settings :). Experimented with it, but haven't made it work yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants