Search code examples
javascriptjquerychartsasp.net-core-mvccanvasjs

CanvasJS Load Data Dynamically MVC Razor


I am using asp.net core MVC to create dynamic charts for my application. I am using CanvasJS to draw the chart.

I would like to draw the chart data based on the selected parameters from the screen. So, I have a dropdownlist and a datatable that defines which data to retrieve from the database.

Problem is that my chart is not loaded after I click UpdateChart button. However when I debug the application and as per the console logs, the js function is working but it doesn't update the data inside the chart.

My View is like

<script>
   var chart;
   function myFunction() {
       console.log("Inside My Function_1");
       chart = new CanvasJS.Chart("chart-container", {
           zoomEnabled: true,
           title: {
               text: '@Html.Raw(ViewBag.ChartText)'//"My Text"
           },
           axisX: {
               title: "chart updates every 2 secs",
               crosshair: {
                   enabled: true,
                   snapToDataPoint: true
               }
           },
           axisY: {
               crosshair: {
                   enabled: true,
                   snapToDataPoint: true,
                   valueFormatString: "#,##0"
               }
           },
           toolTip: {
               shared: true
           },
           legend: {
               dockInsidePlotArea: true,
               verticalAlign: "top",
               horizontalAlign: "right"
           },
           data: [ @Html.Raw(ViewBag.AllData) ]
   });
       console.log("Inside My Function_2");
       chart.render();
       console.log("Inside My Function_3");

       }
   window.onload = myFunction;


   function GetData() {
       var table = $('#dataTable').DataTable();
       var data = table.$('input[type="checkbox"]').serializeArray();
       $.ajax({
           type: "POST",
           url: '@Url.Action("UpdateChart","Home")', //"/Home/UpdateChart",
           contentType: "application/x-www-form-urlencoded",
           data: data,
           dataType: "html",
           success: function (result) {
               console.log("Container remove called.");
               chart.destroy();
               //$('#chart-container').remove();
               //console.log("Container removed called.");
               //$('#graph-container').append('<div id="chart-container" class="chart-area-big"><div>');
               //console.log("Container appened again.");

               myFunction();
               console.log(result);
           }
       });
   }

</script>

       <div id="graph-container" class="card shadow mb-4">
           <div class="d-block card-header py-3">
               <h6 class="m-0 font-weight-bold text-primary">Chart</h6>
           </div>
           <div id="chart-container" class="chart-area-big">

           </div>
       </div>
<button type="button" id="getDataBtn" class="btn btn-success" onclick="GetData();">Update Chart</button>

And my controller is like

public IActionResult ChartNew()
        {
            ChartRepository repository = new ChartRepository();
            GeneralObjects.ServiceResponse response = repository.GetChartData();
            List<Devices> tmpList = repository.GetCustomerDevices();
            ViewData["CustomerDevices"] = new Microsoft.AspNetCore.Mvc.Rendering.SelectList(tmpList, "Id", "SerialNumber");

            string query = "SELECT mqttpacket_1606008363.id, datatypes.data_name ,mqttpacket_1606008363.data_value,packetinformation.inserted_time  FROM mqttpacket_1606008363 JOIN packetinformation ON mqttpacket_1606008363.packet_id = packetinformation.id JOIN datatypes ON mqttpacket_1606008363.data_type_id = datatypes.id WHERE packetinformation.inserted_time BETWEEN '2021-03-04 10:44:55.544398' AND '2021-03-05 10:49:55.544398' AND data_type_id = 5 ORDER BY inserted_time asc;";
            response = repository.GetChartData(query);

            ViewBag.ChartText = $"Reading Values of {ViewBag.DataPointName1} and {ViewBag.DataPointName2}";
            ViewBag.AllData = response.This_Object;


            System.Data.DataTable dt = repository.GetDataTypes();
            return View(dt);
        }
        [HttpPost]
        public GeneralObjects.RES UpdateChart()
        {
            
            ChartRepository repository = new ChartRepository();

            string deviceSerialNo = HttpContext.Session.GetString("currentSerialNumber") != null ? HttpContext.Session.GetString("currentSerialNumber").ToString() : "1606008363";
            string selectedDataTypes = HttpContext.Request.Form["chkBox"].ToString();

            string query = repository.PrepSelectQuery(selectedDataTypes, deviceSerialNo, "2021-03-05 10:44:55.544398", "2021-03-11 12:44:55.544398");

            GeneralObjects.ServiceResponse response = repository.GetChartData(query);

            if (response.Return_Code != 0)
                return GeneralObjects.RES.R_NOK;

            TempData["SuccessMSG"] = "Successfull!";
            ViewBag.AllData = response.This_Object;

            return GeneralObjects.RES.R_OKK;
        }

