High Precision Date Axis

Demonstrates the DateTimeNumericAxis with 64-bit precision, handling ranges from Nanoseconds to Billions of Years.

Fullscreen

Edit

 Edit

Docs

drawExample.ts

index.tsx

theme.ts

createDatasets.ts

Copy to clipboard
Minimise
Fullscreen
1import {
2    DateTimeNumericAxis,
3    EllipsePointMarker,
4    MouseWheelZoomModifier,
5    RubberBandXyZoomModifier,
6    ZoomExtentsModifier,
7    ZoomPanModifier,
8    XyDataSeries,
9    NumericAxis,
10    FastLineRenderableSeries,
11    SciChartSurface,
12    NumberRange,
13    EAutoRange,
14    EAxisAlignment,
15    EExecuteOn,
16    SmartDateLabelProvider,
17    EHighPrecisionLabelMode,
18    EDatePrecision,
19    formatNumber,
20    ENumericFormat,
21} from "scichart";
22import { TDatasetId, createDatasets } from "./createDatasets";
23import { appTheme } from "../../../theme";
24
25export const drawExample = async (rootElement: string | HTMLDivElement) => {
26    const { wasmContext, sciChartSurface } = await SciChartSurface.create(rootElement, {
27        theme: appTheme.SciChartJsTheme,
28    });
29
30    const xAxis = new DateTimeNumericAxis(wasmContext, {
31        axisAlignment: EAxisAlignment.Bottom,
32        useNativeText: true,
33        growBy: new NumberRange(0.05, 0.05),
34        labelProvider: new SmartDateLabelProvider({
35            highPrecisionLabelMode: EHighPrecisionLabelMode.Suffix,
36            datePrecision: EDatePrecision.Nanoseconds, 
37            // the default dataset is using nanosecond precision, 
38            // this will be changed when switching datasets
39
40            showWiderDateOnFirstLabel: true,
41            showYearOnWiderDate: true,
42
43            showSecondsOnPreciseDate: true,
44            showSecondsOnWideDate: false,
45        }),
46    });
47
48    // Special handling for huge dates that do not fit in standard JS Date object
49    const sdlp = xAxis.labelProvider as SmartDateLabelProvider;
50    const YEAR = 86400 * 365.25;
51    const originalWideDateFormatter = sdlp.formatDateWide.bind(sdlp);
52    const originalPreciseDateFormatter = sdlp.formatDatePrecise.bind(sdlp);
53
54    sdlp.formatDateWide = (labelRange: string, valueInSeconds: number): string => {
55        // even with huge values, use k, m, b suffixes for thousands, millions, billions or years
56        if (valueInSeconds > YEAR * 9999) {
57            return "Year " + formatNumber(valueInSeconds / YEAR, ENumericFormat.Engineering, 1); // e.g. "Year 500M" -> year 500 million
58        }
59        return originalWideDateFormatter(labelRange, valueInSeconds);
60    };
61    sdlp.formatDatePrecise = (labelRange: string, valueInSeconds: number, rawValue?: number): string => {
62        if (valueInSeconds > YEAR * 9999) {
63            const cutTime = valueInSeconds % 86400; // a bit of a hack, since we can't format dates hours from year 500 Million :)
64            return originalPreciseDateFormatter(labelRange, cutTime, rawValue);
65        }
66        return originalPreciseDateFormatter(labelRange, valueInSeconds, rawValue);
67    };
68    sciChartSurface.xAxes.add(xAxis);
69
70    sciChartSurface.yAxes.add(
71        new NumericAxis(wasmContext, {
72            axisAlignment: EAxisAlignment.Left,
73            growBy: new NumberRange(0.1, 0.1),
74            labelPrecision: 3,
75            autoRange: EAutoRange.Always,
76        })
77    );
78
79    const lineSeries = new FastLineRenderableSeries(wasmContext, {
80        dataSeries: new XyDataSeries(wasmContext, {
81            containsNaN: false,
82            isSorted: true,
83            // x/y values will be appended when switching datasets, for now just create empty data series
84        }),
85        strokeThickness: 2,
86        pointMarker: new EllipsePointMarker(wasmContext, {
87            fill: appTheme.ForegroundColor
88        }),
89    });
90
91    sciChartSurface.renderableSeries.add(lineSeries);
92
93    // Add modifiers
94    sciChartSurface.chartModifiers.add(
95        new MouseWheelZoomModifier(),
96        new ZoomPanModifier(),
97        new ZoomExtentsModifier(),
98        new RubberBandXyZoomModifier({ executeCondition: { button: EExecuteOn.MouseRightButton } })
99    );
100    sciChartSurface.zoomExtents();
101
102    // Datasets handling
103    const datasets = createDatasets();
104
105    const useDataset = (id: TDatasetId) => {
106        const next = datasets.find((d) => d.id === id)!;
107        const dataSeries = lineSeries.dataSeries as XyDataSeries;
108        dataSeries.clear();
109        dataSeries.appendRange(next.xValues, next.yValues);
110
111        const sdlp = xAxis.labelProvider as SmartDateLabelProvider;
112        switch (id) {
113            case "secondPrecision":
114                lineSeries.stroke = appTheme.VividOrange;
115                sdlp.datePrecision = EDatePrecision.Seconds;
116                sdlp.showSecondsOnPreciseDate = true;
117                break;
118            case "millisecondPrecision":
119                lineSeries.stroke = appTheme.VividPink;
120                sdlp.datePrecision = EDatePrecision.Milliseconds;
121                sdlp.showSecondsOnPreciseDate = false;
122                break;
123            case "microsecondPrecision":
124                lineSeries.stroke = appTheme.VividPurple;
125                sdlp.datePrecision = EDatePrecision.Microseconds;
126                sdlp.showSecondsOnPreciseDate = true;
127                break;
128            case "nanosecondPrecision":
129                lineSeries.stroke = appTheme.VividTeal;
130                sdlp.datePrecision = EDatePrecision.Nanoseconds;
131                sdlp.showSecondsOnPreciseDate = true;
132                break;
133        }
134        sciChartSurface.zoomExtents();
135    }
136    useDataset("nanosecondPrecision"); // default to nanosecond precision
137
138    return {
139        wasmContext,
140        sciChartSurface,
141        controls: {
142            zoomInPrecise: () => {
143                const clusterIndex = 15; // on which cluster to zoom in
144                const pointsPerCluster = 10;
145
146                const dataSeries = lineSeries.dataSeries as XyDataSeries;
147                const xValues = dataSeries.getNativeXValues();
148
149                const startDataIndex = clusterIndex * pointsPerCluster;
150                const endDataIndex = startDataIndex + (pointsPerCluster - 1);
151
152                if (endDataIndex >= xValues.size()) return;
153
154                const minX = xValues.get(startDataIndex);
155                const maxX = xValues.get(endDataIndex);
156
157                let padding = 3;
158                xAxis.animateVisibleRange(
159                    new NumberRange(minX - padding, maxX + padding),
160                    3000,
161                    (t) => 1 - Math.pow(1 - t, 10) // very exaggerated ease out :)
162                );
163            },
164            zoomOut: () => {
165                sciChartSurface.zoomExtents(2000);
166            },
167            useDataset
168        },
169    };
170};
171

