// --------------------------------------------------------------------------------------------------------------------
//
// 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);
}
}
}