<commit_before>//
//  ChartDataSet.swift
//  Charts
//
//  Copyright 2015 <NAME> & <NAME>
//  A port of MPAndroidChart for iOS
//  Licensed under Apache License 2.0
//
//  https://github.com/danielgindi/Charts
//

import Foundation

/// Determines how to round DataSet index values for `ChartDataSet.entryIndex(x, rounding)` when an exact x-value is not found.
@objc
public enum ChartDataSetRounding: Int
{
    case up = 0
    case down = 1
    case closest = 2
}

/// The DataSet class represents one group or type of entries (Entry) in the Chart that belong together.
/// It is designed to logically separate different groups of values inside the Chart (e.g. the values for a specific line in the LineChart, or the values of a specific group of bars in the BarChart).
open class ChartDataSet: ChartBaseDataSet
{
    public required init()
    {
        super.init()
        
        _values = [ChartDataEntry]()
    }
    
    public override init(label: String?)
    {
        super.init(label: label)
        
        _values = [ChartDataEntry]()
    }
    
    public init(values: [ChartDataEntry]?, label: String?)
    {
        super.init(label: label)
        
        _values = values == nil ? [ChartDataEntry]() : values
        
        self.calcMinMax()
    }
    
    public convenience init(values: [ChartDataEntry]?)
    {
        self.init(values: values, label: "DataSet")
    }
    
    // MARK: - Data functions and accessors
    
    /// the entries that this dataset represents / holds together
    internal var _values: [ChartDataEntry]!
    
    /// maximum y-value in the value array
    internal var _yMax: Double = -DBL_MAX
    
    /// minimum y-value in the value array
    internal var _yMin: Double = DBL_MAX
    
    /// maximum x-value in the value array
    internal var _xMax: Double = -DBL_MAX
    
    /// minimum x-value in the value array
    internal var _xMin: Double = DBL_MAX
    
    /// *
    /// - note: Calls `notifyDataSetChanged()` after setting a new value.
    /// - returns: The array of y-values that this DataSet represents.
    open var values: [ChartDataEntry]
    {
        get
        {
            return _values
        }
        set
        {
            _values = newValue
            notifyDataSetChanged()
        }
    }
    
    /// Use this method to tell the data set that the underlying data has changed
    open override func notifyDataSetChanged()
    {
        calcMinMax()
    }
    
    open override func calcMinMax()
    {
        if _values.count == 0
        {
            return
        }
        
        _yMax = -DBL_MAX
        _yMin = DBL_MAX
        _xMax = -DBL_MAX
        _xMin = DBL_MAX
        
        for e in _values
        {
            calcMinMax(entry: e)
        }
    }
    
    open override func calcMinMaxY(fromX: Double, toX: Double)
    {
        if _values.count == 0
        {
            return
        }
        
        _yMax = -DBL_MAX
        _yMin = DBL_MAX
        
        let indexFrom = entryIndex(x: fromX, closestToY: Double.nan, rounding: .down)
        let indexTo = entryIndex(x: toX, closestToY: Double.nan, rounding: .up)
        
        if indexTo <= indexFrom { return }
        
        for i in indexFrom..<indexTo
        {
            // only recalculate y
            calcMinMaxY(entry: _values[i])
        }
    }
    
    open func calcMinMaxX(entry e: ChartDataEntry)
    {
        if e.x < _xMin
        {
            _xMin = e.x
        }
        if e.x > _xMax
        {
            _xMax = e.x
        }
    }
    
    open func calcMinMaxY(entry e: ChartDataEntry)
    {
        if e.y < _yMin
        {
            _yMin = e.y
        }
        if e.y > _yMax
        {
            _yMax = e.y
        }
    }
    
    /// Updates the min and max x and y value of this DataSet based on the given Entry.
    ///
    /// - parameter e:
    internal func calcMinMax(entry e: ChartDataEntry)
    {
        calcMinMaxX(entry: e)
        calcMinMaxY(entry: e)
    }
    
