@umriss-ui/charts 0.7.0 → 0.8.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/CHANGELOG.md +32 -8
- package/README.md +5 -5
- package/dist/charts.js +12 -12
- package/dist/index.d.ts +93 -93
- package/docs/llms-full.md +3079 -1792
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -29,6 +29,30 @@ interface was still expected to move before `0.3.0`.
|
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
|
+
## 0.8.0 – Working time (Sep. 2026)
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- **Operating time is working time** (ADR-0035). The calendar axis and its
|
|
37
|
+
pure modules speak of working time, not of a plant's operating time. A hard
|
|
38
|
+
cut, without deprecated aliases — rename on upgrade:
|
|
39
|
+
|
|
40
|
+
| Before | After |
|
|
41
|
+
|---|---|
|
|
42
|
+
| `operatingCalendar()` | `workingCalendar()` |
|
|
43
|
+
| `toOperatingTime()` | `toWorkingTime()` |
|
|
44
|
+
| `toOperatingTimeClamped()` | `toWorkingTimeClamped()` |
|
|
45
|
+
| `operatingTicks()` | `workingTicks()` |
|
|
46
|
+
| `operatingTimeTicks()` | `workingTimeTicks()` |
|
|
47
|
+
| `OperatingCalendar` | `WorkingCalendar` |
|
|
48
|
+
| `OperatingInterval` | `WorkingInterval` |
|
|
49
|
+
| `OperatingTimeTick` | `WorkingTimeTick` |
|
|
50
|
+
| `OperatingTimeTick.operatingTime` | `WorkingTimeTick.workingTime` |
|
|
51
|
+
| `RemovedSpan.operatingTime` | `RemovedSpan.workingTime` |
|
|
52
|
+
|
|
53
|
+
`calendar` on `XAxis`/`YAxis`, `CalendarInput`, `calendarFrom`,
|
|
54
|
+
`toWallClock`, `breaks` and `removedIntervals` keep their names.
|
|
55
|
+
|
|
32
56
|
## 0.7.0 – Data table, marks and stacks (Sep. 2026)
|
|
33
57
|
|
|
34
58
|
### Added
|
|
@@ -201,7 +225,7 @@ gone** - occupancy is drawn by `@umriss-ui/schedule` (ADR-0026).
|
|
|
201
225
|
band came out in the palette's second colour, after three bands in its
|
|
202
226
|
fourth. It now gets the first. A series without a `name` counts its position
|
|
203
227
|
among the series that take a colour.
|
|
204
|
-
- **The
|
|
228
|
+
- **The working-time axis labels in en-GB by level.** Without a
|
|
205
229
|
`tickFormat` it wrote every tick as `dd.MM. HH:mm`; it now labels as the
|
|
206
230
|
time axis does - `15:00`, and the date on the first tick of a new day,
|
|
207
231
|
`17 Mar 06:00` - and the tooltip's x value as `17 Mar 15:23`. Its ticks
|
|
@@ -331,12 +355,12 @@ gone** - occupancy is drawn by `@umriss-ui/schedule` (ADR-0026).
|
|
|
331
355
|
found none and drew nothing, silently. Without an `axisId` a limit now binds
|
|
332
356
|
to the first axis of its orientation - an `<XAxis id="time">` too - and an
|
|
333
357
|
unknown `axisId` is a DEV error, as it is for a series.
|
|
334
|
-
- **The
|
|
358
|
+
- **The working-time axis stands on the local clock.** Its day and half-day
|
|
335
359
|
ticks fell on UTC's midnight and were labelled in local time - "01:00"
|
|
336
360
|
where a day begins, in CET. They now fall on local midnight and noon. Explicit
|
|
337
361
|
`ticks` and the value of an x limit are named on the wall clock, like the
|
|
338
|
-
data, and mapped into
|
|
339
|
-
as
|
|
362
|
+
data, and mapped into working time as the data are; before, both were taken
|
|
363
|
+
as working time and landed far off, or pulled the axis out of shape.
|
|
340
364
|
- **Hit testing where areas and points meet.** Under `mode="nearest"` a state
|
|
341
365
|
band or a matrix cell under the pointer counted as distance zero and beat
|
|
342
366
|
every point; a point within 12 px of the pointer now wins, and the area
|
|
@@ -431,7 +455,7 @@ time arithmetic from here, so what it uses is public now.
|
|
|
431
455
|
`light-dark()` included, resolved to values a canvas can draw in the scheme
|
|
432
456
|
that applies at `root`. **`subscribeTheme(notify)`** tells a canvas when to
|
|
433
457
|
resolve again.
|
|
434
|
-
- **`
|
|
458
|
+
- **`toWorkingTimeClamped`** — wall clock to working time without `NaN`: a
|
|
435
459
|
time in removed time lands on its seam.
|
|
436
460
|
|
|
437
461
|
### No longer a release candidate
|
|
@@ -529,7 +553,7 @@ German defaults stood there regardless:
|
|
|
529
553
|
`"Sonstige"`). Whoever names `collectRank` names `remainderName` with it — in
|
|
530
554
|
the type (`ParetoSettings`) and in DEV as an error. `paretoDefaults` no longer
|
|
531
555
|
contains `remainderName`.
|
|
532
|
-
- The labelling of
|
|
556
|
+
- The labelling of a working-time axis without a `tickFormat` of its own is
|
|
533
557
|
`dd.MM. HH:mm`, set by hand. Previously it came out of
|
|
534
558
|
`toLocaleString(undefined, …)` and looked different on every machine.
|
|
535
559
|
- `"Series n"` remains the last resort for a series without a `name`, but warns
|
|
@@ -569,8 +593,8 @@ ADR-0006 to ADR-0011.
|
|
|
569
593
|
- **`ControlChart`:** the control chart as a composition out of `Line`,
|
|
570
594
|
`LimitLine` and `Scatter` (ADR-0008), and with it the pure modules
|
|
571
595
|
`controlLimits`, `zones`, the four rules and `violations`.
|
|
572
|
-
- **The
|
|
573
|
-
out of `
|
|
596
|
+
- **The working-time axis:** `calendar` on `XAxis`/`YAxis` and the pure modules
|
|
597
|
+
out of `workingTime.ts` — wall clock ↔ working time, ticks, breaks.
|
|
574
598
|
- **`pareto`** as a pure module.
|
|
575
599
|
- **The limit as a rule:** `assess` and `verdictWeight` with their types — the
|
|
576
600
|
same rule as in `@umriss-ui/core`, deliberately there twice (ADR-0006).
|
package/README.md
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Canvas-based charts for data-dense applications: few chart kinds, each one drawn
|
|
4
4
|
properly. Lines, areas, bars, scatters, state bands and matrices compose into
|
|
5
|
-
one chart on shared axes — together with the instruments a
|
|
6
|
-
made of: limit lines and bands, a control chart, a Pareto and
|
|
5
|
+
one chart on shared axes — together with the instruments a monitoring screen is
|
|
6
|
+
made of: limit lines and bands, a control chart, a Pareto and a working-time
|
|
7
7
|
axis.
|
|
8
8
|
|
|
9
9
|
The package depends on **nothing but React**, and it will keep doing so (R-1.2).
|
|
@@ -86,15 +86,15 @@ loaded: Geist when the application has it, the system fonts otherwise.
|
|
|
86
86
|
## What it can do
|
|
87
87
|
|
|
88
88
|
* **Six series kinds** in one chart on shared axes: `Line`, `Area`, `Bar`,
|
|
89
|
-
`Scatter`, `StateBand`, `Matrix`. Occupancy —
|
|
89
|
+
`Scatter`, `StateBand`, `Matrix`. Occupancy — work on people or vehicles, idle time,
|
|
90
90
|
double bookings — is `@umriss-ui/schedule`'s (ADR-0026).
|
|
91
91
|
* **Several axes per orientation**, each with its own extent; only the first
|
|
92
92
|
registered axis per orientation draws a grid.
|
|
93
93
|
* **The instruments**: `LimitLine` and `LimitBand`, `ControlChart` with its four
|
|
94
|
-
rule violations, `pareto()` with a collected remainder, and
|
|
94
|
+
rule violations, `pareto()` with a collected remainder, and a working-time
|
|
95
95
|
axis that takes the empty hours out and marks every removed span.
|
|
96
96
|
* **The pure modules are exported**, not hidden: `assess`, `controlLimits`,
|
|
97
|
-
`zones`, `violations`, `pareto`, `
|
|
97
|
+
`zones`, `violations`, `pareto`, `workingCalendar` and the rest. Whoever
|
|
98
98
|
wants to draw something other than the composition offers should reach the
|
|
99
99
|
arithmetic without rebuilding it.
|
|
100
100
|
* **Performance, measured rather than claimed**, up to three series of a
|
package/dist/charts.js
CHANGED
|
@@ -347,12 +347,12 @@ function On(s) {
|
|
|
347
347
|
e.push({
|
|
348
348
|
from: t.intervals[n - 1].to,
|
|
349
349
|
to: t.intervals[n].from,
|
|
350
|
-
|
|
350
|
+
workingTime: t.offsets[n]
|
|
351
351
|
});
|
|
352
352
|
return e;
|
|
353
353
|
}
|
|
354
354
|
function Hn(s, t, e) {
|
|
355
|
-
return On(s).map((n) => n.
|
|
355
|
+
return On(s).map((n) => n.workingTime).filter((n) => n >= t && n <= e);
|
|
356
356
|
}
|
|
357
357
|
const ke = [
|
|
358
358
|
ot,
|
|
@@ -396,7 +396,7 @@ function Wn(s, t, e, n, i = 0) {
|
|
|
396
396
|
let c = Number.NaN;
|
|
397
397
|
for (let h = l; h <= a; h++) {
|
|
398
398
|
const f = i + h * n, m = ut(f, o);
|
|
399
|
-
Number.isNaN(m) || m === c || (r.push({ wallClock: f,
|
|
399
|
+
Number.isNaN(m) || m === c || (r.push({ wallClock: f, workingTime: m }), c = m);
|
|
400
400
|
}
|
|
401
401
|
return r;
|
|
402
402
|
}
|
|
@@ -410,7 +410,7 @@ function Is(s, t, e, n, i = 0) {
|
|
|
410
410
|
ht(l, o),
|
|
411
411
|
a,
|
|
412
412
|
i
|
|
413
|
-
).map((h) => h.
|
|
413
|
+
).map((h) => h.workingTime).filter((h) => h >= t && h <= e);
|
|
414
414
|
}
|
|
415
415
|
const we = 365 * K, zn = [
|
|
416
416
|
...[1, 2, 5, 10, 15, 30].map((s) => ({ unit: "minute", n: s, ms: s * V })),
|
|
@@ -2085,14 +2085,14 @@ class rn {
|
|
|
2085
2085
|
i.inExtent && (i.orientation !== t || this.limitAxisId(i) !== e || (i.kind === "line" ? n.push(this.limitAt(i, i.value)) : n.push(this.limitAt(i, i.from), this.limitAt(i, i.to))));
|
|
2086
2086
|
return n;
|
|
2087
2087
|
}
|
|
2088
|
-
/** A limit's value in the units of its axis. An x limit on
|
|
2088
|
+
/** A limit's value in the units of its axis. An x limit on a working-time
|
|
2089
2089
|
axis is named on the wall clock, like the data, and mapped as they are. */
|
|
2090
2090
|
limitAt(t, e) {
|
|
2091
2091
|
if (t.orientation !== "x") return e;
|
|
2092
2092
|
const n = this.findAxisConfig("x", this.limitAxisId(t)), i = n === null ? void 0 : this.mapFor(n);
|
|
2093
2093
|
return i === void 0 ? e : i(e);
|
|
2094
2094
|
}
|
|
2095
|
-
/** Pre-mapping of the x values of an axis with
|
|
2095
|
+
/** Pre-mapping of the x values of an axis with a working calendar. The scale
|
|
2096
2096
|
stays affine; the mapping happens beforehand, once per point, in
|
|
2097
2097
|
materialisation - exactly the route ADR-0001 prescribes for a non-affine
|
|
2098
2098
|
axis. */
|
|
@@ -2444,7 +2444,7 @@ class rn {
|
|
|
2444
2444
|
}
|
|
2445
2445
|
/** Lane of a state series in pixels. Without a value the whole domain of its y
|
|
2446
2446
|
axis: a single series fills its band, a stack gets a domain with one unit per
|
|
2447
|
-
|
|
2447
|
+
lane from the caller. */
|
|
2448
2448
|
lanePx(t, e) {
|
|
2449
2449
|
const n = e.scale.domain, i = e.scale.toPx(t.laneFrom ?? n[0]), o = e.scale.toPx(t.laneTo ?? n[1]);
|
|
2450
2450
|
return { top: Math.min(i, o), bottom: Math.max(i, o) };
|
|
@@ -4304,9 +4304,6 @@ export {
|
|
|
4304
4304
|
qt as invalidateTheme,
|
|
4305
4305
|
Ns as localOffset,
|
|
4306
4306
|
ws as mapSeries,
|
|
4307
|
-
Dn as operatingCalendar,
|
|
4308
|
-
Is as operatingTicks,
|
|
4309
|
-
Wn as operatingTimeTicks,
|
|
4310
4307
|
Ws as pareto,
|
|
4311
4308
|
xs as paretoDefaults,
|
|
4312
4309
|
On as removedIntervals,
|
|
@@ -4318,11 +4315,14 @@ export {
|
|
|
4318
4315
|
Cs as sigmaFromLimit,
|
|
4319
4316
|
Tn as subscribeTheme,
|
|
4320
4317
|
Rn as timeStep,
|
|
4321
|
-
ut as toOperatingTime,
|
|
4322
|
-
Cn as toOperatingTimeClamped,
|
|
4323
4318
|
ht as toWallClock,
|
|
4319
|
+
ut as toWorkingTime,
|
|
4320
|
+
Cn as toWorkingTimeClamped,
|
|
4324
4321
|
As as verdictWeight,
|
|
4325
4322
|
ps as violatedIndices,
|
|
4326
4323
|
ms as violations,
|
|
4324
|
+
Dn as workingCalendar,
|
|
4325
|
+
Is as workingTicks,
|
|
4326
|
+
Wn as workingTimeTicks,
|
|
4327
4327
|
as as zones
|
|
4328
4328
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -127,10 +127,10 @@ export declare interface AxisConfig<T = unknown> {
|
|
|
127
127
|
/** The values are instants in milliseconds: ticks on local boundaries,
|
|
128
128
|
labels by level. A calendar implies it. */
|
|
129
129
|
time?: boolean;
|
|
130
|
-
/**
|
|
131
|
-
materialisation maps wall clock time onto
|
|
130
|
+
/** Working calendar: the intervals in which time counts. With it,
|
|
131
|
+
materialisation maps wall clock time onto working time before the scale
|
|
132
132
|
calculates - the scale stays affine (ADR-0001). */
|
|
133
|
-
calendar?: readonly
|
|
133
|
+
calendar?: readonly WorkingInterval[];
|
|
134
134
|
/** y axes only: this axis' ticks on the first y axis' grid. */
|
|
135
135
|
alignTicks?: boolean;
|
|
136
136
|
/** x axes only: where wheel, drag, pinch and double click propose a
|
|
@@ -190,17 +190,17 @@ export declare interface BarSeriesConfig<T = unknown> extends SeriesBase<T>, Sta
|
|
|
190
190
|
barWidth: number;
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
/** The breaks in
|
|
193
|
+
/** The breaks in working time that lie within the extent [from, to] - what the
|
|
194
194
|
axis must mark, in domain units. */
|
|
195
195
|
export declare function breaks(input: CalendarInput, from: number, to: number): number[];
|
|
196
196
|
|
|
197
197
|
/** Calendar from an input - a built calendar is passed straight through, a raw
|
|
198
198
|
list is built once and remembered. */
|
|
199
|
-
export declare function calendarFrom(input: CalendarInput):
|
|
199
|
+
export declare function calendarFrom(input: CalendarInput): WorkingCalendar;
|
|
200
200
|
|
|
201
201
|
/** Every function of this module takes either: the raw list as it stands on the
|
|
202
202
|
axis, or the calendar built from it. */
|
|
203
|
-
export declare type CalendarInput =
|
|
203
|
+
export declare type CalendarInput = WorkingCalendar | readonly WorkingInterval[];
|
|
204
204
|
|
|
205
205
|
export declare function Chart<T>(props: ChartProps<T>): ReactNode;
|
|
206
206
|
|
|
@@ -310,7 +310,7 @@ declare interface CommonProps {
|
|
|
310
310
|
is nearly always a value and not a moment. */
|
|
311
311
|
orientation?: "x" | "y";
|
|
312
312
|
/** Two severities, not five: five urgencies are five colours, and five colours
|
|
313
|
-
on a
|
|
313
|
+
on a dense screen are noise. */
|
|
314
314
|
severity?: Severity;
|
|
315
315
|
/** What the value means. A line at 90 does not say what 90 is. */
|
|
316
316
|
label?: string;
|
|
@@ -601,7 +601,7 @@ export declare interface LineProps<T> {
|
|
|
601
601
|
to be seen by - `always`, or `never`, not even that one. */
|
|
602
602
|
markers?: "auto" | "always" | "never";
|
|
603
603
|
/** Sample-and-hold: each value holds as a horizontal until the next sample
|
|
604
|
-
and jumps there - a
|
|
604
|
+
and jumps there - a target, a digital signal. A gap ends the hold at
|
|
605
605
|
its x. The tooltip reports the sample the hold began with. */
|
|
606
606
|
step?: boolean;
|
|
607
607
|
}
|
|
@@ -696,70 +696,6 @@ export declare interface MatrixSeriesConfig<T = unknown> extends SeriesBase<T> {
|
|
|
696
696
|
|
|
697
697
|
export declare const MINUTE: number;
|
|
698
698
|
|
|
699
|
-
/** An operating calendar: sorted, merged intervals with the operating time
|
|
700
|
-
accumulated before each one begins. An empty calendar is no calendar: it maps
|
|
701
|
-
unchanged.
|
|
702
|
-
|
|
703
|
-
Build once, then pass around: the mapping runs once per point, and were it to
|
|
704
|
-
sort and accumulate every time, the calendar would be the most expensive
|
|
705
|
-
thing about the frame. */
|
|
706
|
-
export declare interface OperatingCalendar {
|
|
707
|
-
readonly intervals: readonly OperatingInterval[];
|
|
708
|
-
/** Operating time accumulated before the respective interval begins. */
|
|
709
|
-
readonly offsets: readonly number[];
|
|
710
|
-
/** The whole operating time - the axis' extent is [0, total]. */
|
|
711
|
-
readonly total: number;
|
|
712
|
-
}
|
|
713
|
-
|
|
714
|
-
/** Builds a calendar: sorts, merges overlapping and abutting intervals and
|
|
715
|
-
throws away empty, reversed and non-finite ones. Merging is not a courtesy
|
|
716
|
-
but a precondition: only over separated intervals is the reverse mapping
|
|
717
|
-
unambiguous. */
|
|
718
|
-
export declare function operatingCalendar(intervals: readonly OperatingInterval[]): OperatingCalendar;
|
|
719
|
-
|
|
720
|
-
/** An interval in which time counts; thought of as half-open, but mappable from
|
|
721
|
-
both sides at its edges: both `from` and `to` have an operating time. */
|
|
722
|
-
export declare interface OperatingInterval {
|
|
723
|
-
readonly from: number;
|
|
724
|
-
readonly to: number;
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
/** Tick values for an axis extent that already stands in OPERATING TIME - the
|
|
728
|
-
route the axis layout takes.
|
|
729
|
-
|
|
730
|
-
The extent is trimmed to the operating time that exists (an extent widened to
|
|
731
|
-
nice boundaries reaches beyond it), calculated back into wall clock time, and
|
|
732
|
-
the candidates arise there. The step comes from the span in operating time and
|
|
733
|
-
not from the one in wall clock time: roughly one candidate per step of
|
|
734
|
-
operating time survives, and calculated from the wall clock span, four out of
|
|
735
|
-
ten wanted ticks would be left. */
|
|
736
|
-
export declare function operatingTicks(input: CalendarInput, from: number, to: number, count: number, offset?: number): number[];
|
|
737
|
-
|
|
738
|
-
/** A tick: where it stands on the clock and where it lies on the axis. */
|
|
739
|
-
export declare interface OperatingTimeTick {
|
|
740
|
-
readonly wallClock: number;
|
|
741
|
-
readonly operatingTime: number;
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
/** Ticks for an operating time axis, from an extent in WALL CLOCK TIME.
|
|
745
|
-
|
|
746
|
-
The candidates arise in wall clock time on multiples of the step - hours,
|
|
747
|
-
shift changes, days - whatever lies in removed time falls away, the rest is
|
|
748
|
-
mapped. Never the other way round: ticks generated in operating time land in
|
|
749
|
-
the middle of a shift and yield an axis labelled 14.5 and 29.0 which nobody
|
|
750
|
-
can read.
|
|
751
|
-
|
|
752
|
-
The offset shifts the grid; with it a local time hits its own midnight without
|
|
753
|
-
this module having to know about time zones.
|
|
754
|
-
|
|
755
|
-
If two candidates fall on the same operating time - the end of one shift and
|
|
756
|
-
the beginning of the next - the earlier one stays: two labels on the same
|
|
757
|
-
pixel would be one too many.
|
|
758
|
-
|
|
759
|
-
Both times come back, because the axis needs both: the operating time to
|
|
760
|
-
place the tick, the wall clock time to label it. */
|
|
761
|
-
export declare function operatingTimeTicks(input: CalendarInput, from: number, to: number, step: number, offset?: number): OperatingTimeTick[];
|
|
762
|
-
|
|
763
699
|
export declare interface Padding {
|
|
764
700
|
top: number;
|
|
765
701
|
right: number;
|
|
@@ -850,7 +786,7 @@ export declare interface Rect {
|
|
|
850
786
|
height: number;
|
|
851
787
|
}
|
|
852
788
|
|
|
853
|
-
/** The removed spans between the
|
|
789
|
+
/** The removed spans between the working intervals, for the mark in the axis
|
|
854
790
|
band. A chart that takes a weekend out and does not say so claims a
|
|
855
791
|
continuity it does not have. Before the first and after the last interval
|
|
856
792
|
there is nothing to mark: that lies outside the axis' extent. */
|
|
@@ -860,8 +796,8 @@ export declare function removedIntervals(input: CalendarInput): RemovedSpan[];
|
|
|
860
796
|
export declare interface RemovedSpan {
|
|
861
797
|
readonly from: number;
|
|
862
798
|
readonly to: number;
|
|
863
|
-
/**
|
|
864
|
-
readonly
|
|
799
|
+
/** Working time on which the whole span lies - a point, not a stretch. */
|
|
800
|
+
readonly workingTime: number;
|
|
865
801
|
}
|
|
866
802
|
|
|
867
803
|
/** Any number of CSS colours - a token, `light-dark(…)`, `var(--…)`, a
|
|
@@ -1012,7 +948,7 @@ export declare type SeriesKind = SeriesConfig["kind"];
|
|
|
1012
948
|
|
|
1013
949
|
/** How seriously a violation weighs. Exactly two: one severity that advises and
|
|
1014
950
|
one that calls for action. Five severities would be five colours, and five
|
|
1015
|
-
colours on a
|
|
951
|
+
colours on a dense screen are noise. Whoever needs a third
|
|
1016
952
|
distinction sets a second limit. */
|
|
1017
953
|
export declare type Severity = "warning" | "alarm";
|
|
1018
954
|
|
|
@@ -1149,7 +1085,15 @@ export declare interface TooltipProps<T> {
|
|
|
1149
1085
|
render?: (hit: TooltipHit<T>) => ReactNode;
|
|
1150
1086
|
}
|
|
1151
1087
|
|
|
1152
|
-
/**
|
|
1088
|
+
/** Working time → wall clock time; outside [0, total] there is none.
|
|
1089
|
+
|
|
1090
|
+
At a seam - the end of an interval which is at the same time the beginning of
|
|
1091
|
+
the next - the beginning of the next comes out: from there time counts again,
|
|
1092
|
+
and a pointer aiming there aims at the coming interval. Only the end of the last
|
|
1093
|
+
interval has no next and comes back as itself. */
|
|
1094
|
+
export declare function toWallClock(workingTime: number, input: CalendarInput): number;
|
|
1095
|
+
|
|
1096
|
+
/** Wall clock time → working time.
|
|
1153
1097
|
|
|
1154
1098
|
A point in a removed interval is a gap and becomes `NaN` - the encoding every
|
|
1155
1099
|
gap of this library already uses, and the drawing loop breaks the mark at it
|
|
@@ -1159,30 +1103,22 @@ export declare interface TooltipProps<T> {
|
|
|
1159
1103
|
before the first and after the last interval.
|
|
1160
1104
|
|
|
1161
1105
|
The end of one interval and the beginning of the next fall on the same value:
|
|
1162
|
-
in
|
|
1106
|
+
in working time they are neighbours, and the line between two points on
|
|
1163
1107
|
either side is drawn. That is not a lie but the whole purpose of the axis; the
|
|
1164
1108
|
mark in the axis band tells the reader that time was taken out there. */
|
|
1165
|
-
export declare function
|
|
1109
|
+
export declare function toWorkingTime(wallClock: number, input: CalendarInput): number;
|
|
1166
1110
|
|
|
1167
|
-
/** Wall clock time →
|
|
1111
|
+
/** Wall clock time → working time, but without NaN: whatever lies in removed
|
|
1168
1112
|
time falls onto the seam that this span collapses onto anyway; whatever lies
|
|
1169
1113
|
before the first or after the last interval onto 0 or onto the whole
|
|
1170
|
-
|
|
1114
|
+
working time respectively.
|
|
1171
1115
|
|
|
1172
1116
|
Why this exists: the materialised x values must stay ascending. Binary search
|
|
1173
1117
|
- for a hit as for a segment boundary - assumes that, and every comparison
|
|
1174
1118
|
with NaN is false, so that a search over a block of NaN silently lands on the
|
|
1175
1119
|
wrong point. The clamped value is a POSITION, not a statement: the point
|
|
1176
1120
|
itself is carried as a gap and is never drawn and never hit. */
|
|
1177
|
-
export declare function
|
|
1178
|
-
|
|
1179
|
-
/** Operating time → wall clock time; outside [0, total] there is none.
|
|
1180
|
-
|
|
1181
|
-
At a seam - the end of an interval which is at the same time the beginning of
|
|
1182
|
-
the next - the beginning of the next comes out: from there time counts again,
|
|
1183
|
-
and a pointer aiming there aims at the coming shift. Only the end of the last
|
|
1184
|
-
interval has no next and comes back as itself. */
|
|
1185
|
-
export declare function toWallClock(operatingTime: number, input: CalendarInput): number;
|
|
1121
|
+
export declare function toWorkingTimeClamped(wallClock: number, input: CalendarInput): number;
|
|
1186
1122
|
|
|
1187
1123
|
/** What a value is. Four outcomes, not three.
|
|
1188
1124
|
|
|
@@ -1212,6 +1148,70 @@ export declare interface Violation {
|
|
|
1212
1148
|
listed beside the chart as well as marked on it. */
|
|
1213
1149
|
export declare function violations(values: readonly number[], limits: ControlLimits, options?: Partial<RuleOptions>): Violation[];
|
|
1214
1150
|
|
|
1151
|
+
/** A working calendar: sorted, merged intervals with the working time
|
|
1152
|
+
accumulated before each one begins. An empty calendar is no calendar: it maps
|
|
1153
|
+
unchanged.
|
|
1154
|
+
|
|
1155
|
+
Build once, then pass around: the mapping runs once per point, and were it to
|
|
1156
|
+
sort and accumulate every time, the calendar would be the most expensive
|
|
1157
|
+
thing about the frame. */
|
|
1158
|
+
export declare interface WorkingCalendar {
|
|
1159
|
+
readonly intervals: readonly WorkingInterval[];
|
|
1160
|
+
/** Working time accumulated before the respective interval begins. */
|
|
1161
|
+
readonly offsets: readonly number[];
|
|
1162
|
+
/** The whole working time - the axis' extent is [0, total]. */
|
|
1163
|
+
readonly total: number;
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
/** Builds a calendar: sorts, merges overlapping and abutting intervals and
|
|
1167
|
+
throws away empty, reversed and non-finite ones. Merging is not a courtesy
|
|
1168
|
+
but a precondition: only over separated intervals is the reverse mapping
|
|
1169
|
+
unambiguous. */
|
|
1170
|
+
export declare function workingCalendar(intervals: readonly WorkingInterval[]): WorkingCalendar;
|
|
1171
|
+
|
|
1172
|
+
/** An interval in which time counts; thought of as half-open, but mappable from
|
|
1173
|
+
both sides at its edges: both `from` and `to` have a working time. */
|
|
1174
|
+
export declare interface WorkingInterval {
|
|
1175
|
+
readonly from: number;
|
|
1176
|
+
readonly to: number;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
/** Tick values for an axis extent that already stands in WORKING TIME - the
|
|
1180
|
+
route the axis layout takes.
|
|
1181
|
+
|
|
1182
|
+
The extent is trimmed to the working time that exists (an extent widened to
|
|
1183
|
+
nice boundaries reaches beyond it), calculated back into wall clock time, and
|
|
1184
|
+
the candidates arise there. The step comes from the span in working time and
|
|
1185
|
+
not from the one in wall clock time: roughly one candidate per step of
|
|
1186
|
+
working time survives, and calculated from the wall clock span, four out of
|
|
1187
|
+
ten wanted ticks would be left. */
|
|
1188
|
+
export declare function workingTicks(input: CalendarInput, from: number, to: number, count: number, offset?: number): number[];
|
|
1189
|
+
|
|
1190
|
+
/** A tick: where it stands on the clock and where it lies on the axis. */
|
|
1191
|
+
export declare interface WorkingTimeTick {
|
|
1192
|
+
readonly wallClock: number;
|
|
1193
|
+
readonly workingTime: number;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
/** Ticks for a working time axis, from an extent in WALL CLOCK TIME.
|
|
1197
|
+
|
|
1198
|
+
The candidates arise in wall clock time on multiples of the step - hours,
|
|
1199
|
+
interval changes, days - whatever lies in removed time falls away, the rest is
|
|
1200
|
+
mapped. Never the other way round: ticks generated in working time land in
|
|
1201
|
+
the middle of an interval and yield an axis labelled 14.5 and 29.0 which nobody
|
|
1202
|
+
can read.
|
|
1203
|
+
|
|
1204
|
+
The offset shifts the grid; with it a local time hits its own midnight without
|
|
1205
|
+
this module having to know about time zones.
|
|
1206
|
+
|
|
1207
|
+
If two candidates fall on the same working time - the end of one interval and
|
|
1208
|
+
the beginning of the next - the earlier one stays: two labels on the same
|
|
1209
|
+
pixel would be one too many.
|
|
1210
|
+
|
|
1211
|
+
Both times come back, because the axis needs both: the working time to
|
|
1212
|
+
place the tick, the wall clock time to label it. */
|
|
1213
|
+
export declare function workingTimeTicks(input: CalendarInput, from: number, to: number, step: number, offset?: number): WorkingTimeTick[];
|
|
1214
|
+
|
|
1215
1215
|
export declare function XAxis<T>(props: XAxisProps<T>): null;
|
|
1216
1216
|
|
|
1217
1217
|
export declare interface XAxisProps<T> extends CommonProps_2<T> {
|
|
@@ -1229,11 +1229,11 @@ export declare interface XAxisProps<T> extends CommonProps_2<T> {
|
|
|
1229
1229
|
readings lie less than a minute apart. Another language is a `tickFormat`,
|
|
1230
1230
|
which is handed the instant. `calendar` implies it. */
|
|
1231
1231
|
time?: boolean;
|
|
1232
|
-
/**
|
|
1233
|
-
stands in
|
|
1232
|
+
/** Working calendar: the intervals in which time counts. With it the axis
|
|
1233
|
+
stands in working time - nights and weekends are out, and every
|
|
1234
1234
|
removed span gets a break mark. The scale stays affine; the mapping happens
|
|
1235
1235
|
in materialisation (ADR-0001). */
|
|
1236
|
-
calendar?: readonly
|
|
1236
|
+
calendar?: readonly WorkingInterval[];
|
|
1237
1237
|
/** Zoom and pan, controlled: Ctrl or ⌘ with the wheel - and a pinch - zoom
|
|
1238
1238
|
around the pointer, a drag, a horizontal wheel or Shift with the wheel pan,
|
|
1239
1239
|
a double click proposes the whole data range. Each proposes a domain in
|