Initial Commit
This commit is contained in:
136
Charts/Filters/FrequencyFilter.cs
Normal file
136
Charts/Filters/FrequencyFilter.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using Microsoft.Research.DynamicDataDisplay.Charts.Filters;
|
||||
|
||||
namespace Microsoft.Research.DynamicDataDisplay.Filters
|
||||
{
|
||||
public sealed class FrequencyFilter : PointsFilterBase
|
||||
{
|
||||
|
||||
/// <summary>Visible region in screen coordinates</summary>
|
||||
private Rect screenRect;
|
||||
|
||||
#region IPointFilter Members
|
||||
|
||||
public override void SetScreenRect(Rect screenRect)
|
||||
{
|
||||
this.screenRect = screenRect;
|
||||
}
|
||||
|
||||
// todo probably use LINQ here.
|
||||
public override List<Point> Filter(List<Point> points)
|
||||
{
|
||||
if (points.Count == 0) return points;
|
||||
|
||||
List<Point> resultPoints = points;
|
||||
List<Point> currentChain = new List<Point>();
|
||||
|
||||
if (points.Count > 2 * screenRect.Width)
|
||||
{
|
||||
resultPoints = new List<Point>();
|
||||
|
||||
double currentX = Math.Floor(points[0].X);
|
||||
foreach (Point p in points)
|
||||
{
|
||||
if (Math.Floor(p.X) == currentX)
|
||||
{
|
||||
currentChain.Add(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Analyse current chain
|
||||
if (currentChain.Count <= 2)
|
||||
{
|
||||
resultPoints.AddRange(currentChain);
|
||||
}
|
||||
else
|
||||
{
|
||||
Point first = MinByX(currentChain);
|
||||
Point last = MaxByX(currentChain);
|
||||
Point min = MinByY(currentChain);
|
||||
Point max = MaxByY(currentChain);
|
||||
resultPoints.Add(first);
|
||||
|
||||
Point smaller = min.X < max.X ? min : max;
|
||||
Point greater = min.X > max.X ? min : max;
|
||||
if (smaller != resultPoints.GetLast())
|
||||
{
|
||||
resultPoints.Add(smaller);
|
||||
}
|
||||
if (greater != resultPoints.GetLast())
|
||||
{
|
||||
resultPoints.Add(greater);
|
||||
}
|
||||
if (last != resultPoints.GetLast())
|
||||
{
|
||||
resultPoints.Add(last);
|
||||
}
|
||||
}
|
||||
currentChain.Clear();
|
||||
currentChain.Add(p);
|
||||
currentX = Math.Floor(p.X);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resultPoints.AddRange(currentChain);
|
||||
|
||||
return resultPoints;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private static Point MinByX(IList<Point> points)
|
||||
{
|
||||
Point minPoint = points[0];
|
||||
foreach (Point p in points)
|
||||
{
|
||||
if (p.X < minPoint.X)
|
||||
{
|
||||
minPoint = p;
|
||||
}
|
||||
}
|
||||
return minPoint;
|
||||
}
|
||||
|
||||
private static Point MaxByX(IList<Point> points)
|
||||
{
|
||||
Point maxPoint = points[0];
|
||||
foreach (Point p in points)
|
||||
{
|
||||
if (p.X > maxPoint.X)
|
||||
{
|
||||
maxPoint = p;
|
||||
}
|
||||
}
|
||||
return maxPoint;
|
||||
}
|
||||
|
||||
private static Point MinByY(IList<Point> points)
|
||||
{
|
||||
Point minPoint = points[0];
|
||||
foreach (Point p in points)
|
||||
{
|
||||
if (p.Y < minPoint.Y)
|
||||
{
|
||||
minPoint = p;
|
||||
}
|
||||
}
|
||||
return minPoint;
|
||||
}
|
||||
|
||||
private static Point MaxByY(IList<Point> points)
|
||||
{
|
||||
Point maxPoint = points[0];
|
||||
foreach (Point p in points)
|
||||
{
|
||||
if (p.Y > maxPoint.Y)
|
||||
{
|
||||
maxPoint = p;
|
||||
}
|
||||
}
|
||||
return maxPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user