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

Problem with charts in UITableView cells #2888

Closed
hfabisiak opened this issue Oct 16, 2017 · 8 comments
Closed

Problem with charts in UITableView cells #2888

hfabisiak opened this issue Oct 16, 2017 · 8 comments

Comments

@hfabisiak
Copy link

hfabisiak commented Oct 16, 2017

Hi! I am trying to show live data from accelerometer and gyroscope, but I get an error:

fatal error: Double value cannot be converted to Int because it is either infinite or NaN

Also the preformance of tableview is very low. After a few seconds it lags a lot. I would like to scroll to the newest values from accelerometer and gyroscope.

`func startAccelerometer() {
let indexPathForAccCell = IndexPath(row: 0, section: 0)
let accCell = testView.tableView.cellForRow(at: indexPathForAccCell) as! ChartCell
let setX = LineChartDataSet(values: ChartDataEntry, label: "X")
let setY = LineChartDataSet(values: ChartDataEntry, label: "Y")
let setZ = LineChartDataSet(values: ChartDataEntry, label: "Z")

    setX.setColor(UIColor.blue)
    setY.setColor(UIColor.green)
    setZ.setColor(UIColor.red)

    setX.drawCirclesEnabled = false
    setY.drawCirclesEnabled = false
    setZ.drawCirclesEnabled = false
    
    setX.lineWidth = 1.0
    setY.lineWidth = 1.0
    setZ.lineWidth = 1.0
    
    accCell.chartView.data = LineChartData(dataSets: [setX,setY,setZ])
    accCell.chartView.setVisibleYRange(minYRange: -0.9, maxYRange: 0.9, axis: .left)
    accCell.chartView.setVisibleXRange(minXRange: Double(1), maxXRange: Double(1000))
    var i = 0.0
    
    if motion.isAccelerometerAvailable {
        let interval = 1.0 / 60.0 
        motion.accelerometerUpdateInterval = interval
        self.gatheringData = true
        
        var lowPassX = LowPassFilter(value: 0.0, filterFactor: 0.85)
        var lowPassY = LowPassFilter(value: 0.0, filterFactor: 0.85)
        var lowPassZ = LowPassFilter(value: 0.0, filterFactor: 0.85)

        motion.startAccelerometerUpdates(to: OperationQueue.main, withHandler: { (data, error) in
            //getting accelerometer data
            if let data = self.motion.accelerometerData {
                let x = data.acceleration.x
                let y = data.acceleration.y
                let z = data.acceleration.z
                
                lowPassX.update(newValue: x)
                lowPassY.update(newValue: y)
                lowPassZ.update(newValue: z)
                
                accCell.chartView.data?.addEntry(ChartDataEntry(x: i, y: lowPassX.value), dataSetIndex: 0)
                accCell.chartView.data?.addEntry(ChartDataEntry(x: i, y: lowPassY.value), dataSetIndex: 1)
                accCell.chartView.data?.addEntry(ChartDataEntry(x: i, y: lowPassZ.value), dataSetIndex: 2)
                accCell.chartView.notifyDataSetChanged()
                accCell.chartView.moveViewToX(Double(CGFloat.greatestFiniteMagnitude))
                i += 1
            }

        })
    }
}`
@liuxuan30
Copy link
Member

several issues here:

  1. why there is inf or NaN? Can you look at it? It means something messes up. You should ALWAYS post full stack trace as we don't know what property or lines of code you hit the error.
  2. table view performance is tricky when you involve live update. You could google some articles to learn the reasons, e.g. update your chart data in other threads and update UI on main thread will solve some. Also remember anything requires high CPU power will lead to lag as well, such as you have too many data to handle in short time.

@hfabisiak
Copy link
Author

hfabisiak commented Oct 17, 2017

