Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using OxyPlot;
- using OxyPlot.Annotations;
- using OxyPlot.Axes;
- using OxyPlot.Series;
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace TRUSTIE
- {
- /// <summary> Editor for color palette. </summary>
- ///
- /// <remarks> James, 23/04/2015. </remarks>
- public partial class OxyPaletteEditor : Form
- {
- #region Events
- /// <summary> Palette changed. </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- public delegate void PaletteChanged();
- /// <summary> Event queue for all listeners interested in OnPaletteChanged events. </summary>
- public event PaletteChanged OnPaletteChanged;
- /// <summary> Invalid color changed. </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- public delegate void InvalidColorChanged();
- /// <summary> Event queue for all listeners interested in OnInvalidColorChanged events. </summary>
- public event InvalidColorChanged OnInvalidColorChanged;
- #endregion
- #region Private Members
- /// <summary> The model. </summary>
- private PlotModel model = new PlotModel
- {
- FixedXYScalingRatio = 1,
- PlotAreaBorderThickness = new OxyThickness(0),
- PlotMargins = new OxyThickness(0, 0, 0, 0)
- };
- /// <summary> The Axis to process. </summary>
- private CategoryAxis xAxis = new CategoryAxis
- {
- GapWidth = 0,
- MaximumPadding = 0,
- MinorTickSize = 0,
- Position = AxisPosition.Bottom,
- TickStyle = OxyPlot.Axes.TickStyle.None
- };
- /// <summary> The Axis to process. </summary>
- private LinearAxis yAxis = new LinearAxis
- {
- AbsoluteMinimum = 0,
- MinimumPadding = 0,
- MaximumPadding = 0,
- MinorTickSize = 0,
- Position = AxisPosition.Left,
- TextColor = OxyColors.Transparent,
- TickStyle = OxyPlot.Axes.TickStyle.None
- };
- /// <summary> The axis.</summary>
- private LinearColorAxis cAxis = new LinearColorAxis { IsAxisVisible = false };
- /// <summary> The cursor i. </summary>
- private LineAnnotation cursor_i = new LineAnnotation
- {
- Color = OxyColors.White,
- LineStyle = OxyPlot.LineStyle.Solid,
- Type = LineAnnotationType.Vertical
- };
- /// <summary> The cursor f. </summary>
- private LineAnnotation cursor_f = new LineAnnotation
- {
- Color = OxyColors.White,
- LineStyle = OxyPlot.LineStyle.Solid,
- Type = LineAnnotationType.Vertical
- };
- /// <summary> The roi. </summary>
- private ImageAnnotation roi;
- /// <summary> The histogram. </summary>
- private ColumnSeries histogram = new ColumnSeries { IsVisible = true };
- /// <summary> The colormap. </summary>
- private HeatMapSeries colormap = new HeatMapSeries { Interpolate = false };
- /// <summary> The current. </summary>
- private OxyPalette current;
- /// <summary> The previous. </summary>
- private OxyPalette previous;
- /// <summary> The initial. </summary>
- private OxyPalette initial;
- /// <summary> The selected color. </summary>
- private object selectedColor;
- /// <summary> The data bins. </summary>
- Dictionary<double, int> data_bins = new Dictionary<double, int>(4096);
- /// <summary> The anchor. </summary>
- private double anchor = 0;
- /// <summary> The dx. </summary>
- private double dx;
- #endregion
- /// <summary> Constructor. </summary>
- ///
- /// <remarks> James, 23/04/2015. </remarks>
- ///
- /// <param name="min"> (Optional) The minimum. </param>
- /// <param name="max"> (Optional) The maximum. </param>
- /// <param name="data"> (Optional) The data. </param>
- /// <param name="initial"> (Optional) The current. </param>
- public OxyPaletteEditor(double min = -50, double max = 50, double[,] data = null, OxyPalette initial = null)
- {
- InitializeComponent();
- this.SuspendLayout();
- model.Axes.Add(xAxis);
- model.Axes.Add(yAxis);
- model.Axes.Add(cAxis);
- colormap.X0 = min;
- colormap.X1 = max;
- colormap.Y0 = 0;
- colormap.Y1 = 1;
- xAxis.Minimum = min;
- xAxis.Maximum = max;
- yAxis.Minimum = 0;
- cAxis.Minimum = min;
- cAxis.Maximum = max;
- this.cAxis.Palette = initial;
- dx = 4096.0 / Math.Abs(max - min);
- this.initial = OxyPalette.Interpolate(4096, initial.Colors.ToArray());
- colormap.Data = new double[4096, 1];
- if (data != null)
- {
- this.ResetData(min, max, data);
- }
- else
- {
- this.Close();
- }
- //this.model.Series.Add(colormap);
- //this.PlotHistogram.Model = CreateHistogram(100000, 200);
- this.model.Series.Add(histogram);
- this.model.MouseDown += model_MouseDown;
- this.model.MouseUp += model_MouseUp;
- this.model.MouseMove += model_MouseMove;
- this.model.PlotType = PlotType.XY;
- this.PlotHistogram.Model = this.model;
- if (initial != null)
- {
- this.Palette = initial;
- }
- else // For the time being
- {
- this.Palette = OxyPalettes.Gray(4096);
- }
- ColorPickerSolid.AddStandardColors();
- ColorPickerGradient.AddStandardGradients();
- this.ResumeLayout();
- }
- public static PlotModel CreateHistogram(int n, int binCount)
- {
- var bins = new Dictionary<string, int>(binCount);
- for (int i = 0; i < binCount; i++)
- {
- bins.Add(Convert.ToString(i), 0);
- }
- var r = new Random(31);
- for (int i = 0; i < n; i++)
- {
- int value = r.Next(binCount);
- bins[Convert.ToString(value)]++;
- }
- var temp = new PlotModel { Title = string.Format("Histogram (bins={0}, n={1})", binCount, n), Subtitle = "Pseudorandom numbers" };
- var series1 = new ColumnSeries { ItemsSource = bins, ValueField = "Value" };
- if (binCount < 100)
- {
- series1.LabelFormatString = "{0}";
- }
- temp.Series.Add(series1);
- temp.Axes.Add(new CategoryAxis { Position = AxisPosition.Bottom, ItemsSource = bins, LabelField = "Key", GapWidth = 0 });
- temp.Axes.Add(new LinearAxis { Position = AxisPosition.Left, MinimumPadding = 0, MaximumPadding = 0.1, AbsoluteMinimum = 0 });
- return temp;
- }
- #region Public Properties
- /// <summary> Gets or sets the palette. </summary>
- ///
- /// <value> The palette. </value>
- public OxyPalette Palette
- {
- get
- {
- return current;
- }
- set
- {
- this.current = OxyPalette.Interpolate(4096, value.Colors.ToArray());
- this.previous = OxyPalette.Interpolate(4096, value.Colors.ToArray());
- this.ResetPalette();
- }
- }
- /// <summary> Gets or sets the invalid. </summary>
- ///
- /// <value> The invalid. </value>
- public OxyColor Invalid
- {
- get;
- set;
- }
- #endregion
- #region Public Methods
- /// <summary> Resets the data. </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- ///
- /// <param name="min"> The minimum. </param>
- /// <param name="max"> The maximum. </param>
- /// <param name="data"> The data. </param>
- public void ResetData(double min, double max, double[,] data)
- {
- xAxis.Minimum = min;
- xAxis.Maximum = max;
- cAxis.Minimum = min;
- cAxis.Maximum = max;
- colormap.X0 = min;
- colormap.X1 = max;
- dx = 4096.0 / Math.Abs(max - min);
- for (int i = 0; i < 4096; i++)
- {
- double div = Math.Round(min + ((Math.Abs(max - min) / 4096.0) * Convert.ToDouble(i)), 2);
- data_bins.Add(div, 0);
- colormap.Data[i, 0] = div;
- }
- List<double> keys = data_bins.Keys.ToList();
- for (long i = 0; i < data.LongLength; i++)
- {
- int keyindex = keys.BinarySearch
- (
- data[i % data.GetLength(0), i / data.GetLength(0)],
- Comparer<double>.Create
- (
- (a, b) =>
- {
- if (Math.Abs(a - b) < ((Math.Abs(max - min) / 4096.0) / 2))
- {
- return 0;
- }
- else if (a > b)
- {
- return 1;
- }
- else
- {
- return -1;
- }
- }
- )
- );
- if (keyindex > -1)
- {
- data_bins[keys[keyindex]]++;
- }
- }
- this.xAxis.ItemsSource = data_bins;
- this.xAxis.LabelField = "Key";
- this.histogram.ItemsSource = data_bins;
- this.histogram.ValueField = "Value";
- this.yAxis.Maximum = data_bins.Max(b => b.Value);
- this.colormap.Y1 = this.yAxis.Maximum;
- }
- #endregion
- #region Private Methods
- /// <summary> Gets mouse point. </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- ///
- /// <param name="p"> The ScreenPoint to process. </param>
- ///
- /// <returns> The mouse point. </returns>
- private DataPoint GetMousePoint(ScreenPoint p)
- {
- return this.histogram.InverseTransform(p);
- }
- /// <summary> Resets the palette. </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- private void ResetPalette()
- {
- this.current = OxyPalette.Interpolate(4096, this.initial.Colors.ToArray());
- this.previous = OxyPalette.Interpolate(4096, this.initial.Colors.ToArray());
- if (this.OnPaletteChanged != null) this.OnPaletteChanged();
- //this.model.Annotations.ToList().RemoveAll(a => a is ImageAnnotation);
- //OxyColor[,] colors = new OxyColor[4096, 1];
- //for (int i = 0; i < 4096; i++)
- //{
- // colors[i, 0] = OxyColor.FromArgb(255, this.initial.Colors[i].R, this.initial.Colors[i].G, this.initial.Colors[i].B);
- //}
- //this.model.Annotations.Add
- //(
- // new ImageAnnotation
- // {
- // X = new PlotLength(this.xAxis.Minimum, PlotLengthUnit.Data),
- // Y = new PlotLength(this.yAxis.Minimum, PlotLengthUnit.Data),
- // Layer = AnnotationLayer.BelowSeries,
- // ImageSource = OxyImage.Create(colors, ImageFormat.Png),
- // Height = new PlotLength(1, PlotLengthUnit.RelativeToPlotArea),
- // Width = new PlotLength(Math.Abs(this.xAxis.Maximum - this.xAxis.Minimum), PlotLengthUnit.Data),
- // Interpolate = false,
- // HorizontalAlignment = OxyPlot.HorizontalAlignment.Left,
- // VerticalAlignment = VerticalAlignment.Bottom
- // }
- //);
- this.model.InvalidatePlot(true);
- }
- #endregion
- #region Event Handlers
- /// <summary> Event handler. Called by model for mouse down events. </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- ///
- /// <param name="sender"> Source of the event. </param>
- /// <param name="e"> Oxy mouse down event information. </param>
- private void model_MouseDown(object sender, OxyMouseDownEventArgs e)
- {
- if (e.ChangedButton == OxyMouseButton.Left && selectedColor != null)
- {
- DataPoint p = this.GetMousePoint(e.Position);
- if
- (
- p.X >= this.xAxis.Minimum &&
- p.X <= this.xAxis.Maximum &&
- p.Y >= this.yAxis.Minimum &&
- p.Y <= this.yAxis.Maximum
- )
- {
- cursor_i.X = p.X;
- cursor_f.X = p.X;
- anchor = p.X;
- this.model.Annotations.Add(cursor_i);
- this.model.Annotations.Add(cursor_f);
- //this.model.Annotations.Add
- //(
- // new ImageAnnotation
- // {
- // X = new PlotLength(cursor_i.X, PlotLengthUnit.Data),
- // Y = new PlotLength(0, PlotLengthUnit.Data),
- // Layer = AnnotationLayer.BelowSeries,
- // Height = new PlotLength(1, PlotLengthUnit.RelativeToPlotArea),
- // Width = new PlotLength(p.X - cursor_i.X, PlotLengthUnit.Data),
- // Interpolate = false,
- // HorizontalAlignment = OxyPlot.HorizontalAlignment.Left,
- // VerticalAlignment = VerticalAlignment.Bottom
- // }
- //);
- //roi = this.model.Annotations.Last(a => a is ImageAnnotation) as ImageAnnotation;
- e.Handled = true;
- }
- }
- }
- /// <summary> Event handler. Called by model for mouse move events. </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- ///
- /// <param name="sender"> Source of the event. </param>
- /// <param name="e"> Oxy mouse event information. </param>
- private void model_MouseMove(object sender, OxyMouseEventArgs e)
- {
- if (selectedColor != null && cursor_i.Parent == this.model)
- {
- DataPoint p = this.GetMousePoint(e.Position);
- if
- (
- p.X >= this.xAxis.Minimum &&
- p.X <= this.xAxis.Maximum &&
- p.Y >= this.yAxis.Minimum &&
- p.Y <= this.yAxis.Maximum
- )
- {
- //if (roi != null)
- //{
- double diff = Math.Abs(p.X - anchor);
- int length = Convert.ToInt32(diff * dx);
- bool shorter = false;
- if (p.X >= anchor)
- {
- shorter = diff < Math.Abs(cursor_f.X - anchor);
- cursor_f.X = p.X;
- }
- else
- {
- shorter = diff < Math.Abs(cursor_i.X - anchor);
- cursor_i.X = p.X;
- }
- if (shorter)
- {
- this.current = OxyPalette.Interpolate(4096, this.previous.Colors.ToArray());
- }
- //OxyColor[,] imgData = new OxyColor[length, 1];
- int start = Convert.ToInt32(Math.Abs(cursor_i.X - this.xAxis.Minimum) * dx);
- if (selectedColor is Color)
- {
- for (int i = 0; i < length; i++)
- {
- Color color = (Color)selectedColor;
- //imgData[i, 0] =
- this.current.Colors[start + i] = OxyColor.FromArgb(255, color.R, color.G, color.B);
- }
- }
- else if (selectedColor is Color[])
- {
- Color[] gradient = selectedColor as Color[];
- OxyColor[] colors = new OxyColor[gradient.Length];
- for (int i = 0; i < gradient.Length; i++)
- {
- colors[i] = OxyColor.FromArgb(255, gradient[i].R, gradient[i].G, gradient[i].B);
- }
- OxyColor[] data = OxyPalette.Interpolate(length, colors).Colors.ToArray();
- for (int i = 0; i < length; i++)
- {
- //imgData[i, 0] =
- this.current.Colors[start + i] = data[i];
- }
- }
- this.model.InvalidatePlot(true);
- if (this.OnPaletteChanged != null) this.OnPaletteChanged();
- //if (p.X == cursor_i.X)
- //{
- // roi.X = new PlotLength(p.X, PlotLengthUnit.Data);
- //}
- //roi.Width = new PlotLength(diff, PlotLengthUnit.Data);
- //Task.Run(() => { roi.ImageSource = OxyImage.Create(imgData, ImageFormat.Png); });
- }
- e.Handled = true;
- //}
- }
- }
- /// <summary> Event handler. Called by model for mouse up events. </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- ///
- /// <param name="sender"> Source of the event. </param>
- /// <param name="e"> Oxy mouse event information. </param>
- private void model_MouseUp(object sender, OxyMouseEventArgs e)
- {
- this.model.Annotations.Remove(cursor_i);
- this.model.Annotations.Remove(cursor_f);
- this.previous = OxyPalette.Interpolate(4096, this.current.Colors.ToArray());
- this.model.InvalidatePlot(true);
- e.Handled = true;
- }
- #endregion
- /// <summary>
- /// Event handler. Called by ColorPickerSolid for selected index changed events.
- /// </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- ///
- /// <param name="sender"> Source of the event. </param>
- /// <param name="e"> Event information. </param>
- private void ColorPickerSolid_SelectedIndexChanged(object sender, EventArgs e)
- {
- if (this.current != null)
- {
- this.selectedColor = ColorPickerSolid.SelectedItem.Color;
- }
- }
- /// <summary>
- /// Event handler. Called by ColorPickerGradient for selected index changed events.
- /// </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- ///
- /// <param name="sender"> Source of the event. </param>
- /// <param name="e"> Event information. </param>
- private void ColorPickerGradient_SelectedIndexChanged(object sender, EventArgs e)
- {
- if (this.current != null)
- {
- this.selectedColor = ColorPickerGradient.SelectedItem.Colors;
- }
- }
- /// <summary> Event handler. Called by ButtonReset for click events. </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- ///
- /// <param name="sender"> Source of the event. </param>
- /// <param name="e"> Event information. </param>
- private void ButtonReset_Click(object sender, EventArgs e)
- {
- if (this.initial != null)
- {
- this.ResetPalette();
- this.model.InvalidatePlot(true);
- }
- }
- /// <summary> Event handler. Called by ButtonColorUndefined for click events. </summary>
- ///
- /// <remarks> James, 20/05/2015. </remarks>
- ///
- /// <param name="sender"> Source of the event. </param>
- /// <param name="e"> Event information. </param>
- private void ButtonColorUndefined_Click(object sender, EventArgs e)
- {
- if (this.ColorDialog.ShowDialog() == DialogResult.OK)
- {
- this.Invalid = OxyColor.FromArgb
- (
- this.ColorDialog.Color.A,
- this.ColorDialog.Color.R,
- this.ColorDialog.Color.G,
- this.ColorDialog.Color.B
- );
- if (this.OnInvalidColorChanged != null) this.OnInvalidColorChanged();
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement