oxyplot / oxyplot

A cross-platform plotting library for .NET
https://oxyplot.github.io/
MIT License
3.29k stars 963 forks source link

LineSeries is disappearing in Logarithmic Axis Zoom #1250

Open WZSE opened 6 years ago

WZSE commented 6 years ago

I have attached the gif of this issue. Please see that.

I'm using one line series and three scatter series. X Axis is log, Y is Linear. This is WPF application using PlotView.

DataPoints I have used

Platform: OxyPlot.Core.2.0.0-unstable1035.

2018-10-24_18-02-08

Edit, This seems happening only in WPF context. PNG export of this image is working fine at this zoom level

WZSE commented 6 years ago

OxyWPFTest.zip Uploaded the project to reproduce.

WZSE commented 6 years ago

2018-11-15_14-44-29 Another issue with AreaSeries.

WZSE commented 5 years ago

Okey, I fixed the issue in first gif. It's due to WPF rendering related and any pixels more than a number is not rendering properly in wpf. To know more check the following:

https://www.scichart.com/questions/question/lines-disappear-when-zoom-in https://stackoverflow.com/questions/13731593/horizontal-or-vertical-wpf-lines-limited-to-125-000-pixels https://www.codeproject.com/Questions/192350/Elements-disappearing-on-large-Canvas https://stackoverflow.com/questions/29552339/how-to-avoid-a-single-pixel-line-disappear-in-wpf

The code change I have made is in CanvasRenderContext.cs file, DrawLineBalanced method.

Instead of this line var p = aliased ? this.ToPixelAlignedPoint(points[i]) : this.ToPoint(points[i]); I wrote my method ToPixelBoundaryPoint as var p = aliased ? ToPoint(points[i]) : ToPixelBoundaryPoint(points[i]);

And the below method is not optimized for performance or not even a valid logic. It gets my job done, so I'm OK with it. But I request @objorke to optimize it.

 private Point ToPixelBoundaryPoint(ScreenPoint pt)
{
    double x; double y;
    if (pt.X >= 150000.0)
    {
        x = 150000.0;
    }

    else if (pt.X <= 0)
    {
        x = pt.X/10000;
    }

    else if (pt.X <= -1000000)
    {
        x = 150000.0;
    }
    else
        x = pt.X;
    if (pt.Y >= 150000.0)
    {
        y = 150000;
    }
    else
        y = pt.Y;
    return new Point(x, y);
}
WZSE commented 5 years ago

About Area Series I didn't knew we have to use Points2 property. My Points were closed polygons. However Points2is being calculated from Points collection and this is using ConstantY2dproperty.

Since no Points2& ConstantY2is set, the default value of ConstantY2which is 0, used in Points2calculation. So while you move the screen Points2 which has 0 in it's y axis is trying to render causing the above issue shown in the second gif.

I tried setting Points2and another issue popped up with IsXMonotonicproperty calculated incorrectly with my DataPoints. Check the gif

2018-11-23_11-40-05

WZSE commented 5 years ago

To avoid the above issue I had to change internal methods. Since Oxyplot is based on VS2017 project I thought of fixing this issue by extending AreaSeriesand avoiding the IsXMonotonicproperty based optimization. That solved the issue in the 3rd gif and fixed incorrect fill shown in the 2nd gif.

However I still see sometimes the lines in the AreaSeries are trying to reach (X,0) point while panning/zooming the chart in AreaSeries.