c# - Smooth chart update from multithreaded data source -


we have several graphs show filtered data surface emg sensors. data received on tcp , propagated using event. datapackets of type datapackets , such filtered out. i'm using buffer let packets pass through @ 30fps. i'm listening event using reactive extensions follows:

observable.fromevent<packet>(h => this.dataservice.packetreceived += h, h=> this.dataservice.packetreceived -= h)           .oftype<datapacket>()           .buffer(timespan.fromseconds(1.0 / 30))           .observeondispatcher()           .subscribe(               packet => this.receivedatapackets(packet.tolist()),               err => this.log.error("error subscribing data packets", err),               () => this.log.info("finished listening data packets")); 

to display emg data use telerik chartview. problem i'm having data update not smooth, graph choppy.

there several reasons this:

  1. telerik chart not fast enough 1000 data points per second
  2. dispatchertimer not fire @ constant rate
  3. data not received @ constant rate

point 1 solved sampling input data 1000 points visible in graph.

point 2 cannot solved unfortunately. tried raising priority render not @ all. http://social.msdn.microsoft.com/forums/en-us/5eea6700-1c79-4da6-9b68-efa480ed3a36/simplify-wpf-dispatcher-calls?forum=rx

point 3 related point 2. try solve both timed queue using system.debug.stopwatch. datapackets contain timestamp , used let them through @ constant rate on dispatcher thread. suspect not since dispatcherrate not linked refresh rate of renderthread.

what can reduce choppiness? tried lightningchart ultimate supposed much faster. indeed have better performance , there no need sampling, can render each , every datapoint. samples provided lightningchart run butter smooth, read data in main thread. when implement chart in our multi-threaded program still suffers combination of point 2 , 3 (and fact more expensive telerik chartview.)

[update]

classic mistake. datasource using dispatchertimer gather data. changing observable.interval massively increased performance.

i have had similar troubles chart control a while ago. found charting controls not handle 1000+ datapoints. found trying re-render more 5-15 times per second pretty tough on dispatcher.

things suggest are:

  1. aim lower frame rate. hoping updates chart every 33ms?
  2. look reduce data set 1000 points. again play numbers see works target spec pc , controls/datatemplating. this old post may you. provides way pick x useful points render collection
  3. dial fancy animations or ui rendered per point on chart. if adding more items each have tool tips, brushes, animations , excess layout panels, pay cost. note not pay cost created, later when gc tries clear out these thousands of ui objects.
  4. do less work on dispatcher. know not much, move tolist() , on other thread. also, dont send empty lists processed (if applicable events)
  5. consider using d3/ddd charts. while not great when reviewed them, colleagues have had success them since then.

    observable.fromevent<packet>(h => this.dataservice.packetreceived += h, h=> this.dataservice.packetreceived -= h)   .oftype<datapacket>()   .buffer(timespan.fromseconds(1.0 / 8))  //reduce fps   .select(packet=>packet.tolist())        //reduce work done on dispatcher   .where(packet=>packet.count>0)          //dont send empty sets dispatcher   .observeondispatcher()   .subscribe(       packet => this.receivedatapackets(packet),       err => this.log.error("error subscribing data packets", err),       () => this.log.info("finished listening data packets")); 

i not sure if helps, here another link code presentation. part of presentation how stream data via rx wpf chart. potentially rip whole thing.


Comments

Popular posts from this blog

java.util.scanner - How to read and add only numbers to array from a text file -

html - Repeat image to extend header to fill screen -

javascript - Backbone.js getting target attribute -