LogarithmNumericTicksProvider is causing overflows during zoom and pan

Aug 14, 2009 at 4:43 PM

Hi,

  I have created a chart with logarithmic Y axis. When ever I am zooming and panning, at this point of code, I am getting overflows

  private double[] CreateTicks(Range<double> range)
  {

// Code snipped

   int count = (int)(maxUp - minDown + 1);

   var ticks = new double[count];

The value of the cound is invariably a large negative number. So any ideas how to fix this? Looking forward for the logarithamic axis make the cut to the  stable version. Thanks for the great component.

 

Thanks,

Srikanth Kotagiri

 

 

Aug 18, 2009 at 1:35 PM

I am having the same trouble with the latest checkout 28448

Editor
Aug 31, 2009 at 3:00 PM
Edited Aug 31, 2009 at 3:01 PM

Hi!

You should be careful with logarithmic axis - if Viewport.Visible rectangle somewhere crosses zero or has a subrectangle in negative area, it will throw an exception, because of data domain of logarithmic function, which is broken in such situation.

What value of Viewport.Visible did you have?

 

Regards,

Mikhail.

Aug 31, 2009 at 3:30 PM

Hi,

 

  it is fairly in the negative region :). Is there any way I can force the viewport.visible to stay in the positive region?

 

Thanks,

Srikanth

Sep 8, 2009 at 1:43 PM

I'm still having this problem.

When the range comes into the CreateTicks, it is 4.9E-324 - Infinity

How is this calculated?

None of my Log values are next or near 0

 

Editor
Sep 9, 2009 at 7:36 AM

Hi!

When I've used logarithmic axis the latest time, I wrote the following:

 

<d3:ChartPlotter Name="plotter" Domain="{x:Static d3:DataDomains.XPositive}">
  <d3:ChartPlotter.MainHorizontalAxis>
    <d3:HorizontalAxis>
      <d3:HorizontalAxis.TicksProvider>
        <d3:LogarithmNumericTicksProvider/>
      </d3:HorizontalAxis.TicksProvider>
    </d3:HorizontalAxis>
  </d3:ChartPlotter.MainHorizontalAxis>
			
  <d3:ChartPlotter.DataTransform>
    <d3:Log10XTransform/>
  </d3:ChartPlotter.DataTransform>
</d3:ChartPlotter>

Domain is a property of Viewport, it is a rectangle which limits possible values of visible area.

And to set visible area in data coordinates, I used the following C# code:

 

var genericPlotter = plotter.GetGenericPlotter();
genericPlotter.DataRect = new GenericRect<double, double>(9, 0, 110, 2);

Best regards,

Mikhail.

 

 

Dec 28, 2009 at 5:30 PM
Edited Dec 29, 2009 at 2:55 PM

Hi,

I am having similar issues. With Mikhail's suggestion, zoom and pan functions are now fixed; however, an exception still occurs when I double-click on the graph. Any workarounds for that?

Also, the first three ticker x labels (my log scale is X-axis) are all zeros on my plot. After that, correct log scales are displayed. Is this also a known issue?

Moreover, I am seeing 2 legends on the plot even though I only plotted one curve. How can I get rid of this additional legend?

All above issues are happening in the latest Nightly build from Dec. 12 v0.3.4703.0.

Thanks,
Faisal

 

Feb 9, 2010 at 4:06 PM

Mikhail,

Any update on these issues will be very useful. If I double click on the plot then it crashes. I was able to get around the other problems i.e. 2 legends and x-axis showing zeros but not the crashing issue.

Also, in log10 x-axis mode, I have 2 plots one on each y axis and they share the x-axis; however, the second plot seems to be squished together. I think the 2nd plot starts from where the first plot ends.

If you are back from your vacation then please help me with these issues in D3 LineCharts.

Thanks,
Faisal

Editor
Feb 17, 2010 at 12:29 PM

Hi Faisal,

Sorry for making you wait.

What value of Visible property is in your program that causes described behavior?

