This project is read-only.

How to know when the chart finished to draw?

Aug 10, 2009 at 6:36 PM

Hello,

I am trying to do an application where I load the data to display in a line chart from different files, one file a the time, then save the screenshot of each genenrated chart automatically as a new png file for each of the input files.

The problem that I am having is that my screenshots only shows the empty chart even when I am waiting for 100 milliseconds before change the chart content with the content of the next file, I could not find how to know when the chart finished to draw.

Basically in my program I got the list a files that are read one at the time, I update a ObservableDataSource with the data and set the X and Y mapping accordingly and add this as a linegraph to the chart, then I call Viewport.FitToView method to redraw the chart (as some of your samples)

When I do this process one file at the time the chart display properly and I can save the correct screenshot, but if I do it automatically the screenshot always has a empty chart.

Is there a way to know when the chart finished to draw?

 or there is a better way to do this?

Regards,

Pedro

 

 

Aug 10, 2009 at 6:44 PM

Hi Pedro,

this is interesting question, can you please send me source code of an application that can reproduce this bug?

I'll try to do it myself, too.

My e-mail is thecentury+d3@gmail.com

 

Regards,

Mikhail.

 

Aug 10, 2009 at 7:00 PM
Edited Aug 10, 2009 at 7:01 PM

Hi Pedro,

solution is rather simple - subscribe to Loaded event of added LineGraph being added each time, and in handler of this event you are able to get right screenshot.

A little bit later I'll upload to *Source code* next changeset with repro of your case - it would be in Nightly, in DynamicDataDisplay.sln, solution folder Repros, and it is named MultipleScreenshotsRepro.

Simply - it tries to make a screenshot just after adding a chart and after it has loaded, and saves this two screenshots to "C:\" with different names. Screenshot after Loaded event is right, and other isn't.

 

Regards,

Mikhail.

Aug 10, 2009 at 7:09 PM

Hi Mikhail,

Thank you for your quick response. I actually solve my problem calling UpdateLayout() method before calling  SaveScreenshot() method. I think this is not a good solution because problable decrease the performance but it actually allows me to save the correct screenshot each time that I loop with a different file.

I definitely will try your solution which I think is a better way to do it.

I will be looking forward to checkout your sample MultipleScreenshotsRepro

Thank you very much,

Pedro

 

Aug 10, 2009 at 7:27 PM

Hi Pedro

I've uploaded the version of code with your repro.

It is changeset 28419.

Mikhail.

Aug 10, 2009 at 9:07 PM

Hi Mikhail,

Thank you for your sample, It is a much better way to implement the functionality to save the screenshot once that the chart finishid to load.

In another topic, I tried to replace the DynamicDataDisplay.dll I was using with the once that I got compiling the solution that I just download (28419) and I got an error in my xaml.

I was working with a previous version 0.3.2 which I got when I downloaded the TwoAxesSample. The error is that with the new dll it does not find a definition of NewAxisNavigation, I am using a second axis with an inner plotter pretty much in the same way that I found in the TwoAxesSample, I check the new download and I found that the same sample implement a different xaml and it does not have the reference to the NewAxisNavigation, which I remove from my xaml but if I tried to zoom using the mouse I got an error saying that it has a null reference.

This is the xaml for the old TwoAxesSample

<Window x:Class="TwoIndependentAxes.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d3="http://research.microsoft.com/DynamicDataDisplay/1.0"
        Title="DynamicDataDisplay Sample" WindowState="Maximized"
        Icon="{x:Static d3:D3IconHelper.DynamicDataDisplayWhiteIcon}">
    <Grid>
        <d3:ChartPlotter Name="plotter">
   <d3:InjectedPlotter Name="innerPlotter" Background="Aqua">
    <d3:VerticalAxis Placement="Left"/>
    <d3:VerticalAxis Placement="Right"/>
    <d3:RectangleHighlight Bounds="0.3,0.3,0.1,0.1"/>
   </d3:InjectedPlotter>
   
   
   <d3:NewAxisNavigation Placement="Left"/>
   <d3:NewAxisNavigation Placement="Bottom"/>
   <d3:NewAxisNavigation Placement="Right"/>
   <d3:RectangleHighlight Bounds="0.7,0.7,0.1,0.1"/>
        </d3:ChartPlotter>
    </Grid>
