@nowline/layout 0.8.5 → 0.9.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/dist/axis-columns.d.ts +70 -0
- package/dist/axis-columns.d.ts.map +1 -0
- package/dist/axis-columns.js +104 -0
- package/dist/axis-columns.js.map +1 -0
- package/dist/band-scale.d.ts.map +1 -1
- package/dist/calendar-resolver.d.ts +27 -0
- package/dist/calendar-resolver.d.ts.map +1 -0
- package/dist/calendar-resolver.js +132 -0
- package/dist/calendar-resolver.js.map +1 -0
- package/dist/calendar.d.ts +0 -19
- package/dist/calendar.d.ts.map +1 -1
- package/dist/calendar.js +4 -44
- package/dist/calendar.js.map +1 -1
- package/dist/canvas-width.d.ts +23 -0
- package/dist/canvas-width.d.ts.map +1 -0
- package/dist/canvas-width.js +26 -0
- package/dist/canvas-width.js.map +1 -0
- package/dist/capacity.d.ts +28 -0
- package/dist/capacity.d.ts.map +1 -1
- package/dist/capacity.js +64 -29
- package/dist/capacity.js.map +1 -1
- package/dist/chart-translation.d.ts +22 -0
- package/dist/chart-translation.d.ts.map +1 -0
- package/dist/chart-translation.js +83 -0
- package/dist/chart-translation.js.map +1 -0
- package/dist/container-header-geometry.d.ts +64 -0
- package/dist/container-header-geometry.d.ts.map +1 -0
- package/dist/container-header-geometry.js +89 -0
- package/dist/container-header-geometry.js.map +1 -0
- package/dist/dsl-utils.d.ts +3 -4
- package/dist/dsl-utils.d.ts.map +1 -1
- package/dist/dsl-utils.js +8 -25
- package/dist/dsl-utils.js.map +1 -1
- package/dist/edge-routing.d.ts +69 -78
- package/dist/edge-routing.d.ts.map +1 -1
- package/dist/edge-routing.js +271 -401
- package/dist/edge-routing.js.map +1 -1
- package/dist/frame-tab-geometry.d.ts +24 -14
- package/dist/frame-tab-geometry.d.ts.map +1 -1
- package/dist/frame-tab-geometry.js +69 -23
- package/dist/frame-tab-geometry.js.map +1 -1
- package/dist/header-card-geometry.d.ts +12 -0
- package/dist/header-card-geometry.d.ts.map +1 -1
- package/dist/header-card-geometry.js +14 -2
- package/dist/header-card-geometry.js.map +1 -1
- package/dist/header-logo.d.ts +28 -0
- package/dist/header-logo.d.ts.map +1 -0
- package/dist/header-logo.js +51 -0
- package/dist/header-logo.js.map +1 -0
- package/dist/i18n.d.ts +11 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +11 -1
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +20 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/inline-date-pin-geometry.d.ts +19 -11
- package/dist/inline-date-pin-geometry.d.ts.map +1 -1
- package/dist/inline-date-pin-geometry.js +45 -46
- package/dist/inline-date-pin-geometry.js.map +1 -1
- package/dist/item-bar-geometry.d.ts +192 -4
- package/dist/item-bar-geometry.d.ts.map +1 -1
- package/dist/item-bar-geometry.js +258 -5
- package/dist/item-bar-geometry.js.map +1 -1
- package/dist/item-port-geometry.d.ts +13 -0
- package/dist/item-port-geometry.d.ts.map +1 -0
- package/dist/item-port-geometry.js +63 -0
- package/dist/item-port-geometry.js.map +1 -0
- package/dist/layout-context.d.ts +115 -51
- package/dist/layout-context.d.ts.map +1 -1
- package/dist/layout-context.js +96 -5
- package/dist/layout-context.js.map +1 -1
- package/dist/layout-insights.d.ts.map +1 -1
- package/dist/layout-insights.js +73 -1
- package/dist/layout-insights.js.map +1 -1
- package/dist/layout.d.ts +35 -0
- package/dist/layout.d.ts.map +1 -1
- package/dist/layout.js +18 -1315
- package/dist/layout.js.map +1 -1
- package/dist/nodes/anchor-node.d.ts.map +1 -1
- package/dist/nodes/anchor-node.js +11 -4
- package/dist/nodes/anchor-node.js.map +1 -1
- package/dist/nodes/content-extent.d.ts +24 -0
- package/dist/nodes/content-extent.d.ts.map +1 -0
- package/dist/nodes/content-extent.js +100 -0
- package/dist/nodes/content-extent.js.map +1 -0
- package/dist/nodes/dependency-edges.d.ts +6 -0
- package/dist/nodes/dependency-edges.d.ts.map +1 -0
- package/dist/nodes/dependency-edges.js +148 -0
- package/dist/nodes/dependency-edges.js.map +1 -0
- package/dist/nodes/footnote-node.d.ts +24 -3
- package/dist/nodes/footnote-node.d.ts.map +1 -1
- package/dist/nodes/footnote-node.js +129 -25
- package/dist/nodes/footnote-node.js.map +1 -1
- package/dist/nodes/group-node.d.ts +10 -21
- package/dist/nodes/group-node.d.ts.map +1 -1
- package/dist/nodes/group-node.js +79 -154
- package/dist/nodes/group-node.js.map +1 -1
- package/dist/nodes/header-node.d.ts +56 -0
- package/dist/nodes/header-node.d.ts.map +1 -0
- package/dist/nodes/header-node.js +163 -0
- package/dist/nodes/header-node.js.map +1 -0
- package/dist/nodes/include-node.d.ts +22 -12
- package/dist/nodes/include-node.d.ts.map +1 -1
- package/dist/nodes/include-node.js +95 -62
- package/dist/nodes/include-node.js.map +1 -1
- package/dist/nodes/item-measure.d.ts +135 -0
- package/dist/nodes/item-measure.d.ts.map +1 -0
- package/dist/nodes/item-measure.js +514 -0
- package/dist/nodes/item-measure.js.map +1 -0
- package/dist/nodes/item-node.d.ts +162 -9
- package/dist/nodes/item-node.d.ts.map +1 -1
- package/dist/nodes/item-node.js +256 -69
- package/dist/nodes/item-node.js.map +1 -1
- package/dist/nodes/marker-band.d.ts +118 -0
- package/dist/nodes/marker-band.d.ts.map +1 -0
- package/dist/nodes/marker-band.js +303 -0
- package/dist/nodes/marker-band.js.map +1 -0
- package/dist/nodes/marker-geometry.js +1 -1
- package/dist/nodes/marker-geometry.js.map +1 -1
- package/dist/nodes/milestone-node.d.ts +112 -15
- package/dist/nodes/milestone-node.d.ts.map +1 -1
- package/dist/nodes/milestone-node.js +246 -95
- package/dist/nodes/milestone-node.js.map +1 -1
- package/dist/nodes/nowline-node.d.ts +8 -0
- package/dist/nodes/nowline-node.d.ts.map +1 -0
- package/dist/nodes/nowline-node.js +74 -0
- package/dist/nodes/nowline-node.js.map +1 -0
- package/dist/nodes/parallel-node.d.ts +7 -12
- package/dist/nodes/parallel-node.d.ts.map +1 -1
- package/dist/nodes/parallel-node.js +66 -32
- package/dist/nodes/parallel-node.js.map +1 -1
- package/dist/nodes/region-markers.d.ts +41 -0
- package/dist/nodes/region-markers.d.ts.map +1 -0
- package/dist/nodes/region-markers.js +130 -0
- package/dist/nodes/region-markers.js.map +1 -0
- package/dist/nodes/roadmap-node.d.ts +9 -72
- package/dist/nodes/roadmap-node.d.ts.map +1 -1
- package/dist/nodes/roadmap-node.js +38 -788
- package/dist/nodes/roadmap-node.js.map +1 -1
- package/dist/nodes/row-track.d.ts +33 -0
- package/dist/nodes/row-track.d.ts.map +1 -0
- package/dist/nodes/row-track.js +170 -0
- package/dist/nodes/row-track.js.map +1 -0
- package/dist/nodes/sequence-item.d.ts +25 -0
- package/dist/nodes/sequence-item.d.ts.map +1 -0
- package/dist/nodes/sequence-item.js +396 -0
- package/dist/nodes/sequence-item.js.map +1 -0
- package/dist/nodes/sequence-one.d.ts +5 -0
- package/dist/nodes/sequence-one.d.ts.map +1 -0
- package/dist/nodes/sequence-one.js +26 -0
- package/dist/nodes/sequence-one.js.map +1 -0
- package/dist/nodes/swimlane-node.d.ts +5 -17
- package/dist/nodes/swimlane-node.d.ts.map +1 -1
- package/dist/nodes/swimlane-node.js +62 -147
- package/dist/nodes/swimlane-node.js.map +1 -1
- package/dist/nodes/wave-node.d.ts +52 -0
- package/dist/nodes/wave-node.d.ts.map +1 -0
- package/dist/nodes/wave-node.js +483 -0
- package/dist/nodes/wave-node.js.map +1 -0
- package/dist/non-working-display.d.ts +14 -0
- package/dist/non-working-display.d.ts.map +1 -0
- package/dist/non-working-display.js +28 -0
- package/dist/non-working-display.js.map +1 -0
- package/dist/phases/date-window.d.ts +48 -0
- package/dist/phases/date-window.d.ts.map +1 -0
- package/dist/phases/date-window.js +130 -0
- package/dist/phases/date-window.js.map +1 -0
- package/dist/phases/finalize.d.ts +198 -0
- package/dist/phases/finalize.d.ts.map +1 -0
- package/dist/phases/finalize.js +1058 -0
- package/dist/phases/finalize.js.map +1 -0
- package/dist/phases/measure.d.ts +77 -0
- package/dist/phases/measure.d.ts.map +1 -0
- package/dist/phases/measure.js +222 -0
- package/dist/phases/measure.js.map +1 -0
- package/dist/phases/place.d.ts +28 -0
- package/dist/phases/place.d.ts.map +1 -0
- package/dist/phases/place.js +225 -0
- package/dist/phases/place.js.map +1 -0
- package/dist/renderable.d.ts.map +1 -1
- package/dist/renderable.js +23 -3
- package/dist/renderable.js.map +1 -1
- package/dist/resolve-today.d.ts +11 -1
- package/dist/resolve-today.d.ts.map +1 -1
- package/dist/resolve-today.js +26 -12
- package/dist/resolve-today.js.map +1 -1
- package/dist/row-packer.d.ts +42 -16
- package/dist/row-packer.d.ts.map +1 -1
- package/dist/row-packer.js +51 -78
- package/dist/row-packer.js.map +1 -1
- package/dist/schedule.d.ts +58 -1
- package/dist/schedule.d.ts.map +1 -1
- package/dist/schedule.js +280 -106
- package/dist/schedule.js.map +1 -1
- package/dist/start-rules.d.ts +27 -0
- package/dist/start-rules.d.ts.map +1 -0
- package/dist/start-rules.js +91 -0
- package/dist/start-rules.js.map +1 -0
- package/dist/start-terms.d.ts +23 -0
- package/dist/start-terms.d.ts.map +1 -0
- package/dist/start-terms.js +27 -0
- package/dist/start-terms.js.map +1 -0
- package/dist/status-dot.d.ts +46 -0
- package/dist/status-dot.d.ts.map +1 -0
- package/dist/status-dot.js +78 -0
- package/dist/status-dot.js.map +1 -0
- package/dist/style-resolution.d.ts.map +1 -1
- package/dist/style-resolution.js +23 -43
- package/dist/style-resolution.js.map +1 -1
- package/dist/text-measure.d.ts +28 -0
- package/dist/text-measure.d.ts.map +1 -0
- package/dist/text-measure.js +70 -0
- package/dist/text-measure.js.map +1 -0
- package/dist/themes/contrast.d.ts +4 -0
- package/dist/themes/contrast.d.ts.map +1 -0
- package/dist/themes/contrast.js +32 -0
- package/dist/themes/contrast.js.map +1 -0
- package/dist/themes/dark.d.ts.map +1 -1
- package/dist/themes/dark.js +28 -1
- package/dist/themes/dark.js.map +1 -1
- package/dist/themes/grayscale.d.ts.map +1 -1
- package/dist/themes/grayscale.js +28 -1
- package/dist/themes/grayscale.js.map +1 -1
- package/dist/themes/index.d.ts +4 -11
- package/dist/themes/index.d.ts.map +1 -1
- package/dist/themes/index.js +6 -4
- package/dist/themes/index.js.map +1 -1
- package/dist/themes/light.d.ts.map +1 -1
- package/dist/themes/light.js +28 -1
- package/dist/themes/light.js.map +1 -1
- package/dist/themes/shape.d.ts +31 -0
- package/dist/themes/shape.d.ts.map +1 -1
- package/dist/themes/shared.d.ts +44 -50
- package/dist/themes/shared.d.ts.map +1 -1
- package/dist/themes/shared.js +79 -83
- package/dist/themes/shared.js.map +1 -1
- package/dist/time-scale.d.ts +42 -6
- package/dist/time-scale.d.ts.map +1 -1
- package/dist/time-scale.js +109 -17
- package/dist/time-scale.js.map +1 -1
- package/dist/types.d.ts +528 -11
- package/dist/types.d.ts.map +1 -1
- package/dist/view-preset.d.ts +61 -6
- package/dist/view-preset.d.ts.map +1 -1
- package/dist/view-preset.js +439 -24
- package/dist/view-preset.js.map +1 -1
- package/dist/wave-barrier.d.ts +107 -0
- package/dist/wave-barrier.d.ts.map +1 -0
- package/dist/wave-barrier.js +174 -0
- package/dist/wave-barrier.js.map +1 -0
- package/dist/wave-hatch.d.ts +4 -0
- package/dist/wave-hatch.d.ts.map +1 -0
- package/dist/wave-hatch.js +21 -0
- package/dist/wave-hatch.js.map +1 -0
- package/dist/wave-layout.d.ts +99 -0
- package/dist/wave-layout.d.ts.map +1 -0
- package/dist/wave-layout.js +130 -0
- package/dist/wave-layout.js.map +1 -0
- package/dist/working-calendar.d.ts +128 -4
- package/dist/working-calendar.d.ts.map +1 -1
- package/dist/working-calendar.js +725 -51
- package/dist/working-calendar.js.map +1 -1
- package/dist/working-span.d.ts +11 -0
- package/dist/working-span.d.ts.map +1 -0
- package/dist/working-span.js +18 -0
- package/dist/working-span.js.map +1 -0
- package/package.json +7 -7
- package/src/axis-columns.ts +140 -0
- package/src/calendar-resolver.ts +161 -0
- package/src/calendar.ts +4 -45
- package/src/canvas-width.ts +36 -0
- package/src/capacity.ts +71 -30
- package/src/chart-translation.ts +88 -0
- package/src/container-header-geometry.ts +116 -0
- package/src/dsl-utils.ts +8 -26
- package/src/edge-routing.ts +347 -491
- package/src/frame-tab-geometry.ts +78 -25
- package/src/header-card-geometry.ts +17 -2
- package/src/header-logo.ts +67 -0
- package/src/i18n.ts +22 -1
- package/src/index.ts +97 -12
- package/src/inline-date-pin-geometry.ts +55 -58
- package/src/item-bar-geometry.ts +341 -5
- package/src/item-port-geometry.ts +69 -0
- package/src/layout-context.ts +210 -72
- package/src/layout-insights.ts +109 -2
- package/src/layout.ts +57 -1530
- package/src/nodes/anchor-node.ts +11 -4
- package/src/nodes/content-extent.ts +107 -0
- package/src/nodes/dependency-edges.ts +171 -0
- package/src/nodes/footnote-node.ts +171 -31
- package/src/nodes/group-node.ts +92 -215
- package/src/nodes/header-node.ts +255 -0
- package/src/nodes/include-node.ts +124 -110
- package/src/nodes/item-measure.ts +723 -0
- package/src/nodes/item-node.ts +358 -80
- package/src/nodes/marker-band.ts +406 -0
- package/src/nodes/marker-geometry.ts +1 -1
- package/src/nodes/milestone-node.ts +321 -136
- package/src/nodes/nowline-node.ts +87 -0
- package/src/nodes/parallel-node.ts +69 -39
- package/src/nodes/region-markers.ts +194 -0
- package/src/nodes/roadmap-node.ts +46 -950
- package/src/nodes/row-track.ts +217 -0
- package/src/nodes/sequence-item.ts +433 -0
- package/src/nodes/sequence-one.ts +40 -0
- package/src/nodes/swimlane-node.ts +66 -206
- package/src/nodes/wave-node.ts +609 -0
- package/src/non-working-display.ts +32 -0
- package/src/phases/date-window.ts +191 -0
- package/src/phases/finalize.ts +1303 -0
- package/src/phases/measure.ts +329 -0
- package/src/phases/place.ts +318 -0
- package/src/renderable.ts +23 -3
- package/src/resolve-today.ts +28 -25
- package/src/row-packer.ts +85 -84
- package/src/schedule.ts +362 -114
- package/src/start-rules.ts +113 -0
- package/src/start-terms.ts +38 -0
- package/src/status-dot.ts +81 -0
- package/src/style-resolution.ts +27 -57
- package/src/text-measure.ts +71 -0
- package/src/themes/contrast.ts +34 -0
- package/src/themes/dark.ts +28 -1
- package/src/themes/grayscale.ts +28 -1
- package/src/themes/index.ts +10 -7
- package/src/themes/light.ts +28 -1
- package/src/themes/shape.ts +38 -0
- package/src/themes/shared.ts +85 -93
- package/src/time-scale.ts +117 -19
- package/src/types.ts +529 -20
- package/src/view-preset.ts +520 -27
- package/src/wave-barrier.ts +242 -0
- package/src/wave-hatch.ts +25 -0
- package/src/wave-layout.ts +203 -0
- package/src/working-calendar.ts +875 -57
- package/src/working-span.ts +19 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// HeaderNode — the roadmap header (title, author, company logo) in both
|
|
2
|
+
// positions, `beside` (a card left of the chart) and `above` (a band over
|
|
3
|
+
// it). `measure` sizes it before anything else is laid out, because the
|
|
4
|
+
// header decides where the chart starts: its left edge in beside mode,
|
|
5
|
+
// its top in above mode, and how low the header rows must end so the
|
|
6
|
+
// beside card fits (specs/layout-phases.md §3.7).
|
|
7
|
+
//
|
|
8
|
+
// HeaderNode does not implement `Renderable`: that signature is built
|
|
9
|
+
// around a time scale and a row band, which a header has no use for.
|
|
10
|
+
import { HEADER_AUTHOR_FONT_SIZE_PX, HEADER_AUTHOR_LINE_HEIGHT_PX, HEADER_CARD_PADDING_BOTTOM, HEADER_CARD_PADDING_TOP, HEADER_CARD_PADDING_X, HEADER_LOGO_GAP_PX, HEADER_LOGO_PAD_Y_PX, HEADER_TITLE_FONT_SIZE_PX, HEADER_TITLE_LINE_HEIGHT_PX, HEADER_TITLE_TO_AUTHOR_GAP_PX, } from '../header-card-geometry.js';
|
|
11
|
+
import { estimateTextWidth, wrapText } from '../text-measure.js';
|
|
12
|
+
import { HEADER_ABOVE_HEIGHT_PX, HEADER_BESIDE_MAX_WIDTH_PX, HEADER_BESIDE_MIN_WIDTH_PX, } from '../themes/shared.js';
|
|
13
|
+
// Left margin between the canvas's left edge and the visible card. The
|
|
14
|
+
// matching right-side breathing room is owned by `GUTTER_PX` (the canonical
|
|
15
|
+
// content gutter, applied between `chartLeftX` and `originX`), so the gap
|
|
16
|
+
// from the card's right edge to the timeline strip is the same as the gap
|
|
17
|
+
// between two adjacent items.
|
|
18
|
+
const HEADER_CARD_OUTER_PAD = 6;
|
|
19
|
+
/** Clearance (px) the beside card keeps from the canvas top. */
|
|
20
|
+
const HEADER_CARD_TOP_INSET = 4;
|
|
21
|
+
/** Gap (px) between the header (or the canvas top) and the chart. */
|
|
22
|
+
const CHART_TOP_GAP_PX = 8;
|
|
23
|
+
export class HeaderNode {
|
|
24
|
+
input;
|
|
25
|
+
constructor(input) {
|
|
26
|
+
this.input = input;
|
|
27
|
+
}
|
|
28
|
+
measure() {
|
|
29
|
+
const { title, author, style, logo } = this.input;
|
|
30
|
+
const isBeside = style.headerPosition === 'beside';
|
|
31
|
+
// Pre-size the beside-mode header card. Width = max line width +
|
|
32
|
+
// padding, clamped to MIN..MAX with word-wrap once the title
|
|
33
|
+
// exceeds MAX. Above mode keeps the fixed-strip geometry (full
|
|
34
|
+
// canvas width, fixed height) but still reads the wrapped lines.
|
|
35
|
+
const sized = sizeBesideHeader(title, author, logo);
|
|
36
|
+
// Above-mode strip: fixed height, bumped only when the logo plus
|
|
37
|
+
// its clearance is taller (`logo-size:xl`).
|
|
38
|
+
const aboveHeight = logo
|
|
39
|
+
? Math.max(HEADER_ABOVE_HEIGHT_PX, logo.height + 2 * HEADER_LOGO_PAD_Y_PX)
|
|
40
|
+
: HEADER_ABOVE_HEIGHT_PX;
|
|
41
|
+
return {
|
|
42
|
+
position: style.headerPosition,
|
|
43
|
+
titleLines: sized.titleLines,
|
|
44
|
+
authorLines: sized.authorLines,
|
|
45
|
+
cardWidth: sized.cardWidth,
|
|
46
|
+
cardHeight: sized.cardHeight,
|
|
47
|
+
textCardHeight: sized.textCardHeight,
|
|
48
|
+
logoSlot: sized.logoSlot,
|
|
49
|
+
...(logo ? { logo } : {}),
|
|
50
|
+
chartLeftX: isBeside ? sized.boxWidth : 0,
|
|
51
|
+
aboveHeight,
|
|
52
|
+
chartTopY: isBeside ? CHART_TOP_GAP_PX : aboveHeight + CHART_TOP_GAP_PX,
|
|
53
|
+
// In beside mode the card's BOTTOM aligns with the bottom of the
|
|
54
|
+
// header rows so it visually anchors to the chart's top. The
|
|
55
|
+
// rows must end low enough for the card plus a 4 px top inset;
|
|
56
|
+
// the measure phase pushes the timeline down when they would not.
|
|
57
|
+
minRowsBottomY: isBeside ? sized.cardHeight + HEADER_CARD_TOP_INSET : 0,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The header box, the card, the logo box and the text inset, once the
|
|
62
|
+
* chart's extent is known. Beside: a column `chartLeftX` wide down to
|
|
63
|
+
* the chart bottom, with the card's bottom on `rowsBottomY`. Above: a
|
|
64
|
+
* band `aboveHeight` tall across the canvas, the card filling it.
|
|
65
|
+
*/
|
|
66
|
+
place(measured, frame) {
|
|
67
|
+
const { title, author, style } = this.input;
|
|
68
|
+
const isBeside = measured.position === 'beside';
|
|
69
|
+
const box = isBeside
|
|
70
|
+
? { x: 0, y: 0, width: measured.chartLeftX, height: frame.chartBottomY }
|
|
71
|
+
: { x: 0, y: 0, width: frame.canvasRightX, height: measured.aboveHeight };
|
|
72
|
+
// The visible card inside the box. Beside, its BOTTOM hugs the
|
|
73
|
+
// bottom of the header rows so the title block anchors to the
|
|
74
|
+
// chart's top edge whichever header rows are present; the measure
|
|
75
|
+
// phase already pushed the rows down far enough for the card to
|
|
76
|
+
// keep HEADER_CARD_TOP_INSET from the canvas top.
|
|
77
|
+
const cardBox = isBeside
|
|
78
|
+
? {
|
|
79
|
+
x: HEADER_CARD_OUTER_PAD,
|
|
80
|
+
y: frame.rowsBottomY - measured.cardHeight,
|
|
81
|
+
width: measured.cardWidth,
|
|
82
|
+
height: measured.cardHeight,
|
|
83
|
+
}
|
|
84
|
+
: { x: 0, y: 0, width: frame.canvasRightX, height: measured.aboveHeight };
|
|
85
|
+
// Logo at the card's left padding, vertically centered; the text
|
|
86
|
+
// shifts right past it and centers in the (possibly taller) card.
|
|
87
|
+
let logo;
|
|
88
|
+
let textInset;
|
|
89
|
+
if (measured.logo) {
|
|
90
|
+
logo = {
|
|
91
|
+
box: {
|
|
92
|
+
x: box.x + cardBox.x + HEADER_CARD_PADDING_X,
|
|
93
|
+
y: box.y + cardBox.y + (cardBox.height - measured.logo.height) / 2,
|
|
94
|
+
width: measured.logo.width,
|
|
95
|
+
height: measured.logo.height,
|
|
96
|
+
},
|
|
97
|
+
assetRef: measured.logo.assetRef,
|
|
98
|
+
intrinsic: measured.logo.intrinsic,
|
|
99
|
+
};
|
|
100
|
+
textInset = {
|
|
101
|
+
x: measured.logoSlot,
|
|
102
|
+
y: Math.max(0, (cardBox.height - measured.textCardHeight) / 2),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
box,
|
|
107
|
+
position: style.headerPosition,
|
|
108
|
+
title,
|
|
109
|
+
author,
|
|
110
|
+
titleLines: measured.titleLines,
|
|
111
|
+
authorLines: measured.authorLines,
|
|
112
|
+
cardBox,
|
|
113
|
+
logo,
|
|
114
|
+
...(textInset ? { textInset } : {}),
|
|
115
|
+
style,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function sizeBesideHeader(title, author, logo) {
|
|
120
|
+
const maxContentWidth = HEADER_BESIDE_MAX_WIDTH_PX - 2 * HEADER_CARD_PADDING_X;
|
|
121
|
+
const titleLines = wrapText(title, maxContentWidth, HEADER_TITLE_FONT_SIZE_PX);
|
|
122
|
+
const authorLines = wrapText(author ?? '', maxContentWidth, HEADER_AUTHOR_FONT_SIZE_PX);
|
|
123
|
+
let widest = 0;
|
|
124
|
+
for (const line of titleLines)
|
|
125
|
+
widest = Math.max(widest, estimateTextWidth(line, HEADER_TITLE_FONT_SIZE_PX));
|
|
126
|
+
for (const line of authorLines)
|
|
127
|
+
widest = Math.max(widest, estimateTextWidth(line, HEADER_AUTHOR_FONT_SIZE_PX));
|
|
128
|
+
// A logo sits left of the text and widens the card past the text-only
|
|
129
|
+
// MAX clamp (which bounds the text column, not the logo slot).
|
|
130
|
+
const hasText = titleLines.length > 0 || authorLines.length > 0;
|
|
131
|
+
const logoSlot = logo ? logo.width + (hasText ? HEADER_LOGO_GAP_PX : 0) : 0;
|
|
132
|
+
const naturalCardWidth = widest + 2 * HEADER_CARD_PADDING_X;
|
|
133
|
+
// `HEADER_BESIDE_{MIN,MAX}_WIDTH_PX` bound the **boxWidth** (= cardWidth
|
|
134
|
+
// + left outer pad). Subtract one outer pad to derive the cardWidth
|
|
135
|
+
// bounds.
|
|
136
|
+
const cardWidth = Math.max(HEADER_BESIDE_MIN_WIDTH_PX - HEADER_CARD_OUTER_PAD, Math.min(HEADER_BESIDE_MAX_WIDTH_PX - HEADER_CARD_OUTER_PAD, naturalCardWidth) + logoSlot);
|
|
137
|
+
const titleBlockHeight = titleLines.length > 0 ? (titleLines.length - 1) * HEADER_TITLE_LINE_HEIGHT_PX : 0;
|
|
138
|
+
const authorBlockHeight = authorLines.length > 0
|
|
139
|
+
? HEADER_TITLE_TO_AUTHOR_GAP_PX +
|
|
140
|
+
(authorLines.length - 1) * HEADER_AUTHOR_LINE_HEIGHT_PX
|
|
141
|
+
: 0;
|
|
142
|
+
const textCardHeight = HEADER_CARD_PADDING_TOP + titleBlockHeight + authorBlockHeight + HEADER_CARD_PADDING_BOTTOM;
|
|
143
|
+
// A logo taller than the text block grows the card; logo and text are
|
|
144
|
+
// then both centered vertically.
|
|
145
|
+
const cardHeight = logo
|
|
146
|
+
? Math.max(textCardHeight, logo.height + 2 * HEADER_LOGO_PAD_Y_PX)
|
|
147
|
+
: textCardHeight;
|
|
148
|
+
// `boxWidth` only includes the LEFT outer pad — the right-side breathing
|
|
149
|
+
// room between the card and the chart is owned by `GUTTER_PX` in the
|
|
150
|
+
// measure phase. So `boxWidth` doubles as `chartLeftX` (the card's right
|
|
151
|
+
// edge in canvas coordinates).
|
|
152
|
+
const boxWidth = cardWidth + HEADER_CARD_OUTER_PAD;
|
|
153
|
+
return {
|
|
154
|
+
titleLines,
|
|
155
|
+
authorLines,
|
|
156
|
+
cardWidth,
|
|
157
|
+
cardHeight,
|
|
158
|
+
textCardHeight,
|
|
159
|
+
logoSlot,
|
|
160
|
+
boxWidth,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=header-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"header-node.js","sourceRoot":"","sources":["../../src/nodes/header-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,26 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type
|
|
3
|
-
import type { PositionedIncludeRegion
|
|
4
|
-
export
|
|
5
|
-
sequenceItem: (child: ItemDeclaration, cursor: TrackCursor, ctx: LayoutContext, ownerOverride?: string) => PositionedItem;
|
|
6
|
-
sequenceOne: (child: ItemDeclaration | GroupBlock | ParallelBlock, cursor: TrackCursor, ctx: LayoutContext) => PositionedTrackChild;
|
|
7
|
-
resolveChildStart: (props: EntityProperty[], seqDefault: number, laneLeftX: number, ctx: LayoutContext) => number;
|
|
8
|
-
newCursor: (x: number, y: number) => TrackCursor;
|
|
9
|
-
estimateTextWidth: (text: string, fontSize: number) => number;
|
|
10
|
-
predictItemChipExtraHeight: (item: ItemDeclaration, ctx: LayoutContext) => number;
|
|
11
|
-
}
|
|
12
|
-
export declare function buildIncludeRegions(regions: IsolatedRegion[], ctx: LayoutContext, startY: number, deps: IncludeNodeDeps): {
|
|
1
|
+
import type { IsolatedRegion } from '@nowline/core';
|
|
2
|
+
import { type LayoutContext, type LayoutHelpers } from '../layout-context.js';
|
|
3
|
+
import type { PositionedIncludeRegion } from '../types.js';
|
|
4
|
+
export declare function buildIncludeRegions(regions: IsolatedRegion[], ctx: LayoutContext, startY: number, helpers: LayoutHelpers, chartRightX: number): {
|
|
13
5
|
regions: PositionedIncludeRegion[];
|
|
6
|
+
contexts: LayoutContext[];
|
|
14
7
|
endY: number;
|
|
15
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Size an include's bounding box to the diagram's content: it reaches past
|
|
11
|
+
* `contentRightX`, the furthest bar, spilled caption, marker or now-line
|
|
12
|
+
* anywhere in the chart (and past its own chrome), by a small right pad,
|
|
13
|
+
* so every region in a chart ends at the same edge (specs/rendering.md,
|
|
14
|
+
* Included Roadmaps). It is clamped to `chartRightX`;
|
|
15
|
+
* finalize grows the canvas to hold the pad first (f3). Finalize runs it
|
|
16
|
+
* once per kept region (f4), after the canvas width is final: the spill
|
|
17
|
+
* growth, the timeline extension and the marker labels can all still grow
|
|
18
|
+
* the canvas after the region is placed.
|
|
19
|
+
*/
|
|
20
|
+
export declare function fitIncludeRegionWidth(region: PositionedIncludeRegion, chartRightX: number, contentRightX: number): void;
|
|
21
|
+
/**
|
|
22
|
+
* The width `fitIncludeRegionWidth` gives `region` on a canvas ending at
|
|
23
|
+
* `chartRightX`, with the diagram's content ending at `contentRightX`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function includeRegionWidth(region: PositionedIncludeRegion, chartRightX: number, contentRightX: number): number;
|
|
16
26
|
//# sourceMappingURL=include-node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"include-node.d.ts","sourceRoot":"","sources":["../../src/nodes/include-node.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"include-node.d.ts","sourceRoot":"","sources":["../../src/nodes/include-node.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEnG,OAAO,KAAK,EAAe,uBAAuB,EAAsB,MAAM,aAAa,CAAC;AAuB5F,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,cAAc,EAAE,EACzB,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,aAAa,EACtB,WAAW,EAAE,MAAM,GACpB;IAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAgGjF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACjC,MAAM,EAAE,uBAAuB,EAC/B,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACtB,IAAI,CASN;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,uBAAuB,EAC/B,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,GACtB,MAAM,CAYR"}
|
|
@@ -4,118 +4,151 @@
|
|
|
4
4
|
// vertically with the tick row above the region. The label tab is
|
|
5
5
|
// reserved 18 px above the first region; subsequent regions are
|
|
6
6
|
// separated by GAP_BETWEEN_REGIONS px.
|
|
7
|
-
import {
|
|
7
|
+
import { translateSwimlaneY } from '../chart-translation.js';
|
|
8
8
|
import { includeChromeGeometry } from '../include-chrome-geometry.js';
|
|
9
|
+
import { createLayoutContext } from '../layout-context.js';
|
|
9
10
|
import { resolveStyle } from '../style-resolution.js';
|
|
11
|
+
import { seedWaveEdges } from '../wave-layout.js';
|
|
12
|
+
import { maxLeafItemRightX } from './content-extent.js';
|
|
13
|
+
import { indexFootnotes } from './footnote-node.js';
|
|
14
|
+
import { placeRegionMarkers, regionMarkerLabelsRightX, seedRegionAnchorEdges, } from './region-markers.js';
|
|
10
15
|
import { SwimlaneNode } from './swimlane-node.js';
|
|
11
16
|
const TAB_RESERVE = 18;
|
|
12
17
|
const REGION_INSET_TOP = 14;
|
|
13
18
|
const REGION_INSET_BOTTOM = 14;
|
|
14
19
|
const GAP_BETWEEN_REGIONS = 16;
|
|
15
20
|
// Visual breathing room added past the rightmost element when sizing
|
|
16
|
-
// the include's bounding box.
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
+
// the include's bounding box. The rightmost element is the diagram's, not
|
|
22
|
+
// the region's own: every region reaches the same edge, past the furthest
|
|
23
|
+
// bar, spilled caption, marker or now-line anywhere in the chart. The
|
|
24
|
+
// renderer insets the dashed rect by 8 px, so its edge sits 16 px past it.
|
|
25
|
+
const INCLUDE_CONTENT_RIGHT_PAD_PX = 24;
|
|
26
|
+
export function buildIncludeRegions(regions, ctx, startY, helpers, chartRightX) {
|
|
21
27
|
let y = startY + TAB_RESERVE;
|
|
22
28
|
const out = [];
|
|
29
|
+
const contexts = [];
|
|
23
30
|
let isFirst = true;
|
|
31
|
+
// Region footnotes number on after the host's, in include order.
|
|
32
|
+
let footnotesBefore = ctx.footnoteIndex.size;
|
|
24
33
|
for (const region of regions) {
|
|
25
34
|
if (!isFirst)
|
|
26
35
|
y += GAP_BETWEEN_REGIONS;
|
|
27
36
|
isFirst = false;
|
|
28
37
|
const label = region.content.roadmap?.title ?? region.sourcePath;
|
|
29
38
|
const innerStartY = y + REGION_INSET_TOP;
|
|
30
|
-
const childCtx = {
|
|
39
|
+
const childCtx = createLayoutContext(region, {
|
|
40
|
+
theme: ctx.styleCtx.theme,
|
|
31
41
|
cal: ctx.cal,
|
|
32
|
-
|
|
33
|
-
theme: ctx.styleCtx.theme,
|
|
34
|
-
styles: region.config.styles,
|
|
35
|
-
defaults: region.config.defaults,
|
|
36
|
-
labels: region.content.labels,
|
|
37
|
-
},
|
|
38
|
-
// Each include region declares its own sizes; resolve them under
|
|
39
|
-
// the parent's calendar so child sized items render at the same
|
|
40
|
-
// pixels-per-day scale as the host roadmap.
|
|
41
|
-
sizes: resolveSizes(region.content.sizes, ctx.cal),
|
|
42
|
-
labels: region.content.labels,
|
|
43
|
-
teams: region.content.teams,
|
|
44
|
-
persons: region.content.persons,
|
|
45
|
-
symbols: region.config.symbols,
|
|
46
|
-
footnoteIndex: new Map(),
|
|
47
|
-
footnoteHosts: new Map(),
|
|
42
|
+
schedule: ctx.schedule,
|
|
48
43
|
timeline: ctx.timeline,
|
|
49
44
|
scale: ctx.scale,
|
|
50
45
|
calendar: ctx.calendar,
|
|
46
|
+
axisColumns: ctx.axisColumns,
|
|
51
47
|
bandScale: ctx.bandScale,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
entityMidpoints: new Map(),
|
|
55
|
-
entityVisualLeftX: new Map(),
|
|
56
|
-
entityVisualRightX: new Map(),
|
|
57
|
-
itemArrowSource: new Map(),
|
|
58
|
-
itemFlowKey: new Map(),
|
|
59
|
-
currentFlowKey: '',
|
|
60
|
-
itemSlackAttachY: new Map(),
|
|
61
|
-
slackCorridors: [],
|
|
62
|
-
markerRowPlacements: new Map(),
|
|
48
|
+
waves: ctx.waves,
|
|
49
|
+
}, {
|
|
63
50
|
chartTopY: innerStartY,
|
|
64
51
|
chartBottomY: innerStartY,
|
|
65
52
|
swimlaneBottomY: innerStartY,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
53
|
+
}, { footnotes: indexFootnotes(region.content.footnotes, footnotesBefore) });
|
|
54
|
+
footnotesBefore += region.content.footnotes.size;
|
|
55
|
+
// Region ids stay invisible to the host, but the wave edges are
|
|
56
|
+
// shared: seed them into the region's otherwise empty edge maps.
|
|
57
|
+
// Without waves, the region's own dated anchors resolve inside it
|
|
58
|
+
// instead, as engine C's `scheduleRegion` resolves them, so a lane
|
|
59
|
+
// `after:kickoff` naming the region's anchor starts on its date
|
|
60
|
+
// (specs/scheduler-unification.md §5 F5).
|
|
61
|
+
if (ctx.waves) {
|
|
62
|
+
seedWaveEdges(ctx.waves, childCtx.entityLeftEdges, childCtx.entityRightEdges);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
seedRegionAnchorEdges(region.content.anchors, childCtx);
|
|
66
|
+
}
|
|
70
67
|
const nestedSwimlanes = [];
|
|
71
68
|
let cursorY = innerStartY;
|
|
72
69
|
let bandIndex = 0;
|
|
73
|
-
let nestedContentRightX = childCtx.timeline.originX;
|
|
74
70
|
for (const lane of region.content.swimlanes.values()) {
|
|
75
71
|
childCtx.nextParallelId = 0;
|
|
76
72
|
childCtx.nextGroupId = 0;
|
|
77
|
-
const { positioned, usedHeight
|
|
73
|
+
const { positioned, usedHeight } = new SwimlaneNode({ lane, bandIndex }, helpers).place({ x: childCtx.timeline.originX, y: cursorY }, childCtx);
|
|
78
74
|
nestedSwimlanes.push(positioned);
|
|
79
75
|
cursorY += usedHeight;
|
|
80
76
|
bandIndex++;
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
}
|
|
78
|
+
// The region's own anchors and milestones take a marker row under
|
|
79
|
+
// its label tab, and the lanes move down below it.
|
|
80
|
+
const markers = placeRegionMarkers(region, childCtx, y, innerStartY, cursorY, chartRightX);
|
|
81
|
+
if (markers.laneShift !== 0) {
|
|
82
|
+
for (const lane of nestedSwimlanes)
|
|
83
|
+
translateSwimlaneY(lane, markers.laneShift);
|
|
84
|
+
cursorY += markers.laneShift;
|
|
83
85
|
}
|
|
84
86
|
const innerEndY = cursorY;
|
|
85
87
|
// Floor the region height to one row's bandwidth so an empty or
|
|
86
88
|
// tiny include still presents as a visible band — `bandwidth()`
|
|
87
89
|
// tracks whatever the host theme uses for swimlane row height.
|
|
88
90
|
const regionHeight = Math.max(ctx.bandScale.bandwidth(), innerEndY - y + REGION_INSET_BOTTOM);
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
// gets clamped to the chart's natural right edge so it never
|
|
93
|
-
// extends into the attribution / right-margin area.
|
|
94
|
-
const boxX = 0;
|
|
95
|
-
const { chromeRightX } = includeChromeGeometry(boxX, label, region.sourcePath);
|
|
96
|
-
const naturalRightX = Math.max(chromeRightX, nestedContentRightX) + INCLUDE_CONTENT_RIGHT_PAD_PX;
|
|
97
|
-
const boxWidth = Math.min(ctx.chartRightX - boxX, naturalRightX - boxX);
|
|
91
|
+
// The width waits for the final canvas: finalize (f4) fits every
|
|
92
|
+
// kept region with `fitIncludeRegionWidth` once the canvas stops
|
|
93
|
+
// growing, so placement never reads the canvas.
|
|
98
94
|
const box = {
|
|
99
|
-
x:
|
|
95
|
+
x: 0,
|
|
100
96
|
y,
|
|
101
|
-
width:
|
|
97
|
+
width: 0,
|
|
102
98
|
height: regionHeight,
|
|
103
99
|
};
|
|
104
|
-
|
|
105
|
-
// tinted background fits inside the dashed bracket instead of
|
|
106
|
-
// bleeding past it on the right.
|
|
107
|
-
for (const lane of nestedSwimlanes) {
|
|
108
|
-
lane.box.width = boxWidth;
|
|
109
|
-
}
|
|
110
|
-
out.push({
|
|
100
|
+
const positioned = {
|
|
111
101
|
sourcePath: region.sourcePath,
|
|
112
102
|
label,
|
|
113
103
|
box,
|
|
114
104
|
nestedSwimlanes,
|
|
115
105
|
style: resolveStyle('swimlane', [], ctx.styleCtx),
|
|
116
|
-
}
|
|
106
|
+
};
|
|
107
|
+
if (markers.anchors.length > 0)
|
|
108
|
+
positioned.anchors = markers.anchors;
|
|
109
|
+
if (markers.milestones.length > 0)
|
|
110
|
+
positioned.milestones = markers.milestones;
|
|
111
|
+
out.push(positioned);
|
|
112
|
+
contexts.push(childCtx);
|
|
117
113
|
y += regionHeight;
|
|
118
114
|
}
|
|
119
|
-
return { regions: out, endY: y };
|
|
115
|
+
return { regions: out, contexts, endY: y };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Size an include's bounding box to the diagram's content: it reaches past
|
|
119
|
+
* `contentRightX`, the furthest bar, spilled caption, marker or now-line
|
|
120
|
+
* anywhere in the chart (and past its own chrome), by a small right pad,
|
|
121
|
+
* so every region in a chart ends at the same edge (specs/rendering.md,
|
|
122
|
+
* Included Roadmaps). It is clamped to `chartRightX`;
|
|
123
|
+
* finalize grows the canvas to hold the pad first (f3). Finalize runs it
|
|
124
|
+
* once per kept region (f4), after the canvas width is final: the spill
|
|
125
|
+
* growth, the timeline extension and the marker labels can all still grow
|
|
126
|
+
* the canvas after the region is placed.
|
|
127
|
+
*/
|
|
128
|
+
export function fitIncludeRegionWidth(region, chartRightX, contentRightX) {
|
|
129
|
+
const boxWidth = includeRegionWidth(region, chartRightX, contentRightX);
|
|
130
|
+
region.box.width = boxWidth;
|
|
131
|
+
// Mirror the shrunk width onto each nested swimlane band so the
|
|
132
|
+
// tinted background fits inside the dashed bracket instead of
|
|
133
|
+
// bleeding past it on the right.
|
|
134
|
+
for (const lane of region.nestedSwimlanes) {
|
|
135
|
+
lane.box.width = boxWidth;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* The width `fitIncludeRegionWidth` gives `region` on a canvas ending at
|
|
140
|
+
* `chartRightX`, with the diagram's content ending at `contentRightX`.
|
|
141
|
+
*/
|
|
142
|
+
export function includeRegionWidth(region, chartRightX, contentRightX) {
|
|
143
|
+
const boxX = region.box.x;
|
|
144
|
+
const { chromeRightX } = includeChromeGeometry(boxX, region.label, region.sourcePath);
|
|
145
|
+
// Bars-only extent (never a spilled caption — see
|
|
146
|
+
// `maxLeafItemRightX`), so a long trailing item caption inside
|
|
147
|
+
// the include can overhang the dashed bracket instead of
|
|
148
|
+
// dragging it wider.
|
|
149
|
+
const barsRightX = maxLeafItemRightX(region.nestedSwimlanes);
|
|
150
|
+
const naturalRightX = Math.max(chromeRightX, barsRightX, regionMarkerLabelsRightX(region), contentRightX) +
|
|
151
|
+
INCLUDE_CONTENT_RIGHT_PAD_PX;
|
|
152
|
+
return Math.min(chartRightX - boxX, naturalRightX - boxX);
|
|
120
153
|
}
|
|
121
154
|
//# sourceMappingURL=include-node.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"include-node.js","sourceRoot":"","sources":["../../src/nodes/include-node.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,qEAAqE;AACrE,kEAAkE;AAClE,kEAAkE;AAClE,gEAAgE;AAChE,uCAAuC;
|
|
1
|
+
{"version":3,"file":"include-node.js","sourceRoot":"","sources":["../../src/nodes/include-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import type { EntityProperty, ItemDeclaration, LabelDeclaration } from '@nowline/core';
|
|
2
|
+
import { type ChipRowSample, type SpillChipPack } from '../item-bar-geometry.js';
|
|
3
|
+
import { type LayoutContext } from '../layout-context.js';
|
|
4
|
+
import { type StyleContext } from '../style-resolution.js';
|
|
5
|
+
import type { LinkIconKind, PositionedCapacity, PositionedLabelChip, ResolvedSize, ResolvedStyle, StatusKind } from '../types.js';
|
|
6
|
+
import { type ItemCaptionMeasure, type ItemNodeGeometry } from './item-node.js';
|
|
7
|
+
/** A label chip measured at its natural width, before it is placed. */
|
|
8
|
+
export type ChipSample = ChipRowSample<LabelDeclaration>;
|
|
9
|
+
export interface ResolvedItemMeta {
|
|
10
|
+
/** Secondary line text under the title, or undefined when none. */
|
|
11
|
+
metaText: string | undefined;
|
|
12
|
+
ownerDisplay: string | undefined;
|
|
13
|
+
capacity: PositionedCapacity | null;
|
|
14
|
+
/** Estimated px width of the capacity suffix (incl. its separator). */
|
|
15
|
+
capacityTrailingWidth: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ItemMeasure extends ItemNodeGeometry {
|
|
18
|
+
node: ItemDeclaration;
|
|
19
|
+
/** The snapped start the bar is measured at (`ctx.scale.startX`). */
|
|
20
|
+
startX: number;
|
|
21
|
+
durationDays: number;
|
|
22
|
+
/** Logical width: the item's span in time. */
|
|
23
|
+
naturalWidth: number;
|
|
24
|
+
/**
|
|
25
|
+
* The bar box width: the logical extent `(startX + naturalWidth) -
|
|
26
|
+
* startX` less the insets, as `ItemNode` has always computed it. The
|
|
27
|
+
* caption fit, the narrow-bar spills and the chip pack read it.
|
|
28
|
+
*/
|
|
29
|
+
visualWidth: number;
|
|
30
|
+
/**
|
|
31
|
+
* `naturalWidth` less the insets. Equal to `visualWidth` up to the
|
|
32
|
+
* rounding of the logical extent; the inside-chip fit and the title's
|
|
33
|
+
* first-line reserve read this one, as they always have.
|
|
34
|
+
*/
|
|
35
|
+
naturalVisualWidth: number;
|
|
36
|
+
/** Resolved style with the status tint applied (a copy, never the shared object). */
|
|
37
|
+
style: ResolvedStyle;
|
|
38
|
+
/** The `size:` declaration the item names, or null. */
|
|
39
|
+
size: ResolvedSize | null;
|
|
40
|
+
status: StatusKind;
|
|
41
|
+
progress: number;
|
|
42
|
+
meta: ResolvedItemMeta;
|
|
43
|
+
link: {
|
|
44
|
+
icon: LinkIconKind;
|
|
45
|
+
href?: string;
|
|
46
|
+
};
|
|
47
|
+
chips: {
|
|
48
|
+
samples: ChipSample[];
|
|
49
|
+
outside: boolean;
|
|
50
|
+
pack: SpillChipPack<LabelDeclaration> | null;
|
|
51
|
+
rowCount: number;
|
|
52
|
+
};
|
|
53
|
+
footnoteIndicators: number[];
|
|
54
|
+
caption: ItemCaptionMeasure & {
|
|
55
|
+
/** The title as declared (`title ?? name ?? ''`). */
|
|
56
|
+
title: string;
|
|
57
|
+
/** A narrow bar pushes the link icon, and with it the caption, out of the bar. */
|
|
58
|
+
iconSpills: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* The lines the title paints on (see `resolveCaptionTitleLines`),
|
|
61
|
+
* each truncated with `…` when the spilled caption is capped at the
|
|
62
|
+
* chart's end (`capCaptionAtAxisEnd`).
|
|
63
|
+
*/
|
|
64
|
+
lines: string[];
|
|
65
|
+
/** True when the cap truncated a line; the full title stays the bar's tooltip. */
|
|
66
|
+
truncated: boolean;
|
|
67
|
+
/** Baseline of the caption's last line, px from the bar's top. */
|
|
68
|
+
lastBaseline: number;
|
|
69
|
+
};
|
|
70
|
+
/** Growth over the band height: max(title extra, chip extra). */
|
|
71
|
+
barExtra: number;
|
|
72
|
+
}
|
|
73
|
+
export declare function statusFromProp(raw: string | undefined): StatusKind;
|
|
74
|
+
export declare function parseLinkIcon(link: string | undefined): {
|
|
75
|
+
icon: LinkIconKind;
|
|
76
|
+
href?: string;
|
|
77
|
+
};
|
|
78
|
+
export declare function buildLabelChip(label: LabelDeclaration, ctx: StyleContext, x: number, y: number, maxWidth?: number): PositionedLabelChip;
|
|
79
|
+
/**
|
|
80
|
+
* Status kind and 0..1 progress fraction for an item: a pure function of
|
|
81
|
+
* the item's properties and the layout scope.
|
|
82
|
+
*/
|
|
83
|
+
export declare function resolveItemProgress(props: EntityProperty[], ctx: LayoutContext): {
|
|
84
|
+
status: StatusKind;
|
|
85
|
+
progress: number;
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Assemble an item's meta line and capacity suffix. The caption fit needs
|
|
89
|
+
* the real meta width to know whether a title wraps or spills, and
|
|
90
|
+
* `sequenceItem` paints from the same result.
|
|
91
|
+
*/
|
|
92
|
+
export declare function resolveItemMeta(props: EntityProperty[], ctx: LayoutContext, sizeResolved: ResolvedSize | null, status: StatusKind, progress: number, capacityIconName: string): ResolvedItemMeta;
|
|
93
|
+
/**
|
|
94
|
+
* Footnote numbers attached to an item, ascending. Per `specs/dsl.md`,
|
|
95
|
+
* footnotes attach via the `on:` property on the footnote declaration
|
|
96
|
+
* only — there is no forward `footnote:` property on the host entity.
|
|
97
|
+
* Walk `footnoteHosts` (built from each footnote's `on:` list) and
|
|
98
|
+
* collect every footnote that names this item. The caption fit needs
|
|
99
|
+
* them, since the indicators narrow the title's first line.
|
|
100
|
+
*/
|
|
101
|
+
export declare function collectItemFootnoteIndicators(name: string | undefined, ctx: LayoutContext): number[];
|
|
102
|
+
/**
|
|
103
|
+
* How far the title's first line must stay from the bar's right edge so
|
|
104
|
+
* it clears the top-right decoration cluster.
|
|
105
|
+
*/
|
|
106
|
+
export declare function resolveTitleFirstLineReserve(barWidth: number, footnoteIndicators: readonly number[], beforeRaw: readonly string[]): number;
|
|
107
|
+
/**
|
|
108
|
+
* Compute the extra vertical px the bar grows to fit its label chips
|
|
109
|
+
* (a spilled chip column, or inside-bar chips stacked below a caption
|
|
110
|
+
* that reaches past the default chip row). The bar's painted footprint
|
|
111
|
+
* becomes `bandwidth + chipBarExtra`, the progress strip rides the new
|
|
112
|
+
* bottom, and chip rows pack inside the taller bar (anchored from the
|
|
113
|
+
* bar TOP so row 0 doesn't shift when the bar grows).
|
|
114
|
+
*
|
|
115
|
+
* Returns 0 when chips fit inside the bar, when there are no chips,
|
|
116
|
+
* or when the spilled column happens to fit inside `bandwidth` (a
|
|
117
|
+
* single row with the caption inside, for instance).
|
|
118
|
+
*
|
|
119
|
+
* `captionLastBaseline` is the in-bar caption's last text baseline
|
|
120
|
+
* (px from the bar's top): the meta baseline when the item has a meta
|
|
121
|
+
* line, otherwise the last title line's baseline. A wrapped title
|
|
122
|
+
* pushes it down; see `itemCaptionLastBaselineOffset`.
|
|
123
|
+
*
|
|
124
|
+
* The bar's final growth is `max(titleBarExtra, chipBarExtra)`; the
|
|
125
|
+
* same number is the row-pitch increase the swimlane / group
|
|
126
|
+
* row-packer reserves so the next row clears the taller bar.
|
|
127
|
+
*/
|
|
128
|
+
export declare function computeChipBarExtra(chipsOutside: boolean, captionSpills: boolean, chipRowCount: number, bandwidth: number, captionLastBaseline: number): number;
|
|
129
|
+
/**
|
|
130
|
+
* Measure `node` as a bar starting at `startX`, the snapped start
|
|
131
|
+
* (`ctx.scale.startX`) it will be placed at. Pure: it writes nothing to
|
|
132
|
+
* `ctx`.
|
|
133
|
+
*/
|
|
134
|
+
export declare function measureItem(node: ItemDeclaration, startX: number, ctx: LayoutContext): ItemMeasure;
|
|
135
|
+
//# sourceMappingURL=item-measure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"item-measure.d.ts","sourceRoot":"","sources":["../../src/nodes/item-measure.ts"],"names":[],"mappings":"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"}
|