Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A field crash issue for highestVisibleXIndex #329

Closed
liuxuan30 opened this issue Aug 31, 2015 · 13 comments
Closed

A field crash issue for highestVisibleXIndex #329

liuxuan30 opened this issue Aug 31, 2015 · 13 comments

Comments

@liuxuan30
Copy link
Member

I get below crash captured by Crashlytics twice, not very often, and not sure what would be the cause:

BarLineChartViewBase.swift line 1454
function signature specialization <Arg[0] = Owned To Guaranteed> of BarLineChartViewBase.highestVisibleXIndex.getter : Swift.Int

Corresponding code:

    /// Returns the highest x-index (value on the x-axis) that is still visible on the chart.
    public var highestVisibleXIndex: Int
    {
        var pt = CGPoint(x: viewPortHandler.contentRight, y: viewPortHandler.contentBottom)
        getTransformer(.Left).pixelToValue(&pt)
        return (Int(pt.x) >= _data.xValCount) ? _data.xValCount - 1 : Int(pt.x) <-- line 1454
    }

I am not familiar with swift exceptions, looks like Int(pt.x) is causing the exception? @danielgindi, any ideas?
If no one has ideas, maybe I will add a CLS_LOG to see what happened

@danielgindi
Copy link
Collaborator

Is it possible that _data was nil at the time? Because it is force-unwrapped, and if nil then it could crash...

But the error says Swift.Int...
So maybe Swift crashes when converting aCGFloat.NaN to Int?

But it still does not make sense as the error says it is something with the function signature. Like a call from ObjC when passing wrong argument types, nils etc.

@liuxuan30
Copy link
Member Author

I have added log before getTransformer(.Left).pixelToValue(&pt) and after. Next time I see the crash I will check the log.

@liuxuan30
Copy link
Member Author

Well catch the log:
535 | 00:01:15:110 | $ pt.x 363.825195, xValCount:1 before transform
536 | 00:01:15:111 | $ pt.x nan, xValCount:1 after transform

public var highestVisibleXIndex: Int
{
    var pt = CGPoint(x: viewPortHandler.contentRight, y: viewPortHandler.contentBottom)

    CLSLogv("pt.x %f, xValCount:%d before transform", getVaList([pt.x, _data.xValCount]))

    getTransformer(.Left).pixelToValue(&pt)

    CLSLogv("pt.x %f, xValCount:%d after transform", getVaList([pt.x, _data.xValCount]))

    return (Int(pt.x) >= _data.xValCount) ? _data.xValCount - 1 : Int(pt.x)
}

after pixelToValue the pt.x indeed became nan.

@liuxuan30
Copy link
Member Author

With further debugging,

It turned to be the problem that there is only lineData in the combinedChartView.
It only has 3 LineChartDataSet and only 1 x value, no other data, then it will never set _deltaX to 1 if it is 0 as line chart:

    override func calcMinMax() // combined chart
    {
        super.calcMinMax()

        if (self.barData !== nil || self.candleData !== nil || self.bubbleData !== nil)
        {
            _chartXMin = -0.5
            _chartXMax = Double(_data.xVals.count) - 0.5

            if (self.bubbleData !== nil)
            {
                for set in self.bubbleData.dataSets as! [BubbleChartDataSet]
                {
                    let xmin = set.xMin
                    let xmax = set.xMax

                    if (xmin < chartXMin)
                    {
                        _chartXMin = xmin
                    }

                    if (xmax > chartXMax)
                    {
                        _chartXMax = xmax
                    }
                }
            }

            _deltaX = CGFloat(abs(_chartXMax - _chartXMin))
        }
    }
    internal override func calcMinMax()  // line chart
    {
        super.calcMinMax()

        if (_deltaX == 0.0 && _data.yValCount > 0)
        {
            _deltaX = 1.0
        }
    }

