Skip to content

Latest commit

 

History

History
279 lines (219 loc) · 8.55 KB

recipes.md

File metadata and controls

279 lines (219 loc) · 8.55 KB

Recipes

Recipes show you how to make mashup Keen IO queries in novel ways. Got some cool recipes to share? Add 'em here!

Combine two line charts

Here's an example that takes the data from two different line charts and plots them both onto the same graph.

combined line chart

// use a variable to ensure timeframe & interval for both queries match
var interval = "daily"
var timeframe = "last_30_days"

var pageviews = new Keen.Query("count", { // first query
	eventCollection: "pageviews",
	interval: interval,
	timeframe: timeframe
});

var uniqueVisitors = new Keen.Query("count_unique", { // second query
	eventCollection: "pageviews",
	targetProperty: "uuid",
	interval: interval,
	timeframe: timeframe
});

var chart = new Keen.Dataviz()
	.el(document.getElementById("pageviews"))
	.chartType("linechart")
	.chartOptions({
		hAxis: {
			format:'MMM d',
			gridlines:  {count: 12}
		}
	})
	.prepare();

client.run([pageviews, uniqueVisitors], function(err, response){ // run the queries
	// if (err) handle the error

	var result1 = response[0].result  // data from first query
	var result2 = response[1].result  // data from second query
	var data = []  // place for combined results
	var i=0

	while (i < result1.length) {

		data[i]={ // format the data so it can be charted
			timeframe: result1[i]["timeframe"],
			value: [
				{ category: "Pageviews", result: result1[i]["value"] },
				{ category: "Visitors", result: result2[i]["value"] }
			]
		}
		if (i == result1.length-1) {
			// chart the data
			chart
				.parseRawData({ result: data })
				.render();
		}
		i++;
	}
});

Divide 2 Line Charts

This recipe can be used to calculate stuff like average number of connections per device, posts per user, pageviews per visitor, errors per server, logins per account, etc.

In one query you determine the number of items over a time period (e.g. number of posts daily for the past 30 days).

In the second query you determine the number of unique posters who made those posts.

Then you divide the two to determine the average.

divided line chart

Keen.ready(function(){

  // use a variable to ensure timeframe & interval for both queries match
  var interval = "daily"
  var timeframe = "last_30_days"

  var posts = new Keen.Query("count", { // first query
    eventCollection: "posts",
    interval: interval,
    timeframe: timeframe
  });

  var uniquePosters= new Keen.Query("count_unique", { // second query
    eventCollection: "posts",
    targetProperty: "uuid",
    interval: interval,
    timeframe: timeframe
  });

	var chart = new Keen.Dataviz()
		.el(document.getElementById("chart1"))
		.chartType("linechart")
		.chartOptions({
			lineWidth: 3,
			hAxis: {
				format:'MMM d',
				gridlines:  {count: 12}
			}
		})
		.prepare();

  client.run([posts, uniquePosters], function(err, response){ // run the queries

    var result1 = response[0].result  // data from first query
    var result2 = response[1].result  // data from second query
    var data = []  // place for combined results
    var i=0

    while (i < result1.length) {

      data[i]={ // format the data so it can be charted
        timeframe: result1[i]["timeframe"],
        value: [
          { category: "Posts per peep", result: result1[i]["value"] / result2[i]["value"]}
        ]
      }
      if (i == result1.length-1) {
				// chart the data
				chart
					.parseRawData({ result: data })
					.render();
      }
      i++;
    }
  });
});

Day X Retention

This recipe helps you figure out what percentage of users come back and use your app/site/device X days after some activity (e.g. activation).

This kind of analysis is used very commonly in gaming. Game developers want to answer questions like: Are people coming back to play my game the next day? On day 10? On day 30? Is the new version of my game retaining users better than the last?

Please note that it takes a very long time to generate this chart, especially on large datasets. That's because a Keen Funnel Query is executed for every single point in the chart. If you checkout console when you run this, you'll see all the queries being executed there. The example here runs 7 funnel queries because it calculates retention for each of the past 7 days.

