Line Chart Appends Entries At End After Dynamic Load

9 Answers 69 Views
Charts
Eli
Top achievements
Rank 2
Iron
Iron
Iron
Eli asked on 20 Sep 2023, 06:37 PM

I am creating a dynamic line chart (see previous https://www.telerik.com/account/support-center/view-ticket/1623605) I am facing another issue with the line chart - in which entries are appending for some apparent reason at the end. Instead of the horizontal (x) axis being a consecutively ordered, the chart itself restarts the axis for the second series of data.

 

Here is an image of the current issue I am facing.

 

As you can see above, instead of filling these entries in back at the beginning, the entire horizontal axis restarts from 0. 

The only points that work "correctly" are points that exactly match each other in the beginning.

At 4:54:00 both points share that exact "second" in time so the "green" point appears appropriately.

If the point does not "match" exactly, it is added and appended to the very end of the horizontal axis as I showed above.

What is causing this? Why does the horizontal axis restart?

My code is as follows:


 <div id="example">        
      <div class="demo-section wide">
        <div id="chart"></div>
      </div>
      <script>
          var testNum = "Test Data for #" + '@Model.testNum';       

          var datareader = JSON.parse(Model.dynamicDataRetrievedFromCSV);         

          function createChart() {
              $("#chart").kendoChart({
                  renderAs: "canvas",
                  title: {
                      text: testNum
                  },
                  legend: {
                      visible: true
                  },
                  seriesDefaults: {
                      type: "line",
                      /*stack: true,*/             

                      labels: {
                          visible: false,
                          format: "{0}",
                          background: "transparent"
                      }
                  },
                  valueAxis: {
                      labels: {
                          format: "{0}"
                      },
                      line: {
                          visible: false
                      },
                      min: 0,
                      max: 300

                  },
                  categoryAxis: {
                      majorGridLines: {
                          visible: false
                      },
                      min: 0,
                      max: 10
                  },
                  tooltip: {
                      visible: true,
                      template: "#= series.name #: #= value #"
                  },
                   pannable: {
             
                  },
                  zoomable: {
                      mousewheel: {
                          rate: 0.1
                      },
                      selection: {
                         
                      }
                  }
                
              });
          }

        $(document).ready(createChart);
        $(document).bind("kendo:skinChange", createChart);
          $(document).ready(function () {
              let chart = $("#chart").data("kendoChart");
              var dataParsed = datareader;

              let ds = new kendo.data.DataSource({
                  data: dataParsed,
                  group: "label"
              });
              

              chart.setOptions({
                  dataSource: ds,
                  series: [{
                      field: "value",
                      categoryField: "time",
                      visible: false
                  }]
              }); 
          });
     
      </script>
    </div>

 

Thank you for any help, and thanks for the support you guys have provided over the last couple weeks!

 

 

 

 

9 Answers, 1 is accepted

Sort by
0
Eli
Top achievements
Rank 2
Iron
Iron
Iron
answered on 20 Sep 2023, 06:43 PM

Also, here is a sampleset of my data in JSON format if you need it:

 


var serialized = '[{"label":"WATT-6746","time":"0:00:00","value":"971.7704"} ,{"label":"VOLT-6746","time":"0:00:00","value":"233.09"} ,{"label":"VOLT-10098","time":"0:00:43","value":"115.2"}, {"label":"VOLT-6746","time":"0:00:54","value":"233.12"}, {"label":"VOLT-10098","time":"0:01:34","value":"115.2"}, {"label":"WATT-6746","time":"0:01:54","value":"969.0248"},

{"label":"VOLT-6746","time":"0:01:54","value":"233.14"},

{"label":"VOLT-10098","time":"0:02:24","value":"115.1"},

{"label":"WATT-10098","time":"0:02:24","value":"10.53"},

{"label":"WATT-6746","time":"0:02:54","value":"968.9817"},

{"label":"VOLT-6746","time":"0:02:54","value":"233.14"},

{"label":"VOLT-10098","time":"0:03:13","value":"115.1"},

{"label":"WATT-10098","time":"0:03:13","value":"10.50"},

{"label":"WATT-6746","time":"0:03:54","value":"969.8931"},

{"label":"VOLT-6746","time":"0:03:54","value":"233.13"},

{"label":"VOLT-10098","time":"0:04:03","value":"115.2"},

{"label":"WATT-10098","time":"0:04:03","value":"10.47"},

{"label":"VOLT-10098","time":"0:04:54","value":"115.1"},

{"label":"WATT-10098","time":"0:04:54","value":"10.44"},

{"label":"WATT-6746","time":"0:04:54","value":"971.608"},

{"label":"VOLT-6746","time":"0:04:54","value":"233.14"},

{"label":"VOLT-10098","time":"0:05:43","value":"115.1"},

{"label":"WATT-10098","time":"0:05:43","value":"10.39"},

{"label":"WATT-6746","time":"0:05:54","value":"971.7053"},

{"label":"VOLT-6746","time":"0:05:54","value":"233.1"},

{"label":"VOLT-10098","time":"0:06:34","value":"115.1"},

{"label":"WATT-10098","time":"0:06:34","value":"10.34"},

{"label":"WATT-6746","time":"0:06:55","value":"967.7635"},

{"label":"VOLT-6746","time":"0:06:55","value":"233.12"},

{"label":"VOLT-10098","time":"0:07:24","value":"115.1"},

{"label":"WATT-10098","time":"0:07:24","value":"10.31"},

{"label":"WATT-6746","time":"0:07:54","value":"975.1256"},

{"label":"VOLT-6746","time":"0:07:54","value":"233.1"}]

 