For instance when I select the parameters from the screen response.ThisObject Is like

{type: "line",
markerType:"none",
xValueType:"dateTime",
xValueFormatString:"DDDD MMM YYYY HH:mm:ss",
name:'Discharge',
showInLegend: true,
dataPoints:[{"x":1614937497000.0,"y":315.0},{"x":1614937502000.0,"y":315.0},{"x":1614937507000.0,"y":317.0},{"x":1614937517000.0,"y":320.0},{"x":1614937523000.0,"y":320.0},{"x":1614937528000.0,"y":322.0},{"x":1614937533000.0,"y":322.0},{"x":1614937537000.0,"y":323.0},{"x":1614937543000.0,"y":325.0},{"x":1614937547000.0,"y":325.0},{"x":1614937552000.0,"y":327.0},{"x":1614937563000.0,"y":328.0},{"x":1614937573000.0,"y":330.0},{"x":1614937583000.0,"y":331.0},{"x":1614937588000.0,"y":331.0},{"x":1614937593000.0,"y":332.0},{"x":1614937598000.0,"y":332.0},{"x":1614937603000.0,"y":333.0},{"x":1614937608000.0,"y":334.0}]}
{type: "line",
markerType:"none",
xValueType:"dateTime",
xValueFormatString:"DDDD MMM YYYY HH:mm:ss",
name:'subcooling',
showInLegend: true,
dataPoints:[{"x":1614937507000.0,"y":22.0},{"x":1614937513000.0,"y":22.0},{"x":1614937517000.0,"y":24.0},{"x":1614937528000.0,"y":23.0},{"x":1614937537000.0,"y":24.0},{"x":1614937558000.0,"y":26.0},{"x":1614937568000.0,"y":25.0},{"x":1614937573000.0,"y":23.0},{"x":1614937578000.0,"y":23.0},{"x":1614937603000.0,"y":22.0},{"x":1614937613000.0,"y":21.0}]}

I got this value right before the return GeneralObjects.RES.R_OKK; However, It doesn't get updated...

Thank you in advance for any suggestion.