Each data point on the line chart tells you what percentage of users who signed up 30 days ago used the app that day.

combined line chart

<!DOCTYPE html>
<html lang='en'>
<head>
  <script src='https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.js'></script>
  <script src="https://d26b395fwzu5fz.cloudfront.net/3.2.1/keen.min.js"></script>
  <script>

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

    var TIMEZONE_OFFSET = "-07:00"; // "US/Pacific" (PDT)

    Keen.ready(function(){

      // Last X days that will be displayed in the chart (keep this number small for best performance)
      var daysInChart = 7;

      // Use an action that identifies a first-time user
      var step1CollectionName = "installs";

      // Use an action that happen every session
      var step2CollectionName = "session_starts";

      var actorProperty = "player_id" ;

      // Number of days ago the user did step1
      var retentionPeriod = 30;
      var div = "chart1";

			var chart = new Keen.Dataviz()
				.chartType("linechart")
				.colors(["#6ab975"])
				.el(document.getElementById(div))
				.title("New users still using the app " + retentionPeriod + " days later")
				.width(600)
				.chartOptions({
					legend: { position: "none" },
					vAxis: { format: '#,###.#%' },
					hAxis: { format:'MMM d'}
				})
				.prepare();

      calculateRetention(daysInChart, step1CollectionName, step2CollectionName, retentionPeriod, actorProperty, div);
    });

    function calculateRetention(daysInChart, step1CollectionName, step2CollectionName, retentionPeriod, actorProperty, div) {
      var dataForLineChart = [];

      for (i=0; i < daysInChart; i++) {

        (function(){
          var _i = arguments[0];

          // Calculate dates for when user does step 1
          var firstStepDate = new Date();
          firstStepDate.setDate(firstStepDate.getDate() - daysInChart - retentionPeriod + _i);
          firstStepDate.setUTCHours(0,0,0,0,0);

          var firstStepDateEnd = new Date(firstStepDate);
          firstStepDateEnd.setDate(firstStepDateEnd.getDate() + 1);

          // Calculate dates for when user does step 2
          var secondStepDate = new Date(firstStepDate);
          secondStepDate.setDate(firstStepDate.getDate() + retentionPeriod);

          var secondStepDateEnd = new Date(secondStepDate);
          secondStepDateEnd.setDate(secondStepDateEnd.getDate() + 1);

          // Funnel steps used for calculating retention
          var step1 = {
            eventCollection: step1CollectionName,
            actorProperty: actorProperty,
            timeframe: {
              start: firstStepDate.toISOString().replace("Z","") + TIMEZONE_OFFSET,
              end: firstStepDateEnd.toISOString().replace("Z","") + TIMEZONE_OFFSET
            }
          };

          var step2 = {
            eventCollection: step2CollectionName,
            actorProperty: actorProperty,
            timeframe: {
              start: secondStepDate.toISOString().replace("Z","") + TIMEZONE_OFFSET,
              end: secondStepDateEnd.toISOString().replace("Z","") + TIMEZONE_OFFSET
            }
          };

          var funnel = new Keen.Query('funnel', {steps: [step1, step2]});

          client.run(funnel, function(err, response){
            var percentage = response.result[1]/response.result[0]
            dataForLineChart.push({
              "value" : percentage,
              "timeframe" : {
                "start" : response.steps[1].timeframe["start"],
                "end" : response.steps[1].timeframe["end"]
              }
            })

            if (dataForLineChart.length == daysInChart) {

	            // Need to sort data for line chart!
	            dataForLineChart.sort(function(x, y){
	              date1 = new Date(x.timeframe["start"]);
	              date2 = new Date(y.timeframe["start"]);
	              return date1 - date2;
	            })

	            // draw it!
							chart
								.parseRawData({ result: dataForLineChart })
								.render();
            }
          });

        })(i);

      }
    }
  </script>
</head>
<body>
	<div id="chart1"></div>
</body>
</html>