Search code examples
javascriptchartspie-chartamchartsdrilldown

amCharts Multiple Level Drilldown


I'm trying to produce a report that visually displays data gathered to represent the response rate of an email campaign sent from a college to students.

At the top most level the pie chart shows how many responses have been gathered, At the second level, it shows what the responses gathered were, which can either be to

  • Accept an interview invitation
  • Request alternative date / time
  • Decline the interview

If the interview is declined, we capture what has lead the student to make this choice.

I've followed a few guides on here and on the amCharts website on how to drill down a single layer, and this works successfully as can be seen on the fiddle below.

What I'm struggling with is how to add the required additional level of drill down.

The amCharts website states that you are able to drill down multiple levels, however I'm struggling to achieve this

http://jsfiddle.net/6cLx34bL/

    var piedata = [{"response": "Not Yet Responded",
                "count": 151 
                  }, {
                "response": "Responded",
                "count": 259,
                "subdata": [
                    {"response": "Interview Re-Arranged", "count":28},
                    {"response": "Confirmed Attending", "count":213},
                    {"response": "Withdrawn Prior To Interview", "count":18, "subdata":[
                        {"response": "Course(s) Not Suitable", "count":1},
                        {"response": "Financial Issues", "count":1},
                        {"response": "Other College - Not Listed", "count":1},
                        {"response": "Other College - Local", "count":3},
                        {"response": "Transport Issues", "count":1},
                        {"response": "Unknown", "count":11}]} 
                ]}];

function generateChartDataPie () {
    var chartDataPie = [];
    for (var i = 0; i < piedata.length; i++) {
        if (i== selected) {
            for (var x = 0; x < piedata[i].subdata.length; x++) {
                chartDataPie.push({
                    response: piedata[i].subdata[x].response,
                    count: piedata[i].subdata[x].count,
                    pulled: true
                });
            }
        }
        else {
            chartDataPie.push({
                response: piedata[i].response,
                count: piedata[i].count,
                id: i
            });
        }
    }
    return chartDataPie;
}
var selected;

AmCharts.ready(function() {
    // PIE CHART
    chart = new AmCharts.AmPieChart(AmCharts.themes.light);
    chart.dataProvider = generateChartDataPie();
    chart.titleField = "response";
    chart.valueField = "count";
    chart.outlineColor = "#FFFFFF";
    chart.outlineAlpha = 0.8;
    chart.outlineThickness = 2;
    chart.pulledField = "pulled";
    chart.labelsEnabled = false;

    // ADD TITLE
    chart.addTitle("Click a slice to see the details");

    // AN EVENT TO HANDLE SLICE CLICKS
    chart.addListener("clickSlice", function (event) {
        if (event.dataItem.dataContext.id != undefined) {
            selected = event.dataItem.dataContext.id;
        }
        else {
            selected = undefined;
        }
        chart.dataProvider = generateChartDataPie();
        chart.validateData();
    });

    // WRITE
    chart.write("chartdiv1");
});

Solution

  • Altering the function has accomplished the multiple level drill down, updated function below:

    function generateChartDataPie () {
        var chartDataPie = [];
    
            if (selected) {
                for (var x = 0; x < selected.length; x++) {
                    chartDataPie.push({
                        response: selected[x].response,
                        count: selected[x].count,
                        pulled: true,
                        subdata: selected[x].subdata
                    });
                }
            }
            else {
                chartDataPie = piedata;
            }
        return chartDataPie;
    }