Conversion Analysis

You can use Keen IO to track entities (for example: users) that performed a certain activity in a given timeframe and performed a different activity in a subsequent timeframe.

For example, you can track what percentage of new people who visited your website (or installed your app) in the last 10 days have signed up.

You can use the Funnel API to query for the conversion rate, and use the Dataviz component to visualize the data.

You can look at a conversion rate as a single number, as a time series, or even as a cohort.

Single Number Conversion Rate

Keen IO Metric - Conversion Rate

You can query for the conversion rate by querying the conversion rate for a timeframe, and charting it using a metric chart type.

In order to achieve this, you simply have to:

  1. Initialize Keen IO’s JS SDK.
  2. Create a Keen.Dataviz instance with a Metric chart type.
  3. Create and run a funnel Keen.Query.
  4. Parse the responses and render the chart.

See the example below with all the steps marked!

    <!-- Put this wherever you want the metric to appear in your HTML. -->

    <div id="conversion-number"></div>

    <script type="text/javascript" charset="utf-8">

       //====================================//               
       // Step (1)                           //
       //====================================//                

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

       // Global Properties for Line Chart Viz
       var chartHeight = 400;
       var chartWidth = 600;
       var lineWidth = 3;
       var chartAreaWidth = '60%';
       var chartAreaLeft = '10%';
       var xAxisLabelAngle = '45%';

       // define variable so we can access it later
       var conversionChart;
       var conversionNumberChart;

       Keen.ready(function() {

           //====================================//               
           // Step (2)                           //
           //====================================//                

            conversionNumberChart = new Keen.Dataviz()
                .el(document.getElementById('conversion-number'))
                .chartType('metric')
                .chartOptions({
                  label: 'Conversion',
                  suffix: '%'
                })
                .prepare(); // starts spinner

            // Number of days in your line chart
            // (and for which the avg conversion rate metric is calculated for)
            var daysInChart = 10;  
            var step1CollectionName = 'visits';
            var step2CollectionName = 'sign_up';
            var actor_property = 'session.uuid';

            // Number of days to use for retention analysis
            // (E.g. D7 Retention (T-7 installs return T0) has a retention value of 7)
            // aka DaysSinceFirstPlay.

            // A retentionPeriod of 1 means the number of people who did step2
            // in the 24hour period after their step1 activity.

            // We set it to 'daysInChart' here as we just want to know the conversion rate
            // in general, if you care about the timeframe for which the user has
            // converted – change this number.

            var retentionPeriod = daysInChart;

            calculateConversion(daysInChart,
                                step1CollectionName,
                                step2CollectionName,
                                retentionPeriod,
                                actor_property)
       });

        function funnelQuery(steps, callback) {

           //====================================//               
           // Step (3)                           //
           //====================================//                

            //Instantiate a new Keen.Query for steps.
            var myFunnel = new Keen.Query('funnel', {
               steps: steps
            });

            client.run(myFunnel, callback);
        }

        function calculateConversion(durationInDays,
                                      step1CollectionName,
                                      step2CollectionName,
                                      retentionPeriod,
                                      actor_property) {
            var s1 = {
               event_collection: step1CollectionName,
               actor_property: actor_property,
               timeframe: 'this_' + durationInDays + '_days'
            };

            var s2 = {
               event_collection: step2CollectionName,
               actor_property: actor_property,
               timeframe: 'this_' + durationInDays + '_days'
            };

        funnelQuery([s1, s2], function(err, response) {

           //====================================//               
           // Step (4)                           //
           //====================================//                

            conversionNumberChart
                .parseRawData({ result: 100 * response.result[1]/response.result[0] })
                .title('Conversion')
                .render();
        });
       }
    </script>

Daily Conversion Rate Chart

Keen IO Metric - Daily Conversion Rate

You can chart out the daily conversion rate by querying the conversion rate for each day, and charting it using a series chart type (areachart, linechart, columnchart, or barchart).

In order to achieve this, you simply have to:

  1. Initialize Keen IO’s JS SDK.
  2. Create a Keen.Dataviz instance with an AreaChart chart type.
  3. Create and run Keen.Query instances for each day.
  4. Parse the responses and render the chart.