    /// - returns: The minimum y-value this DataSet holds
    open override var yMin: Double { return _yMin }
    
    /// - returns: The maximum y-value this DataSet holds
    open override var yMax: Double { return _yMax }
    
    /// - returns: The minimum x-value this DataSet holds
    open override var xMin: Double { return _xMin }
    
    /// - returns: The maximum x-value this DataSet holds
    open override var xMax: Double { return _xMax }
    
    /// - returns: The number of y-values this DataSet represents
    open override var entryCount: Int { return _values?.count ?? 0 }
    
    /// - returns: The entry object found at the given index (not x-value!)
    /// - throws: out of bounds
    /// if `i` is out of bounds, it may throw an out-of-bounds exception
    open override func entryForIndex(_ i: Int) -> ChartDataEntry?
    {
        return _values[i]
    }
    
    /// - returns: The first Entry object found at the given x-value with binary search.
    /// If the no Entry at the specified x-value is found, this method returns the Entry at the closest x-value according to the rounding.
    /// nil if no Entry object at that x-value.
    /// - parameter xValue: the x-value
    /// - parameter closestToY: If there are multiple y-values for the specified x-value,
    /// - parameter rounding: determine whether to round up/down/closest if there is no Entry matching the provided x-value
    open override func entryForXValue(
        _ xValue: Double,
        closestToY yValue: Double,
        rounding: ChartDataSetRounding) -> ChartDataEntry?
    {
        let index = self.entryIndex(x: xValue, closestToY: yValue, rounding: rounding)
        if index > -1
        {
            return _values[index]
        }
        return nil
    }
    
    /// - returns: The first Entry object found at the given x-value with binary search.
    /// If the no Entry at the specified x-value is found, this method returns the Entry at the closest x-value.<commit_msg>Fixes index out of range crash.<commit_after>//
//  ChartDataSet.swift
//  Charts
//
//  Copyright 2015 <NAME> & <NAME>
//  A port of MPAndroidChart for iOS
//  Licensed under Apache License 2.0
//
//  https://github.com/danielgindi/Charts
//

import Foundation

/// Determines how to round DataSet index values for `ChartDataSet.entryIndex(x, rounding)` when an exact x-value is not found.
@objc
public enum ChartDataSetRounding: Int
{
    case up = 0
    case down = 1
    case closest = 2
}

/// The DataSet class represents one group or type of entries (Entry) in the Chart that belong together.
/// It is designed to logically separate different groups of values inside the Chart (e.g. the values for a specific line in the LineChart, or the values of a specific group of bars in the BarChart).
open class ChartDataSet: ChartBaseDataSet
{
    public required init()
    {
        super.init()
        
        _values = [ChartDataEntry]()
    }
    
    public override init(label: String?)
    {
        super.init(label: label)
        
        _values = [ChartDataEntry]()
    }
    
    public init(values: [ChartDataEntry]?, label: String?)
    {
        super.init(label: label)
        
        _values = values == nil ? [ChartDataEntry]() : values
        
        self.calcMinMax()
    }
    
    public convenience init(values: [ChartDataEntry]?)
    {
        self.init(values: values, label: "DataSet")
    }
    
    // MARK: - Data functions and accessors
    
    /// the entries that this dataset represents / holds together
    internal var _values: [ChartDataEntry]!
    
    /// maximum y-value in the value array
    internal var _yMax: Double = -DBL_MAX
    
    /// minimum y-value in the value array
    internal var _yMin: Double = DBL_MAX
    
    /// maximum x-value in the value array
    internal var _xMax: Double = -DBL_MAX
    
    /// minimum x-value in the value array
    internal var _xMin: Double = DBL_MAX
    
    /// *
    /// - note: Calls `notifyDataSetChanged()` after setting a new value.
    /// - returns: The array of y-values that this DataSet represents.
    open var values: [ChartDataEntry]
    {
        get
        {
            return _values
        }
        set
        {
            _values = newValue
            notifyDataSetChanged()
        }
    }
    