0
Nikolay
Telerik team
answered on 21 Sep 2023, 11:26 AM

Hello Eli,

Thank you for sharing the Chard declaration and the sample JSON data.

I used it to create a Dojo sample:

https://dojo.telerik.com/eSUQihAN

However, it does not replicate the problem. Is it possible to modify it to showcase the problem? 

Looking forward t your reply.

Regards,
Nikolay
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Kendo family, check out our getting started resources
0
Eli
Top achievements
Rank 2
Iron
Iron
Iron
answered on 21 Sep 2023, 01:28 PM

In the dojo you provided, it is in fact not working correctly.

Notice the 0:00:00 timeframe is appended to the end of the chart, when it should be at the start (see below)

 

https://dojo.telerik.com/eSUQihAN

 

 

0
Nikolay
Telerik team
answered on 22 Sep 2023, 12:25 PM

Hi Eli,

I believe the problem here is that the time property is not a valid JS date. Even if I try to convert it to a date it comes back as an invalid date:

The above "1:07:24" was taken from the JSON data. Once you provide a valid date and set categoryAxis.type to "date" the Chart shall work as expected.

Please let me know if you have any questions.

Regards,
Nikolay
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Kendo family, check out our getting started resources
0
Eli
Top achievements
Rank 2
Iron
Iron
Iron
answered on 22 Sep 2023, 07:16 PM

The issue is that this really isn't a "date", its just time. I even order the items in correct order before passing them to the chart control and it still reorders them incorrectly upon display.

I don't need the axis as a date, I just need it to recognize the "0:00:00" format as a time and order it correctly (or keep the format I pass it)

            var orderedItems = graphItems.AsQueryable().OrderBy(x => x.time).ToList();
            var serialized = JsonConvert.SerializeObject(orderedItems);

Above is my code where I order them before Serializing the object set in the controller.

It does in fact order the items correctly, until the chart control accesses the dataset - is there a way to replicate this in the control?

Does the chart not provide any support for time format (not date - just time)?

I would expect charts displaying only time (without date) along the horizontal axis would be a common occurrence when displaying data.

0
Nikolay
Telerik team
answered on 25 Sep 2023, 12:23 PM

Hello Eli,

I am afraid the Kendo UI components are designed to work with JS dates, and support for time only is not available. 

However, I think the problem here is that the Chart data is grouped. What you need to do is sort categories as demonstrated in this article.

       dataBound: function(e) {
            var axis = e.sender.options.categoryAxis;
            axis.categories = axis.categories.sort();
          }

Dojo demo: https://dojo.telerik.com/eSUQihAN/3

Please let me know if this is what you are looking for.

Regards,
Nikolay
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Kendo family, check out our getting started resources
0
Eli
Top achievements
Rank 2
Iron
Iron
Iron
answered on 28 Sep 2023, 08:07 PM

