echarts4r - stacked bar with label for individual segments and total value

169 views Asked by At

I'm trying to make a stacked bar chart in echarts4r that would label both individual segments' values, as well as the total. Here is a short example:

library(echarts4r)

dataset <- data.frame(
  categories = letters[1:5],
  smaller = 11:15,
  larger = 21:25,
  total = 11:15 + 21:25
)

e_charts(dataset, x = categories) %>%
  e_bar(serie = larger, name = "Big", stack = "stack") %>%
  e_bar(serie = smaller, name = "Small", stack = "stack") %>%
  e_labels(position = "inside")

stacked bar with labeled segments

With this, I'm able to get the values of segments labelled as is the goal. However, I can't figure out how to add a label at the end of the bars that would also label the "total" column.

2

There are 2 answers

2
stefan On BEST ANSWER

A possible R approach building on the idea of @MatthiasMertens. As in his approach I add a third empty or zero series for the totals but pass the total values via the bind= argument. This way the totals get stored in the name attribute of the data and can be added via the formatter "{b}". Finally, thanks to the comment by @Jan we can set legend=NULL to get rid of the additional series in the legend.

library(echarts4r)

dataset <- data.frame(
  categories = letters[1:5],
  smaller = 11:15,
  larger = 21:25,
  total = 11:15 + 21:25
)
dataset$zero <- 0

e_charts(dataset, x = categories) |>
  e_bar(serie = larger, name = "Big", stack = "stack") |>
  e_bar(serie = smaller, name = "Small", stack = "stack") |>
  e_labels(position = "inside") |>
  e_bar(
    serie = zero, bind = total, name = "Total",
    stack = "stack",
    label = list(
      show = TRUE,
      formatter = "{b}",
      position = "top"
    ),
    legend = NULL
  )

enter image description here

0
Matthias Mertens On

Here is a javascript solution for you, I hope you can get some insight from that.

I just used another series for the totals, set the data to 0 (such that there is no visual representation) and used the label formatter function to compute the totals based on the dataIndex

const data = [{x: 'Mon', a: 320, b: 120}, {x: 'Tue', a: 302, b: 132}, {x: 'Wed', a: 301, b: 101}, 
              {x: 'Thu', a: 334, b: 134}, {x: 'Fri', a:390, b: 90}, {x: 'Sat', a: 330, b: 230}, 
              {x: 'Sun', a: 320,  b: 210}];

option = {
  dataset: [{source: data}],
  xAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {},
  series: [
    {
      name: 'a',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      encode: {
        x: 'x',
        y: 'a'
      }
    },
    {
      name: 'b',
      type: 'bar',
      stack: 'total',
      label: {
        show: true
      },
      encode: {
        x: 'x',
        y: 'b'
      }
    },
    {
      type: 'bar',
      stack: 'total',
      label: {
        show: 'true',
        position: 'top',
        formatter: (params) => data[params.dataIndex].a + data[params.dataIndex].b
      },
      data: [0,0,0,0,0,0,0]
    }
  ]
};