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

Push realtime data to kendo chart with signalr

1 Answer 326 Views
Chart
This is a migrated thread and some comments may be shown as answers.
David
Top achievements
Rank 1
David asked on 17 Jun 2015, 09:03 AM

I am building an application in ASP.NET MVC where I am building different Kendo charts to show realtime data with SignalR. I am trying to let the Hub push data constantly to the chart. But I only manage to let the chart update its data on page load, not realtime.

 

<script src="@Url.Content("~/Scripts/jquery.signalR-2.2.0.min.js")"></script>
<script src="@Url.Content("~/signalr/hubs")"></script>
 
<script>
    var hub,
      hubStart;
 
    $(function () {
        var hubUrl = "http://localhost:52373/signalr/hubs";
        var connection = $.hubConnection(hubUrl, { useDefaultPath: false });
        hub = connection.createHubProxy("serverHub");
        $.connection.hub.logging = true;
        hubStart = connection.start();
    });
 
</script>

@(Html.Kendo().Chart<Model.ServerState>()
              .Name("server1")
              .Title(title => title
                  .Text("Server 1")
                  .Color("White")
                  .Font("25px Arial")
              )
              .Legend(legend => legend
                  .Color("Gray")
                  .Position(ChartLegendPosition.Bottom)
                  .Font("20px Arial")
              )
              .ChartArea(chartArea => chartArea
                  .Background("transparent")
              )
              .SeriesDefaults(seriesDefaults =>
                  seriesDefaults.Line().Style(ChartLineStyle.Smooth)
              )
              .Series(series =>
              {
                  series.Line(model => model.Performance.Memory).Name("Memory");
                  series.Line(model => model.Performance.Processor).Name("Processor");
              })
              .CategoryAxis(axis => axis
                  .Title(categoryTitle => categoryTitle
                    .Text("Time")
                    .Font("25px Arial"))
                  .Color("Gray")
                  .Labels(labels => labels
                      .Font("20px Arial"))
                  .MajorGridLines(lines => lines.Visible(false))
              )
              .ValueAxis(axis => axis
                  .Numeric().Labels(labels => labels.Format("{0}%"))
                  .Line(line => line.Visible(false))
                  .AxisCrossingValue(-10)
                  .Color("Gray")
                  .Labels(labels => labels
                      .Font("20px Arial"))
              )
              .Tooltip(tooltip => tooltip
                  .Visible(true)
                  .Format("{0}%")
                )
              .DataSource(source => source
                  .SignalR()
                  .AutoSync(true)
                  .Transport(transport => transport
                      .Promise("hubStart")
                      .Hub("hub")
                      .Client(c => c
                          .Read("read"))
                      .Server(server => server
                          .Read("read")
                          ))
                  .Schema(schema => schema
                      .Model(model =>
                      {
                          model.Id("Id");
                          model.Field("Id", typeof(int)).Editable(false);
                          model.Field("Memory", typeof(float));
                          model.Field("Processor", typeof(float));
                      }
                      )
            ))
)

 

//Best case:
public ServerStateEvent Read()
        {
        //Inside thread which pushes an message containing the object to kendo chart
                Clients.All.sendMessage(msg);
         }
//Current case, this method has to be called by kendo chart to update its data realtime
 public ServerStateEvent Read()
        {
         //this method gets data and returns it to kendo chart
                return msg;
         }

What I want is the "best case" where the Hub pushes data with the sendMessage function to kendo. This does not seems possible?

The current case works but only one time, the autoSync in kendo does not help.

1 Answer, 1 is accepted

Sort by
0
T. Tsonev
Telerik team
answered on 19 Jun 2015, 08:04 AM
Hello,

If I understand correctly, you'd like the SignalR hub to push all records to the chart on each change?
 
What we usually do is to hook the CRUD methods of the SignalR hub. This way the data source can sync up based only on what has changed without transferring all the data.

I'm attaching a sample application that demonstrates this. Also find attached the hub source code.

I hope this helps.

Regards,
T. Tsonev
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Shivar
Top achievements
Rank 1
commented on 26 Jun 2023, 12:33 PM

What triggers this change or forces the chart to update?

I currently have my chart hooked up to CRUD methods but when I insert data into the DB, there's no trigger to update the chart. Am I missing something?

What I added as a hack (which works) is the following:

Server Side - Notify the client of the change

IHubContext context = GlobalHost.ConnectionManager.GetHubContext<DashboardHub>();

context.Clients.All.RefreshData(t.Count);

 

Client Side - Force the chart to update

hub.client.refreshData = function (dataCount) {
        var chart = $("#chart").data("kendoChart");
        chart.dataSource.read();
};

This works but there's an infinite loop between the hub and the client so to get rid of the loop, I used the row count to set a flag and only force the chart to read if the new row count is greater than the old row count.

How do you implement this using a cleaner solution?

Thanks.

Tags
Chart
Asked by
David
Top achievements
Rank 1
Answers by
T. Tsonev
Telerik team
Share this question
or