0
votes

I want to change the x-axis type from datetime to category. For example: Primary Chart would be a line chart by group and drilldown chart would be a column chart.

There is a solution given in Highcharts (Highcharts, Can you change the chart type for drilldowns?, Highcharts chart with 'datetime' xAxis - use categories on drilldown) but I'm not able to translate it to R.

PFB the code.

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

df <- data_frame(
  car_brand = c("Hyundai","Hyundai","Hyundai", "Benz","Benz","Benz", "Tesla","Tesla","Tesla"),
  units_sold = c(10,15,20,11,8,13,6,5,7),
  date = c("2019-01-01", "2019-02-01","2019-03-01","2019-01-01","2019-02-01","2019-03-01","2019-01-01","2019-02-01","2019-03-01")
)

df$units_sold <- as.numeric(df$units_sold)
df$date <- as.Date(df$date)
df$drilldown <- paste(df$car_brand, ",", df$date)
carBrands<- df %>%
  select(date, car_brand)

getCarDetails<- function(brands){

  carList <- list()
  listofdfs <- list() #Create a list in which you intend to save your df's.

  for(i in 1:nrow(brands)){ #Loop through the numbers of ID's instead of the ID's

    #You are going to use games[i] instead of i to get the ID
    BrandCarData <- data_frame(
      car = c("H1","H2","H3","H4","H5"),
      units = c(1,2,3,4,5)
    )
    BrandCarData$units <- as.numeric(BrandCarData$units)
    dsCar <- list_parse2(BrandCarData)
    listofdfs[[i]] <- dsCar
    carList[[i]] <- list (name = brands[[2]][i],
                          type = "column",
                          id = paste(brands[[2]][i], ",", brands[[1]][i]),
                          data = listofdfs[[i]])
  }

  return(carList) #Return the list of dataframes.
}

listCar <- getCarDetails(brands = carBrands)

dfDates <- NULL
dfDates$Date <- datetime_to_timestamp(as.Date(df$date, format = "%Y-%m-%d"))
hc <- hchart(df,"line", hcaes(x=date, y =
                                units_sold, group
                              = car_brand )) %>%
  hc_xAxis(categories = dfDates$Date, title = list(text = "<b>Date</b>"), type = "datetime") %>%
  hc_plotOptions(column = list(dataLabels = list(enabled = FALSE), enableMouseTracking = TRUE))%>%
  hc_tooltip(borderWidth = 1.5,
             pointFormat = paste('<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>')) %>%
  hc_legend(enabled = TRUE) %>%
  hc_title(text = "Brand Units Sold Monthy Trend",
           style = list(fontSize = "12px", fontWeight = "bold")) %>%
  hc_yAxis(title = list(text = "<b>Units <br>(In Thousands)</br></b>"))
hc

hc1 <- hc %>%
  hc_drilldown(allowPointDrilldown = TRUE,
               series = listCar)
hc1

Brand-wise Units Sold Monthly Trend

Units Sold for Each Car Model

As can be seen from the attached graphs, the x-axis of second chart is still showing x-axis labels in datetime format.

Any suggestions?

2

2 Answers

0
votes

Similar question: Drilldown to multiple series from different groups - Highcharter (in R)

You can also find similar Highcharts drilldown examples in R (Highcharter) here: https://stackoverflow.com/users/8618934/raf18seb?tab=answers

edit: I copied/pasted code from my link above and added just one line "type: 'column'". Here is a working example of drilldown from line to column:

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

df <- tibble(x = c(1, 2, 3, 2, 3, 4, 3, 5, 4), y = c(1, 2, 1, 3, 3, 2, 4, 6, 5), key = c(rep("A", 3), rep("B", 3), rep("C", 3)),
             drilldown = c(rep("a", 3), rep("b", 3), rep("c", 3)))

drill1 <- data.frame(
  x = c(1,2,3),
  y = c(3, 3, 1)
)
drill1 <- list_parse2(drill1)

drill2 <- data.frame(
  x = c(1,2,4),
  y = c(1, 5, 1)
)
drill2 <- list_parse2(drill2)

drill3 <- data.frame(
  x = c(1,2,4),
  y = c(4, 3, 1)
)
drill3 <- list_parse2(drill3)


