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

Assertion failed: data must be asc ordered by time. TIME DIPLICATES #1700

Open
Yaroslav-Bulavin opened this issue Sep 23, 2024 · 8 comments
Open

Comments

@Yaroslav-Bulavin
Copy link

Lightweight Charts™ Version: ^4.2.0

Steps/code to reproduce:

From the error I understand that I have the same time property for a few entries:
Assertion failed: data must be asc ordered by time, index=3, time=1727077163.929, prev time=1727077163.929;

I using data from the backend to get coin price history, approximately 400 items in the array.
Array item:

currency_code: "BTC"
high24hr: "64146.2"
id: 1161674
low24hr: "62603.6"
price: "62890.13"
timestamp: "2024-09-20T13:57:28.947Z"
vol24hr: "238901766.70551"

I have an endpoint that saves data in storage:

getCoinPriceHistory: builder.query<GetCoinPriceHistory, { coin: CoinEnum }>(
      {
        query: ({ coin }) => ({
          url: `/prices/${coin}`,
        }),
        async onQueryStarted(id, { dispatch, queryFulfilled }) {
          try {
            const { data } = await queryFulfilled;
            console.log('DUPLICATES', findDuplicateDatesWithTime(data?.prices));
            dispatch(SET_COIN_PRICES(data?.prices || []));
          } catch (err) {}
        },
        providesTags: [ApiTagsEnum.GET_COIN_PRICE_HISTORY],
      },
    ),

I added console.log to find duplications in the response data.
The findDuplicateDatesWithTime function:

function findDuplicateDatesWithTime(data: CurrencyType[]) {
  const duplicates = data.filter((x, i, arr) => {
    return arr.some(
      (y) =>
        new Date(y.timestamp).getTime() / 1000 === new Date(x.timestamp).getTime() / 1000 &&
        y.id !== x.id,
    );
  });
  return duplicates;
}

But it logs me empty array every time(No duplicates have been found). So BE response is valid.
Screenshot 2024-09-23 at 10 59 39

This is how I use timestamp from the response:

const formattedInitPrices = coinPrices.map((info) => ({
      time: (new Date(info.timestamp).getTime() / 1000) as Time,
      value: Number(info?.price),
    }));

The strangest thing is that sometimes it works without any errors after the page refresh, but sometimes it crashes.

Tech stack: react, vite, lightweight-charts, typescript, redux-toolkit

Actual behavior:

Error Assertion failed: data must be asc ordered by time, index=3, time=1727077163.929, prev time=1727077163.929;

Expected behavior:

It should work whenever BE response has unique entries in the array

Screenshots:

CodeSandbox/JSFiddle/etc link:

@Yaroslav-Bulavin Yaroslav-Bulavin changed the title Assertion failed: data must be asc ordered by time. Assertion failed: data must be asc ordered by time. TIME DIPLICATES Sep 23, 2024
@SlicedSilver
Copy link
Contributor

I suspect that your findDuplicateDatesWithTime isn't correctly identifying duplicate timestamps. Any two items which have the same time value would be considered a duplicate even if everything else was different.
In your case, you code is checking if the timestamp values match but also check that the id values match. So perhaps try removing && y.id !== x.id and you'll find the duplicate values.

@ambrizals
Copy link

ambrizals commented Oct 1, 2024

Yeah same i was also getting this error, but actually i have different dateTime but i don't know why chart was flagging this as duplicate.
image (2)

@SlicedSilver
Copy link
Contributor

Are the actual time values that you provide to setData different?

At some point you will be converting your "date" value into a time value.

@ambrizals
Copy link

Are the actual time values that you provide to setData different?

At some point you will be converting your "date" value into a time value.

Yeah of course i do some conversion into mili epoch using new Date().getTime(), even i was trying to divide it 1000 i still can't setData

const milis = dateObj.getTime() / 1000

Screenshot 2024-10-01 at 11 07 32

@SlicedSilver
Copy link
Contributor

The error is suggesting that there are some data points which are either duplicates or multiple data points for the same timestamp.

This can sometimes occur when using external data sources that they will provide more than one data point for timestamp.

For example:

[
  { date: '2014-02-01T12:34:56.789', value: 123 },
  { date: '2014-02-01T12:34:56.789', value: 125 }, // same timestamp as previous
  { date: '2014-02-01T12:35:00.000', value: 125 },
]

You could log your data before providing it to setData to double check.

@Yaroslav-Bulavin
Copy link
Author

I suspect that your findDuplicateDatesWithTime isn't correctly identifying duplicate timestamps. Any two items which have the same time value would be considered a duplicate even if everything else was different. In your case, you code is checking if the timestamp values match but also check that the id values match. So perhaps try removing && y.id !== x.id and you'll find the duplicate values.

@SlicedSilver it doesn't make sense. If I remove y.id !== x.id comparison, the script will return me all the initial array, because using y.id !== x.I find If my array has entries with the same time but different id. Id field is always unique.

@SlicedSilver
Copy link
Contributor

So you want to keep data points with the same timestamp as long as the ids are different?

Therefore you are okay with this:

[
  { currency_code: "BTC", id: 1161674, price: "62890.00", timestamp:, "2024-09-20T13:57:28.947Z" },
  { currency_code: "BTC", id: 1161675, price: "62892.00", timestamp:, "2024-09-20T13:57:28.947Z" }, // same timestamp as previous
]

Well the library will see this as a problem because you have two data points at the same timestamp. Which one should it plot? because it can only plot one.

Id field is always unique.

Therefore the findDuplicateDatesWithTime will never find any timestamp duplicates because the ids will never match.

@safaritrader
Copy link

if you want too keep duplicates an easy way is to pull that duplicates out of that array and add it to another series!
or another way is to use index instead of time and assign the real time to another key for identification.

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

4 participants