Stack trace:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x101657b54)
    frame #0: 0x0000000101657b54 libswiftCore.dylib`function signature specialization <preserving fragile attribute, Arg[2] = Dead, Arg[3] = Dead> of Swift._fatalErrorMessage(Swift.StaticString, Swift.StaticString, file: Swift.StaticString, line: Swift.UInt, flags: Swift.UInt32) -> Swift.Never + 120
    frame #1: 0x0000000100ea909c Charts`AxisRendererBase.computeAxisValues(min=NaN, max=NaN, self=0x00000001c0447860) at AxisRendererBase.swift:125
    frame #2: 0x00000001010165d4 Charts`XAxisRenderer.computeAxisValues(min=NaN, max=NaN, self=0x00000001c0447860) at XAxisRenderer.swift:62
    frame #3: 0x0000000101016504 Charts`XAxisRenderer.computeAxis(min=1.7976931348623157E+308, max=-1.7976931348623157E+308, inverted=false, self=0x00000001c0447860) at XAxisRenderer.swift:57
    frame #4: 0x0000000100ece8b4 Charts`BarLineChartViewBase.draw(rect=(origin = (x = 0, y = 0), size = (width = 394, height = 310)), self=0x000000011fe56fb0) at BarLineChartViewBase.swift:196
    frame #5: 0x0000000100ed0d88 Charts`@objc BarLineChartViewBase.draw(_:) at BarLineChartViewBase.swift:0
    frame #6: 0x000000018da99a38 UIKit`-[UIView(CALayerDelegate) drawLayer:inContext:] + 408
    frame #7: 0x00000001885e4c88 QuartzCore`-[CALayer drawInContext:] + 296
    frame #8: 0x00000001884e0290 QuartzCore`CABackingStoreUpdate_ + 232
    frame #9: 0x00000001885ea96c QuartzCore`___ZN2CA5Layer8display_Ev_block_invoke + 52
    frame #10: 0x00000001885e46b4 QuartzCore`-[CALayer _display] + 1672
    frame #11: 0x0000000188557fdc QuartzCore`CA::Context::commit_transaction(CA::Transaction*) + 520
    frame #12: 0x000000018857e340 QuartzCore`CA::Transaction::commit() + 540
    frame #13: 0x000000018857f180 QuartzCore`CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*) + 92
    frame #14: 0x00000001845af8b8 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
    frame #15: 0x00000001845ad270 CoreFoundation`__CFRunLoopDoObservers + 412
    frame #16: 0x00000001845ad82c CoreFoundation`__CFRunLoopRun + 1292
    frame #17: 0x00000001844ce2d8 CoreFoundation`CFRunLoopRunSpecific + 436
    frame #18: 0x000000018635ff84 GraphicsServices`GSEventRunModal + 100
    frame #19: 0x000000018da7b880 UIKit`UIApplicationMain + 208
  * frame #20: 0x0000000100a699d0 PATRON`main at AppDelegate.swift:13
    frame #21: 0x0000000183ff256c libdyld.dylib`start + 4

@liuxuan30
Copy link
Member

liuxuan30 commented Oct 19, 2017

computeAxis(min=1.7976931348623157E+308, max=-1.7976931348623157E+308

this seems wrong. You need to debug why it causes this way. It's in _xAxis.calculate()

    internal override func calcMinMax()
    {
        // calculate / set x-axis range
        _xAxis.calculate(min: _data?.xMin ?? 0.0, max: _data?.xMax ?? 0.0)

post the value how it calculates to an inf.

It looks like you are passing empty data sets into the chart so no data to calculate the range. You should get your data first and then create the chart. Try that way. This is similar in another thread #2845

@hfabisiak
Copy link
Author

What if I want to live stream accelerometer data and show it in a chart?

@hfabisiak
Copy link
Author

It doesn't crash now when added these three lines at the beginning:
_ = setX.addEntry(ChartDataEntry(x: 0.0, y: 0.0)) _ = setY.addEntry(ChartDataEntry(x: 0.0, y: 0.0)) _ = setZ.addEntry(ChartDataEntry(x: 0.0, y: 0.0))
But it doesn't scroll to the newest value

@hfabisiak
Copy link
Author

graph
My graph is just scaling, but I want to scroll it. When too many values appear ~1200, it starts to lag

@hfabisiak
Copy link
Author

Problem solved

@liuxuan30
Copy link
Member

performance issue solved? What's your solution?

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

2 participants