Rolling window graph

Oct 5, 2009 at 11:06 PM

Hi

I am trying to create a "rolling window" type graph. Essentially I want it to work like the Simulation sample, just with the modification that after a certain number of data points (say 1000) has been added to the graph, the x-axis should automatically scroll to only show the last 1000 data points. Ideally it should be possible to scroll back in order to view older data points, and when a new data point is added the x-axis should again automatically scroll forward to show the 1000 most recently added data points (like a standard trading candlestick chart)

The sample MultipleDataPoints is close to this behaviour and I could probably hack it to do approx. what I want, but I assume there is a better way to implement it.

 

Regards and thanks in advance

 

 

 

 

Editor
Oct 17, 2009 at 12:13 PM

Hi,

 

First of all, some theory: DynamicDataDisplay's ChartPlotter (to be more precise, its Viewport) can be in two modes - 'FitToView' mode, when visible area is determined as a union of all charts' content bounds, and the second mode, when user (or programmer) have specified some value of plotter.Viewport.Visible and this value is a visible area, with no regard to charts' content bounds. Simulation sample works quite using this mechanism, so in the beginning chart is fitted to view and that's why its visible area is updated when content bounds of line chart changes.

And now how can you solve your task:

1) there is a special little system that can help you - it is called Viewport restrictions and it is a small bit of code that is called whenever viewport.Visible changes and allows you to change the way how the final value of visible is calculated. Also there are a little bit restrictions - those that are contained in FitToViewRestrictions collection of viewport - these are applied only when viewport is in fit-to-view mode. I have created a sample for you, it is available in the recent changeset (29055), in DynamicDataDisplay.sln, and there in Samples/Simple solution folder. In this sample I'm adding to plotter.Viewport.FitToViewRestrictions a new instance of FixedWidthRestriction, which allows us to have visible only the latest width values of data.

2) Also I have added a logic to the method that adds new point to data, that calls FitToView() method of Plotter - this is smth that you are describing like when a new data point is added the x-axis should again automatically scroll forward to show the 1000 most recently added data points.

 

Hope this sample will help you,

Best regards,

Mikhail.

Oct 19, 2009 at 9:32 AM

Hi Mikhail,

D3 is an awesome library - thank you!

I am also very interested in the Rolling Windows Graph; however, I don't see the sample that you referred to in the Samples folder (no Simple solution) in  29055.  If I am looking in the wrong place, please let me know.

Thank you and the team for sharing your hard work.

Best regards,

David Roh

Editor
Oct 19, 2009 at 11:56 AM

Hi David,

you need to open Nightly/sln/DynamicDataDisplay.sln/"Samples" solution folder/"Simple" sub folder/DynamicPointAddSample.csproj.

Best regards,

Mikhail.

Oct 19, 2009 at 12:04 PM

Thank you Mikhail - I was looking in the DevSamples folder instead of the Samples folder.

Best regards,

David Roh

Oct 19, 2009 at 12:26 PM

Hi Mikhail,

I have an interest in joining the development team.

Best regards,

David Roh

JK1@SoftwareByDavid.com

 

Editor
Oct 19, 2009 at 3:31 PM
Edited Oct 19, 2009 at 3:38 PM

Hi David,

 

You are the first who had such an interest, so we do not have yet some mechanism of doing this.

First of all, why do you want to join us? Do you have some additions to D3 that as you think can be interesting to others? What are they, or what are you going to develop?

Also there is a legal question of you taking part in development of D3. I'm not sure we are allowed by Microsoft to take other people into our team, but I'll investigate this question.

 

But of course we are grateful to you for such a desire. Maybe it can be implemented by creating another project (e.g., "DynamicDataDisplay Additions" or smth like that) and adding you as its developer - this is only one of mine ideas, it doesn't mean that we are to do it.

Best regards,

Mikhail.

Oct 19, 2009 at 4:02 PM

Hi Mikhail,

My interest in D3 is for some statistical analysis programs and some data visualization programs (I am also interested in working on combining your polynomial parser with D3 - I know that it is planned).
 
My motivation is simple - there are bugs in D3 that need to be fixed - if I fix them in my local code then I am out of synch with CodePlex.  In addition, it would be nice to contribute for the many hours of development time that I have received from CodePlex.
 
