Open Saranjithpk opened 6 years ago
please take a look at
frame #8: 0x0000000110177e05 Charts`XAxisRenderer.computeAxisValues(min=NaN, max=NaN, self=0x0000600000e58630) at XAxisRenderer.swift:62
frame #9: 0x0000000110177d3e Charts`XAxisRenderer.computeAxis(min=0, max=2.02, inverted=false, self=0x0000600000e58630) at XAxisRenderer.swift:57
why computeAxis
generate NaN. Something wrong with your matrix.
please debug and provide more debug trace so we know where goes off.
open override func computeAxis(min: Double, max: Double, inverted: Bool)
{
var min = min, max = max
if let transformer = self.transformer
{
// calculate the starting and entry point of the y-labels (depending on
// zoom / contentrect bounds)
if viewPortHandler.contentWidth > 10 && !viewPortHandler.isFullyZoomedOutX
{
let p1 = transformer.valueForTouchPoint(CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentTop))
let p2 = transformer.valueForTouchPoint(CGPoint(x: viewPortHandler.contentRight, y: viewPortHandler.contentTop))
if inverted
{
min = Double(p2.x)
max = Double(p1.x)
}
else
{
min = Double(p1.x)
max = Double(p2.x)
}
}
}
computeAxisValues(min: min, max: max)
}
please debug this function and print out all values that lead min/max to NaN
I just put your code in computeAxis Function. but I can't find any bool named inverted
in the same. So I just removed the if loop and kept true block only.
What I put is as below,
@objc open func computeAxisValues(min: Double, max: Double)
{
guard let axis = self.axis else { return }
var min = min, max = max
if let transformer = self.transformer
{
// calculate the starting and entry point of the y-labels (depending on
// zoom / contentrect bounds)
if (viewPortHandler?.contentWidth)! > CGFloat(10.0) && !(viewPortHandler?.isFullyZoomedOutX)!
{
let p1 = transformer.valueForTouchPoint(CGPoint(x: (viewPortHandler?.contentLeft)!, y: (viewPortHandler?.contentTop)!))
let p2 = transformer.valueForTouchPoint(CGPoint(x: (viewPortHandler?.contentRight)!, y: (viewPortHandler?.contentTop)!))
min = Double(p2.x)
max = Double(p1.x)
print("p1.x:", p1.x,"p1.y:", p1.y,"p2.x:",p2.x,"p2.y:",p2.y,"Min:", min, "Max:", max)
}
// Rest of code here.
}
My log before selection on selection and on crash as below,
p1.x: 0.609658677494641 p1.y: 110.0 p2.x: 3.43860364530313 p2.y: 110.0 Min: 3.43860364530313 Max: 0.609658677494641
p1.x: 0.630491120754639 p1.y: 110.0 p2.x: 3.41873694444591 p2.y: 110.0 Min: 3.41873694444591 Max: 0.630491120754639
p1.x: 0.630491120754639 p1.y: 110.0 p2.x: 3.41873694444591 p2.y: 110.0 Min: 3.41873694444591 Max: 0.630491120754639
p1.x: 0.651229249533855 p1.y: 110.0 p2.x: 3.398960185875 p2.y: 110.0 Min: 3.398960185875 Max: 0.651229249533855
p1.x: 0.651229249533855 p1.y: 110.0 p2.x: 3.398960185875 p2.y: 110.0 Min: 3.398960185875 Max: 0.651229249533855
p1.x: 0.667225140225756 p1.y: 110.0 p2.x: 3.38370582653968 p2.y: 110.0 Min: 3.38370582653968 Max: 0.667225140225756
p1.x: 0.667225140225756 p1.y: 110.0 p2.x: 3.38370582653968 p2.y: 110.0 Min: 3.38370582653968 Max: 0.667225140225756
p1.x: 0.696229955557689 p1.y: 110.0 p2.x: 3.35604560529598 p2.y: 110.0 Min: 3.35604560529598 Max: 0.696229955557689
p1.x: 0.696229955557689 p1.y: 110.0 p2.x: 3.35604560529598 p2.y: 110.0 Min: 3.35604560529598 Max: 0.696229955557689
p1.x: 0.71513346472276 p1.y: 110.0 p2.x: 3.33801841774783 p2.y: 110.0 Min: 3.33801841774783 Max: 0.71513346472276
p1.x: 0.71513346472276 p1.y: 110.0 p2.x: 3.33801841774783 p2.y: 110.0 Min: 3.33801841774783 Max: 0.71513346472276
p1.x: 0.730490532059137 p1.y: 110.0 p2.x: 3.32337326744029 p2.y: 110.0 Min: 3.32337326744029 Max: 0.730490532059137
p1.x: 0.730490532059137 p1.y: 110.0 p2.x: 3.32337326744029 p2.y: 110.0 Min: 3.32337326744029 Max: 0.730490532059137
p1.x: 0.751410107522615 p1.y: 110.0 p2.x: 3.30342347362082 p2.y: 110.0 Min: 3.30342347362082 Max: 0.751410107522615
p1.x: 0.751410107522615 p1.y: 110.0 p2.x: 3.30342347362082 p2.y: 110.0 Min: 3.30342347362082 Max: 0.751410107522615
p1.x: 0.751410107522615 p1.y: 110.0 p2.x: 3.30342347362082 p2.y: 110.0 Min: 3.30342347362082 Max: 0.751410107522615
p1.x: 0.751410107522615 p1.y: 110.0 p2.x: 3.30342347362082 p2.y: 110.0 Min: 3.30342347362082 Max: 0.751410107522615
Selected 3.0 90.0 Index) // Logged from selection delegate
p1.x: 0.751410107522615 p1.y: 110.0 p2.x: 3.30342347362082 p2.y: 110.0 Min: 3.30342347362082 Max: 0.751410107522615
p1.x: 0.751410107522615 p1.y: 101.0 p2.x: 3.30342347362082 p2.y: 101.0 Min: 3.30342347362082 Max: 0.751410107522615
p1.x: 0.751410107522615 p1.y: 110.0 p2.x: 3.30342347362082 p2.y: 110.0 Min: 3.30342347362082 Max: 0.751410107522615
p1.x: 0.751410107522615 p1.y: 1.61792382137608e+308 p2.x: 3.30342347362082 p2.y: 1.61792382137608e+308 Min: 3.30342347362082 Max: 0.751410107522615
2018-06-22 11:06:33.865541+0530 PersonalCare[72271:1394154] [Unknown process name] CGAffineTransformInvert: singular matrix.
2018-06-22 11:06:33.865712+0530 PersonalCare[72271:1394154] [Unknown process name] CGAffineTransformInvert: singular matrix.
p1.x: nan p1.y: nan p2.x: nan p2.y: nan Min: nan Max: nan
(lldb)
All variables in the scope during the crash
min Double 78
max Double 102
self Charts.YAxisRenderer 0x000060400103a180
axis Charts.YAxis 0x00007fdafdf6ddf0
Charts.AxisBase Charts.AxisBase
drawBottomYLabelEntryEnabled Bool true
drawTopYLabelEntryEnabled Bool true
inverted Bool false
drawZeroLineEnabled Bool false
zeroLineColor NSUIColor? 0x0000600000443750
zeroLineWidth CGFloat 1
zeroLineDashPhase CGFloat 0
zeroLineDashLengths [CGFloat]? nil none
spaceTop CGFloat 0.10000000000000001
native CGFloat.NativeType 0.10000000000000001
spaceBottom CGFloat 0.10000000000000001
native CGFloat.NativeType 0.10000000000000001
labelPosition Charts.YAxis.LabelPosition outsideChart
_axisDependency Charts.YAxis.AxisDependency right
minWidth CGFloat 0
native CGFloat.NativeType 0
maxWidth CGFloat +Inf
native CGFloat.NativeType +Inf
min Double NaN
max Double NaN
interval Double NaN
n Int 140732830998736
yMin Double NaN
yMax Double NaN
labelCount Int 6
range Double NaN
rawInterval Double NaN
intervalMagnitude Double
intervalSigDigit Int
Please let me know if these information is enough.
Thanks for your support.
This function I post is within the library... what you mean by I just put your code in computeAxis Function.
? If you really copy the code into your project, it won't matter anyway.
What you should do is to add some break points before and after transformer.valueForTouchPoint
and figure out what lead to NaN.
Yeah. I got what u meant now. I have checked the same and seems issue fixed by adding these lines of code into AxisRenderBase.swift at line 125 Since interval is getting as nan.
if !(interval > 0 || interval < 0) {
print("Crash solved")
return
}
// Rest of code..
let intervalMagnitude = ChartUtils.roundToNextSignificant(number: pow(10.0, Double(Int(log10(interval)))))
let intervalSigDigit = Int(interval / intervalMagnitude)
as I said, the point is to figure out how the NaN is created, not to avoid it after that.
I think nan is created after some calculations done inside the charts library. I can give all the datasets given to charts when crash occurs. It will be great if you can tell me what is the purpose of using this interval property, so that I can debug the same code better
Please let me know if need any further assistance to track issue. Thanks for your help and support.
hmm, interval is used to calculate the proper 'interval' to use.. I don't remember very clearly, but the code should tell. Will you be able to know what number causes to NaN? We didn't need all data sets values, just what calculation leads to NaN
Hi @Saranjithpk did you ever get anywhere with this?
The best I can tell atm is that the point values by transformer.valueForTouchPoint
in the computeAxisValues
of XAxisRenderer
have x
and y
property values of .nan
. That is what's leading to the downstream exception in AxisRendererBase
computeAxisValues
.
Some quick logging shows that for some reason the tx
and ty
values of pixelToValueMatrix
are nan
:
pixelToValueMatrix: CGAffineTransform(a: 19.2000124087434, b: 0.0, c: -0.0, d: -0.344167172330097, tx: nan, ty: nan)
Will continue to dig into how it got into this state and update as I learn more but if you've already made it out of the rabbit hole would appreciate any assistance!
ok not sure if my case is the same as @Saranjithpk but I was able to trace it back to a mistake in my code that passed a duration
of 0
into moveViewToAnimated(xValue: Double, yValue: Double, axis: YAxis.AxisDependency, duration: TimeInterval)
. This in turn led to the phase
value to be set to nan
in updateAnimationPhase
and the rest of the dominoes fell from there.
Glad to have figured this out and would like to contribute something to hopefully keep others from falling into this same trap. @liuxuan30 given the info I've provided, I'm wondering if you think it makes more sense to enforce duration > 0
in AnimatedViewPortJob
(though its default value is 0 too so would want to update that as well) or if something else should be done to protect the phase
value from being set to nan
i.e. if duration <= 0 { phase = 1.0 }
?
having this issue too. pixelToValueMatrix
contains nan in tx and ty.
figured out that _matrixValueToPx
begin to contain nan values in prepareMatrixValuePx
, because chartYMin
== +Inf, which is because leftAxis.axisRange is inf.
This happens because leftAxis is disabled and never configured. Not sure if this code should even be calculated if the axis is disabled.
If i comment the line that disables leftAxis - no crash is occured. If I set the values to leftAxis with values for rightAxis + disable leftAxis, no crash is occured.
@liuxuan30 Any update on this ?
What did you do?
ℹ I zoomed the charts and made a selection to one of the data point.
What did you expect to happen?
ℹ The delegate method with selected coordinates should be called.
What happened instead?
ℹ Crash happed.
Crash log:
Charts Environment
Charts version/Branch/Commit Number:3.0.4 Xcode version:9.2 Swift version:4 Platform(s) running Charts:iOS 11.3 macOS version running Xcode: 10.13.4
Demo Project
ℹ Please link to or upload a project we can download that reproduces the issue.