Home forums Using CanvasJS Drilldown with Ajax and MVC

This topic contains 4 replies, has 2 voices, and was last updated by  Manoj Mohan 2 months, 2 weeks ago.

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #26516

    I’m trying to do a multi drill down, using MVC and Ajax. The MVC Controller is setup with several methods that return Json(dataPoints);

    Javascript is my weakpoint. I’m trying to have each click load the separate chart details, trigger an ajax request relevant to the layer and then render the chart. This is made from mashing several of your tutorials together with some stackoverflow answers.

    It doesn’t work. Can you point me in the right direction?

    `
    @model IEnumerable<Ctrack.Dashboard.Data.DataPoint>

    @{
    ViewData[“Title”] = “Index”;
    Layout = “~/Views/Shared/_Layout.cshtml”;
    }

    <h1>Json Controller</h1>

    <div id=”chartContainer”></div>

    <script>
    window.onload = function () {
    var processDate = new Date(@Html.Raw(ViewBag.ProcessDate));
    var currentLayer = 0; //defult starting layer

    var dataPoints = [];

    var chart = new CanvasJS.Chart(“chartContainer”, {
    title: {
    text: “Rendering Chart with dataPoints from External JSON”
    },
    data: [{
    type: “line”,
    dataPoints: dataPoints,
    }]
    });

    var optionsLayer0 = {
    click: layer0DrilldownHandler,
    cursor: “pointer”,
    explodeOnClick: false,
    innerRadius: “75%”,
    legendMarkerType: “square”,
    name: “Total Events”,
    radius: “100%”,
    showInLegend: true,
    startAngle: 45,
    type: “pie”,
    animationEnabled: true,
    title: {
    text: “Total Events”
    },
    data: []
    };

    var optionsLayer1 = {
    click: layer1DrilldownHandler,
    cursor: “pointer”,
    explodeOnClick: false,
    innerRadius: “75%”,
    legendMarkerType: “square”,
    name: “Events breakdown by Event Type”,
    radius: “100%”,
    showInLegend: true,
    startAngle: 45,
    type: “doughnut”,
    animationEnabled: true,
    theme: “light2”,
    title: {
    text: “Events breakdown by Event Type”
    },
    data: []
    };

    var optionsLayer2 = {
    click: layer2DrilldownHandler,
    cursor: “pointer”,
    explodeOnClick: false,
    innerRadius: “75%”,
    legendMarkerType: “square”,
    name: “Event Type by Driver”,
    radius: “100%”,
    showInLegend: true,
    startAngle: 90,
    type: “doughnut”,
    animationEnabled: true,
    theme: “light2”,
    title: {
    text: “Event Type by Driver”
    },
    data: []
    };

    var ajaxOptions = [
    {
    url: “~/Views/Json/GetLayer0”,
    data: {
    processDate: processDate,
    orgCode: orgCode
    },
    callback : handleLayer0
    },
    {
    url: “~/Views/Json/GetLayer1”,
    data: {
    processDate: processDate,
    orgCode: orgCode},
    callback : handleLayer1

    },
    {
    url: “~/Views/Json/GetLayer2”,
    data: {
    processDate: processDate,
    orgCode: orgCode,
    eventType: eventType},
    callback : handleLayer2

    }
    ];

    function doAjax( layerIndex) {
    $.ajax({
    dataType: “json”,
    url: ajaxOptions[layerIndex].url,
    data: ajaxOptions[layerIndex].data,
    success: function (serverResponse) {

    //once a successful response has been received,
    //no HTTP error or timeout reached,
    //run the callback for this request
    ajaxOptions[layerIndex].callback(serverResponse);

    },
    complete : function () {

    //note that the “success” callback will fire
    //before the “complete” callback
    console.log(“Ajax call complete”);
    }
    });
    }

    function handleLayer0(data) {
    console.table(data);
    currentLayer = 0;

    $.each(data, function (key, value) {
    dataPoints.push({ x: value[0], y: parseInt(value[1]) });
    });
    $(“#chartContainer”).CanvasJSChart(optionsLayer0);
    chart.render();
    }

    function handleLayer1(data) {
    console.table(data);
    currentLayer = 1;

    $.each(data, function (key, value) {
    dataPoints.push({ x: value[0], y: parseInt(value[1]) });
    });
    $(“#chartContainer”).CanvasJSChart(optionsLayer1);
    chart.render();
    }

    function handleLayer2(data) {
    console.table(data);
    currentLayer = 2;

    $.each(data, function (key, value) {
    dataPoints.push({ x: value[0], y: parseInt(value[1]) });
    });
    $(“#chartContainer”).CanvasJSChart(optionsLayer2);
    chart.render();
    }

    function layer0DrilldownHandler(e) {
    //getAllProperties(e);
    //getAllMethods(e);

    e.chart.options = optionsLayer0;
    e.chart.options.data = visitorsData[e.dataPoint.name];
    e.chart.options.title = { text: e.dataPoint.name }
    doAjax(currentLayer);
    e.chart.render();
    $(“#backButton”).toggleClass(“invisible”);
    }

    function layer1DrilldownHandler(e) {
    //getAllProperties(e);
    //getAllMethods(e);

    e.chart.options = optionsLayer1;
    e.chart.options.data = visitorsData[e.dataPoint.name];
    e.chart.options.title = { text: e.dataPoint.name }
    doAjax(currentLayer);
    e.chart.render();
    $(“#backButton”).toggleClass(“invisible”);
    }

    function layer2DrilldownHandler(e) {
    //getAllProperties(e);
    //getAllMethods(e);
    eventType = e.chart.name; //bad guess
    e.chart.options = optionsLayer2;
    e.chart.options.data = visitorsData[e.dataPoint.name]; //no idea
    e.chart.options.title = { text: e.dataPoint.name } //no idea
    doAjax(currentLayer);
    e.chart.render();
    $(“#backButton”).toggleClass(“invisible”);
    }

    $(“#backButton”).click(function () {
    if (currentLayer >= 1) {
    currentLayer–;
    }

    if (currentLayer <= 0)
    {
    currentLayer = 0;
    $(this).toggleClass(“invisible”);
    }

    doAjax(currentLayer);
    });

    doAjax(currentLayer); //once document is ready
    }

    function getAllProperties(object) {
    for (var prop in object) {
    console.log(prop);
    }
    }

    function getAllMethods(object) {
    return Object.getOwnPropertyNames(object).filter(function (p) {
    return typeof object[p] == ‘function’;
    });
    }

    </script>

    #26545

    @hecatonchireslm,

    Considering this thread as a duplicate of Drilldown with Ajax and MVC and hence closing the same.

    —-
    Manoj Mohan
    Team CanvasJS

    #26562

    I had a friend help me through a few rough bits. Currently getting the console error You cannot combine “column” with pie chart which is interesting as I’m not referencing either. I’m trying to load a doughnut.

          var param = {
                orgCode: "HVO",
                processDate: new Date("2019-08-26"),
                eventType: "",
                driverId: ""
            }
    
            // which layer is being displayed.  0 is the start.  increases as drilled down
            var currentLayer = 0; //0 is default starting layer
    
            // container passed to charts
            var dataPoints = [];
    
            var chart = new CanvasJS.Chart("chartContainer", {
                title: {
                    text: "Rendering Chart with dataPoints from External JSON"
                },
                data: [{
                    type: "doughnut",
                    dataPoints: dataPoints,
                }]
            });
    
            // array holding options for each layers charts
            var chartOptions = [
                {
                    click: layer0ClickHandler,
                    cursor: "pointer",
    	            title: {
    		            text: "Events breakdown by Event Type"
    	            },
                    data: [
                        {
                            type: "doughnut",
                            dataPoints: []
                        }
                    ]
                },
                {
                    click: layer0ClickHandler,
                    cursor: "pointer",
    	            title: {
    		            text: "Event Type grouped by Driver"
    	            },
                    data: [
                        {
                            type: "doughnut",
                            dataPoints: []
                        }
                    ]
                }
    		     ,
                {
                    click: layer0ClickHandler,
                    cursor: "pointer",
    	            title: {
    		            text: "Event Type by Driver"
    	            },
                    data: [
                        {
                            type: "doughnut",
                            dataPoints: []
                        }
                    ]
                }
            ];
    
            // array holding the AJAX options when a layer is clicked
            var ajaxOptions  = [
                {
                    
                    url: "JsonChartJs/GetLayer0",
                    data: {
                        layer: 0,
                        processDate: encodeURIComponent(formatDateInput(param.processDate)),
                        orgCode: encodeURIComponent(param.orgCode)
                    },
                    callback : layer0CallbackHandler
                },
                {
                    url: "JsonChartJs/GetLayer1",
                    data: {
                        layer: 1,
                        processDate: encodeURIComponent(formatDateInput(param.processDate)),
                        orgCode: encodeURIComponent(param.orgCode),
                        eventType: encodeURIComponent(param.eventType)
                    },
                    callback : layer1CallbackHandler
    
                },
                {
                    url: "JsonChartJs/GetLayer2",
                    data: {
                        layer: 2,
                        processDate: encodeURIComponent(formatDateInput(param.processDate)),
                        orgCode: encodeURIComponent(param.orgCode),
                        eventType: encodeURIComponent(param.eventType),
                        driverId: encodeURIComponent(param.driverId)
                    },
                    callback : layer2CallbackHandler
    
                }
            ];
    
            //AJAX call based on current layer.  Returns to designated callback handler (in options)
            function doAjax(layerIndex) {
                console.log("Ajax Url: " + ajaxOptions[layerIndex].url);
                $.ajax({
                    type: "GET",
                    cache: false,
                    dataType: "json",
                    url: ajaxOptions[layerIndex].url,
                    data: ajaxOptions[layerIndex].data,
                    success: function (serverResponse) {
    
                        //once a successful response has been received,
                        //no HTTP error or timeout reached,
                        //run the callback for this request
                        ajaxOptions[layerIndex].callback(serverResponse);
    
                    },
                    complete : function () {
    
                        //note that the "done" callback will fire
                        //before the "always" callback
                        console.log("Ajax call complete");
                    }
                });
             }
    
            // Callback handlers.  Currently all the same.  Will differentiate 
            // as layers devlop and data requirements change
    
            function layer0CallbackHandler(data) {
                console.log("func layer0CallbackHandler");
                //console.table(data);
                currentLayer = 0;
                dataPoints.length = 0;
                $.each(data, function (key, value) {
                    dataPoints.push({ label: value["name"], y: parseInt(value["y"]), color: value["color"] });
                });
    
                chartOptions[currentLayer].data.push(dataPoints);
    
                chart.options = chartOptions[currentLayer];
                
                //$("#chartContainer").CanvasJS.Chart(chartOptions[currentLayer]);
                chart.render();
            }
    #26579

    Following is my chart object just before chart.render() Logged with JSON.stringify(chart)
    `{
    “options”: {
    “cursor”: “pointer”,
    “title”: {
    “text”: “Events breakdown by Event Type”
    },
    “data”: [
    {
    “type”: “doughnut”,
    “dataPoints”: [
    [
    {
    “label”: “Severe G-Force”,
    “y”: 2,
    “color”: “blueviolet”
    },
    {
    “label”: “High G-Force”,
    “y”: 21,
    “color”: “darkmagenta”
    },
    {
    “label”: “Driving w/o Seatbelt”,
    “y”: 38,
    “color”: “midnightblue”
    },
    {
    “label”: “Speed Violation”,
    “y”: 171,
    “color”: “red”
    }
    ]
    ]
    }
    ]
    }
    }’

    Chart renders as an empty box with the Chart Title (Events breakdown by Event Type) and a tiny canvas.js link in the bottom right

    #26581

    @hecatonchireslm,

    Can you kindly share sample project over Google-Drive / OneDrive along with sample data so that we can understand the scenario better and help you out?

    —-
    Manoj Mohan
    Team CanvasJS

Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.