// -------------------------------------------------------------------------------------------------------------------- // // Copyright (c) 2014 OxyPlot contributors // // // Renders a 'flag' above the x-axis at the specified positions (in the Values list). // // -------------------------------------------------------------------------------------------------------------------- namespace ExampleLibrary { using System.Collections.Generic; using System.Linq; using OxyPlot; using OxyPlot.Axes; using OxyPlot.Series; /// /// Renders a 'flag' above the x-axis at the specified positions (in the Values list). /// public class FlagSeries : ItemsSeries { /// /// The symbol position (y coordinate). /// private double symbolPosition; /// /// The symbol text size. /// private OxySize symbolSize; /// /// Initializes a new instance of the class. /// public FlagSeries() { this.Values = new List(); this.Color = OxyColors.Black; this.FontSize = 10; this.Symbol = ((char)0xEA).ToString(); this.Font = "Wingdings 2"; this.TrackerFormatString = "{0}: {1}"; } /// /// Gets or sets the color of the symbols. /// /// The color. public OxyColor Color { get; set; } /// /// Gets the maximum value. /// /// The maximum value. public double MaximumX { get; private set; } /// /// Gets the minimum value. /// /// The minimum value. public double MinimumX { get; private set; } /// /// Gets or sets the symbol to draw at each value. /// /// The symbol. public string Symbol { get; set; } /// /// Gets the values. /// /// The values. public List Values { get; private set; } /// /// Gets the x-axis. /// /// The x-axis. public Axis XAxis { get; private set; } /// /// Gets or sets the x-axis key. /// /// The x-axis key. public string XAxisKey { get; set; } /// /// Gets the point on the series that is nearest the specified point. /// /// The point. /// Interpolate the series if this flag is set to true. /// A TrackerHitResult for the current hit. public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate) { foreach (var v in this.Values) { if (double.IsNaN(v) || v < this.XAxis.ActualMinimum || v > this.XAxis.ActualMaximum) { continue; } double x = this.XAxis.Transform(v); var r = new OxyRect(x - (this.symbolSize.Width / 2), this.symbolPosition - this.symbolSize.Height, this.symbolSize.Width, this.symbolSize.Height); if (r.Contains(point)) { return new TrackerHitResult { Series = this, DataPoint = new DataPoint(v, double.NaN), Position = new ScreenPoint(x, this.symbolPosition - this.symbolSize.Height), Text = StringHelper.Format(this.ActualCulture, this.TrackerFormatString, null, this.Title, v) }; } } return null; } /// /// Renders the series on the specified render context. /// /// The rendering context. public override void Render(IRenderContext rc) { if (this.XAxis == null) { return; } this.symbolPosition = this.PlotModel.PlotArea.Bottom; this.symbolSize = rc.MeasureText(this.Symbol, this.ActualFont, this.ActualFontSize); foreach (var v in this.Values) { if (double.IsNaN(v) || v < this.XAxis.ClipMinimum || v > this.XAxis.ClipMaximum) { continue; } double x = this.XAxis.Transform(v); rc.DrawText( new ScreenPoint(x, this.symbolPosition), this.Symbol, this.Color, this.ActualFont, this.ActualFontSize, this.ActualFontWeight, 0, HorizontalAlignment.Center, VerticalAlignment.Bottom); } } /// /// Renders the legend symbol on the specified render context. /// /// The rendering context. /// The legend rectangle. public override void RenderLegend(IRenderContext rc, OxyRect legendBox) { rc.DrawText( legendBox.Center, this.Symbol, this.Color, this.ActualFont, this.ActualFontSize, this.ActualFontWeight, 0, HorizontalAlignment.Center, VerticalAlignment.Middle); } /// /// Check if this data series requires X/Y axes. (e.g. Pie series do not require axes) /// /// True if no axes are required. protected override bool AreAxesRequired() { return true; } /// /// Ensures that the axes of the series is defined. /// protected override void EnsureAxes() { this.XAxis = this.XAxisKey != null ? this.PlotModel.GetAxis(this.XAxisKey) : this.PlotModel.DefaultXAxis; } /// /// Check if the data series is using the specified axis. /// /// An axis which should be checked if used /// True if the axis is in use. protected override bool IsUsing(Axis axis) { return axis == this.XAxis; } /// /// Sets default values (colors, line style etc) from the plot model. /// protected override void SetDefaultValues() { } /// /// Updates the axis maximum and minimum values. /// protected override void UpdateAxisMaxMin() { this.XAxis.Include(this.MinimumX); this.XAxis.Include(this.MaximumX); } /// /// Updates the data from the ItemsSource. /// protected override void UpdateData() { // todo } /// /// Updates the maximum and minimum values of the series. /// protected override void UpdateMaxMin() { this.MinimumX = this.Values.Min(); this.MaximumX = this.Values.Max(); } } }