diff --git a/DESCRIPTION b/DESCRIPTION index 73cf983..3f091ed 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -24,7 +24,9 @@ Suggests: dplyr, knitr, rmarkdown, - shiny + shiny, + gapminder, + highcharter RoxygenNote: 6.1.1 URL: https://github.com/dreamRs/apexcharter BugReports: https://github.com/dreamRs/apexcharter/issues diff --git a/inst/examples/advanced-configuration.R b/inst/examples/advanced-configuration.R index 0d08af2..ca46164 100644 --- a/inst/examples/advanced-configuration.R +++ b/inst/examples/advanced-configuration.R @@ -15,11 +15,7 @@ data("mpg", package = "ggplot2") count(mpg, class) %>% mutate(pct = n/sum(n)) %>% apex(mapping = aes(class, pct), type = "column") %>% - ax_colors("#617a89") %>% - ax_labs( - title = "Seminal ggplot2 column chart example with percents", - subtitle = "Example taken from {hrbrthemes} readme" - ) %>% + ax_colors("#617a89")%>% ax_yaxis( title = list(text = "Weight (tons)"), labels = list( @@ -29,6 +25,9 @@ count(mpg, class) %>% ), tickAmount = 6 ) %>% + ax_xaxis( + title = list(text = "Fuel efficiency (mpg)") + ) %>% ax_tooltip( y = list( title = list( @@ -36,9 +35,10 @@ count(mpg, class) %>% ) ) ) %>% - ax_xaxis( - title = list(text = "Fuel efficiency (mpg)") - ) %>% + ax_labs( + title = "Seminal ggplot2 column chart example with percents", + subtitle = "Example taken from {hrbrthemes} readme" + ) %>% ax_title( style = list(fontSize = "22px") ) %>% @@ -62,15 +62,24 @@ unhcr_ts %>% apex(aes(date, n, group = continent_origin), type = "line") %>% ax_legend(position = "bottom") %>% ax_stroke(width = 2) %>% - ax_colors("#440154", "#414487", "#2A788E", "#22A884", "#7AD151", - "#FDE725") %>% + ax_colors("#440154", "#414487", "#2A788E", + "#22A884", "#7AD151", "#FDE725") %>% ax_yaxis( labels = list( - formatter = htmlwidgets::JS("function(val) {return (val/1e6).toFixed(0);}") + formatter = JS("function(val) {return (val/1e6).toFixed(0);}") ), title = list(text = "Number of refugees (in million)") ) %>% - ax_xaxis(type = "datetime", labels = list(format = "yyyy")) %>% + ax_xaxis(labels = list(format = "yyyy")) %>% + ax_tooltip( + x = list(format = "yyyy"), + y = list( + formatter = JS( + # thousand separator in javascript + "function(value) {return value.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");}" + ) + ) + ) %>% ax_annotations( points = list( list( @@ -81,15 +90,6 @@ unhcr_ts %>% ) ) ) %>% - ax_tooltip( - x = list(format = "yyyy"), - y = list( - formatter = JS( - # thousand separator in javascript - "function(value) {return value.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");}" - ) - ) - ) %>% ax_labs( title = "Continent of origin for refugees population", subtitle = "Data from the UN Refugee Agency" @@ -109,7 +109,6 @@ unhcr_ts %>% data("gapminder", package = "gapminder") - gapminder %>% filter(year == 2007) %>% mutate( @@ -127,7 +126,11 @@ gapminder %>% title = list(text = "life expectancy at birth (in years)") ) %>% ax_xaxis( - tickAmount = 8, tooltip = list(enabled = FALSE), + tickAmount = 8, + labels = list( + formatter = JS("function(val) {return val.toFixed(2);}") + ), + tooltip = list(enabled = FALSE), title = list(text = "GDP per capita (log-scale)") ) %>% ax_grid(xaxis = list(lines = list(show = TRUE))) %>% @@ -202,13 +205,6 @@ data("vaccines", package = "highcharter") apex(vaccines, aes(year, state, fill = count), type = "heatmap") %>% ax_chart(animations = list(enabled = FALSE)) %>% ax_dataLabels(enabled = FALSE) %>% - ax_legend( - formatter = JS( - "function(seriesName, opts) { - if (seriesName == 'Missing') return null; else return seriesName; - }" - ) - ) %>% ax_stroke(width = 0) %>% ax_plotOptions( heatmap = heatmap_opts( @@ -254,6 +250,19 @@ apex(vaccines, aes(year, state, fill = count), type = "heatmap") %>% ) ) ) %>% + ax_legend( + formatter = JS( + "function(seriesName, opts) { + if (seriesName == 'Missing') return null; else return seriesName; + }" + ) + ) %>% + ax_yaxis( + labels = list( + style = list(fontSize = "8px"), + offsetY = -20 + ) + ) %>% ax_annotations( xaxis = list( list( @@ -264,7 +273,6 @@ apex(vaccines, aes(year, state, fill = count), type = "heatmap") %>% fillColor = "firebrick", label = list( borderColor = "firebrick", - style = list(color = "#FFF", background = "firebrick"), text = "Vaccine Intoduced", orientation = "horizontal", diff --git a/vignettes/advanced-configuration.Rmd b/vignettes/advanced-configuration.Rmd new file mode 100644 index 0000000..689c3d4 --- /dev/null +++ b/vignettes/advanced-configuration.Rmd @@ -0,0 +1,835 @@ +--- +title: "Advanced configuration examples" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Advanced configuration examples} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>" +) +``` + +```{r setup, message=FALSE, warning=FALSE} +library(apexcharter) +library(dplyr) +``` + + +Here some advanced configuration examples to use the full potential of [ApexCharts](https://apexcharts.com/). + + + +# Bar chart + +This example is taken from [{hrbrthemes}](https://github.com/hrbrmstr/hrbrthemes) readme, it use `mpg` dataset from [{ggplot2}](https://github.com/tidyverse/ggplot2). + + +Tranform data and initialize the chart : + +```{r} +data("mpg", package = "ggplot2") + +bars <- count(mpg, class) %>% + mutate(pct = n/sum(n)) %>% + apex(mapping = aes(class, pct), type = "column") +``` + +Change color used : + +```{r} +bars <- bars %>% + ax_colors("#617a89") +``` + +Modify the y-axis and add a percent symbol after the labels : + +```{r} +bars <- bars %>% + ax_yaxis( + title = list(text = "Weight (tons)"), + labels = list( + formatter = JS( + "function(value) {return Math.round(value * 100) + '%';}" + ) + ), + tickAmount = 6 + ) +``` + +Add a title to the x-axis : + +```{r} +bars <- bars %>% + ax_xaxis( + title = list(text = "Fuel efficiency (mpg)") + ) +``` + + +Modify the tooltip to display "Percentage" instead of the variable name "pct" : + +```{r} +bars <- bars %>% + ax_tooltip( + y = list( + title = list( + formatter = JS("function() {return 'Percentage';}") + ) + ) + ) +``` + +Add title and subtitle and format them : + +```{r} +bars <- bars %>% + ax_labs( + title = "Seminal ggplot2 column chart example with percents", + subtitle = "Example taken from {hrbrthemes} readme" + ) %>% + ax_title( + style = list(fontSize = "22px") + ) %>% + ax_subtitle( + style = list(fontSize = "16px", color = "#BDBDBD") + ) +``` + +Final result looks like : + +```{r} +bars +``` + +
+View full code + +```{r, eval=FALSE} +data("mpg", package = "ggplot2") + +count(mpg, class) %>% + mutate(pct = n/sum(n)) %>% + apex(mapping = aes(class, pct), type = "column") %>% + ax_colors("#617a89")%>% + ax_yaxis( + title = list(text = "Weight (tons)"), + labels = list( + formatter = JS( + "function(value) {return Math.round(value * 100) + '%';}" + ) + ), + tickAmount = 6 + ) %>% + ax_xaxis( + title = list(text = "Fuel efficiency (mpg)") + ) %>% + ax_tooltip( + y = list( + title = list( + formatter = JS("function() {return 'Percentage';}") + ) + ) + ) %>% + ax_labs( + title = "Seminal ggplot2 column chart example with percents", + subtitle = "Example taken from {hrbrthemes} readme" + ) %>% + ax_title( + style = list(fontSize = "22px") + ) %>% + ax_subtitle( + style = list(fontSize = "16px", color = "#BDBDBD") + ) +``` + +
+ +
+
+ + +# Lines + +Dataset used is from the UNHCR (The UN Refugee Agency) and contains data about UNHCR's populations of concern summarised by continent of orginin. + +Tranform data and initialize the chart : + +```{r} +data("unhcr_ts") + +lines <- unhcr_ts %>% + filter(population_type == "Refugees (incl. refugee-like situations)") %>% + mutate(date = as.Date(paste0(year, "-01-01"))) %>% + apex(aes(date, n, group = continent_origin), type = "line") +``` + +Put the legend at the bottom : + +```{r} +lines <- lines %>% + ax_legend(position = "bottom") +``` + +Change the width of the lines : + +```{r} +lines <- lines %>% + ax_stroke(width = 2) +``` + +Change the colors (Viridis palette) : + +```{r} +lines <- lines %>% + ax_colors("#440154", "#414487", "#2A788E", + "#22A884", "#7AD151", "#FDE725") +``` + +Data are in million, in the y-axis we divide by `1e6` to limit the number of digits : + +```{r} +lines <- lines %>% + ax_yaxis( + labels = list( + formatter = JS("function(val) {return (val/1e6).toFixed(0);}") + ), + title = list(text = "Number of refugees (in million)") + ) +``` + +Only display the years in the x-axis labels : + +```{r} +lines <- lines %>% + ax_xaxis(labels = list(format = "yyyy")) +``` + +Same in tooltip, and a thousand separator in the value displayed : + +```{r} +lines <- lines %>% + ax_tooltip( + x = list(format = "yyyy"), + y = list( + formatter = JS( + # thousand separator in javascript + "function(value) {return value.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");}" + ) + ) + ) +``` + +Add an annotation to the chart to identify the [Great Lakes refugee crisis](https://en.wikipedia.org/wiki/Great_Lakes_refugee_crisis) in 1994 : + +```{r} +lines <- lines %>% + ax_annotations( + points = list( + list( + x = JS("new Date('1994').getTime()"), + y = 6935296, + label = list(text = "Great Lakes refugee crisis", offsetY = 0), + marker = list(size = 6) + ) + ) + ) +``` + +Add title and subtitle and format them : + +```{r} +lines <- lines %>% + ax_labs( + title = "Continent of origin for refugees population", + subtitle = "Data from the UN Refugee Agency" + ) %>% + ax_title( + style = list(fontSize = "22px") + ) %>% + ax_subtitle( + style = list(fontSize = "16px", color = "#BDBDBD") + ) +``` + + +Final result looks like : + +```{r} +lines +``` + +
+View full code + +```{r, eval=FALSE} +data("unhcr_ts") + +unhcr_ts %>% + filter(population_type == "Refugees (incl. refugee-like situations)") %>% + mutate(date = as.Date(paste0(year, "-01-01"))) %>% + apex(aes(date, n, group = continent_origin), type = "line") %>% + ax_legend(position = "bottom") %>% + ax_stroke(width = 2) %>% + ax_colors("#440154", "#414487", "#2A788E", + "#22A884", "#7AD151", "#FDE725") %>% + ax_yaxis( + labels = list( + formatter = htmlwidgets::JS("function(val) {return (val/1e6).toFixed(0);}") + ), + title = list(text = "Number of refugees (in million)") + ) %>% + ax_xaxis(labels = list(format = "yyyy")) %>% + ax_tooltip( + x = list(format = "yyyy"), + y = list( + formatter = JS( + # thousand separator in javascript + "function(value) {return value.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\");}" + ) + ) + ) %>% + ax_annotations( + points = list( + list( + x = JS("new Date('1994').getTime()"), + y = 6935296, + label = list(text = "Great Lakes refugee crisis", offsetY = 0), + marker = list(size = 6) + ) + ) + ) %>% + ax_labs( + title = "Continent of origin for refugees population", + subtitle = "Data from the UN Refugee Agency" + ) %>% + ax_title( + style = list(fontSize = "22px") + ) %>% + ax_subtitle( + style = list(fontSize = "16px", color = "#BDBDBD") + ) +``` + +
+ +
+
+ +# Scatter plot + +Dataset used is from [{gapminder}](https://github.com/jennybc/gapminder). + +Tranform data and initialize the chart : + +```{r} +data("gapminder", package = "gapminder") + +scatter <- gapminder %>% + filter(year == 2007) %>% + mutate( + gdpPercap = log(gdpPercap), + pop = sqrt(pop / pi) / 1500 + ) %>% + apex( + mapping = aes(gdpPercap, + lifeExp, + z = pop, + group = continent, + label = country), + type = "scatter", + height = "500px" + ) +``` + +Enable zoom on both axis : + +```{r} +scatter <- scatter %>% + ax_chart(zoom = list( + enabled = TRUE, type = "xy" + )) +``` + + +Show y-axis border and ticks, no decimals in labels : + +```{r} +scatter <- scatter %>% + ax_yaxis( + decimalsInFloat = 0, + axisBorder = list(show = TRUE), + axisTicks = list(show = TRUE), + title = list(text = "life expectancy at birth (in years)") + ) +``` + +Configuration for x-axis, hide the tooltip displayed on the axis itself (not the main tooltip), dispaly two decimals in the labels (useful when zooming, since values are logarithm there's a lot of decimals) : + +```{r} +scatter <- scatter %>% + ax_xaxis( + tickAmount = 8, + labels = list( + formatter = JS("function(val) {return val.toFixed(2);}") + ), + tooltip = list(enabled = FALSE), + title = list(text = "GDP per capita (log-scale)") + ) +``` + +Display vertical grid lines (on the x-axis, those on the y-axis are enabled by default) : + +```{r} +scatter <- scatter %>% + ax_grid(xaxis = list(lines = list(show = TRUE))) +``` + + +Legend on the right and slightly offset downwards : + +```{r} +scatter <- scatter %>% + ax_legend(position = "right", offsetY = 70) +``` + +Adjust the effect when hovering points : + +```{r} +scatter <- scatter %>% + ax_markers(hover = list(sizeOffset = 0, size = 25)) +``` + +Add a custom tooltip with an HTML string, data used in aesthetic can be accessed in JavaScrip with `w.config.series[seriesIndex].data[dataPointIndex].x` (x is the variable `gdpPercap`), or `w.config.series[seriesIndex].data[dataPointIndex].label` (the country), it's possible to use custom aesthetics to include more data in the chart configuration script. + +```{r} +scatter <- scatter %>% + ax_tooltip(custom = JS(paste( + "function({ series, seriesIndex, dataPointIndex, w }) {", + "console.log(w); return (", + "'
' +", + + "'
' +", + "w.config.series[seriesIndex].data[dataPointIndex].label", + "+ '
' +", + "'
' +", + "'
' +", + + "'' +", + "'Population: ' +", + "'' +", + "'' +", + "Math.round(Math.pow(w.config.series[seriesIndex].data[dataPointIndex].z * 1500, 2) * Math.PI). + toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\") +", + "'' +", + + "'
' +", + + "'' +", + "'GDP per capita: ' +", + "'' +", + "'' +", + "Math.round(Math.exp(w.config.series[seriesIndex].data[dataPointIndex].x)) +", + "'' +", + + "'
' +", + + "'' +", + "'Life expectancy: ' +", + "'' +", + "'' +", + "w.config.series[seriesIndex].data[dataPointIndex].y +", + "'' +", + + + "'
' +", + "'
' +", + + "'
'", + ");", + "}", sep = "\n" + ))) +``` + +Add title and subtitle and format them : + +```{r} +scatter <- scatter %>% + ax_labs( + title = "Life expectancy, GDP and population", + subtitle = "gapminder dataset from {gapminder}" + ) %>% + ax_title( + style = list(fontSize = "22px") + ) %>% + ax_subtitle( + style = list(fontSize = "16px", color = "#BDBDBD") + ) +``` + +Final result looks like : + +```{r} +scatter +``` + +
+View full code + +```{r, eval=FALSE} +data("gapminder", package = "gapminder") + +gapminder %>% + filter(year == 2007) %>% + mutate( + gdpPercap = log(gdpPercap), + pop = sqrt(pop / pi) / 1500 + ) %>% + apex(mapping = aes(gdpPercap, lifeExp, z = pop, group = continent, label = country), type = "scatter") %>% + ax_chart(zoom = list( + enabled = TRUE, type = "xy" + )) %>% + ax_yaxis( + decimalsInFloat = 0, + axisBorder = list(show = TRUE), + axisTicks = list(show = TRUE), + title = list(text = "life expectancy at birth (in years)") + ) %>% + ax_xaxis( + tickAmount = 8, + labels = list( + formatter = JS("function(val) {return val.toFixed(2);}") + ), + tooltip = list(enabled = FALSE), + title = list(text = "GDP per capita (log-scale)") + ) %>% + ax_grid(xaxis = list(lines = list(show = TRUE))) %>% + ax_legend(position = "right", offsetY = 70) %>% + ax_markers(hover = list(sizeOffset = 0, size = 25)) %>% + ax_tooltip(custom = JS(paste( + "function({ series, seriesIndex, dataPointIndex, w }) {", + "console.log(w); return (", + "'
' +", + + "'
' +", + "w.config.series[seriesIndex].data[dataPointIndex].label", + "+ '
' +", + "'
' +", + "'
' +", + + "'' +", + "'Population: ' +", + "'' +", + "'' +", + "Math.round(Math.pow(w.config.series[seriesIndex].data[dataPointIndex].z * 1500, 2) * Math.PI). + toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, \",\") +", + "'' +", + + "'
' +", + + "'' +", + "'GDP per capita: ' +", + "'' +", + "'' +", + "Math.round(Math.exp(w.config.series[seriesIndex].data[dataPointIndex].x)) +", + "'' +", + + "'
' +", + + "'' +", + "'Life expectancy: ' +", + "'' +", + "'' +", + "w.config.series[seriesIndex].data[dataPointIndex].y +", + "'' +", + + + "'
' +", + "'
' +", + + "'
'", + ");", + "}", sep = "\n" + ))) %>% + ax_labs( + title = "Life expectancy, GDP and population", + subtitle = "gapminder dataset from {gapminder}" + ) %>% + ax_title( + style = list(fontSize = "22px") + ) %>% + ax_subtitle( + style = list(fontSize = "16px", color = "#BDBDBD") + ) +``` + +
+ +
+
+ +# Heatmap + +This is an adaption of this fancy [{highcharter} example](http://jkunst.com/highcharter/showcase.html), based from this [WSJ visualisation](http://graphics.wsj.com/infectious-diseases-and-vaccines/). + + +```{r} +data("vaccines", package = "highcharter") + +heatmap <- apex( + vaccines, + aes(year, state, fill = count), + type = "heatmap", + height = "800px" +) +``` + +Remove the animations (little slow otherwise) : + +```{r} +heatmap <- heatmap %>% + ax_chart(animations = list(enabled = FALSE)) +``` + +Remove values displayed in the heatmap : + +```{r} +heatmap <- heatmap %>% + ax_dataLabels(enabled = FALSE) +``` + +Remove space between squared of the heatmap : + +```{r} +heatmap <- heatmap %>% + ax_stroke(width = 0) +``` + +That's not possible to make a continuous scale in the legend (like with highcharter), so we use breakpoints : + +```{r} +heatmap <- heatmap %>% + ax_plotOptions( + heatmap = heatmap_opts( + radius = 0, + enableShades = FALSE, + colorScale = list( + ranges = list( + list( + from = 0, + to = 0.001, + name = "Missing", + color = "#FFF" + ), + list( + from = 0.001, + to = 4, + name = "low", + # color = "#000004" + color = "#FDE725" + ), + list( + from = 4, + to = 70, + name = "mid-low", + # color = "#781C6D", + color = "#35B779" + ), + list( + from = 70, + to = 290, + name = "mid-high", + # color = "#ED6925", + color = "#31688E" + ), + list( + from = 290, + to = 3000, + name = "high", + # color = "#FCFFA4", + color = "#440154" + ) + ) + ) + ) + ) +``` + +Missing values are colored by default, above we set them to be displayed in white, and now we hide the corresponding legend : + +```{r} +heatmap <- heatmap %>% + ax_legend( + formatter = JS( + "function(seriesName, opts) { + if (seriesName == 'Missing') return null; else return seriesName; + }" + ) + ) +``` + +Set size of the y-axis labels : + +```{r} +heatmap <- heatmap %>% + ax_yaxis( + labels = list( + style = list(fontSize = "8px") + ) + ) +``` + +Add a vertical line to identify the year when the vaccine was intrtoduced : + +```{r} +heatmap <- heatmap %>% + ax_annotations( + xaxis = list( + list( + x = 1963, x2 = 1963.1, + strokeDashArray = 0, + opacity = 1, + borderColor = "firebrick", + fillColor = "firebrick", + label = list( + borderColor = "firebrick", + style = list(color = "#FFF", background = "firebrick"), + text = "Vaccine Intoduced", + orientation = "horizontal", + position = "bottom", + offsetY = 10 + ) + ) + ) + ) +``` + +As usual, add title and subtitle and format them : + +```{r} +heatmap <- heatmap %>% + ax_labs( + title = "Infectious Diseases and Vaccines", + subtitle = "vaccines dataset from {highcharter}" + ) %>% + ax_title( + style = list(fontSize = "22px") + ) %>% + ax_subtitle( + style = list(fontSize = "16px", color = "#BDBDBD") + ) +``` + +Final result looks like : + +```{r} +heatmap +``` + +
+View full code + +```{r, eval=FALSE} +data("vaccines", package = "highcharter") + +apex(vaccines, aes(year, state, fill = count), type = "heatmap") %>% + ax_chart(animations = list(enabled = FALSE)) %>% + ax_dataLabels(enabled = FALSE) %>% + ax_stroke(width = 0) %>% + ax_plotOptions( + heatmap = heatmap_opts( + radius = 0, + enableShades = FALSE, + colorScale = list( + ranges = list( + list( + from = 0, + to = 0.001, + name = "Missing", + color = "#FFF" + ), + list( + from = 0.001, + to = 4, + name = "low", + # color = "#000004" + color = "#FDE725" + ), + list( + from = 4, + to = 70, + name = "mid-low", + # color = "#781C6D", + color = "#35B779" + ), + list( + from = 70, + to = 290, + name = "mid-high", + # color = "#ED6925", + color = "#31688E" + ), + list( + from = 290, + to = 3000, + name = "high", + # color = "#FCFFA4", + color = "#440154" + ) + ) + ) + ) + ) %>% + ax_legend( + formatter = JS( + "function(seriesName, opts) { + if (seriesName == 'Missing') return null; else return seriesName; + }" + ) + ) %>% + ax_yaxis( + labels = list( + style = list(fontSize = "8px"), + offsetY = -20 + ) + ) %>% + ax_annotations( + xaxis = list( + list( + x = 1963, x2 = 1963.1, + strokeDashArray = 0, + opacity = 1, + borderColor = "firebrick", + fillColor = "firebrick", + label = list( + borderColor = "firebrick", + style = list(color = "#FFF", background = "firebrick"), + text = "Vaccine Intoduced", + orientation = "horizontal", + position = "bottom", + offsetY = 10 + ) + ) + ) + ) %>% + ax_labs( + title = "Infectious Diseases and Vaccines", + subtitle = "vaccines dataset from {highcharter}" + ) %>% + ax_title( + style = list(fontSize = "22px") + ) %>% + ax_subtitle( + style = list(fontSize = "16px", color = "#BDBDBD") + ) +``` + +
+ + + +