I ended up solving this issue fully. I am posting my process to help anyone else who could come upon this thread.

Since you mentioned the time being a string and being unable to order a string formatted as time, I chose to append the [HMS] time to a real date, and pass the datetime together, so that the grid would have something to order correctly.

Here is my controller where I am creating the JSON object set after parsing the CSV data (we append the 00:00:38 or whatever to the end of a real date)


string beginningDate = "0001-01-01";
 string[] timeParts = originalTestTime.Split(':');
 DateTime initialDate = DateTime.ParseExact(beginningDate, "yyyy-MM-dd", CultureInfo.InvariantCulture);//use the date as a starting point
                                                                                                                                      
 int hours = int.Parse(timeParts[0]);
 int minutes = int.Parse(timeParts[1]);
 int seconds = int.Parse(timeParts[2]);
 DateTime resultDate = initialDate.AddHours(hours)
                                  .AddMinutes(minutes)
                                  .AddSeconds(seconds); 
 co.time = resultDate;

So, our entry ends up looking as something like 

0001-01-01T00:00:38

And it is recognized by the chart as a datetime.

This allows the chart to order the entries correctly.

I then ran into another issue - the labels for the x axis included this 0001-01-01 date, so I then called the shortLabels() function from the CategoryAxis to remove that extra nonsense:

categoryAxis: {
                      majorGridLines: {
                          visible: false
                      },
                      baseUnitStep: 40,
                      labels: {
                          template: "#= shortLabels(value) #",
                          rotation: "auto"
                      },
                      min: 0,
                      max: 10
                  },

 

The shortLabels function trims off the dates from the dataset, clearly after the chart control has been sorted.

But another issue arose. If I had more than 24 hours worth of datapoints - it would start the time over. So it would read

23:59:45

00:00:38 (second day)

So i wrote another piece of the function that automatically corrects this time for the labels in chart.

 function shortLabels(value) {           
              const text = value.split("T")
              
              if (text[0] == "0001-01-02") {

                  var a = text[1].split(':'); 
                  const seconds = (+a[0]) * 60 * 60  + (+a[1]) * 60 + (+a[2]);
                  
                  const secondsAdded = parseInt(seconds) + 86400;
                  var hoursLeft = Math.floor(secondsAdded / 3600);
                  var min = Math.floor((secondsAdded - hoursLeft * 3600) / 60);
                  var secondsLeft = secondsAdded - hoursLeft * 3600 - min * 60;
                  secondsLeft = Math.round(secondsLeft * 100) / 100;
                  var newTime = hoursLeft < 10 ? "0" + hoursLeft : hoursLeft;
                  newTime += ":" + (min < 10 ? "0" + min : min);
                  newTime += ":" + (secondsLeft < 10 ? "0" + secondsLeft : secondsLeft);
                  return kendo.toString(newTime);
              }
              else
              {
                  return kendo.toString(text[1]);
              }
          }  

If the date is within 24 hours, we simply parse out the date the return just the HMS time to be displayed.

If the date exceeds 24 hours, we catch this, convert the original HMS to second, add 24 hours worth of seconds, and then convert back to HMS for the chart.

The final product is working chart! Thanks for all the help along the way.

 

0
Nikolay
Telerik team
answered on 29 Sep 2023, 12:37 PM

Hi Eli,

Thank you very much for the update and for sharing the solution you came up with.

If you allow me I will convert this to a forum thread so others can benefit from it.

Regards,
Nikolay
Progress Telerik

Stay tuned by visiting our public roadmap and feedback portal pages! Or perhaps, if you are new to our Kendo family, check out our getting started resources
0
Eli
Top achievements
Rank 2
Iron
Iron
Iron
answered on 30 Sep 2023, 12:03 AM
Yes go ahead! Thanks!
Nikolay
Telerik team
commented on 02 Oct 2023, 11:24 AM

Hi Eli,

Thank you for the permission. This is now a forum thread where the community can benefit from your replies.

Regards,

Nikolay

Tags
Charts
Asked by
Eli
Top achievements
Rank 2
Iron
Iron
Iron
Answers by
Eli
Top achievements
Rank 2
Iron
Iron
Iron
Nikolay
Telerik team
Share this question
or