I am very busy so there are no guarantees for the amount of time that I will be able to contribute.
 
Send me an email address and I will return my resume - I have 10+ years of C#, 25+ years of C++, 20 years of Windows, 2 years of WPF and 2 years of Silverlight.
 
Best regards,
David Roh
Editor
Oct 21, 2009 at 8:14 AM

Hi David,

 

Sorry, but as this project is developed with the support and management of Microsoft Research Cambridge, we are not allowed to change our team. But we would be very grateful to you if you send us results of your work (I'm speaking now about bugs in D3 you have fixed) to my mail - thecentury@gmail.com.

It would be really great if there would be some notes saying what the bug was and how and where you've fixed it. We'll examine your changes and inculcate them into the most recent code of D3.

 

Parser you were speaking about is my own project, it is connected to D3 only as I'm belonging to D3's development team, though I was really planning some integration of this parser to D3. This integration should be rather simple - it was supposed to be done in the terms of new markers' data source.

As in new markers chart has an ItemsSource property of Object type, we can assign to this property whatever we want, and there is a set of factories that are actually building a dataSource from ItemsSource. Iе was supposed that user is able to pass a function as a string to ItemsSource property, and parser will parse it to some delegate like Func<T> and then this Func<T> will be used to calculate coordinates of markers and line points (as I was going to change LineChart's data source type to this data source from new markers). 

Thank you for your suggestions, I'm looking in future for working together with for making D3 better.

Best regards,

Mikhail.

Oct 21, 2009 at 12:45 PM
Hi Mikhail,
Okay, sounds good - I'll send in my bug fix with documentation.
What country are you in?
Best regards,
David
_____________
David Roh
McKinney, Texas
----- Original Message -----
From: [email removed]
To: [email removed]
Sent: Wednesday, October 21, 2009 3:21 AM
Subject: Re: Rolling window graph [dynamicdatadisplay:71063]

From: thecentury

Hi David,

Sorry, but as this project is developed with the support and management of Microsoft Research Cambridge, we are not allowed to change our team. But we would be very grateful to you if you send us results of your work (I'm speaking now about bugs in D3 you have fixed) to my mail - thecentury@gmail.com.

It would be really great if there would be some notes saying what the bug was and how and where you've fixed it. We'll examine your changes and inculcate them into the most recent code of D3.

Parser you were speaking about is my own project, it is connected to D3 only as I'm belonging to D3's development team, though I was really planning some integration of this parser to D3. This integration should be rather simple - it was supposed to be done in the terms of new markers' data source.

As in new markers chart has an ItemsSource property of Object type, we can assign to this property whatever we want, and there is a set of factories that are actually building a dataSource from ItemsSource. Iе was supposed that user is able to pass a function as a string to ItemsSource property, and parser will parse it to some delegate like Func<T> and then this Func<T> will be used to calculate coordinates of markers and line points (as I was going to change LineChart's data source type to this data source from new markers).

Thank you for your suggestions, I'm looking in future for working together with for making D3 better.

Best regards,

Mikhail.

Editor
Oct 21, 2009 at 12:54 PM

I'm in Moscow, Russian Federation.

 

Best regards,

Mikhail.

Oct 21, 2009 at 1:06 PM
Hi Mikhail
That is what I suspected - my wife and son are from Ukraine so I can get any translation done that I need.
Best regards,
David
----- Original Message -----
From: [email removed]
To: [email removed]
Sent: Wednesday, October 21, 2009 7:54 AM
Subject: Re: Rolling window graph [dynamicdatadisplay:71063]

From: thecentury

I'm in Moscow, Russian Federation.

Best regards,

Mikhail.

Nov 6, 2009 at 3:48 PM
Edited Nov 6, 2009 at 4:28 PM

Hi Mikhail,

I have been experimenting with the DynamicPoints sample you mentioned and have come across a problem.  I reduced the timer tick period to 200ms.  Initially the auto view fit works fine but then gradually slows down.  i.e. the rate at which the viewport is updated slows from 5 times per second down to once every few seconds.  The data is still being added to the linegraph at the correct rate but the viewport is not updating as regularly.

Trying to debug I found the following:

LineGraph.OnDataChanged() is called at the correct rate.  This calls base.UpdateBounds() which calls ViewPort2D.SetContentBounds().  For some reason this is only called at half the rate (cant figure out why but could be obvious to you).  This sets the ContentBoundsProperty dependancy prop which is where the problem seems to arise.  The ViewPortElement2D.OnPropertyChanged() does not seem to be called as many times as the dep prop changes.  I dont know very much about WPF but is this possible? (I have checked and the dep prop is being set to a different value each time)

 

Edit: I have realised that the frequency of view port updates is proportional to number of points in the graph.  If I start the graph with 10000 points then the view port is updated extremely infrequently.

Thanks

Dan

 

 

>    DynamicDataDisplay.dll!Microsoft.Research.DynamicDataDisplay.ViewportElement2D.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs e = {System.Windows.DependencyPropertyChangedEventArgs}) Line 278    C#
     WindowsBase.dll!System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs args) + 0x2c bytes    
     WindowsBase.dll!System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex entryIndex = {System.Windows.EntryIndex}, System.Windows.DependencyProperty dp = {ContentBounds}, System.Windows.PropertyMetadata metadata, System.Windows.EffectiveValueEntry oldEntry, ref System.Windows.EffectiveValueEntry newEntry = {System.Windows.EffectiveValueEntry}, bool coerceWithDeferredReference, System.Windows.OperationType operationType) + 0x515 bytes    
     WindowsBase.dll!System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty dp, object value, System.Windows.PropertyMetadata metadata, bool coerceWithDeferredReference, System.Windows.OperationType operationType, bool isInternal) + 0x1eb bytes    
     WindowsBase.dll!System.Windows.DependencyObject.SetValue(System.Windows.DependencyProperty dp, object value) + 0x2e bytes    
     DynamicDataDisplay.dll!Microsoft.Research.DynamicDataDisplay.Viewport2D.SetContentBounds(System.Windows.DependencyObject obj = {LineGraph: LineGraph}, Microsoft.Research.DynamicDataDisplay.DataRect value = {(4.03125;0) -> 662.90625*811}) Line 54 + 0x3e bytes    C#
     DynamicDataDisplay.dll!Microsoft.Research.DynamicDataDisplay.PointsGraphBase.UpdateBounds(Microsoft.Research.DynamicDataDisplay.DataSources.IPointDataSource dataSource = {Microsoft.Research.DynamicDataDisplay.DataSources.RawDataSource}) Line 108 + 0x38 bytes    C#
     DynamicDataDisplay.dll!Microsoft.Research.DynamicDataDisplay.PointsGraphBase.OnDataChanged() Line 76 + 0x1c bytes    C#
     DynamicDataDisplay.dll!Microsoft.Research.DynamicDataDisplay.LineGraph.OnDataChanged() Line 160 + 0x8 bytes    C#
     DynamicDataDisplay.dll!Microsoft.Research.DynamicDataDisplay.PointsGraphBase.OnDataChanged(object sender = {Microsoft.Research.DynamicDataDisplay.DataSources.RawDataSource}, System.EventArgs e = {System.EventArgs}) Line 71 + 0xb bytes    C#
     DynamicDataDisplay.dll!Microsoft.Research.DynamicDataDisplay.DataSources.EnumerableDataSourceBase<System.Windows.Point>.RaiseDataChanged() Line 50 + 0x1d bytes    C#
     DynamicDataDisplay.dll!Microsoft.Research.DynamicDataDisplay.DataSources.EnumerableDataSourceBase<System.Windows.Point>.observableCollection_CollectionChanged(object sender = Count = 812, System.Collections.Specialized.NotifyCollectionChangedEventArgs e = {System.Collections.Specialized.NotifyCollectionChangedEventArgs}) Line 44 + 0x8 bytes    C#
     WindowsBase.dll!System.Collections.ObjectModel.ObservableCollection<System.Windows.Point>.OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + 0x41 bytes    
     WindowsBase.dll!System.Collections.ObjectModel.ObservableCollection<System.Windows.Point>.InsertItem(int index, System.Windows.Point item) + 0xbc bytes    
     mscorlib.dll!System.Collections.ObjectModel.Collection<System.Windows.Point>.Add(System.Windows.Point item) + 0x49 bytes    
     DynamicPointAddSample.exe!DynamicPointAddSample.Window1.AddNextPoint() Line 69 + 0x37 bytes    C#
     DynamicPointAddSample.exe!DynamicPointAddSample.Window1.timer_Tick(object sender = {System.Windows.Threading.DispatcherTimer}, System.EventArgs e = {System.EventArgs}) Line 56 + 0x8 bytes    C#

