charton 0.5.4

A high-performance, layered charting system for Rust, featuring a flexible data core and multi-backend rendering.
Documentation
### Precision-Preserving `i128` Math

Mapping a 19-digit nanosecond timestamp directly to a screen pixel via `f32` or even `f64` introduces Bit-Drift. At large Unix offsets (e.g., year 2026), `f64` lacks the sufficient mantissa bits to distinguish between nanosecond intervals, resulting in a "staircase effect" or jittery rendering during high-zoom interactions.

Charton solves this by performing all internal domain calculations in `i128` space before converting to a normalized ratio.

### Relative Anchoring & Jitter Prevention

To maintain sub-pixel accuracy, the engine utilizes a Local Anchor Strategy. Instead of calculating global coordinates, it calculates positions relative to the current view's minimum value ($T_{anchor}$):

|Step|Operation|Logic|
|----|---------|-----|
|1. Anchoring|$Toffset​=(Tcurrent​−Tanchor​)$|Integer subtraction in `i128`|
|2. Normalizing|$Ratio=Toffset(f64)​/Range(f64)$​|Safe float division|
|3. Projecting|$Pixel=Ratio×ViewportSize$​|Map to $f32$ for GPU|

By subtracting the large epoch offset in the integer domain first, the resulting delta is small enough to be represented with perfect fidelity in an `f64` ratio, ensuring a smooth rendering experience even at microsecond-level zoom.

### Automatic Scale Degradation (Cosmic Scales)

When the temporal span exceeds the `i64` limit or the capabilities of standard calendar libraries (e.g., spans of millions of years), the Temporal Engine undergoes Semantic Degradation:

* Calendar Mode: Active for spans fitting within the `i64` range. Supports leap years, months, and weekdays via the `time` crate.
* Numerical Mode (Deep Time): Active for cosmic or geological scales. The engine stops attempting to format "Tuesdays" or "Months" and treats the input as a raw numerical axis (e.g., "13.8 Billion Years"), using scientific notation or custom unit-based labels.

### Density-Based Interval Selection

The biggest challenge in temporal axes is preventing label overlap while maintaining a "natural" rhythm. Charton utilizes a Heuristic Step-Ladder to choose the most appropriate time interval based on the current zoom level and physical pixel density.

The engine calculates the `Required_Seconds_Per_Tick` using the formula:

$$Seconds\_Per\_Tick = \frac{Total\_Domain\_Seconds}{Viewport\_Width / Min\_Tick\_Spacing}$$

Where `Min_Tick_Spacing` is typically 50-100 pixels. The engine then snaps to the nearest logical "Human Interval" from a predefined hierarchy:
* Sub-second: 1ms, 5ms, 10ms, 100ms, 500ms
* Seconds/Minutes: 1s, 5s, 15s, 30s, 1min, 5min, 15min, 30min
* Hours/Days: 1hr, 6hr, 12hr, 1day, 1week
* Long-term: 1month, 3months, 1year, 5years, 10years

### Logical Tick Alignment (The "Clean" Start)

A common pitfall in temporal scaling is starting ticks at arbitrary timestamps (e.g., `12:04:13`). To ensure professional aesthetics, Charton performs Calendar Alignment:

1. Step Calculation: Identify the chosen interval (e.g., `1 hour`).
2. Floor Alignment: The first tick is "floored" to the nearest clean boundary. If the data starts at `12:04:13`, the first tick is snapped to `12:00:00` or `13:00:00`.
3. Stride Execution: Ticks are generated by adding the logical `Duration` (using the `time` crate) rather than a fixed number of nanoseconds, ensuring that transitions over leap years or varying month lengths (28 vs. 31 days) remain mathematically and visually correct.

### Contextual Label Formatting

To save horizontal space, Charton uses a Context-Aware Formatter. The label's level of detail is determined by the span of the visible domain:

|Visible Span|Format Key|Example Label|
|Years|`[year]`|`2026`, `2027`|
|Months|`[year]-[month]`|`2026-03`| `2026-04`|
|Days|`[month]-[day]`|`03-25`, `03-26`|
|Hours/Minutes|`[hour]:[minute]`|`15:30`, `16:00`|
|Seconds/Sub-sec|`[hour]:[minute]:[second].[ms]`|`15:30:05.125`|

### Multi-Level Guides (Advanced)

For long-range time series, Charton supports Multi-Level Axes. For instance, an axis might show "Days" as the primary ticks and "Months" as a secondary, bolder category label below them. This prevents the user from losing the "Year/Month" context when zoomed deep into a specific "Hour" range.