ChartsOrg / Charts

Beautiful charts for iOS/tvOS/OSX! The Apple side of the crossplatform MPAndroidChart.
Apache License 2.0
27.58k stars 6k forks source link

Performance on very large data sets #4009

Open paulsUsername opened 5 years ago

paulsUsername commented 5 years ago

I have a standard graph with a very simple implementation, but my data sets are very large and I want them to be swipeable.

Is there anything I can do to help? Some data sets are over 30-40k data points, sometimes up to 70-80k. Ideally, I would like very high quality swiping performance.

If I had certainty of performance I would not be opposed to buying a license and or purchasing support.

thierryH91200 commented 5 years ago

look at #3774 and #3699

i have resolved the problem

drawCircles is very long and dataSet.isDrawCirclesEnabled is not tested

charts/renderers/chartsRenderers/LineChartRenderer

in private func drawCircles(context: CGContext)

private func drawCircles(context: CGContext)
{
    guard
        let dataProvider = dataProvider,
        let lineData = dataProvider.lineData
        else { return }

    let phaseY = animator.phaseY

    let dataSets = lineData.dataSets

    var pt = CGPoint()
    var rect = CGRect()

    context.saveGState()

    for i in 0 ..< dataSets.count
    {
        guard let dataSet = lineData.getDataSetByIndex(i) as? LineChartDataSetProtocol else { continue }

        if !dataSet.isVisible || **!dataSet.isDrawCirclesEnabled** || dataSet.entryCount == 0
        {
            continue
        }

and

dataSet.drawCirclesEnabled = false

paulsUsername commented 5 years ago

To add:

Performance on Android is next to perfect despite using it on an older much lower performance device (Samsung A5).

But iOS, on an iPhone X, performance is terrible and completely unusable

paulsUsername commented 5 years ago

@thierryH91200 Thanks I'll have a look at them

rmehta33 commented 5 years ago

I'm having a similar issue. Is there a way to set a maximum number of entries that can be displayed at once? Since zoomed out, 70k points look the same as 500 points.

paulsUsername commented 5 years ago

@rmehta33 chart.maxVisibleCount might be of use to you

paulsUsername commented 5 years ago

@thierryH91200 Thank you! I am seeing a drastic improvement in performance. Still would like to see it get even better but this is definitely a start. Thanks

thierryH91200 commented 5 years ago

@paulsUsername i have add for the test

func printTimeElapsedWhenRunningCode(title:String, operation:()->()) {
    let startTime = CFAbsoluteTimeGetCurrent()
    operation()
    let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
    print("Time elapsed for \(title): \(timeElapsed) s.")
}

and

    printTimeElapsedWhenRunningCode(title:"drawExtras") {
        renderer.drawExtras(context: context)
    }

the result with the last version is Time elapsed for drawExtras: 3.9924609661102295 s. Time elapsed for drawExtras: 3.962438941001892 s.

and with 3.0.2

Time elapsed for drawExtras: 2.6941299438476562e-05 s. Time elapsed for drawExtras: 1.0013580322265625e-05 s.

the difference is ........... great

liuxuan30 commented 5 years ago

@thierryH91200 any chance it can be forged into a pull request?

paulsUsername commented 5 years ago

@liuxuan30 I can do it If I can get permission to create a branch

liuxuan30 commented 5 years ago

just point to master(preferred) or 4.0 branch

Garenge commented 5 years ago

you can call setVisibleXRangeMaximum after you set data.

paulsUsername commented 4 years ago

just point to master(preferred) or 4.0 branch

Sorry, I am terrible at this git stuff. Not my area of expertise so I'm probably not the best person for it. I can tell you though, the addition of:

    if !dataSet.isVisible || **!dataSet.isDrawCirclesEnabled** || dataSet.entryCount == 0

It makes a really big difference to performance.