SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, iOS Chart, Android Chart and JavaScript Chart Components

Answered Closed
0
0

Hi,

When using splinerenderable series, there visual issues (as if the data points are unsorted) with the spline line at certain zoom levels.
If you zoom in past a certain point, the spline line corrects itself, showing that the data points are sorted in order.
See the attached screenshot and project replicating the issue.
This issue may be related to other issues currently active:

Version
4.3.0.4686
Images
  • You must to post comments
Best Answer
0
0

Hi Eyram,

I took a look on our code and it looks like cubic spline interpolation that we use by default to calculate data points required to render spline line, that goes through all your data points, doesn’t like xValues where distance between points isn’t relatively the same. In your case diff between points in loop is 30 seconds, but after that after getDateGenTimerTask() is called we have a huge gap ( ~50 hours ), which causes this ‘spiral’ drawing.

So to fix it I would suggest you to use alternative algorithm, that we provide ( cosine interpolation instead of cubic spline interpolation ) that performs simpler calculations and should provide smooth line without these artefacts. To do this you will need to subclass SplineLineRenderableSeries to pass alternative IBezierControlPointsProvider implementation like this:

class CustomSplineLineSeries : SplineLineRenderableSeries(
SplineXyRenderPassData(CosineInterpolationControlPointsProvider()),
CompositeHitProvider(PointMarkerHitProvider(), SplineLineHitProvider()),
NearestXyPointProvider())

Then you would need to adjust code where you create spline series ( you would need to create series directly, instead of using builder helper ):

  val lineSeries: SplineLineRenderableSeries = CustomSplineLineSeries().also {
        it.dataSeries = XyDataSeries(Date::class.java, Double::class.javaObjectType)
        it.strokeStyle = mSciChartBuilder?.newPen()?.withColor(ContextCompat.getColor(this, R.color.blue))?.build()
        it.pointMarker = pointMarker
        it.resamplingMode = ResamplingMode.Auto
    }

Can you try it and let me know if it fixes the issue?

Best regards,
Yura

  • Eyram Dornor
    Hi Yura, Your suggestion seems to have solve the spiral spline issues. Thanks a lot for the assistance.
  • You must to post comments
1
0

Hi Eyram,

Thanks for providing project. I tried to run and investigate it, but unfortunately I don’t have a significant progress with locating what causes it. I tried to simplify your code to create simple example that reproduces this issue, but your code with MainActivity contains 1500 lines of code and it’s very hard for me to understand how its logic and how it works. Is it possible for your to create simpler project that reproduces this problem, so I don’t spend alot of time trying to understand how your code works?

Thanks in advance.
Yura

  • Eyram Dornor
    Hi Yura, I have updated the attached project. I’ve simplified things a bit. Just a few points to ease debugging: 1. Data records are created in the service – DataService 2. Important functions related to charting – updateChartViews 3. Functions where new data is fetch and added to charts – fetchChart0Data, fetchChart1Data
  • You must to post comments
0
0

Hi Eyram,

I still don’t fully understand where part of data comes from. I tried to replicate output of your app in simple project. I tried to modify spline chart example from demo application, where there is single chart to ensure that issues that you reported are in fact caused by chart and not by your code, but without success.

At first, I investigated your code and tried to copy paste ‘for’ loop from DataService.onCreate(), which looks like generates data for DataSeries, but in the end I only saw part of output that I see in your application ( I don’t have this long gap in data like in your application ) and I’m not sure why because as far as I see there is only one append() call inside fetchChartData() ( maybe I’m missing some calls? ) and the rest are clear() calls. Then I tried to reduce DATA_GEN_COUNT from 4000 to 40, to reduce size of input data for drawing and find cause of this issue, but it looks like it doesn’t change anything, which is strange.

So I want to ask you if you could provide project where data is generated and added into chart in more clear way. Ideally it would awesome if you could create modify one of our examples from DemoApplication with simplified code, that inserts data into chart ( maybe from some JSON, txt file or something like that )

Thank you in advance.

Best regards,
Yura

  • Eyram Dornor
    Hi Yura, DATA_GEN_COUNT is only used once – the very first time the app is opened (specifically, the first time the service is run). This is used to generate a a certain amount of random value records (starting from 80 hours ago – this is where the long gap in data comes from). So, unless you until the app and re-install, your change will not affect anything. After that the amount of records suggested by DATA_GEN_COUNT is created, a timer is created to create a new record (of random values) going forward (hence the long gap in data). If you disable the timer – that would prevent new records from being created in real-time. The data is loaded via the coroutine (FetchDataCoroutine) – this fetches a certain amount of data based on (MAX_DATA_POINTS_FETCHED). – if there is more data to be fetched, the coroutine lets the caller know along with the fetched data, then proceeds to recursively call the fetch chart data again (until all available data is fetched). The problem still exists after all data is fetched – you can see this by disabling/commenting-out the data generation timer in the background service.
  • You must to post comments
0
0

Hi Eyram,

Here is a modified code of SplineLineChartFragment. I modified its code for data generation to match yours from DataService.

class SplineLineChartFragment : ExampleSingleChartBaseFragment() {

override fun initExample(surface: SciChartSurface) {
    val dataSeries = XyDataSeries<Date, Double>()

    val DATA_GEN_COUNT = 4000

    val startingDate = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
    startingDate.add(Calendar.HOUR, -80)

    for (i in 0 until DATA_GEN_COUNT) {
        startingDate.add(Calendar.SECOND, 30)

        dataSeries.append(startingDate.time, Random.nextDouble())
    }
    surface.suspendUpdates {
        xAxes { dateAxis { growBy = DoubleRange(0.1, 0.1) }}
        yAxes { numericAxis { growBy = DoubleRange(0.2, 0.2) }}
        renderableSeries {
            splineLineRenderableSeries {
                this.dataSeries = dataSeries
                strokeStyle = SolidPenStyle(0xFF006400)

                ellipsePointMarker {
                    setSize(7)
                    strokeStyle = SolidPenStyle(0xFF006400)
                    fillStyle = SolidBrushStyle(0xFFFFFFFF)
                }
            }
        }
        chartModifiers { defaultModifiers() }
    }
}

}

And I can’t reproduce output from your application with this code ( spline line is rendered correctly with code above ). So it’s probably caused by some additional changes in data, but I don’t where they come from. That’s why I’m asking your help with reproducing this issue in simple project where there is no background services, database etc., because currently I’m spending more time to understand logic of your application, than actually fixing the potential bug that may be in our code.

Thanks in advance.

Best regards,
Yura

  • Eyram Dornor
    Hi Yura, Sure, I totally understand. I tried to provide a simple enough example to be closer aligned with our current usage of SciChart. I’ll attempt to reproduce the issue by updating SplineLineChartFragment to replicate the issue. Let me get back to you.
  • Eyram Dornor
    Hi Yura, I’ve updated the attached project. I did what you did, only difference is the chart modifiers are different, there are two synced charts and additional data is periodically generated every 10 seconds (all in the main activity). You can still see the spline issue – when the gap exists. Removing the real-time data generation prevents the gap from forming. Let me know if there’s any other details I can provide.
  • Yura Khariton
    Hi Eyram, thanks for updating project. It looks like I finally found missing piece and could create simple project that reproduces this issue. As I see rendering breaks only after code from getDateGenTimerTask() is invoked ( where you add additional point with current date ), so I’ve added similar change into my code and now I am able to reproduce this weird rendering in spline series. I’m going to debug our code to find what causes and will get back to you. Thank you for help.
  • You must to post comments
Showing 4 results