</Window>

The error I got is

{"Object reference not set to an instance of an object."}

On AxisNavigation in the method: OnMouseWheel event, line: Point zoomTo = mousePos.ScreenToViewport(activePlotter.Transform);

  private void OnMouseWheel(object sender, MouseWheelEventArgs e)
  {
   Point mousePos = e.GetPosition(listeningPanel);

   UpdateActivePlotter(e);

   int delta = -e.Delta;

   Point zoomTo = mousePos.ScreenToViewport(activePlotter.Transform);

   double zoomSpeed = Math.Abs(delta / Mouse.MouseWheelDeltaForOneLine);
   zoomSpeed *= wheelZoomSpeed;
   if (delta < 0)
   {
    zoomSpeed = 1 / zoomSpeed;
   }

   DataRect visible = activePlotter.Viewport.Visible.Zoom(zoomTo, zoomSpeed);
   DataRect oldVisible = activePlotter.Viewport.Visible;
   if (Placement.IsBottomOrTop())
   {
    visible.YMin = oldVisible.YMin;
    visible.Height = oldVisible.Height;
   }
   else
   {
    visible.XMin = oldVisible.XMin;
    visible.Width = oldVisible.Width;
   }
   activePlotter.Viewport.Visible = visible;

   e.Handled = true;
  }

Is this a bug with the new dll or do I have to set something different?

If I use the old dll and the old xaml it works fine.

Thank you,

Pedro

 

Aug 11, 2009 at 2:34 AM

Hi Pedro, 

I think you should try to use the new DynamicDataDisplay.dll and the new TwoAxesSample, where I have successfully migrated from old axis navigation to new axis navigation, so such a rename was performed { AxisNavigation, NewAxisNavigation } -> { OldAxisNavigation, AxisNavigation }.

I don't remember but I have even maybe deleted OldAxisNavigation. So Simply change NewAxisNavigation to AxisNavigation and everything should work ok.

 

Best regards,

Mikhail.

Aug 11, 2009 at 8:57 AM

By the way, if you do not need Legend or some of axes on your screenshots, you can hide them, setting

plotter.LegendVisibility to Visibility.Hidden, and

plotter.Main{Horizontal|Vertical}Axis to Visibility.Collapsed.

 

(I will upload a little bit later a small fix for Legend, that enables manual hiding of legend).

 

Mikhail.

Aug 11, 2009 at 1:55 PM

Hi Mikhail,

Thank you for the update, I will switch to use the new dll.

 

Thank you for your help.

Regards,

Pedro

 

Aug 11, 2009 at 2:31 PM

Hi Mikhail,

Sorry for keep buging you with this.

I test your new sample TwoAxesSample again today, I actually get the same exception there that in my program.

In order to reproduce the exception you could do this.

1) Run the TwoAxesSample

2) click in the horizontal axis with the mouase left click, then roll the mouse wheel to zoom it. This have to be done in that order without doing anything else with the mouse.

You should get an exception on OnMouseWheel event on AxisNavigation, it seems that it does not find the position on the axis then UpdateActivePlotter returns false and when the method try to call activePlotter.Transform active plotter it is null and you get the exception there.

regards,

Pedro

 

Aug 12, 2009 at 3:38 AM

Hi, Pedro,

Thanks for submitting this bug - its is (I hope) fixed now.

All these fixes and a little bit changed TwoIndependentAxes sample are available in SourceCode/LatestChangeset (28446)/Nightly

 

Best regards,

Mikhail.