1

I have some data result are grouped by two properties,

var avgResponseTime = new Keen.Query("average", {
  eventCollection: "some_collection",
  targetProperty: "response_time",
  groupBy: ["inventory", "search_type"]
});

How to render a column chart to display the response_time by inventory per search type? ideally, the columns of the same search type should be stick together

example chart

I tried

client.draw(avgResponseTime, document.getElementById("some-element"), {
  chartType: "columnchart",
  title: "Average response time by inventory",
  chartOptions: {
  isStacked: true
 }
});

it doesn't display the data well.. the column labels are displayed as search_type1, search_type2, search_type1, search_type1 ... (the repeated label probably belongs to the inventory 2)

Thanks.

vegibird
  • 31
  • 3
  • Can you supply a photoshopped version of the chart you're attempting to generate? response_time by inventory per search type would require three axes, but it sounds like you're looking for stacked bar charts. – terrhorn Mar 16 '15 at 16:45
  • terrhorn: just added an image. Thanks – vegibird Mar 26 '15 at 16:02

1 Answers1

1

Keen.Dataviz() can't draw such a chart out of the box via client.draw(), but you can customize the underlying Google chart directly by doing a bit of result manipulation via client.run(). You basically need to loop through the results of the query and build an array that the charting library understands to get what you're looking for.

The Google charts library is inherited by default which means you can instantiate google.visualization.DataTable() directly without the need to include Google's charting library separately.

Example (requires jQuery):

var avgResponseTime = new Keen.Query("average", {
  eventCollection: "some_collection",
  targetProperty: "response_time",
  groupBy: ["inventory", "search_type"]
});

client.run(avgResponseTime, function(error, response) {
  var result = response.result;

  // infer the inventory types
  var inventory_types = [];
  $.each(result, function(index, item) {
    inventory_types.push(item.inventory);
  });
  inventory_types = $.unique(inventory_types);

  // infer the search types
  var search_types = [];
  $.each(result, function(index, item) {
    search_types.push(item.search_type);
  });
  search_types = $.unique(search_types);

  var data = []; // array for our combined data points

  // we need a row for each unique search type
  $.each(search_types, function(index, item) {
    data.push([item]);
  });

  // iterate over each data point and push it into the correct array for our chart
  $.each(result, function(index, item) {
    // verify the search type and put the response time where it belongs
    for (var i = 0; i < search_types.length; i++) {
      if (data[i][0] == item.search_type) {
        data[i].push(item.result);
      }
    }
  });

  // init a datatable so we can customize our chart
  var dataTable = new google.visualization.DataTable();
  dataTable.addColumn('string', 'Inventory');

  // add each of our inventory types as a column in the datatable
  $.each(inventory_types, function(index, item) {
    dataTable.addColumn('number', item);
  });

  // add our response time averages
  dataTable.addRows(data);

  // configure the chart
  var options = {
    title: 'Average response time by inventory',
    height: 250,
    width: 'auto',
    hAxis: {
      title: 'Inventory',
    },
    vAxis: {
      title: 'Average Response Time'
    },
    legend: {
      position: 'top'
    }
  };

  // draw
  var chart = new google.visualization.ColumnChart(document.getElementById('some-element'));
  chart.draw(dataTable, options);
});

This code assumes that your event collection contains events that include at least the following properties:

{
  "search_type": "British Rail",
  "inventory": "Multi-trip",
  "response_time": 600
}
terrhorn
  • 510
  • 4
  • 6