This is a migrated thread and some comments may be shown as answers.

Looping problem - dataBound event calls setOptions which then fires dataBound event

2 Answers 444 Views
Charts
This is a migrated thread and some comments may be shown as answers.
Joshua
Top achievements
Rank 1
Joshua asked on 29 Sep 2016, 03:50 AM

I have a html/javascript chart which I populate via an ajax call. On dataBound, i resize the chart xAxis max and draw plotbands based on the values bound to the grid. Unfortunately, the setOptions call seems to then fire the dataBound event again... and around and around it goes in an endless loop. I got around this by setting a flag so that it only processes the first time. However, the issue I now face is that when I pull new data into the chart later (say because the user expanded the data ranges), i cant reset that flag and let it fire the code in the dataBound event. So, when the user expands the date ranges there is a good chance that my poltbands and axiscrossing settings will be wrong. Any advice?  See below for code...

 

$.ajax({
        type: "POST",
        data: JSON.stringify({
            startDate: $('#txtDateRangeFilter').data('daterangepicker').startDate,
            endDate: $('#txtDateRangeFilter').data('daterangepicker').endDate
        }),
        url: "/User/EChart",
        contentType: "application/json",
        dataType: 'json'
    })
        .done(function (data) {
            var plotbandloaded = false;

            $('#currentDuration').text(Math.round(data.userGoalDetails.DurationHours * 100) / 100 + " hrs");
            $('#goalDuration').text(Math.round(data.userGoalDetails.Goal * 100) / 100 + " hrs");
            $("#chartE").kendoChart(
            {
                dataSource: {
                    data: data.userActivity
                },
                sort: {
                    field: "CreateDateTime",
                    dir: "asc"
                },
                title: {
                    text: ""
                },
                legend: {
                    position: "bottom"
                },
                chartArea: {
                    background: "",
                    width: 300,
                    height: 190
                },
                seriesDefaults: {
                    type: "line",
                    style: "smooth"
                },
                series: [
                    {
                        field: "Minutes",
                        name: "Minutes",
                        axis: "Minutes",
                        color: "#4D4D4D",
                        type: "column"
                    }, {
                        name: "Count",
                        field: "Count",
                        axis: "Count",
                        color: "#00B5A3",
                        type: "line"
                    }
                ],
                valueAxes: [{
                    name: "Minutes",
                    color: "#4D4D4D"
                }, {
                    name: "Count",
                    color: "#00B5A3"
                }],
                categoryAxis: {
                    field: "Day",
                    majorGridLines: {
                        visible: false
                    },
                    axisCrossingValues: [0, 50],
                    labels: {
                        rotation: "auto"
                    }
                },
                tooltip: {
                    visible: true,
                    format: "{0}%",
                    template: "#= series.name #: #= value #"
                },
                dataBound: function (e) {
                    setTimeout(function () {
                        if (plotbandloaded == false) {
                            var goal = Math.round((data.userGoalDetails.Goal * 60) * 100) / 100;
                            var goalTo = goal + (goal * .025);
                            var setMax = goal + (goalTo * .15);
                            var chart = $('#chartE').data("kendoChart");
                            var axisCrossing = chart.options.series[1].data.length + 1;
                            var options = {
                                valueAxes: [{
                                        name: "Minutes",
                                        color: "#4D4D4D",
                                        max: setMax,
                                        plotBands: [{
                                            from: goal,
                                            to: goalTo,
                                            color: "#c00",
                                            opacity: 0.3
                                        }]
                                    }, {
                                        name: "Count",
                                        color: "#00B5A3"
                                    }],
                                categoryAxis: { axisCrossingValues: [0, axisCrossing] }
                                };

                            plotbandloaded = true;
                            chart.setOptions(options);
                        };
                    }, 100)
                }
            });

        });

2 Answers, 1 is accepted

Sort by
0
Joshua
Top achievements
Rank 1
answered on 30 Sep 2016, 01:43 AM

Is there a better way to do this?

 

Anyone, anyone?...

 

This is what I feel like right now...

[https://www.youtube.com/watch?v=uhiCFdWeQfA]

0
Dimo
Telerik team
answered on 03 Oct 2016, 08:17 AM
Hi Joshua,

The Chart's setOptions method recreates and rebinds the widget, so the observed endless loop is expected. Generally, we do not recommend executing a widget's setOptions method in the same widget's event handler.

In this specific case, a possible alternative is to manipulate the chart options directly in the dataBound event. No setTimeout will be needed. A similar approach is used here:

http://docs.telerik.com/kendo-ui/controls/charts/how-to/grouped-line-chart-different-markers

function onDB(e) {
  var chart = e.sender,
      options = chart.options,
      series = options.series;
 
  series[0].markers.type = "triangle";
  series[1].markers.type = "cross";
  series[2].markers.type = "square";
}

Please note that this is not something that works for all Kendo UI widgets.

Regards,
Dimo
Telerik by Progress
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
Tags
Charts
Asked by
Joshua
Top achievements
Rank 1
Answers by
Joshua
Top achievements
Rank 1
Dimo
Telerik team
Share this question
or