Nanosecond timestamps
Nanosecond and microsecond timestamps are unsupported out of the box, due to the numbers generally being too large and having too many decimals for LightningChart JS high precision axis (or normal JavaScript numbers for that matter). However, they can be realized with so called "origin shift" approach.
In practice this means:
- Subtracting all timestamps by the value of first displayed timestamp rounded to closest date, midnight (so counting starts from near 0).
- Informing the charts about the shift using
setDateOriginmethod.
Additionally, nanosecond timestamps should be converted to milliseconds (divided by 1_000_000).
This data preparation can either be done in backend or in the frontend.
If done in frontend, then most likely you need to transfer the timestamp data as BigInt64Array because primitive JavaScript numbers can't accurately store nanosecond timestamps.
Example code:
// data { x: BigInt64Array, y: Float64Array }
const chart = lc.ChartXY({
defaultAxisX: {
type: 'linear-highPrecision',
},
})
const series = chart.addPointLineAreaSeries({ dataPattern: 'ProgressiveX' })
.setAreaFillStyle(emptyFill)
.setStrokeStyle(emptyLine)
// LCJS can't directly consume BigInt64Array
// shift bigint64 data to start from near 0 in order to store it in Float64Array without losing nanosecond precision
const xsShifted = new Float64Array(count)
const shiftDate = new Date(Number(data.x[0]) / 1_000_000)
// shift position should be beginning of date (00:00:00.000)
shiftDate.setUTCHours(0, 0, 0, 0)
const shiftOrigin = shiftDate.getTime() * 1_000_000
const shiftOriginNanos = BigInt(shiftOrigin) * BigInt(1_000_000)
for (let i = 0; i < count; i++) {
xsShifted[i] = Number(data.x[i] - shiftOriginNanos) / 1_000_000
}
series.appendSamples({ xValues: xsShifted, yValues: data.y })
chart.axisX.setTickStrategy(AxisTickStrategies.DateTime, (strategy) => strategy
.setDateOrigin(shiftDate)
)
At these extreme zoom in ranges, there are some limitations in supported series configurations.
- Area fill not supported.
- Thick line series not supported (should use -1 as stroke thickness)
Achievable zoom in capability depends on the total time range of loaded data set. For 1 week of data, it is as in above demonstration - min interval ~= 250 nanoseconds. If longer time period is loaded, then zoom limits kick in earlier.
Here's a rough look up table for convenience:
| time range | min interval |
|---|---|
| 8 hours | 10 nanoseconds |
| 1 week | 250 nanoseconds |
| 1 year | 12 microseconds |
Minimum interval refers to value range on time axis, meaning perceivable minimum time step is considerably smaller than this. Like in above demonstration, you can clearly see steps of 1 nanosecond.