<commit_before>﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BoxPlotSeries.cs" company="OxyPlot">
//   http://oxyplot.codeplex.com, license: Ms-PL
// </copyright>
// <summary>
//   The box plot series.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace OxyPlot
{
    using System.Collections.Generic;
    using System.Linq;

    /// <summary>
    /// The box plot series.
    /// </summary>
    public class BoxPlotSeries : XYAxisSeries
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="BoxPlotSeries"/> class. 
        /// </summary>
        public BoxPlotSeries()
        {
            this.Items = new List<BoxPlotItem>();
            this.TrackerFormatString =
                "X: {1:0.00}\nUpper Whisker: {2:0.00}\nThird Quartil: {3:0.00}\nMedian: {4:0.00}\nFirst Quartil: {5:0.00}\nLower Whisker: {6:0.00}\nOutliers: {7}";
            this.Title = null;
            this.Fill = null;
            this.Stroke = OxyColors.Black;
            this.BoxWidth = 20;
            this.StrokeThickness = 1;
            this.OutlierSize = 2;
            this.WhiskerWidth = 0.5;
        }

        #endregion

        #region Public Properties

        /// <summary>
        ///   Gets or sets the width of the boxes (specified in x-axis units).
        /// </summary>
        /// <value> The width of the boxes. </value>
        public double BoxWidth { get; set; }

        /// <summary>
        ///   Gets or sets the fill color. If null, this color will be automatically set.
        /// </summary>
        /// <value> The fill color. </value>
        public OxyColor Fill { get; set; }

        /// <summary>
        ///   Gets or sets the box plot items.
        /// </summary>
        /// <value> The items. </value>
        public IList<BoxPlotItem> Items { get; set; }

        /// <summary>
        ///   Gets or sets the diameter of the outlier circles (specified in points).
        /// </summary>
        /// <value> The size of the outlier. </value>
        public double OutlierSize { get; set; }

        /// <summary>
        ///   Gets or sets the stroke.
        /// </summary>
        /// <value> The stroke. </value>
        public OxyColor Stroke { get; set; }

        /// <summary>
        ///   Gets or sets the stroke thickness.
        /// </summary>
        /// <value> The stroke thickness. </value>
        public double StrokeThickness { get; set; }

        /// <summary>
        ///   Gets or sets the width of the whiskers (relative to the BoxWidth).
        /// </summary>
        /// <value> The width of the whiskers. </value>
        public double WhiskerWidth { get; set; }

        #endregion

        #region Public Methods

        /// <summary>
        /// Gets the nearest point.
        /// </summary>
        /// <param name="point">
        /// The point. 
        /// </param>
        /// <param name="interpolate">
        /// interpolate if set to <c>true</c> . 
        /// </param>
        /// <returns>
        /// A TrackerHitResult for the current hit. 
        /// </returns>
        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
        {
            double minimumDistance = double.MaxValue;
            var result = new TrackerHitResult(this, DataPoint.Undefined, ScreenPoint.Undefined);
            foreach (var item in this.Items)
            {
                foreach (var outlier in item.Outliers)
                {
                    var sp = this.Transform(item.X, outlier);
                    double d = (sp - point).LengthSquared;
                    if (d < minimumDistance)
                    {
                        result.DataPoint = new DataPoint(item.X, outlier);
                        result.Position = sp;
                        result.Item = item;
                        minimumDistance = d;
                    }
                }

                // check if we are inside the box rectangle
                var rect = this.GetBoxRect(item);
                if (rect.Contains(point))
                {
                    result.DataPoint = new DataPoint(item.X, this.YAxis.InverseTransform(point.Y));
                    result.Position = this.Transform(result.DataPoint);
                    result.Item = item;
                    minimumDistance = 0;
                }

                var topWhisker = this.Transform(item.X, item.UpperWhisker);
                var bottomWhisker = this.Transform(item.X, item.LowerWhisker);

                // check if we are near the line
                var p = ScreenPoint.FindPointOnLine(point, topWhisker, bottomWhisker);
                double d2 = (p - point).LengthSquared;
                if (d2 < minimumDistance)
                {
                    result.DataPoint = this.InverseTransform(p);
                    result.Position = this.Transform(result.DataPoint);
                    result.Item = item;
                    minimumDistance = d2;
                }
            }

            if (minimumDistance < double.MaxValue)
            {
                var item = (BoxPlotItem)result.Item;
                result.Text = StringHelper.Format(
                    this.ActualCulture,
                    this.TrackerFormatString,
                    item,
                    this.Title,
                    result.DataPoint.X,
                    item.UpperWhisker,
                    item.BoxTop,
                    item.Median,
                    item.BoxBottom,
                    item.LowerWhisker,
                    StringHelper.CreateList(this.ActualCulture, item.Outliers, "{0:0.########}"));

                return result;
            }

            return null;
        }

        /// <summary>
        /// Determines whether the specified item contains a valid point.
        /// </summary>
        /// <param name="item">
        /// The item. 
        /// </param>
        /// <param name="xaxis">
        /// The x axis. 
        /// </param>
        /// <param name="yaxis">
        /// The y axis. 
        /// </param>
        /// <returns>
        /// <c>true</c> if the point is valid; otherwise, <c>false</c> . 
        /// </returns>
        public virtual bool IsValidPoint(BoxPlotItem item, Axis xaxis, Axis yaxis)
        {
            return !double.IsNaN(item.X) && !double.IsInfinity(item.X) && !item.Values.Any(double.IsNaN)
                   && !item.Values.Any(double.IsInfinity) && (xaxis != null && xaxis.IsValidValue(item.X))
                   && (yaxis != null && item.Values.All(yaxis.IsValidValue));
        }

        /// <summary>
        /// Renders the series on the specified render context.<commit_msg>BoxPlotSeries: added OutlierTrackerFormatString property<commit_after>﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="BoxPlotSeries.cs" company="OxyPlot">
//   http://oxyplot.codeplex.com, license: Ms-PL
// </copyright>
// <summary>
//   The box plot series.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace OxyPlot
{
    using System.Collections.Generic;
    using System.Linq;

    /// <summary>
    /// The box plot series.
    /// </summary>
    public class BoxPlotSeries : XYAxisSeries
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="BoxPlotSeries"/> class. 
        /// </summary>
        public BoxPlotSeries()
        {
            this.Items = new List<BoxPlotItem>();
            this.TrackerFormatString =
                "X: {1:0.00}\nUpper Whisker: {2:0.00}\nThird Quartil: {3:0.00}\nMedian: {4:0.00}\nFirst Quartil: {5:0.00}\nLower Whisker: {6:0.00}";
            this.OutlierTrackerFormatString =
                "X: {1:0.00}\nY: {2:0.00}";
            this.Title = null;
            this.Fill = null;
            this.Stroke = OxyColors.Black;
            this.BoxWidth = 20;
            this.StrokeThickness = 1;
            this.OutlierSize = 2;
            this.WhiskerWidth = 0.5;
        }

        #endregion

        #region Public Properties

        /// <summary>
        ///   Gets or sets the width of the boxes (specified in x-axis units).
        /// </summary>
        /// <value> The width of the boxes. </value>
        public double BoxWidth { get; set; }

        /// <summary>
        ///   Gets or sets the fill color. If null, this color will be automatically set.
        /// </summary>
        /// <value> The fill color. </value>
        public OxyColor Fill { get; set; }

        /// <summary>
        ///   Gets or sets the box plot items.
        /// </summary>
        /// <value> The items. </value>
        public IList<BoxPlotItem> Items { get; set; }

        /// <summary>
        ///   Gets or sets the diameter of the outlier circles (specified in points).
        /// </summary>
        /// <value> The size of the outlier. </value>
        public double OutlierSize { get; set; }

        /// <summary>
        /// Gets or sets the tracker format string for the outliers.
        /// </summary>
        /// <value>
        /// The tracker format string for the outliers.
        /// </value>
        /// <remarks>
        /// Use {0} for series title, {1} for x- and {2} for y-value.
        /// </remarks>
        public string OutlierTrackerFormatString { get; set; }

        /// <summary>
        ///   Gets or sets the stroke.
        /// </summary>
        /// <value> The stroke. </value>
        public OxyColor Stroke { get; set; }

        /// <summary>
        ///   Gets or sets the stroke thickness.
        /// </summary>
        /// <value> The stroke thickness. </value>
        public double StrokeThickness { get; set; }

        /// <summary>
        ///   Gets or sets the width of the whiskers (relative to the BoxWidth).
        /// </summary>
        /// <value> The width of the whiskers. </value>
        public double WhiskerWidth { get; set; }

        #endregion

        #region Public Methods

        /// <summary>
        /// Gets the nearest point.
        /// </summary>
        /// <param name="point">
        /// The point. 
        /// </param>
        /// <param name="interpolate">
        /// interpolate if set to <c>true</c> . 
        /// </param>
        /// <returns>
        /// A TrackerHitResult for the current hit. 
        /// </returns>
        public override TrackerHitResult GetNearestPoint(ScreenPoint point, bool interpolate)
        {
            double minimumDistance = double.MaxValue;
            var result = new TrackerHitResult(this, DataPoint.Undefined, ScreenPoint.Undefined);
            foreach (var item in this.Items)
            {
                foreach (var outlier in item.Outliers)
                {
                    var sp = this.Transform(item.X, outlier);
                    double d = (sp - point).LengthSquared;
                    if (d < minimumDistance)
                    {
                        result.DataPoint = new DataPoint(item.X, outlier);
                        result.Position = sp;
                        result.Item = item;
                        result.Text = StringHelper.Format(
                            this.ActualCulture,
                            this.OutlierTrackerFormatString,
                            item,
                            this.Title,
                            result.DataPoint.X,
                            outlier);
                        minimumDistance = d;
                    }
                }

                // check if we are inside the box rectangle
                var rect = this.GetBoxRect(item);
                if (rect.Contains(point))
                {
                    result.DataPoint = new DataPoint(item.X, this.YAxis.InverseTransform(point.Y));
                    result.Position = this.Transform(result.DataPoint);
                    result.Item = item;

                    result.Text = StringHelper.Format(
                        this.ActualCulture,
                        this.TrackerFormatString,
                        item,
                        this.Title,
                        result.DataPoint.X,
                        item.UpperWhisker,
                        item.BoxTop,
                        item.Median,
                        item.BoxBottom,
                        item.LowerWhisker);

                    minimumDistance = 0;
                }

                var topWhisker = this.Transform(item.X, item.UpperWhisker);
                var bottomWhisker = this.Transform(item.X, item.LowerWhisker);

                // check if we are near the line
                var p = ScreenPoint.FindPointOnLine(point, topWhisker, bottomWhisker);
                double d2 = (p - point).LengthSquared;
                if (d2 < minimumDistance)
                {
                    result.DataPoint = this.InverseTransform(p);
                    result.Position = this.Transform(result.DataPoint);
                    result.Item = item;
                    result.Text = StringHelper.Format(
                        this.ActualCulture,
                        this.TrackerFormatString,
                        item,
                        this.Title,
                        result.DataPoint.X,
                        item.UpperWhisker,
                        item.BoxTop,
                        item.Median,
                        item.BoxBottom,
                        item.LowerWhisker);
                    minimumDistance = d2;
                }
            }

            if (minimumDistance < double.MaxValue)
            {
                return result;
            }

            return null;
        }

        /// <summary>
        /// Determines whether the specified item contains a valid point.
        /// </summary>
        /// <param name="item">
        /// The item. 
        /// </param>
        /// <param name="xaxis">
        /// The x axis. 
        /// </param>
        /// <param name="yaxis">
        /// The y axis. 
        /// </param>
        /// <returns>
        /// <c>true</c> if the point is valid; otherwise, <c>false</c> . 
        /// </returns>
        public virtual bool IsValidPoint(BoxPlotItem item, Axis xaxis, Axis yaxis)
        {
            return !double.IsNaN(item.X) && !double.IsInfinity(item.X) && !item.Values.Any(double.IsNaN)
                   && !item.Values.Any(double.IsInfinity) && (xaxis != null && xaxis.IsValidValue(item.X))
                   && (yaxis != null && item.Values.All(yaxis.IsValidValue));
        }

        /// <summary>
        /// Renders the series on the specified render context.
{'fraction_non_alphanumeric': 0.14692543684140322, 'fraction_numerical': 0.005468854208350007, 'mean_word_length': 1.1662814215544641, 'pattern_counts': {'":': 0, '<': 143, '<?xml version=': 0, '>': 137, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5884872', 'n_tokens_mistral': 3999, 'n_tokens_neox': 3744, 'n_words': 989}