0

i have made an application in mvc dot net using highcharts i have connected them to DB and showed them in view till now every thing is running fine

but now i want to do is that if DB is updated the charts will be automatically show the updated data. for now i have to refresh the page to view updated data and it's showing well but all i want is not refresh it.

i have searched many articles and found than ajax polling should help me out so in my controller code i have passed all data in ViewData coming from reader

while (reader.Read())
                {
                    energy_kwh.Add(Convert.ToDouble(reader["Energy_kWh"]));
                    power_kw.Add(Convert.ToDouble(reader["Power_kW"]));
                    voltage_1.Add(Convert.ToDouble(reader["Voltage_Phase_1"]));
                    voltage_2.Add(Convert.ToDouble(reader["Voltage_Phase_2"]));
                    voltage_3.Add(Convert.ToDouble(reader["Voltage_Phase_3"]));
                    current_1.Add(Convert.ToDouble(reader["Current_Phase_1"]));
                    current_2.Add(Convert.ToDouble(reader["Current_Phase_2"]));
                    current_3.Add(Convert.ToDouble(reader["Current_Phase_3"]));
                    Meter_datetime.Add(sample_con.ConvertToUnixTimestamp(Convert.ToDateTime(reader["Data_Datetime"])));
                    device_id = Convert.ToInt32(reader["Device_ID"]);
                }

ViewData["energy_kwh"] = energy_kwh;
                ViewData["Meter_datetime"] = Meter_datetime;
                ViewData["power_kw"] = power_kw;
                ViewData["voltage_1"] = voltage_1;
                ViewData["voltage_2"] = voltage_2;
                ViewData["voltage_3"] = voltage_3;
                ViewData["current_1"] = current_1;
                ViewData["current_2"] = current_2;
                ViewData["current_3"] = current_3;
                ViewData["x"] = x;
                ViewData["events"] = events;
                return View();