See the example below with all the steps marked!

    <!-- Put these wherever appropriate in your HTML. -->

    <div id="conversion-chart"></div>

    <script type="text/javascript" charset="utf-8">

       //====================================//               
       // Step (1)                           //
       //====================================//                

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

       // Global Properties for Line Chart Viz
       var chartHeight = 400;
       var chartWidth = 600;
       var lineWidth = 3;
       var chartAreaWidth = '60%';
       var chartAreaLeft = '10%';
       var xAxisLabelAngle = '45%';

       // define variable so we can access it later
       var conversionChart;

       Keen.ready(function() {

            //====================================//               
            // Step (2)                           //
            //====================================//   

            conversionChart = new Keen.Dataviz()
                .el(document.getElementById('conversion-chart'))
                .chartType('areachart')
                .prepare(); // start spinner

            // Number of days in your line chart (and for which the avg
            // conversion rate metric is calculated for)
            var daysInChart = 10;  
            var step1CollectionName = 'visits';
            var step2CollectionName = 'sign_up';
            var actor_property = 'session.uuid';

            // Number of days to use for retention analysis
            // (E.g. D7 Retention (T-7 installs return T0) has a retention value of 7)
            // aka DaysSinceFirstPlay.

            // A retentionPeriod of 1 means the number of people
            // who did step2 in the 24hour period after their step1 activity.

            // We set it to 'daysInChart' here as we just want to know the conversion rate
            // in general, if you care about the timeframe for which the user
            // has converted – change this number.

            var retentionPeriod = daysInChart;

            calculateRetention(daysInChart,
                              step1CollectionName,
                              step2CollectionName,
                              retentionPeriod,
                              actor_property);
       });

       function funnelQuery(steps, callback) {
            //Instantiate a new Keen.Query for steps.
            var myFunnel = new Keen.Query('funnel', {
               steps: steps
            });

            client.run(myFunnel, callback);
       }

       function calculateRetention(daysInChart,
                                  step1CollectionName,
                                  step2CollectionName,
                                  retentionPeriod,
                                  actor_property) {

            //====================================//               
            // Step (3)                           //
            //====================================//  

            var dataForLineChart = [];
            var i = 0;

            while (i < daysInChart) {
                var firstStepDate = new Date();
                firstStepDate.setDate(firstStepDate.getDate() - daysInChart
                                      - retentionPeriod + i);
                firstStepDate.setHours(0,0,0);

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

                var secondStepDate = new Date(firstStepDate);
                secondStepDate.setDate(firstStepDate.getDate());
                // The start timeframe for step 2 is now the same as step 1

                var secondStepDateEnd = new Date(secondStepDate);
                secondStepDateEnd.setDate(secondStepDateEnd.getDate() + retentionPeriod + 1);
                // The end timeframe for step 2 is now a 24hr window

                var s1 = {
                   event_collection: step1CollectionName,
                   actor_property: actor_property,
                   timeframe: {start: firstStepDate, end: firstStepDateEnd}
                };

                var s2 = {
                   event_collection: step2CollectionName,
                   actor_property: actor_property,
                   timeframe: {start: secondStepDate, end: secondStepDateEnd}
                };

                funnelQuery([s1, s2], function(err, response) {

                   //====================================//               
                   // Step (4)                           //
                   //====================================//   

                   var percentage = (response.result[1] / response.result[0]) * 100;
                   dataForLineChart.push({
                       "value" : percentage,
                       "timeframe" : {
                           "start" : response.steps[1].timeframe.start,
                           "end" : response.steps[1].timeframe.end
                       }
                   });

                   if (dataForLineChart.length == daysInChart) {
                       var title = 'Conversion Rate over Time';

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

                       // Let's build this crazy thing!
                       conversionChart
                         .parseRawData({ result: dataForLineChart })
                         .title(title)
                         .height(chartHeight)
                         .width(chartWidth)
                         .chartOptions({
                             chartAreaWidth: chartAreaWidth,
                             chartAreaLeft: chartAreaLeft,
                             hAxis: {
                               slantedText: true,
                               slantedTextAngle: xAxisLabelAngle
                             },
                             legend: { position: 'none' },
                             lineWidth: lineWidth
                         })
                         .render();

                   }
                });
                i++;
            }
       }

    </script>

Conversion Cohorts Table

Keen IO Metric - Conversion Rate Cohorts Table

You can also look at the conversion rate at multiple timeframes for a specific cohort. This is especially useful for retention events or activation events.

In order to achieve this, you have to:

  1. Initialize Keen IO’s JS SDK.
  2. Create a Keen.Dataviz instance with a Table chart type.
  3. Create and run a funnel Keen.Query for each day in the cohort and for each timeframe you’ll be calculating the conversion rate on.
  4. Parse the responses and render the chart.