So when line chart only has one x value, the deltaX would be 0, and then the _matrixValueToPx messed up, the scaleX is inf.

    public func prepareMatrixValuePx(chartXMin chartXMin: Double, deltaX: CGFloat, deltaY: CGFloat, chartYMin: Double)
    {
        let scaleX = (_viewPortHandler.contentWidth / deltaX) // deltaX is 0
        let scaleY = (_viewPortHandler.contentHeight / deltaY)

        // setup all matrices
        _matrixValueToPx = CGAffineTransformIdentity
        _matrixValueToPx = CGAffineTransformScale(_matrixValueToPx, scaleX, -scaleY)
        _matrixValueToPx = CGAffineTransformTranslate(_matrixValueToPx, CGFloat(-chartXMin), CGFloat(-chartYMin))
    }

@danielgindi, if it is combined chart, I would like to put the single line dot in the middle of xAxis, do you know how to set up this special matrix? I will fix it later.

@liuxuan30
Copy link
Member Author

I am thinking current logic does supports well for line chart, if only one x value, it will be draw on the left most side. It's better to draw it in the middle. But I cannot come up a matrix that could do so... Tried set _chartXMin, deltaX, _chartXMax, no luck.

liuxuan30 added a commit to liuxuan30/Charts that referenced this issue Oct 8, 2015
@liuxuan30
Copy link
Member Author

It turned out to be a elegant solution liuxuan30@1bd8c22 exact as how line chart view handles _deltaX.

liuxuan30 added a commit to liuxuan30/Charts that referenced this issue Oct 30, 2015
…data, not each sub data's index

add one more bar data set in demo view controller (+4 squashed commits)
Squashed commits:
[44ce60e] rename some BarChartDataProvider protocol methods not the same as ChartDataProvider
[1bd8c22] Fix issue ChartsOrg#329 check _deltaX when only lineData exists
[90a327d] 1. fix bug in getDataSetIndex, it will detect what dataSet it is and determine how to proceed
2. I also override getMarkerPosition for CombinedChartView
[80aa1b3] add support for grouped bars in CombinedChartView.
add a new demo view controller called GroupedCombinedChartViewController, to illustrate multiple bars + multiple line
liuxuan30 added a commit to liuxuan30/Charts that referenced this issue Oct 30, 2015
…data, not each sub data's index

add one more bar data set in demo view controller (+4 squashed commits)
Squashed commits:
[44ce60e] rename some BarChartDataProvider protocol methods not the same as ChartDataProvider
[1bd8c22] Fix issue ChartsOrg#329 check _deltaX when only lineData exists
[90a327d] 1. fix bug in getDataSetIndex, it will detect what dataSet it is and determine how to proceed
2. I also override getMarkerPosition for CombinedChartView
[80aa1b3] add support for grouped bars in CombinedChartView.
add a new demo view controller called GroupedCombinedChartViewController, to illustrate multiple bars + multiple line
@ffchung
Copy link

ffchung commented Dec 16, 2015

I using last version : just download today

I have same problem "crash issue for highestVisibleXIndex".
after pixelToValue the pt.x indeed became nan.

pt.x 150.0, xValCount:24 before transform
pt.x nan, xValCount:24 after transform

I only have used the LineChartView.

I think the problem is about the Y val not about X. Coz my data on Y is same.

_yMax Double 0.39000000000000001 0.39000000000000001
_yMin Double 0.39000000000000001 0.39000000000000001
_leftAxisMax Double 0.39000000000000001 0.39000000000000001
_leftAxisMin Double 0.39000000000000001 0.39000000000000001
_rightAxisMax Double 0.39000000000000001 0.39000000000000001
_rightAxisMin Double 0.39000000000000001 0.39000000000000001
_yValueSum Double 9.3599999999999994 9.3599999999999994
_yValCount Int 24 24

_xVals [String?]! 24 values Some
[0] String? "0" Some
[1] String? "1" Some
[2] String? "2" Some
[3] String? "3" Some
[4] String? "4" Some
[5] String? "5" Some
[6] String? "6" Some
[7] String? "7" Some
[8] String? "8" Some
[9] String? "9" Some
[10] String? "10" Some
[11] String? "11" Some
[12] String? "12" Some
[13] String? "13" Some
[14] String? "14" Some
[15] String? "15" Some
[16] String? "16" Some
[17] String? "17" Some
[18] String? "18" Some
[19] String? "19" Some
[20] String? "20" Some
[21] String? "21" Some
[22] String? "22" Some
[23] String? "23" Some

