zz-meridian 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zz-meridian",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"description": "Bring ZZ Meridian, a dashboard design system, into a Next.js project, or start a new dashboard on it. Copies the files in; nothing depends on this package at runtime.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/payload/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Every release of ZZ Meridian, newest first. Versions follow semver: a removed or renamed token, prop or card is major; a new card, token or variant is minor; a corrected value is a patch. Each entry says what breaks and what to do instead.
|
|
4
4
|
|
|
5
|
+
## [0.21.0] · 2026-10-20
|
|
6
|
+
|
|
7
|
+
### New
|
|
8
|
+
|
|
9
|
+
- **`TrendChart` takes `whole`** ([#73](https://github.com/zhixuan312/zz-meridian/issues/73)), as `ColumnChart` does since 0.20.0: the values are counts, a stack of counts too, and every level is a whole number, so a running total whose top is 10 draws no level at 2.5 or 7.5. Pass it on a chart of counts; a chart of a quantity that is not one keeps its halves.
|
|
10
|
+
|
|
5
11
|
## [0.20.0] · 2026-10-20
|
|
6
12
|
|
|
7
13
|
### New
|
package/payload/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zz-meridian-template",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"private": true,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "ZZ Meridian: a dashboard design system and starter. Six layers, from DTCG tokens through four layers of React components to product workspaces, and a Design Atlas, in a light and a dark theme.",
|
|
@@ -7,7 +7,7 @@ Status: beta
|
|
|
7
7
|
## Anatomy
|
|
8
8
|
|
|
9
9
|
1. **Plot**: horizontal gridlines in `chart-grid`, the baseline in `chart-axis`, 1px, crisp.
|
|
10
|
-
2. **Y axis**: 3 or 4 "nice" ticks from zero, labels `text-2xs` `ink-3`, tabular, right-aligned in a gutter sized to the longest label. Axis labels drop cents and exact digits (`$12`, `1.2M`), and money from $10,000 reads at a glance (`$25K`, `$5.0B`) so a large scale does not widen the gutter; the tooltip and table carry the exact amounts.
|
|
10
|
+
2. **Y axis**: 3 or 4 "nice" ticks from zero (whole numbers only with `whole`, for a chart of counts or a stack of them, so a top of 10 draws no level at 2.5 or 7.5), labels `text-2xs` `ink-3`, tabular, right-aligned in a gutter sized to the longest label. Axis labels drop cents and exact digits (`$12`, `1.2M`), and money from $10,000 reads at a glance (`$25K`, `$5.0B`) so a large scale does not widen the gutter; the tooltip and table carry the exact amounts.
|
|
11
11
|
3. **X axis**: dates, `text-2xs` `ink-3`, one label per 92px, counted back from today so the last day is always labelled.
|
|
12
12
|
4. **Series**: monotone curves that never overshoot their data.
|
|
13
13
|
5. **Band** (with `band`): the region from the floor up to the band's ceiling, in `fill-track`, under the gridlines, its top edge drawn as the axis is, and its label at an end of that edge — in `ink-2`, since it stands over the fill as often as over the card and `ink-3` on `fill-track` is 4.43:1 in light.
|
|
@@ -125,7 +125,7 @@ import { TrendChart } from '@/components/charts/trend-chart';
|
|
|
125
125
|
/>
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
-
Props: `dates`, `series` (`key`, `label`, `values`, `color`, `kind`), `format` (`count` | `compact` | `cost` | `cost-compact` | `duration` | `percent`), `height` (number or `fill`), `label`, `legend` (defaults to two or more series), `tick`, `stacked`, `baseline`, `band`, `floor`, `marks`, `running` (the last point is still in progress).
|
|
128
|
+
Props: `dates`, `series` (`key`, `label`, `values`, `color`, `kind`), `format` (`count` | `compact` | `cost` | `cost-compact` | `duration` | `percent`), `height` (number or `fill`), `label`, `legend` (defaults to two or more series), `tick`, `stacked`, `whole` (the values are counts: whole levels only), `baseline`, `band`, `floor`, `marks`, `running` (the last point is still in progress).
|
|
129
129
|
|
|
130
130
|
The colour of a stacked part is `stackPart(place, parts)` from `@/components/charts/scale`, the one mix every one-hue stack takes: the accent into the surface, by the part's place from the bottom.
|
|
131
131
|
|
|
@@ -97,6 +97,7 @@ export function TrendChart({
|
|
|
97
97
|
legend,
|
|
98
98
|
tick,
|
|
99
99
|
stacked = false,
|
|
100
|
+
whole = false,
|
|
100
101
|
baseline,
|
|
101
102
|
band,
|
|
102
103
|
floor,
|
|
@@ -118,6 +119,8 @@ export function TrendChart({
|
|
|
118
119
|
tick?: (date: string) => string;
|
|
119
120
|
/** The series are parts of one whole: bands stacked in order, the first at the bottom, each in its categorical slot. */
|
|
120
121
|
stacked?: boolean;
|
|
122
|
+
/** The values are counts, a stack of counts too: every level is a whole number, so a top of 10 draws none at 2.5 or 7.5 (#73). */
|
|
123
|
+
whole?: boolean;
|
|
121
124
|
/** What is usual, drawn as a quiet dashed line across the plot with its label at the end: `{ value: 296, label: 'Median 296ms' }`. */
|
|
122
125
|
baseline?: { value: number; label: string };
|
|
123
126
|
/**
|
|
@@ -177,7 +180,7 @@ export function TrendChart({
|
|
|
177
180
|
const from = floor === undefined ? 0 : Math.min(floor, ...values);
|
|
178
181
|
// The levels, and the floor the plot is drawn to: `ticks[0]` is 0 unless the chart was given a floor, and the two ends
|
|
179
182
|
// of the scale are what every point, area, band and level line is measured against.
|
|
180
|
-
const ticks = ticksBetween(from, max, h < 200 ? 3 : 4);
|
|
183
|
+
const ticks = ticksBetween(from, max, h < 200 ? 3 : 4, whole);
|
|
181
184
|
const low = ticks[0];
|
|
182
185
|
const top = ticks[ticks.length - 1];
|
|
183
186
|
const left = Math.max(...ticks.map((t) => axis(t).length)) * 6.4 + 12;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { render } from '@testing-library/react';
|
|
2
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
3
|
+
|
|
4
|
+
vi.mock('@/components/charts/use-size', async () => {
|
|
5
|
+
const { useRef } = await import('react');
|
|
6
|
+
return { useSize: () => [useRef(null), { width: 640, height: 0 }] as const };
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
import { TrendChart } from '@/components/charts/trend-chart';
|
|
10
|
+
|
|
11
|
+
const dates = ['2026-09-07', '2026-09-14', '2026-09-21', '2026-09-28'];
|
|
12
|
+
/** The levels' labels: the axis text beside each gridline. */
|
|
13
|
+
const levels = (c: HTMLElement) => [...c.querySelectorAll('svg g > line + text')].map((t) => t.textContent);
|
|
14
|
+
|
|
15
|
+
describe('a trend chart of counts (#73)', () => {
|
|
16
|
+
it('draws whole levels only, a running total of ten as a line or as a stack', () => {
|
|
17
|
+
const made = render(<TrendChart label="Items in all" whole dates={dates} series={[{ key: 'n', label: 'Items', values: [2, 5, 7, 10], kind: 'line' }]} />);
|
|
18
|
+
expect(levels(made.container).every((t) => /^\d+$/.test(t ?? ''))).toBe(true);
|
|
19
|
+
expect(levels(made.container)).not.toContain('2.5');
|
|
20
|
+
made.unmount();
|
|
21
|
+
const stack = render(<TrendChart label="Items in all, by team" whole stacked dates={dates} series={[{ key: 'a', label: 'Core', values: [1, 3, 4, 6] }, { key: 'b', label: 'Web', values: [1, 2, 3, 4] }]} />);
|
|
22
|
+
expect(levels(stack.container).every((t) => /^\d+$/.test(t ?? ''))).toBe(true);
|
|
23
|
+
});
|
|
24
|
+
it('keeps halves without it, for a quantity that is not a count', () => {
|
|
25
|
+
const { container } = render(<TrendChart label="Hours waited" dates={dates} series={[{ key: 'n', label: 'Hours', values: [2, 5, 7, 10], kind: 'line' }]} />);
|
|
26
|
+
expect(levels(container)).toContain('2.5');
|
|
27
|
+
});
|
|
28
|
+
});
|