kopia lustrzana https://github.com/dl2alf/AirScout
237 wiersze
7.8 KiB
C#
237 wiersze
7.8 KiB
C#
// --------------------------------------------------------------------------------------------------------------------
|
|
// <copyright file="MatrixSeries.cs" company="OxyPlot">
|
|
// Copyright (c) 2014 OxyPlot contributors
|
|
// </copyright>
|
|
// <summary>
|
|
// Provides a series that visualizes the structure of a matrix.
|
|
// </summary>
|
|
// --------------------------------------------------------------------------------------------------------------------
|
|
|
|
namespace ExampleLibrary
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using OxyPlot;
|
|
using OxyPlot.Series;
|
|
|
|
/// <summary>
|
|
/// Provides a series that visualizes the structure of a matrix.
|
|
/// </summary>
|
|
public class MatrixSeries : XYAxisSeries
|
|
{
|
|
/// <summary>
|
|
/// The image
|
|
/// </summary>
|
|
private OxyImage image;
|
|
|
|
/// <summary>
|
|
/// The matrix
|
|
/// </summary>
|
|
private double[,] matrix;
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="MatrixSeries" /> class.
|
|
/// </summary>
|
|
public MatrixSeries()
|
|
{
|
|
this.GridInterval = 1;
|
|
this.ShowDiagonal = false;
|
|
this.MinimumGridLineDistance = 4;
|
|
this.GridColor = OxyColors.LightGray;
|
|
this.BorderColor = OxyColors.Gray;
|
|
this.NotZeroColor = OxyColors.Black;
|
|
this.ZeroTolerance = 0;
|
|
this.TrackerFormatString = "{0}\r\n[{1},{2}] = {3}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the matrix.
|
|
/// </summary>
|
|
public double[,] Matrix
|
|
{
|
|
get
|
|
{
|
|
return this.matrix;
|
|
}
|
|
|
|
set
|
|
{
|
|
this.image = null;
|
|
this.matrix = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the interval between the grid lines (the grid is hidden if value is 0).
|
|
/// </summary>
|
|
public int GridInterval { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets a value indicating whether to show the diagonal.
|
|
/// </summary>
|
|
/// <value><c>true</c> if the diagonal should be shown; otherwise, <c>false</c>.</value>
|
|
public bool ShowDiagonal { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the minimum grid line distance.
|
|
/// </summary>
|
|
public double MinimumGridLineDistance { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the color of the grid.
|
|
/// </summary>
|
|
/// <value>The color of the grid.</value>
|
|
public OxyColor GridColor { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the color of the border around the matrix.
|
|
/// </summary>
|
|
/// <value>The color of the border.</value>
|
|
public OxyColor BorderColor { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the color of the not zero elements of the matrix.
|
|
/// </summary>
|
|
public OxyColor NotZeroColor { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the zero tolerance (inclusive).
|
|
/// </summary>
|
|
/// <value>The zero tolerance.</value>
|
|
public double ZeroTolerance { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets the point on the series that is nearest the specified point.
|
|
/// </summary>
|
|
/// <param name="point">The point.</param>
|
|
/// <param name="interpolate">Interpolate the series if this flag is set to <c>true</c>.</param>
|
|
/// <returns>A TrackerHitResult for the current hit.</returns>
|
|
public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
|
|
{
|
|
var dp = this.InverseTransform(point);
|
|
int i = (int)dp.Y;
|
|
int j = (int)dp.X;
|
|
|
|
if (i >= 0 && i < this.matrix.GetLength(0) && j >= 0 && j < this.matrix.GetLength(1))
|
|
{
|
|
var value = this.matrix[i, j];
|
|
return new TrackerHitResult
|
|
{
|
|
Series = this,
|
|
DataPoint = dp,
|
|
Position = point,
|
|
Item = null,
|
|
Index = -1,
|
|
Text = StringHelper.Format(this.ActualCulture, this.TrackerFormatString, null, this.Title, i, j, value)
|
|
};
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Renders the series on the specified render context.
|
|
/// </summary>
|
|
/// <param name="rc">The rendering context.</param>
|
|
public override void Render(IRenderContext rc)
|
|
{
|
|
if (this.Matrix == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int m = this.Matrix.GetLength(0);
|
|
int n = this.Matrix.GetLength(1);
|
|
var p0 = this.Transform(0, 0);
|
|
var p1 = this.Transform(n, m);
|
|
|
|
// note matrix index [i,j] maps to image index [j,i]
|
|
if (this.image == null)
|
|
{
|
|
var pixels = new OxyColor[n, m];
|
|
for (int i = 0; i < m; i++)
|
|
{
|
|
for (int j = 0; j < n; j++)
|
|
{
|
|
pixels[j, i] = Math.Abs(this.Matrix[i, j]) <= this.ZeroTolerance ? OxyColors.Transparent : this.NotZeroColor;
|
|
}
|
|
}
|
|
|
|
this.image = OxyImage.Create(pixels, ImageFormat.Png);
|
|
}
|
|
|
|
var clip = this.GetClippingRect();
|
|
var x0 = Math.Min(p0.X, p1.X);
|
|
var y0 = Math.Min(p0.Y, p1.Y);
|
|
var w = Math.Abs(p0.X - p1.X);
|
|
var h = Math.Abs(p0.Y - p1.Y);
|
|
rc.DrawClippedImage(clip, this.image, x0, y0, w, h, 1, false);
|
|
|
|
var points = new List<ScreenPoint>();
|
|
if (this.GridInterval > 0)
|
|
{
|
|
var p2 = this.Transform(this.GridInterval, this.GridInterval);
|
|
if (Math.Abs(p2.Y - p0.Y) > this.MinimumGridLineDistance)
|
|
{
|
|
for (int i = 1; i < n; i += this.GridInterval)
|
|
{
|
|
points.Add(this.Transform(0, i));
|
|
points.Add(this.Transform(n, i));
|
|
}
|
|
}
|
|
|
|
if (Math.Abs(p2.X - p0.X) > this.MinimumGridLineDistance)
|
|
{
|
|
for (int j = 1; j < m; j += this.GridInterval)
|
|
{
|
|
points.Add(this.Transform(j, 0));
|
|
points.Add(this.Transform(j, m));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (this.ShowDiagonal)
|
|
{
|
|
points.Add(this.Transform(0, 0));
|
|
points.Add(this.Transform(n, m));
|
|
}
|
|
|
|
rc.DrawClippedLineSegments(clip, points, this.GridColor, 1, null, LineJoin.Miter, true);
|
|
|
|
if (this.BorderColor.IsVisible())
|
|
{
|
|
var borderPoints = new[]
|
|
{
|
|
this.Transform(0, 0),
|
|
this.Transform(m, 0),
|
|
this.Transform(0, n),
|
|
this.Transform(m, n),
|
|
this.Transform(0, 0),
|
|
this.Transform(0, n),
|
|
this.Transform(m, 0),
|
|
this.Transform(m, n)
|
|
};
|
|
|
|
rc.DrawClippedLineSegments(clip, borderPoints, this.BorderColor, 1, null, LineJoin.Miter, true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the maximum and minimum values of the series.
|
|
/// </summary>
|
|
protected override void UpdateMaxMin()
|
|
{
|
|
base.UpdateMaxMin();
|
|
if (this.Matrix == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
this.MinX = 0;
|
|
this.MaxX = this.Matrix.GetLength(1);
|
|
this.MinY = 0;
|
|
this.MaxY = this.Matrix.GetLength(0);
|
|
}
|
|
}
|
|
} |