High Precision Date Axis Example - React

Overview

This example demonstrates the extreme precision capabilities of the DateTimeNumericAxis in SciChart.js within a React application.

Standard WebGL rendering and many JavaScript charting libraries are limited to 32-bit floating-point coordinates. This limitation typically causes rendering artifacts (jitter) or precision loss when dealing with very large numbers (like astronomical dates) or very small increments (like nanoseconds). SciChart.js utilizes a proprietary 64-bit floating-point coordinate pipeline to overcome this, allowing for visualization of data across vast timescales without loss of detail.

The 4 Precision Ranges

This demo allows you to toggle between four distinct datasets to showcase this flexibility:

  • Nanosecond Precision: A range of 50 Days. Demonstrates extreme detail (1 unit = 1e-9 seconds). Suitable for high-frequency trading or scientific instrumentation.
  • Microsecond Precision: A range of 40 Years. (1 unit = 1e-6 seconds).
  • Millisecond Precision: A range of 70,000 Years. Standard Javascript Date precision, but pushed to historical limits.
  • Seconds Precision: A range of 1 Billion Years. Demonstrates handling values that far exceed the limits of the standard JavaScript Date object (which is limited to approx. 270,000 years).

Technical Implementation

The SmartDateLabelProvider is key to this functionality. By setting the datePrecision property, we instruct the chart how to interpret the raw Float64 data:

  • EDatePrecision.Nanoseconds: Divides input by 1,000,000,000 to get seconds.
  • EDatePrecision.Microseconds: Divides input by 1,000,000.

Furthermore, the highPrecisionLabelMode allows formatting sub-millisecond data using:

Suffix (e.g., '50ns'),

Fractional (e.g., '.000000050')

Scientific (e.g., '5.0e-8') notation, ensuring labels remain readable even at maximum zoom depth.

react Chart Examples & Demos

See Also: Charts added in v5 (9 Demos)

NEW!
React Trading Drawing Tools | React Charts | SciChart.js

React Trading Drawing Tools

Create an interactive React trading charts for technical analysis. Trading Drawing Tools Demo, which shows how to use Polylines, Extended Lines, Rays, Channels, Pitchforks, Pitchfans, Fibonnaci Retracements, Measure, Stop Loss and Take Profit chart drawing tools for Technical Analysis.

NEW!
React Freehand Drawing Tools | React Charts | SciChart.js

React Freehand Drawing Tools

An example of using React FreehandDrawingModifier for arbitrary drawing on trading and financial charts. Can be used for drawing trends, arrow, markers, text, etc.

NEW!
React  Smith Chart | React Charts | SciChart.js Demo

React Smith Chart

Interactive React Smith chart for RF impedance matching — place markers, build matching networks step by step with the component chain, and switch between impedance and admittance grids.

NEW!
High Performance SVG Cursor & Rollover | SciChart.js Demo

High Performance SVG Cursor & Rollover

Demonstrates how to use the SVG render layer in SciChart.js to maintain smooth cursor interaction on heavy charts with millions of points.

NEW!
React Force Directed Graph | React Charts | SciChart.js

React Force Directed Graph

React Force Directed Graph demo by SciChart.js. Visualize network graphs with physics simulation, interactive node dragging, and hover tooltips.

NEW!
React Overview for SubCharts with Range Selection | SciChart

React Overview for SubCharts with Range Selection

Demonstrates how to build synchronized multi-panel charts with an overview range selector using SciChart.js in React

NEW!
React Orderbook Heatmap | React Charts | SciChart.js Demo

Order Book Heatmap

Create a React heatmap chart showing historical orderbook levels, using the high performance SciChart.js chart library. Get free demo now.

NEW!
React Chart with DiscontinuousDateAxis Comparison | SciChart

DiscontinuousDateAxis Comparison with React

NEW!
React Chart with BaseValue Axes | React Charts | SciChart.js

React Chart with BaseValue Axes

Demonstrates BaseValue Axes on a React Chart using SciChart.js to create non-linear and custom-scaled axes

SciChart Ltd, 16 Beaufort Court, Admirals Way, Docklands, London, E14 9XL.