Below, you can find an example that calculates day 1, 7 and 30 conversion rates for a 10 day period (daily cohorts), with the steps highlighted.

    <!-- Put this wherever you want the metric to appear in your HTML. -->

    <div id="conversion-cohorts"></div>

    <script type="text/javascript" charset="utf-8">

        //====================================//               
        // Step (1)                           //
        //====================================//   

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

        // Global Properties for Line Chart Viz
        var chartHeight = 400;
        var chartWidth = 600;
        var lineWidth = 3;
        var chartAreaWidth = '60%';
        var chartAreaLeft = '10%';

        // define variable so we can access it later
        var conversionRetentionChart;

        Keen.ready(function() {

            //====================================//               
            // Step (2)                           //
            //====================================//   

            conversionRetentionChart = new Keen.Dataviz()
                .el(document.getElementById('conversion-cohorts'))
                .chartType('table')
                .chartOptions({
                    label: 'Conversion Cohorts',
                    suffix: '%'
                })
                .prepare();

            // Number of days in your line chart
            // (and for which the avg conversion rate metric is calculated for)
            var daysInChart = 10;  
            var step1CollectionName = 'visits';
            var step2CollectionName = 'sign_up';
            var actor_property = 'session.uuid';

            // Number of days to use for retention analysis
            // (E.g. D7 Retention (T-7 installs return T0) has a retention value of 7)
            // aka DaysSinceFirstPlay.

            // A retentionPeriod of 1 means the number of people who did step2 in the 24hour
            // period after their step1 activity.

            // We set it to 'daysInChart' here as we just want to know the conversion
            // rate in general, if you care about the timeframe for which the user
            // has converted – change this number.

            // Note: this is an array of the days to use – they will all be calculated
            var retentionPeriods = [1, 7, 30];

            calculateConversionRetention(daysInChart,
                                        step1CollectionName,
                                        step2CollectionName,
                                        retentionPeriods,
                                        actor_property);

        });

        function funnelQuery(steps, callback, extraPayload) {

            //====================================//               
            // Step (3)                           //
            //====================================//   

            //Instantiate a new Keen.Query for steps.
            var myFunnel = new Keen.Query('funnel', {
               steps: steps
            });

            client.run(myFunnel, function(err, response) {
               callback(err, response, extraPayload);
            });
        }

        function calculateConversionRetention(daysInChart,
                                              step1CollectionName,
                                              step2CollectionName,
                                              retentionPeriods,
                                              actor_property) {
            var dataForRetentionChart = [];
            var dayIndex = 0;
            var retentionIndex = 0;
            var maxRetention = 0;


            // Find max retention period, so we go back to the past by it (after daysInChart)
            for (var i = 0; i < retentionPeriods.length; i++) {
                var retentionPeriod = retentionPeriods[i];
                if (retentionPeriod > maxRetention)
                    maxRetention = retentionPeriod;
            }

            while (dayIndex < daysInChart) {
                // First row and col is empty to create space for titles
                dataForRetentionChart[0] = [""];

                dataForRetentionChart[dayIndex + 1] =
                    dataForRetentionChart[dayIndex + 1] || [];

                while (retentionIndex < retentionPeriods.length) {
                    var retentionPeriod = retentionPeriods[retentionIndex];

                    // Title for each column
                    dataForRetentionChart[0].push("D" + retentionPeriod + " Conversion");

                    var firstStepDate = new Date();
                    firstStepDate.setDate(firstStepDate.getDate() - daysInChart
                                          - maxRetention + dayIndex);
                    firstStepDate.setHours(0,0,0);

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

                    var secondStepDate = new Date(firstStepDate);
                    secondStepDate.setDate(firstStepDate.getDate());
                    // The start timeframe for step 2 is now the same as step 1

                    var secondStepDateEnd = new Date(secondStepDate);
                    secondStepDateEnd.setDate(secondStepDateEnd.getDate()
                                              + retentionPeriod + 1);
                    // The end timeframe for step 2 is now a 24hr window + retentionPeriod

                    var s1 = {
                       event_collection: step1CollectionName,
                       actor_property: actor_property,
                       timeframe: {start: firstStepDate, end: firstStepDateEnd}
                    };

                    var s2 = {
                       event_collection: step2CollectionName,
                       actor_property: actor_property,
                       timeframe: {start: secondStepDate, end: secondStepDateEnd}
                    };



                    funnelQuery([s1, s2], function(err, response, extraPayload) {

                        //====================================//               
                        // Step (4)                           //
                        //====================================//   

                        var percentage = (response.result[1] / response.result[0]) * 100;

                        var dataDayIndex = extraPayload.dayIndex;
                        var dataRetentionIndex = extraPayload.retentionIndex;

                        // First indexes are for titles / labels - hence the plus 1

                        // Row title
                        dataForRetentionChart[dataDayIndex + 1][0] = extraPayload.date;

                        dataForRetentionChart[dataDayIndex + 1][dataRetentionIndex + 1] =
                            percentage.toPrecision(4) + "%";

                        // Let's build this crazy thing!
                        conversionRetentionChart
                         .parseRawData({ result: dataForRetentionChart })
                         .height(chartHeight)
                         .width(chartWidth)
                         .render();
                    }, {
                        dayIndex: dayIndex,
                        retentionIndex: retentionIndex,
                        date: dateToHumanString(firstStepDate)
                    });
                    retentionIndex++;
                }

                dayIndex++;
                retentionIndex = 0;
            }            
        }

        function dateToHumanString(date) {
            return "" +
                    date.getFullYear()  + "-" +
                    (date.getMonth() + 1) + "-" +
                    date.getDate()  + "";
        }
    </script>