@liuxuan30
Copy link
Member Author

what's the matrix value? You have to print it out
pt.x 150.0, xValCount:24 before transform
pt.x nan, xValCount:24 after transform
The calculation for x is failed.

@ffchung
Copy link

ffchung commented Dec 16, 2015

Which matrix value ? This one ?
_viewPortHandler Charts.ChartViewPortHandler! 0x000000017017e3c0 0x000000017017e3c0
ObjectiveC.NSObject NSObject
_touchMatrix CGAffineTransform
a CGFloat 0.38333333333333336
b CGFloat 0
c CGFloat 0
d CGFloat 1
tx CGFloat 0
ty CGFloat -0

@ffchung
Copy link

ffchung commented Dec 16, 2015

liuxuan30 commented 37 minutes ago
what's the matrix value? You have to print it out
pt.x 150.0, xValCount:24 before transform
pt.x nan, xValCount:24 after transform
The calculation for x is failed.

not only x, y is failed too. both nan

I think it fail to transform. so both nan

@ffchung
Copy link

ffchung commented Dec 16, 2015

I know how it happen now.

When I used the leftAxis.customAxisMax and leftAxis.customAxisMin, and set with same value. in this case both set 0.39. and it will have the problem.

@ffchung
Copy link

ffchung commented Dec 16, 2015

so leftAxis.customAxisMax and leftAxis.customAxisMin must be different value. Just tested

@liuxuan30
Copy link
Member Author

hmm, seems like the matrix.d is nan because of the delta is 0?

liuxuan30 added a commit to liuxuan30/Charts that referenced this issue Feb 26, 2016
…the whole data, not each sub data's index

add one more bar data set in demo view controller (+4 squashed commits)
Squashed commits:
[44ce60e] rename some BarChartDataProvider protocol methods not the same as ChartDataProvider
[1bd8c22] Fix issue ChartsOrg#329 check _deltaX when only lineData exists
[90a327d] 1. fix bug in getDataSetIndex, it will detect what dataSet it is and determine how to proceed
2. I also override getMarkerPosition for CombinedChartView
[80aa1b3] add support for grouped bars in CombinedChartView.
add a new demo view controller called GroupedCombinedChartViewController, to illustrate multiple bars + multiple line
liuxuan30 added a commit to liuxuan30/Charts that referenced this issue Feb 26, 2016
…the whole data, not each sub data's index

add one more bar data set in demo view controller (+4 squashed commits)
Squashed commits:
[44ce60e] rename some BarChartDataProvider protocol methods not the same as ChartDataProvider
[1bd8c22] Fix issue ChartsOrg#329 check _deltaX when only lineData exists
[90a327d] 1. fix bug in getDataSetIndex, it will detect what dataSet it is and determine how to proceed
2. I also override getMarkerPosition for CombinedChartView
[80aa1b3] add support for grouped bars in CombinedChartView.
add a new demo view controller called GroupedCombinedChartViewController, to illustrate multiple bars + multiple line
liuxuan30 added a commit to liuxuan30/Charts that referenced this issue Feb 26, 2016
…the whole data, not each sub data's index

add one more bar data set in demo view controller (+4 squashed commits)
Squashed commits:
[44ce60e] rename some BarChartDataProvider protocol methods not the same as ChartDataProvider
[1bd8c22] Fix issue ChartsOrg#329 check _deltaX when only lineData exists
[90a327d] 1. fix bug in getDataSetIndex, it will detect what dataSet it is and determine how to proceed
2. I also override getMarkerPosition for CombinedChartView
[80aa1b3] add support for grouped bars in CombinedChartView.
add a new demo view controller called GroupedCombinedChartViewController, to illustrate multiple bars + multiple line
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants