4

I have a shiny app with embedded google line charts using the googlevis package. I need to be able to hide a line when clicking on it's legend key. I found this code on how to do it in google charts:

$http://jsfiddle.net/xDUPF/4/light/$

How can I introduce this behavior to a graph created using shiny? can I use the "jscode" parameter for it?

Paul Hiemstra
  • 59,984
  • 12
  • 142
  • 149
MoRkO
  • 51
  • 4

1 Answers1

3

You can achieve this by inserting some extra javascript code. The technique is shown here. When you call gvisLineChart and assign it to x it returns a list. You can inspect the following

x$html$chart[['jsDrawChart']]

it will return something like

// jsDrawChart
function drawChartyourid() {
var data = gvisDatayourid();
var options = {};
options["allowHtml"] = true;
options["series"] = [{targetAxisIndex: 0},
                                              {targetAxisIndex:1}];
options["vAxes"] = [{title:'val1'}, {title:'val2'}];


    var chart = new google.visualization.LineChart(
    document.getElementById('yourid')
    );
    chart.draw(data,options);    
}

You can adjust this piece of javascript code to achieve your aims. As an example here is a ui.R and server.R. The result can be viewed http://spark.rstudio.com/johnharrison/gvisTest

# ui.R

library(shiny)

shinyUI(pageWithSidebar(
  headerPanel("Hello Shiny!"),

  sidebarPanel("Sidebar"),
  mainPanel("Main",
            htmlOutput('gtest'))
)

)


# server.R
library(shiny)
library(googleVis)

shinyServer(function(input, output) {

  output$gtest <- renderGvis({
    df <- data.frame(country=c("US", "GB", "BR"), val1=c(1,3,4), val2=c(23,12,32))
    gt <- gvisLineChart(df, xvar="country", yvar=c("val1", "val2"),
                        options=list(title="Hello World",
                                     titleTextStyle="{color:'red',fontName:'Courier',fontSize:16}",
                                     curveType='function'),chartid = "yourid"
    )
    jsInsert <- "var columns = [];
    // display these data series by default
    var defaultSeries = [1,2,3];
    var series = {};
    for (var i = 0; i < data.getNumberOfColumns(); i++) {
        if (i == 0 || defaultSeries.indexOf(i) > -1) {
            // if the column is the domain column or in the default list, display the series
    columns.push(i);
  } else {
    // otherwise, hide it
    columns[i] = {
    label: data.getColumnLabel(i),
    type: data.getColumnType(i),
    calc: function () {
    return null;
    }
    };
  }
    if (i > 0) {
    // set the default series option
    series[i - 1] = {};
    if (defaultSeries.indexOf(i) == -1) {
    // backup the default color (if set)
    if (typeof (series[i - 1].color) !== 'undefined') {
    series[i - 1].backupColor = series[i - 1].color;
    }
    series[i - 1].color = '#CCCCCC';
    }
    }
}
options['series'] = series;

function showHideSeries () {
  var sel = chart.getSelection();
  // if selection length is 0, we deselected an element
    if (sel.length > 0) {
    // if row is undefined, we clicked on the legend
    if (sel[0].row == null) {
    var col = sel[0].column;
    if (columns[col] == col) {
    // hide the data series
    columns[col] = {
    label: data.getColumnLabel(col),
    type: data.getColumnType(col),
    calc: function () {
    return null;
    }
    };

    // grey out the legend entry
    series[col - 1].color = '#CCCCCC';
    }
    else {
    // show the data series
    columns[col] = col;
    series[col - 1].color = null;
    }
    var view = new google.visualization.DataView(data);
    view.setColumns(columns);
    chart.draw(view, options);
    }
    }
  }

    google.visualization.events.addListener(chart, 'select', showHideSeries);
    chart.draw(data,options);
    "
    gt$html$chart[['jsDrawChart']] <- gsub("chart.draw\\(data,options\\);", jsInsert, gt$html$chart[['jsDrawChart']])
    gt

  })

})
jdharrison
  • 30,085
  • 4
  • 77
  • 89
  • This works beutifully! thanks, only at the end you need to do instead of "chart.draw(data,options);" , we used:\n var view = new google.visualization.DataView(data); view.setColumns(columns); chart.draw(view, options); – MoRkO Dec 24 '13 at 10:27
  • @jdharrison This solutions works great when there are no custom tooltips set for that googleVis chart. When I add custom tooltips and I click on the legend I get the following error: All series on a given axis must be of the same data type. Would it be feasible to modify the javascript code in order to allow for custom tooltips as well? – Christos Nov 28 '14 at 12:36
  • @jdharrison Aditionally this solution modifies the colors you may have assigned to series to the default googleVis colors. Is it possible to modify the code in order to allow custom colors as well? – Christos Nov 30 '14 at 08:04