Repository: danielgindi/Charts
File: Charts/Classes/Charts/BarChartView.swift (Swift)

Code before:
        renderer = BarChartRenderer(delegate: self, animator: _animator, viewPortHandler: _viewPortHandler)
        _xAxisRenderer = ChartXAxisRendererBarChart(viewPortHandler: _viewPortHandler, xAxis: _xAxis, transformer: _leftAxisTransformer, chart: self)
        
        _highlighter = BarChartHighlighter(chart: self)
        
        _chartXMin = -0.5
    }
    
    internal override func calcMinMax()
    {
        super.calcMinMax()
        
        if (_data === nil)
        {
            return
        }
        
        var barData = _data as! BarChartData
        
        // increase deltax by 1 because the bars have a width of 1
        _deltaX += 0.5
        
        // extend xDelta to make space for multiple datasets (if ther are one)
        _deltaX *= CGFloat(_data.dataSetCount)
        
        var maxEntry = 0
        
        for (var i = 0, count = barData.dataSetCount; i < count; i++)
        {
            var set = barData.getDataSetByIndex(i)
            
            if (maxEntry < set!.entryCount)
            {
                maxEntry = set!.entryCount
            }
        }
        
        var groupSpace = barData.groupSpace
        _deltaX += CGFloat(maxEntry) * groupSpace
        _chartXMax = Double(_deltaX) - _chartXMin
    }
    
    /// Returns the Highlight object (contains x-index and DataSet index) of the selected value at the given touch point inside the BarChart.
    public override func getHighlightByTouchPoint(pt: CGPoint) -> ChartHighlight?
    {
        if (_dataNotSet || _data === nil)
        {
            println("Can't select by touch. No data set.")
            return nil
        }
        

Review comment (bug):
Each dataSet will have up to xValsCount entries, however, in some cases, if there is no dataSet's entryCount would be xValsCount, it goes wrong. If the specific xIndex doesn't have entry for every dataSet, the maxEntry count would less than x values count. 

We cannot rely on dataSet.entryCount to get the maxEntry. `maxEntry` may not be the proper name for the new logic. But I am not sure what's the better name to have.

The true meaning of "maxEntry" would always be xValsCount, based on the fact we don't insert Null/NaN entry if no data for the xIndex. If we force the entryCount must be equal to xValsCount, the issue is no longer valid I think, but we have to insert Null/NaN and handle them then.

I am using below data code to test in demo multiple bar charts. It only has data at first index and last index. If you use old logic to calculate maxEntry, then it only draws the first index bars. The last one is missing, and the xAxis is not rendered correctly as well. The `maxEntry` would be 2 in old logic, however I got 11 xIndex. Applying the change, maxEntry will be 11, and the chart looks good.

Acutally, this is the first place I changed when I found the issue. But not enough to fix the bug.

``` Objective-C
- (void)setDataCount:(int)count range:(double)range
{
    NSMutableArray *xVals = [[NSMutableArray alloc] init];
    for (int i = 0; i < 11; i++)
    {
        [xVals addObject:[@(i + 2015) stringValue]];
    }
    NSMutableArray *yVals1 = [[NSMutableArray alloc] init];
    NSMutableArray *yVals2 = [[NSMutableArray alloc] init];

    for (int i = 0; i < 11; i++)
    {
        if (i == 0) {
            [yVals1 addObject:[[BarChartDataEntry alloc] initWithValue:2354235 xIndex:i]];
            [yVals2 addObject:[[BarChartDataEntry alloc] initWithValue:3354235 xIndex:i]];
        } else if (i == 10) {
            [yVals1 addObject:[[BarChartDataEntry alloc] initWithValue:6354235 xIndex:i]];
            [yVals2 addObject:[[BarChartDataEntry alloc] initWithValue:7354235 xIndex:i]];
        } else {
            continue;
        }
    }

    BarChartDataSet *set1 = [[BarChartDataSet alloc] initWithYVals:yVals1 label:@"Company A"];
    [set1 setColor:[UIColor colorWithRed:104/255.f green:241/255.f blue:175/255.f alpha:1.f]];
    BarChartDataSet *set2 = [[BarChartDataSet alloc] initWithYVals:yVals2 label:@"Company B"];
    [set2 setColor:[UIColor colorWithRed:164/255.f green:228/255.f blue:251/255.f alpha:1.f]];

    NSMutableArray *dataSets = [[NSMutableArray alloc] init];
    [dataSets addObject:set1];
    [dataSets addObject:set2];

    BarChartData *data = [[BarChartData alloc] initWithXVals:xVals dataSets:dataSets];
    data.groupSpace = 0.8;
    [data setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];
    _chartView.leftAxis.startAtZeroEnabled = NO;
    _chartView.rightAxis.startAtZeroEnabled = NO;
    _chartView.data = data;
}
```


Code after:
        renderer = BarChartRenderer(delegate: self, animator: _animator, viewPortHandler: _viewPortHandler)
        _xAxisRenderer = ChartXAxisRendererBarChart(viewPortHandler: _viewPortHandler, xAxis: _xAxis, transformer: _leftAxisTransformer, chart: self)
        
        _highlighter = BarChartHighlighter(chart: self)
        
        _chartXMin = -0.5
    }
    
    internal override func calcMinMax()
    {
        super.calcMinMax()
        
        if (_data === nil)
        {
            return
        }
        
        var barData = _data as! BarChartData
        
        // increase deltax by 1 because the bars have a width of 1
        _deltaX += 0.5
        
        // extend xDelta to make space for multiple datasets (if ther are one)
        _deltaX *= CGFloat(_data.dataSetCount)
        
        var maxEntry = barData.xValCount
        
        var groupSpace = barData.groupSpace
        _deltaX += CGFloat(maxEntry) * groupSpace
        _chartXMax = Double(_deltaX) - _chartXMin
    }
    
    /// Returns the Highlight object (contains x-index and DataSet index) of the selected value at the given touch point inside the BarChart.
    public override func getHighlightByTouchPoint(pt: CGPoint) -> ChartHighlight?
    {
        if (_dataNotSet || _data === nil)
        {
            println("Can't select by touch. No data set.")
            return nil
        }
        
        return _highlighter?.getHighlight(x: Double(pt.x), y: Double(pt.y))
    }
    
    /// Returns the bounding box of the specified Entry in the specified DataSet. Returns null if the Entry could not be found in the charts data.
    public func getBarBounds(e: BarChartDataEntry) -> CGRect!
    {
        var set = _data.getDataSetForEntry(e) as! BarChartDataSet!
        
        if (set === nil)
        {