hchart(df, "line", 
       hcaes(x = x, y = y, group = key),
       color = c("#A63A50", "#37123C", "#DDA77B"),
       drilldown = TRUE) %>% 
  hc_chart(events = list(drilldown = JS("function(e) {
            e.preventDefault()
            var chart = this,
              series = [{
                type: 'column',
                data: [5, 5, 5, 3, 2]
              }, {
              type: 'column',
                data: [3, 3, 7, 3, 3]
              }];

            chart.addSingleSeriesAsDrilldown(e.point, series[0]);
            chart.addSingleSeriesAsDrilldown(e.point, series[1]);
            chart.applyDrilldown();
        }"))) %>% 
  hc_plotOptions(line = list(marker = list(enabled = FALSE), legendIndex = 1)) %>% 
  hc_drilldown(
    allowPointDrilldown = TRUE,
    series = list(
      list(
        id = "a",
        data = drill1
      ),
      list(
        id = "b",
        data = drill2
      ),
      list(
        id = "c",
        data = drill3
      )
    )
  )

edit 2:

Here is a code that will allow you to change the xAxis' type to category after drilldown:

hc_chart(events = list(drilldown = JS("function(){
    this.xAxis[0].update({
      categories: ['aaa', 'bbb', 'ccc']
    });
  }"))) %>%

API Reference: https://api.highcharts.com/highcharts/chart.events.drilldown https://api.highcharts.com/class-reference/Highcharts.Axis#update https://api.highcharts.com/highcharts/xAxis.categories

0
votes

Based on raf18seb's inputs, I have found the solution to customizing the x-Axis labels on the drilldown. In addition to that, I will also be sharing how to change title of the chart and axes.

In my earlier code, I was specifying the x-Axis type in hc_xAxis as show in the code below:

hc_xAxis(categories = dfDates$Date, title = list(text = "<b>Date</b>"), type = "datetime") 

This was the main cause of the issue. You should not specify the category at primary level, instead, specify the category type at drilldown level. Please find the modified code below:

getCarDetails<- function(brands){
  //This function can also be used to dynamically populate the data for drilldown //chart instead of specifiying it inside a JS code.
  carList <- list()
  listofdfs <- list() 
  for(i in 1:nrow(brands)){ 
    BrandCarData <- data_frame(
      car = c("H1","H2","H3","H4","H5"),
      units = c(1,2,3,4,5)
    )
    BrandCarData$units <- as.numeric(BrandCarData$units)
    dsCar <- list_parse2(BrandCarData)
    listofdfs[[i]] <- dsCar
    carList[[i]] <- list (name = brands[[2]][i],
                          type = "column", //Specify the xAxis category type
                          id = paste(brands[[2]][i], ",", brands[[1]][i]),
                          data = listofdfs[[i]])
  }

  return(carList) #Return the list of dataframes.
}

Now, in the code below, I have also added the code to change the title of chart and axes on drilldown and drillup.

hchart(df,"line", hcaes(x=format(as.Date(date), "%b,%Y"), y =
                                 units_sold, group
                               = car_brand )
) %>%
  hc_drilldown(allowPointDrilldown = TRUE,
               series = listCar)%>%
  hc_chart(events=list(drilldown=JS('function(e) 
                                      {
                                       this.setTitle({text: "Units Distribution Across Cars"});
                                       this.yAxis[0].axisTitle.attr({ text: "Units (in Thousands)"});
                                       this.xAxis[0].axisTitle.attr({ text: "Car Types" });
                                    }'),
                       drillup = JS("function() {this.update({title: {text: 'Brand-wise Units Sold Monthy Trend' }});
                                                 this.xAxis[0].setTitle({ text: 'Date' });
            this.yAxis[0].setTitle({ text: 'Units Sold (in Thousands)' });}")
  ))%>%
  hc_xAxis(title = list(text = "<b>Date</b>")) %>%
  hc_plotOptions(column = list(dataLabels = list(enabled = FALSE), enableMouseTracking = TRUE))%>%
  hc_tooltip(borderWidth = 1.5,
             pointFormat = paste('<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b><br/>')) %>%
  hc_legend(enabled = TRUE) %>%
  hc_title(text = "Brand-wise Units Sold Monthy Trend",
           style = list(fontSize = "12px", fontWeight = "bold"))%>%
  hc_yAxis(title = list(text = "<b>Units <br>(In Thousands)</br></b>"))

Hope anyone who faces this issue in the future will find this useful.