Search code examples
javascriptrhighchartsdrilldown

How to make 3 levels drilldown plot in R highcharter (possible other packages)


today i started my adventure with highcharter package. I'm interested in drilldown plots.

(fast check what i want to create without r)

http://jsfiddle.net/gh/get/jquery/1.7.2/highslide-software/highcharts.com/tree/master/samples/highcharts/drilldown/basic/

R code with working example of drilldown plot with 2 levels.

library("dplyr")
library("purrr")
library("highcharter")

df <- data_frame(
  name = c("Animals", "Fruits", "Cars"),
  y = c(5, 2, 4),
  drilldown = tolower(name)
)
df


ds <- list.parse3(df)
names(ds) <- NULL
str(ds)
hc <- highchart() %>%
  hc_chart(type = "column") %>%
  hc_title(text = "Basic drilldown") %>%
  hc_xAxis(type = "category") %>%
  hc_legend(enabled = FALSE) %>%
  hc_plotOptions(
    series = list(
      boderWidth = 0,
      dataLabels = list(enabled = TRUE)
    )
  ) %>%
  hc_add_series(
    name = "Things",
    colorByPoint = TRUE,
    data = ds
  )


dfan <- data_frame(
  name = c("Cats", "Dogs", "Cows", "Sheep", "Pigs"),
  value = c(4, 3, 1, 2, 1)
)
dffru <- data_frame(
  name = c("Apple", "Organes"),
  value = c(4, 2)
)
dfcar <- data_frame(
  name = c("Toyota", "Opel", "Volkswage"),
  value = c(4, 2, 2)
)
second_el_to_numeric <- function(ls){
  map(ls, function(x){
    x[[2]] <- as.numeric(x[[2]])
    x
  })
}
dsan <- second_el_to_numeric(list.parse2(dfan))
dsfru <- second_el_to_numeric(list.parse2(dffru))
dscar <- second_el_to_numeric(list.parse2(dfcar))
hc <- hc %>%
  hc_drilldown(
    allowPointDrilldown = TRUE,
    series = list(
      list(
        id = "animals",
        data = dsan
      ),
      list(
        id = "fruits",
        data = dsfru
      ),
      list(
        id = "cars",

        data = dscar
      )
    )
  )
hc

My aim is to create drilldown plots with more than 2 levels. I know this is possible (On javascrip Highchart page there is 3 level example but written in js).

library("dplyr")
library("purrr")
library("highcharter")


df <- data_frame(
  name = c("Animals", "Fruits", "Cars"),
  y = c(5, 2, 4),
  drilldown = tolower(name)
)
df


ds <- list.parse3(df)
names(ds) <- NULL
str(ds)


hc <- highchart() %>%
  hc_chart(type = "column") %>%
  hc_title(text = "Basic drilldown") %>%
  hc_xAxis(type = "category") %>%
  hc_legend(enabled = FALSE) %>%
  hc_plotOptions(
    series = list(
      boderWidth = 0,
      dataLabels = list(enabled = TRUE)
      )
  ) %>%
  hc_add_series(
    name = "Things",
    colorByPoint = TRUE,
    data = ds
  )


dfan <- data_frame(
  name = c("Cats", "Dogs", "Cows", "Sheep", "Pigs"),
  value = c(4, 3, 1, 2, 1)

)
dffru <- data_frame(
  name = c("Apple", "Oranges"),
  value = c(4, 2)
)
dfcar <- data_frame(
  name = c("Toyota", "Opel", "Volkswage"),
  value = c(4, 2, 2),
  drilldown = tolower(name)
)


dfOpel <- data_frame(
  name = c("Insygnia", "Corsa"),
  value = c(1,2)
)


second_el_to_numeric <- function(ls){
  map(ls, function(x){
    x[[2]] <- as.numeric(x[[2]])
    x
  })
}
dsan <- second_el_to_numeric(list.parse2(dfan))
dsfru <- second_el_to_numeric(list.parse2(dffru))
dscar <- second_el_to_numeric(list.parse3(dfcar))
names(dscar) <- NULL

dsOpel <- second_el_to_numeric(list.parse3(dfOpel))
names(dsOpel)

hc <- hc %>%
  hc_drilldown(
    allowPointDrilldown = TRUE,
    series = list(
      list(
        id = "animals",
        data = dsan
      ),
      list(
        id = "fruits",
        data = dsfru
      ),
      list(
        id = "cars",
        data = dscar
      )
    ),
#My idea of change.
    series2 = list(
      list(id = "toyota", data = dsOpel),
      list(id = "opel", data = dsOpel),
      list(id = "volkswage", data = dsOpel)
    )
  )


hc

In highcharter reference manual there is only example with 2 levels (https://cran.r-project.org/web/packages/highcharter/highcharter.pdf)


Solution

  • If you want a multilevel drilldown you have to set id of the drilldown to the data point just like in the pure js highcharts.

    Example: http://jsfiddle.net/6LXVQ/2/ and the most important part:

    drilldown: {
            series: [{
                id: 'animals',
                name: 'Animals',
                data: [{
                    name: 'Cats',
                    y: 4,
                    drilldown: 'cats'
                }, ['Dogs', 2],
                    ['Cows', 1],
                    ['Sheep', 2],
                    ['Pigs', 1]
                ]
            }, {
    
                id: 'cats',
                data: [1, 2, 3]
            }]
        }
    

    You can see here that your data points are not only numbers but objects which containts link to the drilldown series.

    An example using Highcharter - simplified but you should get the idea:

    hc <- highchart() %>%
        hc_chart(type="column") %>%
        hc_xAxis(type="category") %>%
        hc_add_series(
            name = "Things",
            data = list(
                list(
                    name = "Animals",
                    y = 10,
                    drilldown = "animals"
                )
            )
        ) %>%
    
        hc_drilldown(
            series = list(
                list(
                    name = "Animals",
                    id = "animals",
                    data = list(
                        list(
                            name = "Cats",
                            y = 2,
                            drilldown = "cats"
                        )
                    )
                 ),
                 list(
                     name = "Cats",
                     id = "cats",
                     data = list(list(name = "white cats", y = 2), list(name = "black cats", y = 3), list(name = "red cats",y = 4))
                 )
             )
         )
    hc