Solution

  • Do not store the data in ViewBag when do the update with ajax, because the data in ViewBag will not change in the view.

    I suggest you could directly return the data in the update action.

    A simple example changed from Official Site

    @{
        ViewData["Title"] = "Home Page";
    }
    
    <div id="chartContainer" style="height: 370px; width: 100%;"></div>
    
    <button type="button" id="getDataBtn" class="btn btn-success" onclick="Update();">Update Chart</button>
    @section scripts{
    
        <script src="https://canvasjs.com/assets/script/jquery-1.11.1.min.js"></script>
        <script src="https://canvasjs.com/assets/script/jquery.canvasjs.min.js"></script>
        <script>
    
            var dataPoints = [];
            var chart
            function addData(data) {
    
                for (var i = 0; i < data.length; i++) {
                    dataPoints.push({
                        x: new Date(data[i].x),
                        y: data[i].y
                    });
                }
    
                chart = new CanvasJS.Chart("chartContainer", {
                    animationEnabled: true,
                    theme: "light2",
                    title: {
                        text: "Lenovo Group Stock Price-2017"
                    },
                    axisY: {
                        title: "In HK$",
                        titleFontSize: 24
                    },
                    data: [{
                        type: "line",
                        yValueFormatString: "HK$#,###",
                        dataPoints: dataPoints
                    }]
                });
                chart.render();
            }
    
            window.onload = function () {
                $.ajax({
                    method: 'get',
                    url: '/home/json',
                    success: function (data) {
                        addData(data)
                    }
                })
            }
    
            function Update() {
                dataPoints = [];
                $.ajax({
                    method: 'get',
                    url: '/home/json2',
                    success: function (data) {
                        addData(data)
                    }
                })
            
            }
        </script>
    }
    

    Controller:

    public IActionResult Index()
    {
        return View();
    }
    
    public ContentResult JSON()
    {
        List<DataPoint> dataPoints = new List<DataPoint>();
        dataPoints.Add(new DataPoint(1481999400000, 4.67));
        dataPoints.Add(new DataPoint(1482604200000, 4.7));
        dataPoints.Add(new DataPoint(1483209000000, 4.96));
        dataPoints.Add(new DataPoint(1483813800000, 5.12));
        dataPoints.Add(new DataPoint(1484418600000, 5.08));
        dataPoints.Add(new DataPoint(1485023400000, 5.11));
        dataPoints.Add(new DataPoint(1485628200000, 5));
        dataPoints.Add(new DataPoint(1486233000000, 5.2));
        dataPoints.Add(new DataPoint(1486837800000, 4.7));
        dataPoints.Add(new DataPoint(1487442600000, 4.74));
    
        JsonSerializerSettings _jsonSetting = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore };
        return Content(JsonConvert.SerializeObject(dataPoints, _jsonSetting), "application/json");
    }
    
    public ContentResult JSON2()
    {
        List<DataPoint> dataPoints = new List<DataPoint>();
        dataPoints.Add(new DataPoint(1481999400000, 4.67));
        dataPoints.Add(new DataPoint(1482604200000, 4.7));
        dataPoints.Add(new DataPoint(1483209000000, 4.96));
        dataPoints.Add(new DataPoint(1483813800000, 5.12));
        dataPoints.Add(new DataPoint(1484418600000, 5.08));
        dataPoints.Add(new DataPoint(1485023400000, 5.11));
        dataPoints.Add(new DataPoint(1485628200000, 5));
        dataPoints.Add(new DataPoint(1486233000000, 5.2));
        dataPoints.Add(new DataPoint(1486837800000, 4.7));
        dataPoints.Add(new DataPoint(1487442600000, 4.74));
        dataPoints.Add(new DataPoint(1488047400000, 4.67));
        dataPoints.Add(new DataPoint(1488652200000, 4.66));
        dataPoints.Add(new DataPoint(1489257000000, 4.86));
        dataPoints.Add(new DataPoint(1489861800000, 4.91));
        dataPoints.Add(new DataPoint(1490466600000, 5.12));
        dataPoints.Add(new DataPoint(1491071400000, 5.4));
        dataPoints.Add(new DataPoint(1491676200000, 5.08));
        dataPoints.Add(new DataPoint(1492281000000, 5.05));
        dataPoints.Add(new DataPoint(1492885800000, 4.98));
        dataPoints.Add(new DataPoint(1493490600000, 4.89));
        dataPoints.Add(new DataPoint(1494095400000, 4.9));
        dataPoints.Add(new DataPoint(1494700200000, 4.95));
        dataPoints.Add(new DataPoint(1495305000000, 4.88));
        dataPoints.Add(new DataPoint(1495909800000, 5.07));
        JsonSerializerSettings _jsonSetting = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore };
        return Content(JsonConvert.SerializeObject(dataPoints, _jsonSetting), "application/json");
    }
    

    enter image description here