JohnCoene / echarts4r

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

Define stacked bars programmatically #628

Closed enriquepravia closed 1 month ago

enriquepravia commented 1 month ago

Hi there,

I have been working on a stacked bar chart. The dataset I was plotting was:

Caption 1

And the following code would give me a nice stacked bar:

MonthlyTimeSeriesCntByOpRes  %>%
  echarts4r::e_charts(dataset=list(source=MonthlyTimeSeriesCntByOpRes,dimensions = c('mmYYYY', 'Expired', 'Cancelled', 'Succeeded', 'Denied', 'Error')),
                      emphasis = list(focus='series')
  ) %>%
  echarts4r::e_x_axis(type = 'category', data = as.character(MonthlyTimeSeriesCntByOpRes$mmYYYY), axisLabel = list(interval=0), textStyle = list(fontWeight='bold')) %>%
  echarts4r::e_bar(Expired, name = 'Expired', stack="grp") %>%
  echarts4r::e_bar(Cancelled, name = 'Cancelled', stack="grp") %>%
  echarts4r::e_bar(Succeeded, name = 'Succeeded', stack="grp") %>%
  echarts4r::e_bar(Denied, name = 'Denied', stack="grp") %>%
  echarts4r::e_bar(Error, name = 'Error', stack="grp") 

However, I have now the situation in which, according to the date selection, I may encounter with a different number of columns (e.g. 'Error' may not exist). So in some way I need to dynamically define the bars.

According to the following closed issues, I thought this would be resolved by means of the 'group_by' solution: https://github.com/JohnCoene/echarts4r/issues/8 https://github.com/JohnCoene/echarts4r/issues/22

Obviously now my new dataset is not pivoted, but instead has the following columns:

opr -> takes values 'Expired', 'Cancelled', ... mmYYYY opcnt

And so trying to use the group_by approach:

MonthlyTimeSeriesCntByOpRes  %>%
    group_by(opr) %>% 
      echarts4r::e_charts(mmYYYY)  %>%
      echarts4r::e_bar(opcnt, stacked = 'grp')

I ended up with a blank plot.

Any help would be really appreciated.

Thanks in advance and thanks for the echarts4r library. It is such a good work!

enriquepravia commented 1 month ago

I solved my problem following the approach of https://github.com/JohnCoene/echarts4r/issues/120 with the e_list() and defining the data as string with a list of lists which I evaluate later. While it may not be the most elegant solution, it works. In case anyone needs it, here's my code to solve the problem stated above:

(IMPORTANT NOTE: IM CLOSING THE ISSUE BUT THE SOLUTION PROVIDED BELOW DOES NOT USE THE GROUP_BY APPROACH)

      series_as_str <- paste0('list(',
                              do.call(paste,c(
                                lapply(colnames(MonthlyTimeSeriesCntByOpRes %>% select(-c(monthyear,mmYYYY))),
                                       function(x){paste0('list(name = "',
                                                          x,
                                                          '", type = "bar", stack = "stackbar", label = list(show = FALSE), data = as.list(MonthlyTimeSeriesCntByOpRes$',
                                                          x,
                                                          '), color=',
                                                          CntByOpRes %>% filter(last_operation_result==x) %>% pull(colorGrad),
                                                          ', barWidth = 12, itemStyle=list(borderRadius = 12))')}), 
                                sep=','
                              )
                              ),
                              ')'
      )

      opts <- list(
        emphasis = list(focus='series'),
        xAxis = list(
          type = 'category', data = as.list(as.character(MonthlyTimeSeriesCntByOpRes %>% pull(mmYYYY))), axisLabel = list(interval=0), textStyle = list(fontWeight='bold')
        ),
        yAxis = list(
          type = "value"
        ),
        series = eval(parse(text = series_as_str)),
        tooltip =  list(
          trigger='axis',
          axisPointer = list(type = 'line',
                             show = 'false',
                             lineStyle=list(color='rgba(150,150,150,0.1)',
                                            type='solid',
                                            width=50)),
          order = 'seriesDesc'
        )
      )

      echarts4r::e_charts() %>% 
        echarts4r::e_list(opts)