Date-Time Category
FreeArea and line series on a date-time category axis, with day / month / year zoom levels. Labels take the application locale; a bare YYYY-MM-DD is read as a calendar day in local time rather than as UTC midnight. Pure SVG.
import { SvDateTimeCategoryChartComponent } from '@styloviz/charts';Demo & usage
Basic usage
Usage example — open the gallery for the full interactive demo.
An interactive demo for this component lives in the gallery.
Open live demoMore examples
Month zoom
<sv-datetime-category-chart [categories]="days" [series]="series" [options]="{ zoom: 'month' }" />
A report pinned to one language
<sv-datetime-category-chart [categories]="days" [series]="series" locale="de-DE" />
When to use
- A series whose x-axis is dates and whose labels should read as dates.
- When the axis needs to switch between daily, monthly and yearly granularity.
- For a plain ordered axis with no date semantics, the Line Chart is simpler — it never parses a date at all.
Async states
- loading
- empty
- error
- retry
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
| loading | boolean | false | True while the series are being fetched. |
| error | SvDataError | string | null | null | Load failure. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`. |
| emptyMessage | string | 'No data to plot' | Copy for the empty state. |
| filtered | boolean | false | Whether a filter, not an absence of data, is why the chart is empty. |
| categories | string[] | [] | ISO date strings for the X axis, one per data point. A bare `YYYY-MM-DD` is read as a local calendar day; labels are formatted per `options.zoom` and `locale`. |
| series | DateTimeSeries[] | [] | Line series; `data` holds one value per category. The area under a line is filled per the series' `fill`, else `options.showArea` (on by default). |
| title | string | '' | Chart title rendered above the plot; also used as the plot's accessible name. |
| height | number | 320 | Chart height in pixels. |
| options | DateTimeCategoryOptions | {} | Display options: grid, legend, area fill (`showArea`, default true; a series' own `fill` wins), date-label `zoom` (`'day'` | `'month'` | `'year'`, default `'month'`) and animation duration. |
| locale | string | inject(LOCALE_ID) | BCP 47 locale for the date labels on the x-axis. Defaults to the application's `LOCALE_ID` — the same value `DatePipe` uses — so an app that has configured its locale gets matching axis labels without doing anything here. Override per chart for a report that must read in one fixed language whoever opens it. Only the LABELS are localised. The `categories` themselves stay ISO strings, because they are also the join key for the series and a localised key would differ between two readers looking at the same dashboard. |
| customClass | string | '' | Extra CSS classes applied to the root wrapper. |
Outputs
| Event | Payload type | Description |
|---|---|---|
| retry | void | The host should re-run the failed load. |
| categoryHover | DateTimeCategoryEvent | Emitted when a category is hovered or keyboard-focused. |
| categorySelect | DateTimeCategoryEvent | Emitted when a category is clicked or activated via keyboard (Enter/Space). |
<sv-datetime-category-chart-pro>
Also in this family — SvDateTimeCategoryChartProComponent from @styloviz-pro/charts.
Async states
- loading
- empty
- error
- retry
Inputs
| Name | Type | Default | Description |
|---|---|---|---|
| loading | boolean | false | True while the series are being fetched. |
| error | SvDataError | string | null | null | Load failure. Use `toSvDataError()` from `@styloviz/core` to normalize an `HttpErrorResponse`. |
| emptyMessage | string | 'No data to plot' | Copy for the empty state. |
| filtered | boolean | false | Whether a filter, not an absence of data, is why the chart is empty. |
| categories | string[] | [] | ISO date strings for the X axis, one per data point. A bare `YYYY-MM-DD` is read as a local calendar day; labels are formatted per `options.zoom` and `locale`. |
| series | DateTimeSeries[] | [] | Line series; `data` holds one value per category. The area under a line is filled per the series' `fill`, else `options.showArea` (on by default). |
| title | string | '' | Chart title rendered above the plot; also used as the plot's accessible name. |
| height | number | 320 | Chart height in pixels. |
| options | DateTimeCategoryOptions | {} | Display options: grid, legend, area fill (`showArea`, default true; a series' own `fill` wins), date-label `zoom` (`'day'` | `'month'` | `'year'`, default `'month'`) and animation duration. |
| locale | string | inject(LOCALE_ID) | BCP 47 locale for the date labels on the x-axis. Defaults to the application's `LOCALE_ID` — the same value `DatePipe` uses — so an app that has configured its locale gets matching axis labels without doing anything here. Override per chart for a report that must read in one fixed language whoever opens it. Only the LABELS are localised. The `categories` themselves stay ISO strings, because they are also the join key for the series and a localised key would differ between two readers looking at the same dashboard. |
| customClass | string | '' | Extra CSS classes applied to the root wrapper. |
Outputs
| Event | Payload type | Description |
|---|---|---|
| retry | void | The host should re-run the failed load. |
| categoryHover | DateTimeCategoryEvent | Emitted when a category is hovered or keyboard-focused. |
| categorySelect | DateTimeCategoryEvent | Emitted when a category is clicked or activated via keyboard (Enter/Space). |
Wire it to your API
This component is headless about transport: it renders what you give it and reports what the user asks for. Nothing below requires @styloviz/data — drive it from whatever you already use.
Template
Bound to the names this component actually exposes.
<sv-datetime-category-chart [series]="data.items()" [loading]="data.loading()" [error]="data.error()" [filtered]="data.filtered()" (retry)="data.reload()" />
Host class
Drive the three async inputs from your own fetch.
// This component reports its state but does not emit a query, so drive // it from your own fetch and bind the three async inputs. readonly items = signal<Row[]>([]); readonly loading = signal(false); readonly error = signal<SvDataError | null>(null); async load(): Promise<void> { this.loading.set(true); this.error.set(null); try { this.items.set(await this.api.fetchRows()); } catch (e) { this.error.set(toSvDataError(e)); } finally { this.loading.set(false); } }
- This component does not emit a query, so it renders what you give it. Fetch on your own trigger and bind `series`, `loading` and `error`.
- Set `filtered` when a search or filter is active. It is the difference between "you have no orders" and "no orders match this filter" — telling a customer with 4,000 orders the first one reads as a bug.
- Normalize failures with `toSvDataError()` from `@styloviz/core`. It derives `retryable` from the status, so a 404 does not get a "Try again" button that can only fail again.
Full walkthrough: Connecting to a backend.
Customization & theming
- Day, month and year zoom levels.
- Per-chart locale override, defaulting to the app's LOCALE_ID.
- Area or line rendering per series, with the usual grid and legend switches.
Best practices
- Do: Keep the categories as ISO strings. They are the join key for the series as well as the source of the labels, and a localised key would differ between two people looking at the same dashboard.
- Do: Let the locale come from the app. It defaults to LOCALE_ID — the same value DatePipe resolves — so a correctly configured application gets matching labels everywhere. Set it per chart only for a report that must read in one fixed language whoever opens it.
- Tip: A bare YYYY-MM-DD is a calendar day, and this chart reads it as one in local time. ECMA-262 requires the date-only form to parse as UTC midnight, which is why a naive implementation labels a daily axis a day early for everyone west of Greenwich.
Accessibility
- The axis label, the tooltip and the accessible name are formatted once from one function, so the three cannot disagree about what day a column is.
- An unparseable category falls back to the raw string the host sent rather than printing "Invalid Date" down the whole axis.
Feedback on Date-Time Category
Spotted a gap in this page, or something that didn't work as described? Comments are GitHub Discussions in the public styloviz/community repo, so posting needs a GitHub account.