#' @title Create a Google Combo Chart
#'
#' @description Creates a Combo Chart using the googleVis R package
#'
#' @param table A \code{character}. The name of the table from which the data should be retrieved
#' @param targetVar A \code{character}. The name of the column with the vertical axis variable.
#' @param groupVar A \code{character}. The name of the column with the variable by which \code{targetVar} should be grouped
#' @param timeVar A \code{character}. The name of the column with the horizontal axis variable
#' @param min A \code{numeric} value or a \code{date string} in the format 'yyyy-mm-dd'. Lower bound for the \code{timeVar}
#' @param max A \code{numeric} value or a \code{date string} in the format 'yyyy-mm-dd'. Upper bound for the \code{timeVar}
#' @param lineVar A \code{character}. The name of the column with the variable that should be used to draw a line according to an operation.
#' @param operation A \code{charater}. The operation that should be used to draw the line. Please check the \code{\link{applyOperation}} documentation for more information.
#' @param restrictions A n x 2 \code{matrix}. The n equality restrictions that make timeVar and groupVar values unique when combined.
#' @param alternatives A n x 2 \code{matrix}. Alternative values of a column (joined by 'or' conditions in a SQL query). The first column must contain the names of the columns. The second, its values.
#' @param filename A \code{character}. The name of the .html file where the chart should be printed. The extension (.html) is not needed.
#'
#' @return A \code{character vector} if the chart was successfully created, with the name of two files: the .html file where the chart was printed and the .csv file where the source data was saved.
#' Otherwise, an error string returned by one of validation functions listed under the 'Parameters validation' section.
#'
#' @section Parameters validation:
#' The parameters are checked according to the rules estabilished in validation functions and in the following order:
#' \enumerate{
#' \item targetVar, groupVar, timeVar, min, max, restrictions: \code{\link{validateGoogleChartParameters}}
#' \item lineVar: \code{\link{validateTargetVariables}} and \code{\link{validateConsistency}}.
#' \item lineVar, operation, groupVar: If \code{groupVar} is \code{NULL}, \code{lineVar} must be also \code{NULL}. Besides, \code{operation} cannot be \code{NULL} when \code{lineVar} is not \code{NULL}.
#'}
#'
#' @seealso \code{\link[googleVis]{gvisComboChart}}
#'
#' @export
#' @import googleVis
createGoogleComboChart <- function(table, targetVar, groupVar, timeVar, min = NA, max = NA, lineVar = NULL, operation = NULL, restrictions = NULL, alternatives = NULL, filename = NULL){
#-- Process parameters
if(!is.null(restrictions) && length(restrictions) == 0){
restrictions <- NULL
}
if(!is.null(alternatives) && length(alternatives) == 0){
alternatives <- NULL
}
if(!is.null(lineVar) && lineVar == ""){
lineVar <- NULL
}
if(!is.null(operation) && operation == ""){
operation <- NULL
}
if(!is.na(min) && min == ""){
min <- NA
}
if(!is.na(max) && max == ""){
max <- NA
}
if(!is.null(groupVar) && groupVar == ""){
groupVar <- NULL
}
#-- Import data
columns <- c(targetVar, groupVar, timeVar)
if(!is.null(lineVar) && !(lineVar %in% targetVar)){
columns <- c(columns, lineVar)
}
limits <- t(as.data.frame(c(timeVar, min, max)))
data <- importData(table, columns, restrictions, limits, alternatives)
#-- Validate parameters
validationMessage <- validateGoogleChartParameters(data, table, targetVar, groupVar, timeVar, min, max, restrictions)
if(validationMessage != .VALID){
return(validationMessage)
}
if(!is.null(lineVar) && !(lineVar %in% targetVar)){
if(is.null(groupVar)){
return(.ERROR_GOOGLE_COMBO_1)
}
if(is.null(operation)){
return(.ERROR_GOOGLE_COMBO_2)
}
validationMessage <- validateTargetVariables(data,lineVar)
if(validationMessage != .VALID){
return(validationMessage)
}
validationMessage <- validateConsistency(data,timeVar,groupVar,lineVar)
if(validationMessage != .VALID){
return(validationMessage)
}
}
#-- Create a dataset in which each column is either a time variable or a category with target values
if(!is.null(groupVar)) {
levels <- levels(data[,groupVar])
ncolumns <- length(levels) + 1
nrows <- length(unique(data[,timeVar]))
newData <- data.frame(matrix(ncol = ncolumns, nrow = nrows))
names(newData)[1] <- timeVar
newData[,1] <- unique(data[,timeVar])
index = 2
for(level in levels){
names(newData)[index] <- level
newData[,index] <- data[data[,groupVar] == level, targetVar]
index = index + 1
}
target <- getColumnAlias(table, targetVar)
}
else { #groupVar == NULL
ncolumns <- ncol(data)
isTarget <- !(names(data) %in% timeVar)
if(ncolumns == 2){
name <- names(data)[isTarget]
cols <- as.data.frame(data[,isTarget])
names(cols) <- name
}
else {
cols <- data[,!(names(data) %in% timeVar)]
}
newData <- cbind(data[,timeVar], cols)
names(newData)[1] <- timeVar
for(index in 2:ncolumns){
names(newData)[index] <- getColumnAlias(table, names(newData)[index])
}
target <- names(newData)[2:ncolumns]
}
title = formatGoogleChartTitle(table, restrictions, target)
#-- Set chart options
options <- list( title = title,
seriesType="bars",
chartArea = "{width : '72%', left: 30}",
width=750,
height=320 )
#-- Create line
if(!is.null(operation)){
if(lineVar == targetVar || is.null(groupVar)){
newCol <- applyOperation(newData[2:ncolumns],operation)
}
else {
temp <- matrix(nrow = nrows, ncol = length(levels))
index = 1
for(level in levels){
temp[,index] <- data[data[,groupVar] == level, lineVar]
index = index + 1
}
newCol <- applyOperation(temp,operation)
}
name <- paste(operation, ": ", getColumnAlias(table,lineVar), sep="")
newData <- cbind(newData, newCol)
ncolumns = ncolumns + 1
names(newData)[ncolumns] <- name
options <- c(options, series = paste("{", ncolumns - 2,": {type: 'line'}}",sep=""))
}
#-- Create the combo chart and print it
chartObj = gvisComboChart(newData, xvar=timeVar, yvar=names(newData)[2:ncolumns], options=options)
chartFile <- printGoogleChart(chartObj, filename)
#-- Create a csv file with the data that was used
dataFile <- printChartData(newData,chartFile)
return(c(chartFile,dataFile))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.