// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2014 OxyPlot contributors // // // Provides a Avalonia wrapper for the . // // -------------------------------------------------------------------------------------------------------------------- using System.Diagnostics.Contracts; using Avalonia; namespace OxyPlot.Avalonia { using global::Avalonia.Media; using global::Avalonia.Metadata; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; /// /// Provides a Avalonia wrapper for the . /// public class LinearColorAxis : Axis { /// /// Identifies the dependency property. /// public static readonly StyledProperty> GradientStopsProperty = AvaloniaProperty.Register>(nameof(GradientStops)); /// /// Identifies the dependency property. /// public static readonly StyledProperty HighColorProperty = AvaloniaProperty.Register(nameof(HighColor), Colors.White); /// /// Identifies the dependency property. /// public static readonly StyledProperty LowColorProperty = AvaloniaProperty.Register(nameof(LowColor), Colors.Black); /// /// Identifies the dependency property. /// public static readonly StyledProperty PaletteSizeProperty = AvaloniaProperty.Register(nameof(PaletteSize), 20, validate: ValidatePaletteSize); /// /// Initializes a new instance of the class. /// public LinearColorAxis() { InternalAxis = new Axes.LinearColorAxis(); GradientStops = new List(); } /// /// Gets or sets the palette size. /// public int PaletteSize { get { return GetValue(PaletteSizeProperty); } set { SetValue(PaletteSizeProperty, value); } } /// /// Gets or sets the high color. /// public Color HighColor { get { return GetValue(HighColorProperty); } set { SetValue(HighColorProperty, value); } } /// /// Gets or sets the low color. /// public Color LowColor { get { return GetValue(LowColorProperty); } set { SetValue(LowColorProperty, value); } } /// /// Gets or sets the gradient stops. /// [Content] public IList GradientStops { get { return GetValue(GradientStopsProperty); } set { SetValue(GradientStopsProperty, value); } } /// /// Creates the model. /// /// /// An axis object. /// public override Axes.Axis CreateModel() { SynchronizeProperties(); return InternalAxis; } /// /// Synchronizes the properties. /// protected override void SynchronizeProperties() { base.SynchronizeProperties(); var axis = InternalAxis as Axes.LinearColorAxis; Contract.Requires(axis != null); if (GradientStops != null) { axis.Palette = GradientStops.Count > 2 ? Interpolate(GradientStops.ToList(), PaletteSize) : new OxyPalette(); } axis.HighColor = HighColor.ToOxyColor(); axis.LowColor = LowColor.ToOxyColor(); axis.Minimum = Minimum; axis.Maximum = Maximum; } /// /// Translates a collection of to an . /// /// /// The gradient stops collection to convert. /// /// /// The palette size. /// /// /// The interpolated . /// private static OxyPalette Interpolate(List stops, int paletteSize) { Debug.Assert(stops.Count >= 2, "Can't interpolate less than 2 gradient stops."); Debug.Assert(paletteSize > 0, "Palette size must be non-zero positive number."); var palette = new List(); stops.Sort((x1, x2) => x1.Offset.CompareTo(x2.Offset)); var palettePositions = stops[0].Offset; var step = (double)stops.Count / paletteSize; for (int i = 0; i < stops.Count - 1; i++) { var start = stops[i]; var end = stops[i + 1]; while (palettePositions <= end.Offset) { palette.Add( OxyColor.Interpolate( start.Color.ToOxyColor(), end.Color.ToOxyColor(), (palettePositions - start.Offset) / (end.Offset - start.Offset))); palettePositions += step; } } return new OxyPalette(palette); } /// /// Validates the palette size. /// /// /// The property value. /// /// /// The validation result. /// private static bool ValidatePaletteSize(int value) { return value >= 1; } static LinearColorAxis() { GradientStopsProperty.Changed.AddClassHandler(AppearanceChanged); HighColorProperty.Changed.AddClassHandler(AppearanceChanged); LowColorProperty.Changed.AddClassHandler(AppearanceChanged); PaletteSizeProperty.Changed.AddClassHandler(AppearanceChanged); } } }