JohnCoene / echarts4r

🐳 ECharts 5 for R
http://echarts4r.john-coene.com/
Other
585 stars 82 forks source link

How to not show bars without value? #551

Closed rdatasculptor closed 11 months ago

rdatasculptor commented 1 year ago

Does anyone have a solution for this issue: bars without value are still shown

consider this example:

df <- data.frame(
    x = LETTERS[1:10], 
    y = seq(1, 20, by = 2),
    z = runif(10, 5, 20)
) |> mutate(y = ifelse(x == "B", NA, y))

df |> 
    e_charts(x) |> 
    e_bar(y)

As you can see B as an x axis category is still shown. For me this is strange, because now it seems its value is 0, instead of NA. Is there a way to not show category B if its value is not available? (And ofcourse I mean a solution within echarts4r, and not simply remove B from the data frame using R)

Most appreciated!

(I guess it is not really possible, because echarts community encounters the same similar problems: https://github.com/apache/echarts/issues/9899

munoztd0 commented 1 year ago

Hi could you tell me an application where filtering the NA from the dataset would not be suitable ?

rdatasculptor commented 1 year ago

@munoztd0 I finally got some focus to make an example. (and thank you so much for your help in maintaining this package!)

I love to stretch the limits of echarts4r if it helps me not having to use shiny :). In this particular case I would like to use the legend as an additional data filtering methode together with the timeline feature.

Here's my example:

df <- data.frame(
  id = c(1,2,3,4,5,6,7,8,9,10),
  group = c(1,1,1,1,1,2,2,2,2,2),
  subgroup1 = c(sample(30:100, 2), NA, NA, NA, sample(30:100, 2), NA, NA, NA),
  subgroup2 = c(NA, NA, sample(30:100, 3), NA, NA,  sample(30:100, 3))
)

df %>%
  group_by(group) %>%
  e_charts(id, timeline = TRUE) %>%
  e_bar(subgroup1) %>%
  e_bar(subgroup2) %>%
  e_x_axis(axisLabel = list(show = FALSE)) %>%
  e_legend(selectedMode = "single")

As you can see the timeline makes it in the chart possible to change between group 1 and 2, and the legend makes it possible to change between subgroup 1 and 2. Needless to say that if you remove the NA's from the data frame using R code I will loose too much information in the final chart.
So if it is possible to let echarts not show NA values as empty bars but jus not show them at all it would help to filter and navigate though groups and subgroups in a neat way.

These are just thoughts, I can't always predict if it is even possible in the js part of echarts4r.

munoztd0 commented 1 year ago

Hi,

I am definitely not sure what you actual need is.

Weirdly enough, I don't think it has to do with not showing NAs..

Let me try to understand. Your problem is that there is a "gap" between 1 and 8 in this render.

image

But that is not because of the NAs ( I think)

If you run:

library(echarts4r)

df <- data.frame(
  id = c(1,2,3,4,5,6,7,8,9,10),
  group = c(1,1,1,1,1,2,2,2,2,2),
  subgroup1 = c(sample(30:100, 2), 55, 55, 55, sample(30:100, 2), 55, 55, 55),
  subgroup2 = c(55, 55, sample(30:100, 3), 55, 55,  sample(30:100, 3))
)

df |>
  group_by(group) |>
  e_charts(id, timeline = TRUE) |>
  e_bar(subgroup1, stack = "grp") |>
  e_bar(subgroup2, stack = "grp") |>
  e_x_axis(axisLabel = list(show = FALSE)) |>
  e_legend(selectedMode = "single")

You get this which is the same with df with no NAs

image

So the issue seems that you would like the x axis to retract to not show the full range of ID possibilities ?

rdatasculptor commented 1 year ago

"So the issue seems that you would like the x axis to retract to not show the full range of ID possibilities ?"

Exactly that.

Thank you for your effort to dig into this!

munoztd0 commented 12 months ago

Ok so this has nothing to do with NAs.

Im going to see what going on under the hood with the "timeline" flag.

munoztd0 commented 12 months ago

Ok after a lot of thought I figured that the actual problem is not the "timeline" is more the method.

So instead of using a "timeline" for the transition why don't we just use an actual "transition" as with e_morph ?

G

library(echarts4r)

#### I was sure that the by putting the data in a tidy long format it would help me debug this and I think this is the key #### 

df <- data.frame(
  id = as.factor(c(1,2,3,4,5,6,7,8,9,10)),  ### also modified this but does this need to be  an integer data type or just an ordered factor should be ok ?
  group = c(1,1,1,1,1,2,2,2,2,2),
  measure = c(sample(30:100, 10)),
  subgroup = c('A', 'A', 'B', 'B', 'A', 'A', 'B', 'B', 'A', 'A')
)

#### long live long format data ####

e1 <- df |> 
  filter(group ==1) |>
  group_by(subgroup) |>
  e_charts(id) |>
  e_bar(measure, 
    universalTransition = TRUE,
    animationDurationUpdate = 1000L
  )|> 
  e_title("Group 1")

e2 <- df |> 
  filter(group ==2) |>
  group_by(subgroup) |>
  e_charts(id) |>
  e_bar(measure, 
    universalTransition = TRUE,
    animationDurationUpdate = 1000L
  ) |> 
  e_title("Group 2")

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

trans_morph <- e_morph(e1, e2, callback = cb) |> 
  htmlwidgets::prependContent(
    htmltools::tags$button("Toggle between groups", id = "toggle")
  )

Created on 2023-07-11 with reprex v2.0.2.9000

image

image

I am sure this could be optimized but first let me know what you think @rdatasculptor , love solving this puzzles btw!

rdatasculptor commented 11 months ago

Back from a short holiday. Great thoughts @munoztd0. In the end I think e_morph() will solve a lot of problems :). I will try to add my take on this idea soon.

Indeed my problem wasn't caused by NA's, but I just wondered if we could make echarts4r not show bars (or the space where the bar is located) where the values is NA.