What value is returned by plotter.GetGenericPlotter().DataRect?

Mikhail.

Feb 17, 2010 at 3:42 PM
Edited Feb 17, 2010 at 4:02 PM

Mikhail,

No worries. I am so glad you are back.

plotter.GetGenericPlotter().DataRect returns: {(1,0) - (10,1)} i.e. XMax=10.0, XMin=1.0, YMax=1.0, YMin=0.0

Value of Visible property is 'Infinity, Infinity, NaN, NaN' and it is crashing in Viewport2D.cs line 227:

    set { SetValue(VisibleProperty, value); }

Here is the detailed execption trace:

System.ArgumentException was unhandled
  Message="'Infinity,Infinity,NaN,NaN' is not a valid value for property 'Visible'."
  Source="WindowsBase"
  StackTrace:
       at System.Windows.DependencyObject.ProcessCoerceValue(DependencyProperty dp, PropertyMetadata metadata, EntryIndex& entryIndex, Int32& targetIndex, EffectiveValueEntry& newEntry, EffectiveValueEntry& oldEntry, Object& oldValue, Object baseValue, CoerceValueCallback coerceValueCallback, Boolean coerceWithDeferredReference, Boolean skipBaseValueChecks)
       at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry& newEntry, Boolean coerceWithDeferredReference, OperationType operationType)
       at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, OperationType operationType, Boolean isInternal)
       at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
       at Microsoft.Research.DynamicDataDisplay.Viewport2D.set_Visible(DataRect value)
       at Microsoft.Research.DynamicDataDisplay.Navigation.KeyboardNavigation.ZoomToPoint(Double coeff)
       at Microsoft.Research.DynamicDataDisplay.Navigation.KeyboardNavigation.ZoomInToMouseExecute(Object target, ExecutedRoutedEventArgs e)
       at System.Windows.Input.CommandBinding.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
       at System.Windows.Input.CommandManager.ExecuteCommandBinding(Object sender, ExecutedRoutedEventArgs e, CommandBinding commandBinding)
       at System.Windows.Input.CommandManager.FindCommandBinding(CommandBindingCollection commandBindings, Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
       at System.Windows.Input.CommandManager.FindCommandBinding(Object sender, RoutedEventArgs e, ICommand command, Boolean execute)
       at System.Windows.Input.CommandManager.OnExecuted(Object sender, ExecutedRoutedEventArgs e)
       at System.Windows.UIElement.OnExecutedThunk(Object sender, ExecutedRoutedEventArgs e)
       at System.Windows.Input.ExecutedRoutedEventArgs.InvokeEventHandler(Delegate genericHandler, Object target)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
       at System.Windows.Input.RoutedCommand.ExecuteImpl(Object parameter, IInputElement target, Boolean userInitiated)
       at System.Windows.Input.RoutedCommand.ExecuteCore(Object parameter, IInputElement target, Boolean userInitiated)
       at System.Windows.Input.CommandManager.TranslateInput(IInputElement targetElement, InputEventArgs inputEventArgs)
       at System.Windows.UIElement.OnMouseDownThunk(Object sender, MouseButtonEventArgs e)
       at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
       at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
       at System.Windows.Input.InputManager.ProcessStagingArea()
       at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
       at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
       at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
       at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.Run()
       at System.Windows.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run(Window window)
       at System.Windows.Application.Run()

Thank you,

Faisal

 

My Source file is attached below (innerPlotter is not working for me so eventhough it is declared, I am not using it yet):

 

D3LineChart.xaml

<UserControl x:Class="CustomControls.D3LineChart"
    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"
    Height="Auto" Width="Auto">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="200*" />
        </Grid.RowDefinitions>
        <d3:ChartPlotter Grid.Row="0" Grid.Column="0" x:Name="plotter" NewLegendVisible="False" Domain="{x:Static d3:DataDomains.XPositive}">
            <!--<d3:InjectedPlotter x:Name="innerPlotter" Background="Aqua" SetViewportBinding="False">
                <d3:VerticalAxis Placement="Right"/>
                <d3:VerticalAxisTitle Content="Torque" Placement="Right"/>
            </d3:InjectedPlotter>-->
           
            <d3:AxisNavigation Placement="Bottom"/>
            <d3:AxisNavigation Placement="Right"/>
            <d3:AxisNavigation Placement="Left"/>

            <!--<d3:ChartPlotter.MainHorizontalAxis>
                <d3:HorizontalAxis>
                    <d3:HorizontalAxis.TicksProvider>
                        <d3:LogarithmNumericTicksProvider/>
                    </d3:HorizontalAxis.TicksProvider>
                </d3:HorizontalAxis>
            </d3:ChartPlotter.MainHorizontalAxis>-->

                    

            <!--<d3:VerticalAxisTitle Content="Group Delay (micro-sec)" />
            <d3:HorizontalAxisTitle>Frequency</d3:HorizontalAxisTitle>-->
           
            <d3:ChartPlotter.DataTransform>
                <d3:Log10XTransform/>
            </d3:ChartPlotter.DataTransform>

            <!--<Button Content="Remove all charts" Name="removeAllChartsBtn" Click="removeAllChartsBtn_Click"/>-->
        </d3:ChartPlotter>
    </Grid>
</UserControl>

 

D3LineChart.xaml.cs

 

using System.Collections.Generic;
using System.Windows.Controls;
using System.Windows.Media;
using Microsoft.Research.DynamicDataDisplay.DataSources;
using Microsoft.Research.DynamicDataDisplay;
using Microsoft.Research.DynamicDataDisplay.Charts;
using Microsoft.Research.DynamicDataDisplay.Charts.Axes.Numeric;

namespace CustomControls
{
    /// <summary>
    /// Interaction logic for D3LineChart.xaml
    /// </summary>
    public partial class D3LineChart : UserControl
    {
        private AxisInfo _xAxisInfo;
        private IList<AxisInfo> _yAxisInfoList;
        private IList<AxisInfo> _yAxisInfoSecList;

        private string _chartTitle = string.Empty;
        public string ChartTitle
        {
            get { return _chartTitle; }
            set { _chartTitle = value; }
        }
                 
        public D3LineChart()
        {
            InitializeComponent();
        }

        public D3LineChart(AxisInfo xAxisInfo, IList<AxisInfo> yAxisInfoList) : this()
        {
            _xAxisInfo = xAxisInfo;
            _yAxisInfoList= yAxisInfoList;

            if (_xAxisInfo != null && _yAxisInfoList != null)
            {
                DrawPlots();
            }
        }

        public D3LineChart(AxisInfo xAxisInfo, IList<AxisInfo> yAxisInfoList, IList<AxisInfo> yAxisInfoSecList)
        {
            InitializeComponent();
            _xAxisInfo = xAxisInfo;
            _yAxisInfoList = yAxisInfoList;
            _yAxisInfoSecList = yAxisInfoSecList;

            if (_xAxisInfo != null && _yAxisInfoList != null)
            {
                DrawPlots();
            }
        }               
       
        private void DrawPlots()              
        {
            HorizontalAxis xAxis = (HorizontalAxis)plotter.MainHorizontalAxis;
            xAxis.TicksProvider = new LogarithmNumericTicksProvider(10);
            xAxis.LabelProvider = new UnroundingLabelProvider();
            xAxis.ShowMajorLabels = true;
            xAxis.ShowMinorTicks = true;
            xAxis.SnapsToDevicePixels = true;

            xAxis.LabelProvider.SetCustomFormatter(info => info.Tick.ToString("#.######e0"));

            HorizontalAxisTitle HAT = new HorizontalAxisTitle()
            {
                Content = _xAxisInfo.AxisTitle
            };

            plotter.MainHorizontalAxis = xAxis;
            plotter.Children.Add(HAT);
            ((NumericAxis)plotter.MainHorizontalAxis).AxisControl.TicksPath.Stroke = Brushes.Blue;

            VerticalAxis yAxis = (VerticalAxis)plotter.MainVerticalAxis;
            yAxis.TicksProvider = new NumericTicksProvider();
            yAxis.LabelProvider = new UnroundingLabelProvider();
            yAxis.ShowMajorLabels = true;
            yAxis.ShowMinorTicks = true;
            yAxis.SnapsToDevicePixels = true;

           
            VerticalAxisTitle VAT = new VerticalAxisTitle()
            {
                Content = _yAxisInfoList[0].AxisTitle
            };

            plotter.MainVerticalAxis = yAxis;
            plotter.Children.Add(VAT);
            plotter.AxisGrid.DrawVerticalMinorTicks = true;
            plotter.AxisGrid.DrawHorizontalMinorTicks = true;
            plotter.MainVerticalAxis.Background = new LinearGradientBrush(Colors.White, Colors.LightGray, 90);

            var xPoints = _xAxisInfo.AxisDataPoints.AsXDataSource();

            // Create the main plot
            foreach (AxisInfo yAxInfo in _yAxisInfoList)
            {
                var yPoints = yAxInfo.AxisDataPoints.AsYDataSource();

                CompositeDataSource plot = xPoints.Join(yPoints);
                plotter.AddLineGraph(plot, yAxInfo.PlotColor, yAxInfo.PlotLineThickness, yAxInfo.AxisLegend);
            }
                       

            // add secondary y-axis plots if any exist
            if (_yAxisInfoSecList != null)
            {
                InjectedPlotter innerPlotter = new InjectedPlotter();
                innerPlotter.SetViewportBinding = false;
                plotter.Children.Add(innerPlotter);

                HorizontalAxis ax = new HorizontalAxis();
                ax.Placement = AxisPlacement.Top;
                ax.TicksProvider = new LogarithmNumericTicksProvider(10);
                ax.LabelProvider = new UnroundingLabelProvider();
                ax.LabelProvider.SetCustomFormatter(info => info.Tick.ToString("#.######e0"));
                ax.ShowMajorLabels = true;
                ax.ShowMinorTicks = true;
                ax.SnapsToDevicePixels = true;
                ax.AxisControl.TicksPath.Stroke = Brushes.Red;
                plotter.Children.Add(ax);
               

                VerticalAxis yAxisSec = new VerticalAxis()
                {
                    TicksProvider = new NumericTicksProvider(),
                    LabelProvider = new UnroundingLabelProvider(),
                    ShowMinorTicks = true,
                    ShowMajorLabels = true,
                    SnapsToDevicePixels = true,
                    Placement = AxisPlacement.Right
                };

                VerticalAxisTitle VATsecondary = new VerticalAxisTitle()
                {
                    Content = _yAxisInfoSecList[0].AxisTitle,
                    Placement = AxisPlacement.Right
                };

                innerPlotter.MainVerticalAxis = yAxisSec;
                innerPlotter.Children.Add(VATsecondary);
                innerPlotter.MainVerticalAxis.Background = new LinearGradientBrush(Colors.White, Colors.Red, 90);

                foreach (AxisInfo yAxInfoSec in _yAxisInfoSecList)
                {
                    var ySecPoints = yAxInfoSec.AxisDataPoints.AsYDataSource();

                    CompositeDataSource plotSec = xPoints.Join(ySecPoints);
                    /*innerP*/plotter.AddLineGraph(plotSec, yAxInfoSec.PlotColor, yAxInfoSec.PlotLineThickness, yAxInfoSec.AxisLegend);
                }

    }

    public class AxisInfo
    {
        public string AxisTitle;
        public string AxisLegend;
        public double[] AxisDataPoints;
        public Color PlotColor = Colors.Black;
        public int PlotLineThickness = 1;
    }
}

Mar 19, 2010 at 8:03 PM

Hi Mikhail,

Were you able to fix this issue? This happens frequently if you zoom out too much and then try to zoom back in using the middle mouse wheel.

Thanks,
Faisal