above 'x' is the sreen width only in my view i have created a global getSVG method that takes an array of charts as an argument

 $(function () { Highcharts.getSVG = function (charts) {
        var svgArr = [],
            top = 0,
            width = 0;

        $.each(charts, function(i, chart) {
            var svg = chart.getSVG();
            svg = svg.replace('<svg', '<g transform="translate(0,' + top + ')" ' );
            svg=svg.replace('</svg>', '</g>');

            top += chart.chartHeight;
            width = Math.max(width, chart.chartWidth);

            svgArr.push(svg);
        });

        return '<svg height="'+ top +'" width="' + width + '" version="1.1" xmlns="http://www.w3.org/2000/svg">' + svgArr.join('') + '</svg>';
    };

and also created a global export Charts method that takes an array of charts as an argument, and exporting options as the second argument

 Highcharts.exportCharts = function(charts, options) {

            // Merge the options
            options = Highcharts.merge(Highcharts.getOptions().exporting, options);

            // Post to export server
            Highcharts.post(options.url, {
                filename: options.filename || 'chart',
                type: options.type,
                width: options.width,
                svg: Highcharts.getSVG(charts)
            });
        };

after that i have arranged data coming from controller like this

var myArrayX_kwh = [];
        var myArrayY_kwh = [];
        var myArrayY_power = [];
        var myArrayY_voltage_1 = [];
        var myArrayY_voltage_2 = [];
        var myArrayY_voltage_3 = [];
        var myArrayY_current_1 = [];
        var myArrayY_current_2 = [];
        var myArrayY_current_3 = [];

        var arry_kwh = [];
        var arry_power = [];
        var arry_voltage_1 = [];
        var arry_voltage_2 = [];
        var arry_voltage_3 = [];
        var arry_current_1 = [];
        var arry_current_2 = [];
        var arry_current_3 = [];

then i have 2 for loops that will push data in array like this

@foreach (var st in ViewData["Meter_datetime"] as List<double?>)
        {
        @:myArrayX_kwh.push(@st);
    }

    @foreach (var st in ViewData["energy_kwh"] as List<double?>)
    {
        @:myArrayY_kwh.push(@st);
    }
    @foreach (var st in ViewData["power_kw"] as List<double?>)
    {
        @:myArrayY_power.push(@st);
    }
    @foreach (var st in ViewData["voltage_1"] as List<double?>)
    {
        @:myArrayY_voltage_1.push(@st);
    }
    @foreach (var st in ViewData["voltage_2"] as List<double?>)
    {
        @:myArrayY_voltage_2.push(@st);
    }
    @foreach (var st in ViewData["voltage_3"] as List<double?>)
    {
        @:myArrayY_voltage_3.push(@st);
    }
    @foreach (var st in ViewData["current_1"] as List<double?>)
    {
        @:myArrayY_current_1.push(@st);
    }
    @foreach (var st in ViewData["current_2"] as List<double?>)
    {
        @:myArrayY_current_2.push(@st);
    } @foreach (var st in ViewData["current_3"] as List<double?>)
     {
      @:myArrayY_current_3.push(@st);
    }


    for (var i = 0; i < myArrayX_kwh.length; i++) {
        arry_kwh.push({ x: myArrayX_kwh[i], y: myArrayY_kwh[i], });
        arry_power.push({ x: myArrayX_kwh[i], y: myArrayY_power[i], });
        arry_voltage_1.push({ x: myArrayX_kwh[i], y: myArrayY_voltage_1[i], });
        arry_voltage_2.push({ x: myArrayX_kwh[i], y: myArrayY_voltage_2[i], });
        arry_voltage_3.push({ x: myArrayX_kwh[i], y: myArrayY_voltage_3[i], });
        arry_current_1.push({ x: myArrayX_kwh[i], y: myArrayY_current_1[i], });
        arry_current_2.push({ x: myArrayX_kwh[i], y: myArrayY_current_2[i], });
        arry_current_3.push({ x: myArrayX_kwh[i], y: myArrayY_current_3[i], });
    }

then i have initialized and written the code for my charts

 var chart1 = new Highcharts.Chart({

        chart: {
            renderTo: 'container1',
            type: 'column',
            zoomType: 'xy',
            resetZoomButton: {
                position: {
                    align: 'right', // by default
                    verticalAlign: 'top', // by default
                    x: -250,
                    y: 5,
                    //height: 25
                },

                relativeTo: 'chart'
            }
        },
        title: {
            text: 'Energy vs Date & Time',
            style: {
                //color: '#FF00FF',
                fontWeight: 'bold',
                //fontSize: '12px'
                //sfont: 'bold 200px Verdana, sans-serif',
            }
        },
        xAxis: {
            //  categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
            type: 'datetime',
           // max: new Date().getTime(),
            //labels: {

            // //   format: {value:}
            //    style: {
            //        fontSize: '13px',
            //        fontFamily: 'Verdana, sans-serif'
            //    }
            //}
        }, yAxis: {
            title: {
                text: 'Energy (kWh)',
                style: {
                    //color: '#FF00FF',
                    fontSize: '12px',
                    //sfont: 'bold 200px Verdana, sans-serif',
                }
            }

        },

as i am displaying 4 charts so i have done the same as like above with other 3 here the things are working good all the data from DB is showing in charts and if DB is updated then on page refresh it is showed but as i wrote above i don't want to refresh the page

for this i have done

var dt = JSON.stringify({
            "arryKwh": arry_kwh,
            "arryPower": arry_power,
            "arryVoltage_1": arry_voltage_1,
            "arryVoltage_2": arry_voltage_2,
            "arryVoltage_3": arry_voltage_3,
            "arryCurrent_1": arry_current_1,
            "arryCurrent_2": arry_current_2,
            "arryCurrent_3": arry_current_3
        });  

after that i have done an ajax call and passed data into success alert to view whether it's having my data or not

 (function poll() {              
            setTimeout(function () {
                  $.ajax({                      
                    type: "POST",
                    url: "/Home/MultiGraph/",                      
                    data:dt,
                    success: function (data)
                    {
                        alert(data)

                    }, 
                });
                poll();
            }, 5000);
        })();

But when i run the application the alert message display with this

I am missing something but what it is i don't know

I have found SignalR but i think it would be time taking as i have to write all things again

Another solution came to mind is that may be if i set a condition in view or controller in which it checks if the DB is updated than it automatically refresh the page

I am confused any help will be appreciated

  • The AJAX call is receiving a web page. You need to use an ApiController to return just data. If you create a new ApiController (WebApi) it will create the stubs for all the Http verbs and you can access the data from them. I'd recommend having a `lastUpdated` datetime or a hash value of some sort that will change when the database is updated. Use AJAX to check that so that your polling is only requesting small amounts of data each time, so you can do it frequently (every second or two should be fine). Then, if there's a change, have an action that gets the full dataset for you. – Reinstate Monica Cellio Sep 02 '16 at 06:49
  • I have a action which is giving me all the data from database –  Sep 02 '16 at 07:04
  • In that case, try returning a `PartialView` and replacing the graph with that. You're getting a full page (`View`) from your call to the controller, and that's obviously not going to help. A `PartialView` will return the markup for that specific method. – Reinstate Monica Cellio Sep 02 '16 at 07:32
  • Alternatively, have a look at this question that may point you in the right direction... http://stackoverflow.com/questions/16186083/making-a-simple-ajax-call-to-controller-in-asp-net-mvc – Reinstate Monica Cellio Sep 02 '16 at 07:32

0 Answers0