@nowline/layout 0.0.0-dev.20261016061049.g87033e4 → 0.0.0-dev.20261016123749.g5260133
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/layout-context.d.ts +2 -1
- package/dist/layout-context.d.ts.map +1 -1
- package/dist/layout-context.js +2 -1
- package/dist/layout-context.js.map +1 -1
- package/dist/nodes/footnote-node.d.ts +23 -5
- package/dist/nodes/footnote-node.d.ts.map +1 -1
- package/dist/nodes/footnote-node.js +126 -25
- package/dist/nodes/footnote-node.js.map +1 -1
- package/dist/nodes/include-node.d.ts +2 -1
- package/dist/nodes/include-node.d.ts.map +1 -1
- package/dist/nodes/include-node.js +27 -27
- package/dist/nodes/include-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 +123 -0
- package/dist/nodes/region-markers.js.map +1 -0
- package/dist/phases/finalize.d.ts.map +1 -1
- package/dist/phases/finalize.js +34 -5
- package/dist/phases/finalize.js.map +1 -1
- package/dist/phases/place.d.ts +5 -0
- package/dist/phases/place.d.ts.map +1 -1
- package/dist/phases/place.js +5 -2
- package/dist/phases/place.js.map +1 -1
- package/dist/positioned-shift.d.ts +1 -1
- package/dist/positioned-shift.d.ts.map +1 -1
- package/dist/positioned-shift.js +17 -2
- package/dist/positioned-shift.js.map +1 -1
- package/dist/themes/shared.d.ts.map +1 -1
- package/dist/themes/shared.js +4 -2
- package/dist/themes/shared.js.map +1 -1
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/layout-context.ts +2 -1
- package/src/nodes/footnote-node.ts +161 -26
- package/src/nodes/include-node.ts +30 -26
- package/src/nodes/region-markers.ts +185 -0
- package/src/phases/finalize.ts +41 -10
- package/src/phases/place.ts +16 -1
- package/src/positioned-shift.ts +15 -2
- package/src/themes/shared.ts +4 -2
- package/src/types.ts +40 -0
package/dist/layout-context.d.ts
CHANGED
|
@@ -170,7 +170,8 @@ export interface ContextSource {
|
|
|
170
170
|
* `chartTopY` from the timeline with both bottoms at 0, a region sets all
|
|
171
171
|
* three y fields to its inner start. The canvas width is not part of a
|
|
172
172
|
* context: placement never reads it (finalize owns the `CanvasExtent`).
|
|
173
|
-
* A region passes
|
|
173
|
+
* A region passes its own footnote index, numbered on after the host's,
|
|
174
|
+
* and no marker placements. The caller seeds
|
|
174
175
|
* the wave edges.
|
|
175
176
|
*/
|
|
176
177
|
export declare function createLayoutContext(source: ContextSource, shared: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-context.d.ts","sourceRoot":"","sources":["../src/layout-context.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"layout-context.d.ts","sourceRoot":"","sources":["../src/layout-context.ts"],"names":[],"mappings":"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"}
|
package/dist/layout-context.js
CHANGED
|
@@ -26,7 +26,8 @@ export function scheduledItemDays(ctx, item) {
|
|
|
26
26
|
* `chartTopY` from the timeline with both bottoms at 0, a region sets all
|
|
27
27
|
* three y fields to its inner start. The canvas width is not part of a
|
|
28
28
|
* context: placement never reads it (finalize owns the `CanvasExtent`).
|
|
29
|
-
* A region passes
|
|
29
|
+
* A region passes its own footnote index, numbered on after the host's,
|
|
30
|
+
* and no marker placements. The caller seeds
|
|
30
31
|
* the wave edges.
|
|
31
32
|
*/
|
|
32
33
|
export function createLayoutContext(source, shared, chart, init) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-context.js","sourceRoot":"","sources":["../src/layout-context.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,yEAAyE;AACzE,0EAA0E;AAC1E,8BAA8B;AAa9B,OAAO,EAAwB,YAAY,EAAE,MAAM,eAAe,CAAC;AAsCnE,MAAM,UAAU,SAAS,CAAC,CAAS,EAAE,CAAS;IAC1C,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACxC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAkB,EAAE,IAAqB;IACvE,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChD,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACX,iBAAiB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,IAAI,WAAW,8BAA8B,CACxF,CAAC;IACN,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,CAAC;AAC1B,CAAC;AAkID
|
|
1
|
+
{"version":3,"file":"layout-context.js","sourceRoot":"","sources":["../src/layout-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,31 @@
|
|
|
1
1
|
import type { FootnoteDeclaration } from '@nowline/core';
|
|
2
2
|
import type { LayoutContext } from '../layout-context.js';
|
|
3
3
|
import type { PositionedFootnoteArea } from '../types.js';
|
|
4
|
-
/** Each footnote's 1-based number (
|
|
4
|
+
/** Each footnote's 1-based number (in document order) and its `on:` host ids. */
|
|
5
5
|
export interface FootnoteIndex {
|
|
6
6
|
index: Map<string, number>;
|
|
7
7
|
hosts: Map<string, string[]>;
|
|
8
8
|
}
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Pure: depends only on the footnote declarations. Numbers start after
|
|
11
|
+
* `precedingCount` (an isolated region continues after the host and the
|
|
12
|
+
* regions before it). The map's order is document order: the resolver
|
|
13
|
+
* inserts a file's own footnotes as declared, then each merged include's.
|
|
14
|
+
*/
|
|
15
|
+
export declare function indexFootnotes(footnotes: Map<string, FootnoteDeclaration>, precedingCount?: number): FootnoteIndex;
|
|
16
|
+
/** An isolated region's footnotes, numbered and styled by its own context. */
|
|
17
|
+
export interface RegionFootnotes {
|
|
18
|
+
/** The region's title, as on its label tab. */
|
|
19
|
+
title: string;
|
|
20
|
+
footnotes: Map<string, FootnoteDeclaration>;
|
|
21
|
+
ctx: LayoutContext;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The panel below the chart, spanning the final canvas (`chartRightX`):
|
|
25
|
+
* the host's footnotes, then each region's under its title, each in
|
|
26
|
+
* document order. The canvas does not grow for the panel: an entry whose
|
|
27
|
+
* title or description runs past the panel's inner right edge wraps onto
|
|
28
|
+
* more rows, which start at the title's x and use the whole width.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildFootnotePanel(footnotes: Map<string, FootnoteDeclaration>, ctx: LayoutContext, chartBottomY: number, chartRightX: number, regions?: readonly RegionFootnotes[]): PositionedFootnoteArea;
|
|
13
31
|
//# sourceMappingURL=footnote-node.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footnote-node.d.ts","sourceRoot":"","sources":["../../src/nodes/footnote-node.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"footnote-node.d.ts","sourceRoot":"","sources":["../../src/nodes/footnote-node.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAQ1D,OAAO,KAAK,EAER,sBAAsB,EAGzB,MAAM,aAAa,CAAC;AAErB,iFAAiF;AACjF,MAAM,WAAW,aAAa;IAC1B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAC3C,cAAc,SAAI,GACnB,aAAa,CAQf;AAED,8EAA8E;AAC9E,MAAM,WAAW,eAAe;IAC5B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IAC5C,GAAG,EAAE,aAAa,CAAC;CACtB;AAUD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAC9B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAC3C,GAAG,EAAE,aAAa,EAClB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,SAAS,eAAe,EAAO,GACzC,sBAAsB,CA0DxB"}
|
|
@@ -1,44 +1,145 @@
|
|
|
1
1
|
// FootnoteNode + indexFootnotes / buildFootnotePanel — footnote area at the bottom of the
|
|
2
|
-
// chart. Each footnote gets a stable index (1-based,
|
|
2
|
+
// chart. Each footnote gets a stable index (1-based, in document order) and
|
|
3
3
|
// records its `on:` host references so item / swimlane sequencing can
|
|
4
|
-
// emit the matching superscript indicators.
|
|
5
|
-
//
|
|
4
|
+
// emit the matching superscript indicators. An isolated region's
|
|
5
|
+
// footnotes continue the numbering after the host's, in include order,
|
|
6
|
+
// and share the one panel under a heading row with the region's title.
|
|
7
|
+
// An entry whose text does not fit the panel's width wraps onto more
|
|
8
|
+
// rows at the title's x. The panel grows to fit: 28 px header + (entry
|
|
9
|
+
// rows and region headings × FOOTNOTE_ROW_HEIGHT) + 16 px padding.
|
|
6
10
|
import { propValues } from '../dsl-utils.js';
|
|
7
11
|
import { resolveStyle } from '../style-resolution.js';
|
|
12
|
+
import { estimateTextWidth, wrapText } from '../text-measure.js';
|
|
8
13
|
import { FOOTNOTE_HEADER_HEIGHT_PX, FOOTNOTE_PANEL_PADDING_PX, FOOTNOTE_ROW_HEIGHT, } from '../themes/shared.js';
|
|
9
|
-
/**
|
|
10
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Pure: depends only on the footnote declarations. Numbers start after
|
|
16
|
+
* `precedingCount` (an isolated region continues after the host and the
|
|
17
|
+
* regions before it). The map's order is document order: the resolver
|
|
18
|
+
* inserts a file's own footnotes as declared, then each merged include's.
|
|
19
|
+
*/
|
|
20
|
+
export function indexFootnotes(footnotes, precedingCount = 0) {
|
|
11
21
|
const index = new Map();
|
|
12
22
|
const hosts = new Map();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
index.set(id, i + 1);
|
|
23
|
+
[...footnotes.entries()].forEach(([id, f], i) => {
|
|
24
|
+
index.set(id, precedingCount + i + 1);
|
|
16
25
|
hosts.set(id, propValues(f.properties, 'on'));
|
|
17
26
|
});
|
|
18
27
|
return { index, hosts };
|
|
19
28
|
}
|
|
20
|
-
/**
|
|
21
|
-
|
|
29
|
+
/** Font sizes (px) of an entry's title and description. */
|
|
30
|
+
const FOOTNOTE_TEXT_FONT_SIZE_PX = 11;
|
|
31
|
+
/** The description column never starts closer than this to the title's x. */
|
|
32
|
+
const FOOTNOTE_DESCRIPTION_MIN_OFFSET_PX = 120;
|
|
33
|
+
/** Per-character advance the description column is placed by. */
|
|
34
|
+
const FOOTNOTE_TITLE_CHAR_ADVANCE_PX = 6;
|
|
35
|
+
const DESCRIPTION_LEAD = '— ';
|
|
36
|
+
/**
|
|
37
|
+
* The panel below the chart, spanning the final canvas (`chartRightX`):
|
|
38
|
+
* the host's footnotes, then each region's under its title, each in
|
|
39
|
+
* document order. The canvas does not grow for the panel: an entry whose
|
|
40
|
+
* title or description runs past the panel's inner right edge wraps onto
|
|
41
|
+
* more rows, which start at the title's x and use the whole width.
|
|
42
|
+
*/
|
|
43
|
+
export function buildFootnotePanel(footnotes, ctx, chartBottomY, chartRightX, regions = []) {
|
|
44
|
+
const boxX = FOOTNOTE_PANEL_PADDING_PX;
|
|
45
|
+
const boxY = chartBottomY + FOOTNOTE_PANEL_PADDING_PX;
|
|
46
|
+
const boxWidth = chartRightX - 2 * FOOTNOTE_PANEL_PADDING_PX;
|
|
47
|
+
const titleX = boxX + 2 * FOOTNOTE_PANEL_PADDING_PX;
|
|
48
|
+
const textRightX = boxX + boxWidth - FOOTNOTE_PANEL_PADDING_PX;
|
|
49
|
+
const firstRowY = boxY + FOOTNOTE_HEADER_HEIGHT_PX + FOOTNOTE_PANEL_PADDING_PX;
|
|
22
50
|
const entries = [];
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
51
|
+
let row = 0;
|
|
52
|
+
const add = (decls, source, region) => {
|
|
53
|
+
for (const [id, f] of decls) {
|
|
54
|
+
const title = f.title ?? id;
|
|
55
|
+
const description = f.description?.text;
|
|
56
|
+
const lines = entryLines(title, description, titleX, textRightX);
|
|
57
|
+
const y = firstRowY + row * FOOTNOTE_ROW_HEIGHT;
|
|
58
|
+
const at = (l) => ({
|
|
59
|
+
x: l.x,
|
|
60
|
+
y: y + l.row * FOOTNOTE_ROW_HEIGHT,
|
|
61
|
+
text: l.text,
|
|
62
|
+
});
|
|
63
|
+
const entry = {
|
|
64
|
+
number: source.footnoteIndex.get(id) ?? entries.length + 1,
|
|
65
|
+
y,
|
|
66
|
+
title,
|
|
67
|
+
titleLines: lines.title.map(at),
|
|
68
|
+
description,
|
|
69
|
+
style: resolveStyle('footnote', f.properties, source.styleCtx),
|
|
70
|
+
};
|
|
71
|
+
if (lines.description.length > 0)
|
|
72
|
+
entry.descriptionLines = lines.description.map(at);
|
|
73
|
+
if (region !== undefined)
|
|
74
|
+
entry.region = region;
|
|
75
|
+
entries.push(entry);
|
|
76
|
+
row += lines.rows;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
add(footnotes, ctx);
|
|
80
|
+
for (const r of regions) {
|
|
81
|
+
if (r.footnotes.size === 0)
|
|
82
|
+
continue;
|
|
83
|
+
// The region's heading takes a row of its own above its entries.
|
|
84
|
+
const headingY = firstRowY + row * FOOTNOTE_ROW_HEIGHT;
|
|
85
|
+
row += 1;
|
|
86
|
+
const first = entries.length;
|
|
87
|
+
add(r.footnotes, r.ctx, r.title);
|
|
88
|
+
entries[first].regionHeadingY = headingY;
|
|
89
|
+
}
|
|
32
90
|
const box = {
|
|
33
|
-
x:
|
|
34
|
-
y:
|
|
35
|
-
width:
|
|
91
|
+
x: boxX,
|
|
92
|
+
y: boxY,
|
|
93
|
+
width: boxWidth,
|
|
36
94
|
height: entries.length === 0
|
|
37
95
|
? 0
|
|
38
|
-
: FOOTNOTE_HEADER_HEIGHT_PX +
|
|
39
|
-
entries.length * FOOTNOTE_ROW_HEIGHT +
|
|
40
|
-
FOOTNOTE_PANEL_PADDING_PX,
|
|
96
|
+
: FOOTNOTE_HEADER_HEIGHT_PX + row * FOOTNOTE_ROW_HEIGHT + FOOTNOTE_PANEL_PADDING_PX,
|
|
41
97
|
};
|
|
42
98
|
return { box, entries };
|
|
43
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* Wrap one entry into rows. The title starts at `titleX`; the description
|
|
102
|
+
* follows on the title's row at the description column (`— ` first) and
|
|
103
|
+
* wraps at `titleX`. A wrapped title, or a description whose first word
|
|
104
|
+
* does not fit beside the title, starts the description on a row of its
|
|
105
|
+
* own. A single word wider than the panel stays whole on its row, as
|
|
106
|
+
* `wrapText` never splits a word.
|
|
107
|
+
*/
|
|
108
|
+
function entryLines(title, description, titleX, textRightX) {
|
|
109
|
+
const fullWidth = textRightX - titleX;
|
|
110
|
+
const titleRows = fitsOrWraps(title, fullWidth, fullWidth);
|
|
111
|
+
const titleLines = titleRows.map((text, row) => ({ x: titleX, row, text }));
|
|
112
|
+
if (!description)
|
|
113
|
+
return { title: titleLines, description: [], rows: titleRows.length };
|
|
114
|
+
const leadWidth = estimateTextWidth(DESCRIPTION_LEAD, FOOTNOTE_TEXT_FONT_SIZE_PX);
|
|
115
|
+
const firstWord = description.trim().split(/\s+/)[0] ?? '';
|
|
116
|
+
const columnX = titleX +
|
|
117
|
+
Math.max(FOOTNOTE_DESCRIPTION_MIN_OFFSET_PX, title.length * FOOTNOTE_TITLE_CHAR_ADVANCE_PX);
|
|
118
|
+
const besideTitle = titleRows.length === 1 &&
|
|
119
|
+
leadWidth + estimateTextWidth(firstWord, FOOTNOTE_TEXT_FONT_SIZE_PX) <=
|
|
120
|
+
textRightX - columnX;
|
|
121
|
+
const firstX = besideTitle ? columnX : titleX;
|
|
122
|
+
const firstRow = besideTitle ? titleRows.length - 1 : titleRows.length;
|
|
123
|
+
const rows = fitsOrWraps(description, fullWidth, textRightX - firstX - leadWidth);
|
|
124
|
+
const descriptionLines = rows.map((text, i) => ({
|
|
125
|
+
x: i === 0 ? firstX : titleX,
|
|
126
|
+
row: firstRow + i,
|
|
127
|
+
text: i === 0 ? `${DESCRIPTION_LEAD}${text}` : text,
|
|
128
|
+
}));
|
|
129
|
+
return {
|
|
130
|
+
title: titleLines,
|
|
131
|
+
description: descriptionLines,
|
|
132
|
+
rows: firstRow + rows.length,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* `text` as is when it fits `firstWidth`, else wrapped (`wrapText`, which
|
|
137
|
+
* collapses whitespace), so an entry that fits keeps its exact text.
|
|
138
|
+
*/
|
|
139
|
+
function fitsOrWraps(text, width, firstWidth) {
|
|
140
|
+
if (estimateTextWidth(text, FOOTNOTE_TEXT_FONT_SIZE_PX) <= firstWidth)
|
|
141
|
+
return [text];
|
|
142
|
+
const rows = wrapText(text, width, FOOTNOTE_TEXT_FONT_SIZE_PX, firstWidth);
|
|
143
|
+
return rows.length > 0 ? rows : [text];
|
|
144
|
+
}
|
|
44
145
|
//# sourceMappingURL=footnote-node.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"footnote-node.js","sourceRoot":"","sources":["../../src/nodes/footnote-node.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,
|
|
1
|
+
{"version":3,"file":"footnote-node.js","sourceRoot":"","sources":["../../src/nodes/footnote-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { IsolatedRegion } from '@nowline/core';
|
|
2
2
|
import { type LayoutContext, type LayoutHelpers } from '../layout-context.js';
|
|
3
3
|
import type { PositionedIncludeRegion } from '../types.js';
|
|
4
|
-
export declare function buildIncludeRegions(regions: IsolatedRegion[], ctx: LayoutContext, startY: number, helpers: LayoutHelpers): {
|
|
4
|
+
export declare function buildIncludeRegions(regions: IsolatedRegion[], ctx: LayoutContext, startY: number, helpers: LayoutHelpers, chartRightX: number): {
|
|
5
5
|
regions: PositionedIncludeRegion[];
|
|
6
|
+
contexts: LayoutContext[];
|
|
6
7
|
endY: number;
|
|
7
8
|
};
|
|
8
9
|
/**
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;AAEpD,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGnG,OAAO,KAAK,EAAe,uBAAuB,EAAsB,MAAM,aAAa,CAAC;AAsB5F,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;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAShG;AAED,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,uBAAuB,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAY/F"}
|
|
@@ -4,12 +4,14 @@
|
|
|
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 { parseIsoDate, propValue } from '../dsl-utils.js';
|
|
8
7
|
import { includeChromeGeometry } from '../include-chrome-geometry.js';
|
|
9
8
|
import { createLayoutContext } from '../layout-context.js';
|
|
9
|
+
import { shiftSwimlaneY } from '../positioned-shift.js';
|
|
10
10
|
import { resolveStyle } from '../style-resolution.js';
|
|
11
11
|
import { seedWaveEdges } from '../wave-layout.js';
|
|
12
12
|
import { maxLeafItemRightX } from './content-extent.js';
|
|
13
|
+
import { indexFootnotes } from './footnote-node.js';
|
|
14
|
+
import { placeRegionMarkers, regionMarkerLabelsRightX, seedRegionAnchorEdges, } from './region-markers.js';
|
|
13
15
|
import { SwimlaneNode } from './swimlane-node.js';
|
|
14
16
|
const TAB_RESERVE = 18;
|
|
15
17
|
const REGION_INSET_TOP = 14;
|
|
@@ -20,10 +22,13 @@ const GAP_BETWEEN_REGIONS = 16;
|
|
|
20
22
|
// against an item's right edge while still trimming the wide
|
|
21
23
|
// chart-width whitespace left over from full-width sizing.
|
|
22
24
|
const INCLUDE_CONTENT_RIGHT_PAD_PX = 32;
|
|
23
|
-
export function buildIncludeRegions(regions, ctx, startY, helpers) {
|
|
25
|
+
export function buildIncludeRegions(regions, ctx, startY, helpers, chartRightX) {
|
|
24
26
|
let y = startY + TAB_RESERVE;
|
|
25
27
|
const out = [];
|
|
28
|
+
const contexts = [];
|
|
26
29
|
let isFirst = true;
|
|
30
|
+
// Region footnotes number on after the host's, in include order.
|
|
31
|
+
let footnotesBefore = ctx.footnoteIndex.size;
|
|
27
32
|
for (const region of regions) {
|
|
28
33
|
if (!isFirst)
|
|
29
34
|
y += GAP_BETWEEN_REGIONS;
|
|
@@ -44,18 +49,19 @@ export function buildIncludeRegions(regions, ctx, startY, helpers) {
|
|
|
44
49
|
chartTopY: innerStartY,
|
|
45
50
|
chartBottomY: innerStartY,
|
|
46
51
|
swimlaneBottomY: innerStartY,
|
|
47
|
-
}, {});
|
|
52
|
+
}, { footnotes: indexFootnotes(region.content.footnotes, footnotesBefore) });
|
|
53
|
+
footnotesBefore += region.content.footnotes.size;
|
|
48
54
|
// Region ids stay invisible to the host, but the wave edges are
|
|
49
55
|
// shared: seed them into the region's otherwise empty edge maps.
|
|
50
56
|
// Without waves, the region's own dated anchors resolve inside it
|
|
51
57
|
// instead, as engine C's `scheduleRegion` resolves them, so a lane
|
|
52
58
|
// `after:kickoff` naming the region's anchor starts on its date
|
|
53
|
-
// (specs/scheduler-unification.md §5 F5).
|
|
59
|
+
// (specs/scheduler-unification.md §5 F5).
|
|
54
60
|
if (ctx.waves) {
|
|
55
61
|
seedWaveEdges(ctx.waves, childCtx.entityLeftEdges, childCtx.entityRightEdges);
|
|
56
62
|
}
|
|
57
63
|
else {
|
|
58
|
-
seedRegionAnchorEdges(region, childCtx);
|
|
64
|
+
seedRegionAnchorEdges(region.content.anchors, childCtx);
|
|
59
65
|
}
|
|
60
66
|
const nestedSwimlanes = [];
|
|
61
67
|
let cursorY = innerStartY;
|
|
@@ -68,6 +74,14 @@ export function buildIncludeRegions(regions, ctx, startY, helpers) {
|
|
|
68
74
|
cursorY += usedHeight;
|
|
69
75
|
bandIndex++;
|
|
70
76
|
}
|
|
77
|
+
// The region's own anchors and milestones take a marker row under
|
|
78
|
+
// its label tab, and the lanes move down below it.
|
|
79
|
+
const markers = placeRegionMarkers(region, childCtx, y, innerStartY, cursorY, chartRightX);
|
|
80
|
+
if (markers.laneShift !== 0) {
|
|
81
|
+
for (const lane of nestedSwimlanes)
|
|
82
|
+
shiftSwimlaneY(lane, markers.laneShift);
|
|
83
|
+
cursorY += markers.laneShift;
|
|
84
|
+
}
|
|
71
85
|
const innerEndY = cursorY;
|
|
72
86
|
// Floor the region height to one row's bandwidth so an empty or
|
|
73
87
|
// tiny include still presents as a visible band — `bandwidth()`
|
|
@@ -89,30 +103,15 @@ export function buildIncludeRegions(regions, ctx, startY, helpers) {
|
|
|
89
103
|
nestedSwimlanes,
|
|
90
104
|
style: resolveStyle('swimlane', [], ctx.styleCtx),
|
|
91
105
|
};
|
|
106
|
+
if (markers.anchors.length > 0)
|
|
107
|
+
positioned.anchors = markers.anchors;
|
|
108
|
+
if (markers.milestones.length > 0)
|
|
109
|
+
positioned.milestones = markers.milestones;
|
|
92
110
|
out.push(positioned);
|
|
111
|
+
contexts.push(childCtx);
|
|
93
112
|
y += regionHeight;
|
|
94
113
|
}
|
|
95
|
-
return { regions: out, endY: y };
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Seed a region's dated anchors into its context's edge maps at their x on
|
|
99
|
-
* the host's scale, the way the host seeds its own (`phases/place.ts`).
|
|
100
|
-
* Engine C resolves exactly these inside a region without waves: its
|
|
101
|
-
* milestones resolve after the region's lanes, so an item never sees them,
|
|
102
|
-
* and a wave roadmap's region walk sees only the wave edges. An anchor
|
|
103
|
-
* outside the date window is skipped, as on the host.
|
|
104
|
-
*/
|
|
105
|
-
function seedRegionAnchorEdges(region, childCtx) {
|
|
106
|
-
for (const [id, anchor] of region.content.anchors) {
|
|
107
|
-
const date = parseIsoDate(propValue(anchor.properties, 'date'));
|
|
108
|
-
if (!date)
|
|
109
|
-
continue;
|
|
110
|
-
const x = childCtx.scale.forwardWithinDomain(date);
|
|
111
|
-
if (x === null)
|
|
112
|
-
continue;
|
|
113
|
-
childCtx.entityLeftEdges.set(id, x);
|
|
114
|
-
childCtx.entityRightEdges.set(id, x);
|
|
115
|
-
}
|
|
114
|
+
return { regions: out, contexts, endY: y };
|
|
116
115
|
}
|
|
117
116
|
/**
|
|
118
117
|
* Shrink-wrap an include's bounding box to fit chrome + content (with a
|
|
@@ -142,7 +141,8 @@ export function includeRegionWidth(region, chartRightX) {
|
|
|
142
141
|
// the include can overhang the dashed bracket instead of
|
|
143
142
|
// dragging it wider.
|
|
144
143
|
const barsRightX = maxLeafItemRightX(region.nestedSwimlanes);
|
|
145
|
-
const naturalRightX = Math.max(chromeRightX, barsRightX) +
|
|
144
|
+
const naturalRightX = Math.max(chromeRightX, barsRightX, regionMarkerLabelsRightX(region)) +
|
|
145
|
+
INCLUDE_CONTENT_RIGHT_PAD_PX;
|
|
146
146
|
return Math.min(chartRightX - boxX, naturalRightX - boxX);
|
|
147
147
|
}
|
|
148
148
|
//# 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;AAGvC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"include-node.js","sourceRoot":"","sources":["../../src/nodes/include-node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { AnchorDeclaration, IsolatedRegion } from '@nowline/core';
|
|
2
|
+
import type { LayoutContext } from '../layout-context.js';
|
|
3
|
+
import type { PositionedAnchor, PositionedIncludeRegion, PositionedMilestone } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* How far a region's marker labels stay inside the region box on either
|
|
6
|
+
* side: the renderer's 8 px border inset plus 8 px of air.
|
|
7
|
+
*/
|
|
8
|
+
export declare const REGION_MARKER_INSET_X_PX = 16;
|
|
9
|
+
/** A region's placed markers and how far its lanes move down for them. */
|
|
10
|
+
export interface RegionMarkers {
|
|
11
|
+
anchors: PositionedAnchor[];
|
|
12
|
+
milestones: PositionedMilestone[];
|
|
13
|
+
/** The lanes' shift: 0 when the region has no marker to draw. */
|
|
14
|
+
laneShift: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Place `region`'s anchors and milestones once its lanes are laid out
|
|
18
|
+
* from `lanesTopY` down to `lanesBottomY`, inside a region whose top
|
|
19
|
+
* border is at `regionTopY`. The pack is bounded by the region's left
|
|
20
|
+
* inset and by `chartRightX` (the canvas before finalize grows it) less
|
|
21
|
+
* the right inset; a label that fits on neither side packs to the right
|
|
22
|
+
* and finalize f3 grows the canvas for it (`regionMarkerCanvasRightX`).
|
|
23
|
+
* The caller shifts the lanes by `laneShift`.
|
|
24
|
+
*/
|
|
25
|
+
export declare function placeRegionMarkers(region: IsolatedRegion, ctx: LayoutContext, regionTopY: number, lanesTopY: number, lanesBottomY: number, chartRightX: number): RegionMarkers;
|
|
26
|
+
/**
|
|
27
|
+
* The canvas right edge `region`'s marker labels need: a label that fits
|
|
28
|
+
* on neither side of its marker inside the region's insets grows the
|
|
29
|
+
* canvas until it fits on the right, the host's marker-row rule. Returns
|
|
30
|
+
* `chartRightX` when every label fits.
|
|
31
|
+
*/
|
|
32
|
+
export declare function regionMarkerCanvasRightX(region: PositionedIncludeRegion, chartRightX: number): number;
|
|
33
|
+
/** The right end of `region`'s rightmost marker label, or 0 with none. */
|
|
34
|
+
export declare function regionMarkerLabelsRightX(region: PositionedIncludeRegion): number;
|
|
35
|
+
/**
|
|
36
|
+
* Seed a region's dated anchors into its context's edge maps at their x on
|
|
37
|
+
* the host's scale, the way the host seeds its own (`phases/place.ts`).
|
|
38
|
+
* An anchor outside the date window is skipped, as on the host.
|
|
39
|
+
*/
|
|
40
|
+
export declare function seedRegionAnchorEdges(anchors: ReadonlyMap<string, AnchorDeclaration>, ctx: LayoutContext): void;
|
|
41
|
+
//# sourceMappingURL=region-markers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"region-markers.d.ts","sourceRoot":"","sources":["../../src/nodes/region-markers.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAYlG;;;GAGG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAQ3C,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,UAAU,EAAE,mBAAmB,EAAE,CAAC;IAClC,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAC9B,MAAM,EAAE,cAAc,EACtB,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GACpB,aAAa,CA2Cf;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACpC,MAAM,EAAE,uBAAuB,EAC/B,WAAW,EAAE,MAAM,GACpB,MAAM,CAaR;AAED,0EAA0E;AAC1E,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,uBAAuB,GAAG,MAAM,CAMhF;AAqCD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACjC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC/C,GAAG,EAAE,aAAa,GACnB,IAAI,CAKN"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Region markers — an isolated region's own anchors and milestones, drawn
|
|
2
|
+
// in a marker row of the region's own, under its label tab
|
|
3
|
+
// (specs/rendering.md § Included Roadmap Region). The row packs with the
|
|
4
|
+
// host's packer and label rules, bounded by the region's dashed border
|
|
5
|
+
// instead of the chart; the region's lanes move down by its height, and
|
|
6
|
+
// each cut line stops at the region's last lane.
|
|
7
|
+
import { estimateTextWidth } from '../text-measure.js';
|
|
8
|
+
import { buildAnchors } from './anchor-node.js';
|
|
9
|
+
import { datePinnedMarkerEntries, markerLabelsRightX, markerRowPlacements, packMarkerRow, } from './marker-band.js';
|
|
10
|
+
import { MARKER_ROW_PITCH_PX } from './marker-geometry.js';
|
|
11
|
+
import { buildMilestones, positionMilestones } from './milestone-node.js';
|
|
12
|
+
/**
|
|
13
|
+
* How far a region's marker labels stay inside the region box on either
|
|
14
|
+
* side: the renderer's 8 px border inset plus 8 px of air.
|
|
15
|
+
*/
|
|
16
|
+
export const REGION_MARKER_INSET_X_PX = 16;
|
|
17
|
+
/** The region marker band's top, below the region's top border. */
|
|
18
|
+
const REGION_MARKER_BAND_TOP_PX = 8;
|
|
19
|
+
/** Air between the region marker band and the region's first lane. */
|
|
20
|
+
const REGION_MARKER_BAND_GAP_PX = 6;
|
|
21
|
+
/**
|
|
22
|
+
* Place `region`'s anchors and milestones once its lanes are laid out
|
|
23
|
+
* from `lanesTopY` down to `lanesBottomY`, inside a region whose top
|
|
24
|
+
* border is at `regionTopY`. The pack is bounded by the region's left
|
|
25
|
+
* inset and by `chartRightX` (the canvas before finalize grows it) less
|
|
26
|
+
* the right inset; a label that fits on neither side packs to the right
|
|
27
|
+
* and finalize f3 grows the canvas for it (`regionMarkerCanvasRightX`).
|
|
28
|
+
* The caller shifts the lanes by `laneShift`.
|
|
29
|
+
*/
|
|
30
|
+
export function placeRegionMarkers(region, ctx, regionTopY, lanesTopY, lanesBottomY, chartRightX) {
|
|
31
|
+
// A milestone `after:` an anchor reads the anchor's edge. Without waves
|
|
32
|
+
// the edges are already seeded for the lanes; with waves they are
|
|
33
|
+
// seeded here, after the lanes, so the lanes still see only the wave
|
|
34
|
+
// edges.
|
|
35
|
+
seedRegionAnchorEdges(region.content.anchors, ctx);
|
|
36
|
+
const placements = buildMilestones(region.content.milestones, ctx);
|
|
37
|
+
const entries = regionMarkerEntries(region.content.anchors, placements, ctx);
|
|
38
|
+
if (entries.length === 0)
|
|
39
|
+
return { anchors: [], milestones: [], laneShift: 0 };
|
|
40
|
+
const leftX = REGION_MARKER_INSET_X_PX;
|
|
41
|
+
const packed = packMarkerRow(entries, leftX, markerLabelsRightX(entries, leftX, chartRightX - REGION_MARKER_INSET_X_PX, estimateTextWidth), estimateTextWidth);
|
|
42
|
+
const bandTopY = regionTopY + REGION_MARKER_BAND_TOP_PX;
|
|
43
|
+
const laneShift = bandTopY + packed.rowCount * MARKER_ROW_PITCH_PX + REGION_MARKER_BAND_GAP_PX - lanesTopY;
|
|
44
|
+
const cutBottomY = lanesBottomY + laneShift;
|
|
45
|
+
const rows = markerRowPlacements(packed.placements, bandTopY);
|
|
46
|
+
ctx.markerRowPlacements = rows;
|
|
47
|
+
ctx.chartTopY = lanesTopY + laneShift;
|
|
48
|
+
ctx.swimlaneBottomY = cutBottomY;
|
|
49
|
+
const anchors = buildAnchors(region.content.anchors, ctx, new Set());
|
|
50
|
+
// Placement read each predecessor's y before the lanes moved.
|
|
51
|
+
const milestones = positionMilestones(placements.map((p) => ({
|
|
52
|
+
...p,
|
|
53
|
+
cutTopY: ctx.chartTopY,
|
|
54
|
+
cutBottomY,
|
|
55
|
+
slackArrows: p.slackArrows?.map((a) => ({ x: a.x, y: a.y + laneShift })),
|
|
56
|
+
})), rows);
|
|
57
|
+
return { anchors, milestones, laneShift };
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The canvas right edge `region`'s marker labels need: a label that fits
|
|
61
|
+
* on neither side of its marker inside the region's insets grows the
|
|
62
|
+
* canvas until it fits on the right, the host's marker-row rule. Returns
|
|
63
|
+
* `chartRightX` when every label fits.
|
|
64
|
+
*/
|
|
65
|
+
export function regionMarkerCanvasRightX(region, chartRightX) {
|
|
66
|
+
const entries = [
|
|
67
|
+
...(region.anchors ?? []).map((a) => positionedEntry(a, false)),
|
|
68
|
+
...(region.milestones ?? []).map((m) => positionedEntry(m, true)),
|
|
69
|
+
];
|
|
70
|
+
if (entries.length === 0)
|
|
71
|
+
return chartRightX;
|
|
72
|
+
const rightX = markerLabelsRightX(entries, region.box.x + REGION_MARKER_INSET_X_PX, chartRightX - REGION_MARKER_INSET_X_PX, estimateTextWidth);
|
|
73
|
+
return rightX + REGION_MARKER_INSET_X_PX;
|
|
74
|
+
}
|
|
75
|
+
/** The right end of `region`'s rightmost marker label, or 0 with none. */
|
|
76
|
+
export function regionMarkerLabelsRightX(region) {
|
|
77
|
+
let rightX = 0;
|
|
78
|
+
for (const m of [...(region.anchors ?? []), ...(region.milestones ?? [])]) {
|
|
79
|
+
rightX = Math.max(rightX, m.labelBox.x + m.labelBox.width);
|
|
80
|
+
}
|
|
81
|
+
return rightX;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The host's marker order: the date-pinned anchors, the dated milestones,
|
|
85
|
+
* then the after-only ones, so the stable sort in `packMarkerRow` breaks
|
|
86
|
+
* a tie on x the same way the host's band does.
|
|
87
|
+
*/
|
|
88
|
+
function regionMarkerEntries(anchors, milestones, ctx) {
|
|
89
|
+
const entries = datePinnedMarkerEntries(anchors, new Map(), ctx.scale);
|
|
90
|
+
const milestoneEntry = (m) => ({
|
|
91
|
+
id: m.id,
|
|
92
|
+
centerX: m.x,
|
|
93
|
+
radius: m.radius,
|
|
94
|
+
title: m.title,
|
|
95
|
+
fontSize: 10,
|
|
96
|
+
bold: true,
|
|
97
|
+
});
|
|
98
|
+
entries.push(...milestones.filter((m) => m.fixed).map(milestoneEntry));
|
|
99
|
+
entries.push(...milestones.filter((m) => !m.fixed).map(milestoneEntry));
|
|
100
|
+
return entries;
|
|
101
|
+
}
|
|
102
|
+
function positionedEntry(m, bold) {
|
|
103
|
+
return {
|
|
104
|
+
id: m.id ?? '',
|
|
105
|
+
centerX: m.center.x,
|
|
106
|
+
radius: m.radius,
|
|
107
|
+
title: m.title,
|
|
108
|
+
fontSize: 10,
|
|
109
|
+
bold,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Seed a region's dated anchors into its context's edge maps at their x on
|
|
114
|
+
* the host's scale, the way the host seeds its own (`phases/place.ts`).
|
|
115
|
+
* An anchor outside the date window is skipped, as on the host.
|
|
116
|
+
*/
|
|
117
|
+
export function seedRegionAnchorEdges(anchors, ctx) {
|
|
118
|
+
for (const e of datePinnedMarkerEntries(anchors, new Map(), ctx.scale)) {
|
|
119
|
+
ctx.entityLeftEdges.set(e.id, e.centerX);
|
|
120
|
+
ctx.entityRightEdges.set(e.id, e.centerX);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=region-markers.js.map
|