    /// Use this method to tell the data set that the underlying data has changed
    open override func notifyDataSetChanged()
    {
        calcMinMax()
    }
    
    open override func calcMinMax()
    {
        if _values.count == 0
        {
            return
        }
        
        _yMax = -DBL_MAX
        _yMin = DBL_MAX
        _xMax = -DBL_MAX
        _xMin = DBL_MAX
        
        for e in _values
        {
            calcMinMax(entry: e)
        }
    }
    
    open override func calcMinMaxY(fromX: Double, toX: Double)
    {
        if _values.count == 0
        {
            return
        }
        
        _yMax = -DBL_MAX
        _yMin = DBL_MAX
        
        let indexFrom = entryIndex(x: fromX, closestToY: Double.nan, rounding: .down)
        let indexTo = entryIndex(x: toX, closestToY: Double.nan, rounding: .up)
        
        if indexTo <= indexFrom { return }
        
        for i in indexFrom..<indexTo
        {
            // only recalculate y
            calcMinMaxY(entry: _values[i])
        }
    }
    
    open func calcMinMaxX(entry e: ChartDataEntry)
    {
        if e.x < _xMin
        {
            _xMin = e.x
        }
        if e.x > _xMax
        {
            _xMax = e.x
        }
    }
    
    open func calcMinMaxY(entry e: ChartDataEntry)
    {
        if e.y < _yMin
        {
            _yMin = e.y
        }
        if e.y > _yMax
        {
            _yMax = e.y
        }
    }
    
    /// Updates the min and max x and y value of this DataSet based on the given Entry.
    ///
    /// - parameter e:
    internal func calcMinMax(entry e: ChartDataEntry)
    {
        calcMinMaxX(entry: e)
        calcMinMaxY(entry: e)
    }
    
    /// - returns: The minimum y-value this DataSet holds
    open override var yMin: Double { return _yMin }
    
    /// - returns: The maximum y-value this DataSet holds
    open override var yMax: Double { return _yMax }
    
    /// - returns: The minimum x-value this DataSet holds
    open override var xMin: Double { return _xMin }
    
    /// - returns: The maximum x-value this DataSet holds
    open override var xMax: Double { return _xMax }
    
    /// - returns: The number of y-values this DataSet represents
    open override var entryCount: Int { return _values?.count ?? 0 }
    
    /// - returns: The entry object found at the given index (not x-value!)
    /// - throws: out of bounds
    /// if `i` is out of bounds, it may throw an out-of-bounds exception
    open override func entryForIndex(_ i: Int) -> ChartDataEntry?
    {
        guard i >= 0 && i < _values.count else {
            return nil
        }
        return _values[i]
    }
    
    /// - returns: The first Entry object found at the given x-value with binary search.
    /// If the no Entry at the specified x-value is found, this method returns the Entry at the closest x-value according to the rounding.
    /// nil if no Entry object at that x-value.
    /// - parameter xValue: the x-value
    /// - parameter closestToY: If there are multiple y-values for the specified x-value,
    /// - parameter rounding: determine whether to round up/down/closest if there is no Entry matching the provided x-value
    open override func entryForXValue(
        _ xValue: Double,
        closestToY yValue: Double,
        rounding: ChartDataSetRounding) -> ChartDataEntry?
    {
        let index = self.entryIndex(x: xValue, closestToY: yValue, rounding: rounding)
        if index > -1
        {
            return _values[index]
        }
        return nil
    }
    
    /// - returns: The first Entry object found at the given x-value with binary search.
    /// If the no Entry at the specified x-value is found, this method returns the Entry at the closest x-value.
{'fraction_non_alphanumeric': 0.08545665122435474, 'fraction_numerical': 0.002233620119126406, 'mean_word_length': 1.7632, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 18, 'https://': 2, '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': '6078132', 'n_tokens_mistral': 3535, 'n_tokens_neox': 3509, 'n_words': 1246}