How do I get a PointPairList for the visible curve data only and not all points in the Curveitem list? This list should change dynamically when zooming or panning.
Thanks.
How do I get a PointPairList for the visible curve data only and not all points in the Curveitem list? This list should change dynamically when zooming or panning.
Thanks.
There doesn't appear to be a ZedGraph API method that does this for you. The code below, though, demonstrates a VisiblePoints method that returns a PointPairList and works under one very specific ZedGraph use case.
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using ZedGraph;
namespace ZedGraphMain
{
public class ZedGraphDemo : Form
{
public ZedGraphDemo()
{
var graphControl = new ZedGraphControl();
graphControl.Dock = DockStyle.Fill;
graphControl.IsShowPointValues = true;
Controls.Add(graphControl);
var points = new PointPairList();
for (double i = 0; i <= 5.0; i += 1)
points.Add(i, i);
var curve = graphControl.GraphPane.AddCurve("A Label", points, Color.ForestGreen);
graphControl.RestoreScale(graphControl.GraphPane);
graphControl.ZoomEvent += (_, __, ___) => LogVisibility(graphControl, curve, points);
}
private static PointPairList VisiblePoints(ZedGraphControl control, LineItem lineItem, PointPairList points)
{
var pointPairList = new PointPairList();
pointPairList.AddRange(points.Where(pp => IsVisible(control, lineItem, pp)).ToList());
return pointPairList;
}
private static bool IsVisible(ZedGraphControl control, LineItem lineItem, PointPair point)
{
GraphPane pane = control.GraphPane;
Scale xScale = lineItem.GetXAxis(pane).Scale;
Scale yScale = lineItem.GetYAxis(pane).Scale;
return point.X > xScale.Min && point.X < xScale.Max && point.Y > yScale.Min && point.Y < yScale.Max;
}
private static void LogVisibility(ZedGraphControl control, LineItem lineItem, PointPairList points)
{
List<PointPair> visiblePoints = VisiblePoints(control, lineItem, points);
Console.Out.WriteLine(DateTime.Now + ": " + string.Join(",", visiblePoints.Select(pp => string.Format("({0:N1}, {1:N1})", pp.X, pp.Y))));
}
}
}
The existing FilteredPointList matches exactly your requirements.
It contains a detailed explanation about how to use it as well as a link to a ZedGraph wiki.
I do believe the the PointPairList always contains ALL the points.
The plotted points are always there, it's just how they are translated to pixels changes with zooms & pans.
I know I needed to create my own AverageFilteredList for large data sets. I had tens of thousands of points, and the application would grind to a halt due to memory usage (implementation removed for brevity):
public class AverageFilteredPointList : IPointList
{
<snip>
public int Count { get; set; }
public int MaxPts { get; set; }
public PointPair this[int index] { get; set; }
public void SetBounds(double min, double max, int maxPts) { }
}
I think you'll have to implement your own IPointList class that handles it's own internal points when zooming/panning occurs if you want to gather information like what "point" is visible.
Also, and I'm not sure if this will help you, but you can use the following GraphPane function to figure out what actual DataPoint the pixel position is at:
ReverseTransform(pt, out xSampleData, out ySampleData);