KLineChart icon indicating copy to clipboard operation
KLineChart copied to clipboard

[Bug] Overlay that extends the last data point will be positioned wrong if new data are appended

Open char101 opened this issue 1 year ago • 10 comments

Version

latest

Steps to Reproduce

  1. Create a segment overlay extending past the last data point
  2. Add new data by scrolling to the left
  3. Scroll back to the right

Current Behavior

Right point of overlay is misplaced.

Expected Behavior

Right point position is retained.

Environment

- OS:
- Browser:
- Framework:

Any additional comments?

When adding new data, dataIndex points in overlays that do not have a timestamp need to be updated with the new data length.

char101 avatar Dec 11 '23 13:12 char101

You have to create the overlay using timestamp instead of dataIndex.

Or update the overlay instance after new (historical) data is loaded.

jinusean avatar Dec 15 '23 05:12 jinusean

I obviously write the overlay is past the last data point. When an overlay is stretched past the last data point, the point values does not contain a timestamp key, because there is no timestamp.

char101 avatar Dec 15 '23 06:12 char101

Запись экрана от 14.03.2024 15:22:06.webm

I join the question. If you do not specify the dataIndex, in the point structure, then the point is added to the beginning.

The offset occurs because the initial index also changes during dynamic loading of data. Thus, if I load 300 candlesticks each time I scroll to the left, the index of the point does not change and it probably needs to be changed manually.

Is it possible to use timestamp instead of dataIndex or how to updat? How would you recommend updating the dataIndex in this case?

sazanof avatar Mar 14 '24 12:03 sazanof

An easy way is to store the dataIndex without timestamp as negative value, thus -1 means the last dataIndex.

char101 avatar Mar 14 '24 12:03 char101

Explain why the overlay can only be drawn to future time using dataIndex instead of timestamp.

Currently, the chart does not have periods and trading sessions, but is rendered based on data, so it is impossible to determine an accurate time in the future.

liihuu avatar Mar 14 '24 13:03 liihuu

Which is why in Chart.updateData you need to update dataIndex of overlay coordinates that have no timestamp because the dataIndex has been shifted.

char101 avatar Mar 14 '24 13:03 char101

The problem also arises when overlapping existing candles (with timestamp). An example is in the video.

Запись экрана от 14.03.2024 16:42:28.webm

I can not use Chart.updateData in setLoadDataCallback, because I got candles recurcievly loading and browser freezes

Code, that I use to load historical data:

this.chart.setLoadDataCallback(async data => {
                this.fromCandle = data
                setTimeout(async () => {
                    if (data.type === 'forward') {
                        const candles = await this.getCandles()
                        data.callback(candles, true)
                    } else {
                        data.callback([], true)
                    }
                }, 500)
            })

If you do not call the method data.callback(candles, true), then the next loading of candles will not work

Also I received websockets message to add candles to to front of chart

Echo.private(`candles.sync.${this.value.security.id}.${this.tf}`)
            .listen('CandlesSyncCompleteEvent', (e) => {
                const candles = e.candles.map(c => {
                    c.timestamp = formatDate(c.timestamp)
                    console.log(c, new Date(c.timestamp))
                    this.chart.updateData(c)
                    this.candles.push(c)
                    return c
                })
            })

17-00 image 17-01 image After reloading page image

I tried: points: [{"value": 91993.04878472222, "dataIndex": 300, "timestamp": "2024-03-14 16:41"}] or points: [{"value": 91993.04878472222, "dataIndex": 300, "timestamp": 1710434460000}] or dataIndex:0 or (-1)

but the overlay sets incorrectly. What did I miss?

sazanof avatar Mar 14 '24 14:03 sazanof

It seems that a bug has been found on my side. In my case, I don't have to save dataIndex to DB and everywhere to use milliseconds format of timestamp!

sazanof avatar Mar 14 '24 14:03 sazanof

Which is why in Chart.updateData you need to update dataIndex of overlay coordinates that have no timestamp because the dataIndex has been shifted.

Yes, I am trying to fix it.

liihuu avatar Mar 17 '24 15:03 liihuu

There is also the problem of restoring an overlay (from database) where coordinates contains only dataIndex. In this case using a relative offset is better because it can be persisted.

For example:

// 3 bars after 1710753641000
{timestamp: 1710753641000, offset: 3}

// 3 bars before 1710753641000
{timestamp: 1710753641000, offset: -3}

char101 avatar Mar 18 '24 09:03 char101