Editor
Nov 8, 2009 at 4:30 PM

Hi Dan,

This is a bug, and it is fixed now thanks to your report :)

The problem was in viewport's Visible update method, which used approximate relative comparison of content bounds. Now it is possible to turn this off.

Next version of nightly DynamicDataDisplay will not contain it. Also you would propably interested in changes in DynamicPointAddSample that are necessary to be done to archive proper behavior.

Best regards,

Mikhail.

Mar 18, 2010 at 4:22 PM

I downloaded the most recent version of DynamicDataDisplay and changeset (29055) that is mentioned in this post.  However, in the most recent version I can't seem to find anything related to FitToViewRestrictions.  It seems that Viewport2D has gone through a lot of changes since that changeset.  

Could someone please explain how it is possible to do this (when a new data point is added the x-axis should again automatically scroll forward to show the 1000 most recently added data points.) with the most current version of DynamicDataDisplay?

Thank you for any help,

Ricky

Mar 18, 2010 at 4:41 PM
Take a look Under "Samples->Simple->DynamicPointAddSample" and see if this provides any help. David Roh
Mar 18, 2010 at 4:46 PM

I can't find Samples->Simple->DynamicPointAddSample in the newest release.  I'm looking at it in the 29055 changeset and I see that, but the code has changed significantly since then it seems.

