Histograms

A histogram is a great type of visualization for examining data distributions. Unlike bar charts, histograms track one thing along the x-axis (e.g. percentiles, time, cost, or number of events). In other words, each bar of a histogram represents a different frequency of the same variable. In the image below, for example, you’ll see that each bar represents user session length increments of 60 seconds.

Session Length Histogram

This histogram reveals that most user sessions (29.4%) last about 120 seconds, or 2 minutes.

Session Length

To create a histogram for session lengths, like the one shown above, you can run a count analysis on an event collection for completed sessions (e.g. session_end). Along the x-axis you’ll have segments of time lapsed in a session, and along the y-axis you’ll have the percentage of sessions that fit into a given session length cohort.

Note: this recipe incorporates the D3 histogram recipe, which is explained a bit further down on this page.

var client = new Keen({
  projectId: "YOUR_PROJECT_ID",
  readKey: "YOUR_READ_KEY"
});

Keen.ready(function(){

  histogram('dom-element-id', {
      segment_length: 60,  // In seconds
      data_points: 10,  // i.e. There will be 10 bars on our chart
      analysis_type: 'count',
      query_parameters: {
          event_collection: 'session_end',
          timeframe: timeframe,
          filters: []
      }
  });

});

Creating a Histogram with D3

You can use D3 to create histograms for your Keen IO data!

Example:

var timeframe = 'last_7_days';
  var colors = [
      "#56c5d1", // Add colors as desired.
  ];

  /*
  Histogram function
  ------------------------------------------------------------------------

  It shows the distribution of actions after the session begins.
  For example a few users make a payment within 10 seconds, most at
  30 seconds, some at 2min.

  */

  var histogram = function(selector, options) {

      if (!options) options = {};

      var config = {
          segment_length: options.segment_length || 20,
          data_points: options.data_points || 10
      };

      var queries = [];

      for (var i = 0; i < options.data_points; i++) {
          (function(index){
              var start_time = index * config.segment_length;
              var end_time = start_time + config.segment_length;
              var clone = JSON.parse(JSON.stringify(options.query_parameters));
              var q = new Keen.Query(options.analysis_type, clone);

              // Each data bucket contains values that are greater that or equal
              // (`gte`) to our starting value and less than (`lt`) our ending
              // value. Because we're using index positions to define `start_time`
              // and `end_time`, our buckets would look like 0-19, 20-39, 40-59,
              // and so on.
              q.params.filters.push(
                 {
                      'property_name':'session.age',  // In seconds
                      'operator':'gte',
                      'property_value': Number(start_time)
                 },{
                      'property_name':'session.age',
                      'operator':'lt',
                      'property_value': Number(end_time)
                 }
              );
              queries.push(q);
          })(i);
      }

      client.run(queries, function(err, response){
          // if (err) throw('Error!');

          var histogramData = [{ keys: 'Chart Title', values: [] }];
          var sum = 0;

          // Sum so we can calculate percentages
          Keen.utils.each(response, function(record,index){
              sum += record.result;
          });

          Keen.utils.each(response, function(record, index){
              var start_time = index * config.segment_length;
              var end_time = start_time + config.segment_length;
              histogramData[0].values.push({
                  'label' : start_time,
                  'value' : record.result / sum  // Calculate percentage
              });
          });

          nv.addGraph(function() {
              var chart = nv.models.discreteBarChart()
                  .margin({ top: 10, right: 0, bottom: 20, left: 50 })
                  .color([colors[0]])
                  .x(function(d) { return d.label; })
                  .y(function(d) { return d.value; })
                  .staggerLabels(false)
                  .tooltips(true)
                  .transitionDuration(250);

              chart.yAxis
                  .tickFormat(d3.format('.1%'));

              d3.select('#' + selector + ' svg.chart')
                  .datum(histogramData)
                  .call(chart);

              nv.utils.windowResize(chart.update);

              return chart;
          });
      });
  };

});

Creating a Histogram with Keen IO

Here’s a recipe for creating a histogram with Keen IO’s data visualization library!