Mar 18, 2010 at 4:53 PM

I was looking at the source files and samples, not the most recent changeset, sorry.  Hopefully this will solve my issue.  Thank you!

Mar 18, 2010 at 4:56 PM
I am using the 31108 change set Dec 12, 2009 under nightly in The DynamicDataDisplay solution.
 
David Roh
Mar 18, 2010 at 5:16 PM

ok, now I'm completely confused.

The files I originally downloaded to work with were DynamicDataDisplay v0.3 Binaries and DynamicDataDisplay v0.3 Source.

The 31108 change set looks like it has completely different code than this, such as:

-The 31108 change set contains "fitToViewRestrictions" and uses it in the DynamicPointAddSample.

-The source listed on the "downloads" page does not have this in its code anywhere.

 

I guess the solution is to use the 31108 changeset instead of the latest source download available? Just seems weird to me.

<d3:ChartPlotter.FitToViewRestrictions>
<d3:FollowWidthRestriction Width="50"/>
</d3:ChartPlotter.FitToViewRestrictions>

 

 

Mar 18, 2010 at 5:21 PM

and even when I try the stable source that comes along with that change set, the "fitToViewRestrictions" is nowhere to be found.

What am I doing wrong??? confused.....

Jan 25, 2013 at 10:33 PM

This is the patch Nightly/src/Samples/Simple/DynamicPointAddSample/Window1.xaml...but the example is very basic

Aug 21, 2013 at 12:19 PM
Edited Aug 21, 2013 at 12:21 PM
Hi ,

First of all thanks for sharing your hard work.

Now here is my problem ,I'm trying to use the example you have provided here
"https://dynamicdatadisplay.codeplex.com/SourceControl/changeset/view/29055#Nightly/src/Samples/Simple/DynamicPointAddSample/"

but its giving me error
  1. The attachable property 'FitToViewRestrictions' was not found in type 'ChartPlotter'.
  2. The type 'd3:FollowWidthRestriction' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.
could you please tell me why m'I getting these error and how to resolve these error.

Thanks
Raj
Oct 27, 2013 at 2:00 PM
Same here.

"The attachable property 'FitToViewRestrictions' was not found in type 'ChartPlotter'.".

It seems that "FiToViewRestrictions" has been removed from the current version.

Could someone confirm this?

Thanks,

Wei
Jul 3, 2014 at 1:12 PM
Does anyone know what happened to 'FitToViewRestrictions'? Or know of an alternative solution for rolling graphs?

Thanks, Andrea