@diagrammo/dgmo 0.39.0 → 0.41.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/advanced.cjs +372 -162
- package/dist/advanced.js +372 -162
- package/dist/auto.cjs +373 -163
- package/dist/auto.js +92 -92
- package/dist/auto.mjs +373 -163
- package/dist/cli.cjs +115 -115
- package/dist/index.cjs +550 -217
- package/dist/index.js +550 -217
- package/docs/language-reference.md +17 -0
- package/gallery/fixtures/block.dgmo +16 -0
- package/gallery/fixtures/event-line.dgmo +26 -0
- package/package.json +1 -1
- package/src/diagnostics.ts +0 -0
- package/src/echarts.ts +5 -0
- package/src/error-card.ts +200 -0
- package/src/event-line/parser.ts +155 -55
- package/src/event-line/renderer.ts +350 -139
- package/src/index.ts +7 -30
- package/src/journey-map/renderer.ts +50 -18
package/dist/advanced.js
CHANGED
|
@@ -103,7 +103,7 @@ function vennAliasKeywordRemovedMessage(args) {
|
|
|
103
103
|
return `Venn 'alias' keyword was removed. Use 'as' instead \u2014 '${args.name} as ${args.alias}'.`;
|
|
104
104
|
}
|
|
105
105
|
function pipeOperatorRemovedMessage() {
|
|
106
|
-
return `'|'
|
|
106
|
+
return `'|' is no longer metadata syntax \u2014 write metadata inline as 'key: value' (e.g. "Name color: red"), or remove the '|'.`;
|
|
107
107
|
}
|
|
108
108
|
function ganttBarePercentRemovedMessage(percent) {
|
|
109
109
|
return `Bare-percent progress shorthand '| ${percent}' was removed. Use 'progress: ${percent.replace(/%$/, "")}' (integer 0\u2013100, no '%').`;
|
|
@@ -13678,7 +13678,8 @@ function buildScatterOption(parsed, palette, isDark, textColor, axisLineColor, g
|
|
|
13678
13678
|
solid: parsed.solidFill === true
|
|
13679
13679
|
}),
|
|
13680
13680
|
borderColor: catColor,
|
|
13681
|
-
borderWidth: CHART_BORDER_WIDTH
|
|
13681
|
+
borderWidth: CHART_BORDER_WIDTH,
|
|
13682
|
+
opacity: SCATTER_FILL_OPACITY
|
|
13682
13683
|
},
|
|
13683
13684
|
label: labelConfig,
|
|
13684
13685
|
emphasis: emphasisConfig,
|
|
@@ -13705,6 +13706,7 @@ function buildScatterOption(parsed, palette, isDark, textColor, axisLineColor, g
|
|
|
13705
13706
|
{
|
|
13706
13707
|
type: "scatter",
|
|
13707
13708
|
data,
|
|
13709
|
+
itemStyle: { opacity: SCATTER_FILL_OPACITY },
|
|
13708
13710
|
label: labelConfig,
|
|
13709
13711
|
emphasis: emphasisConfig,
|
|
13710
13712
|
blur: blurConfig
|
|
@@ -15010,7 +15012,7 @@ async function renderExtendedChartForExport(content, theme, palette) {
|
|
|
15010
15012
|
chart.dispose();
|
|
15011
15013
|
}
|
|
15012
15014
|
}
|
|
15013
|
-
var EMPHASIS_SELF, EMPHASIS_SERIES, BLUR_DIM, EMPHASIS_LINE, CHART_BASE, CHART_BORDER_WIDTH, VALID_EXTENDED_TYPES, KNOWN_EXTENDED_OPTIONS, EXTENDED_CHART_DOORS, FIT_PADDING, OFFSCREEN, fitStackedLabelToSegment, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
|
|
15015
|
+
var EMPHASIS_SELF, EMPHASIS_SERIES, BLUR_DIM, EMPHASIS_LINE, CHART_BASE, CHART_BORDER_WIDTH, SCATTER_FILL_OPACITY, VALID_EXTENDED_TYPES, KNOWN_EXTENDED_OPTIONS, EXTENDED_CHART_DOORS, FIT_PADDING, OFFSCREEN, fitStackedLabelToSegment, ECHART_EXPORT_WIDTH, ECHART_EXPORT_HEIGHT, STANDARD_CHART_TYPES;
|
|
15014
15016
|
var init_echarts = __esm({
|
|
15015
15017
|
"src/echarts.ts"() {
|
|
15016
15018
|
"use strict";
|
|
@@ -15064,6 +15066,7 @@ var init_echarts = __esm({
|
|
|
15064
15066
|
tooltip: { show: false }
|
|
15065
15067
|
};
|
|
15066
15068
|
CHART_BORDER_WIDTH = 2;
|
|
15069
|
+
SCATTER_FILL_OPACITY = 0.65;
|
|
15067
15070
|
VALID_EXTENDED_TYPES = /* @__PURE__ */ new Set([
|
|
15068
15071
|
"sankey",
|
|
15069
15072
|
"chord",
|
|
@@ -15161,6 +15164,8 @@ function parseEventLine(content, palette) {
|
|
|
15161
15164
|
let currentTagGroup = null;
|
|
15162
15165
|
let currentEvent = null;
|
|
15163
15166
|
let currentEra = null;
|
|
15167
|
+
let eraIndent = -1;
|
|
15168
|
+
let currentEventIndent = 0;
|
|
15164
15169
|
const aliasMap = /* @__PURE__ */ new Map();
|
|
15165
15170
|
for (let i = 0; i < lines.length; i++) {
|
|
15166
15171
|
const line11 = lines[i];
|
|
@@ -15235,52 +15240,15 @@ function parseEventLine(content, palette) {
|
|
|
15235
15240
|
});
|
|
15236
15241
|
continue;
|
|
15237
15242
|
}
|
|
15238
|
-
if (indent >
|
|
15239
|
-
if (!currentEvent) {
|
|
15240
|
-
pushWarning(
|
|
15241
|
-
lineNumber,
|
|
15242
|
-
`Indented description "${trimmed}" has no event above it \u2014 add an event line first. (\xA728)`
|
|
15243
|
-
);
|
|
15244
|
-
continue;
|
|
15245
|
-
}
|
|
15243
|
+
if (currentEvent && indent > currentEventIndent) {
|
|
15246
15244
|
const descLine = trimmed.startsWith("- ") ? `\u2022 ${trimmed.substring(2)}` : trimmed;
|
|
15247
15245
|
currentEvent.description.push(descLine);
|
|
15248
15246
|
continue;
|
|
15249
15247
|
}
|
|
15250
|
-
currentTagGroup = null;
|
|
15251
|
-
if (trimmed.toLowerCase() === "no-scale") {
|
|
15252
|
-
options.scale = false;
|
|
15253
|
-
continue;
|
|
15254
|
-
}
|
|
15255
|
-
const sideMatch = trimmed.match(SIDE_RE);
|
|
15256
|
-
if (sideMatch) {
|
|
15257
|
-
options.side = sideMatch[1].toLowerCase();
|
|
15258
|
-
continue;
|
|
15259
|
-
}
|
|
15260
|
-
if (trimmed.toLowerCase() === "no-box") {
|
|
15261
|
-
options.noBox = true;
|
|
15262
|
-
continue;
|
|
15263
|
-
}
|
|
15264
|
-
if (trimmed.toLowerCase() === "no-legend") {
|
|
15265
|
-
options.noLegend = true;
|
|
15266
|
-
continue;
|
|
15267
|
-
}
|
|
15268
|
-
const dirMatch = trimmed.match(DIRECTION_RE);
|
|
15269
|
-
if (dirMatch) {
|
|
15270
|
-
const dir = dirMatch[1].toUpperCase();
|
|
15271
|
-
if (dir !== "LR") {
|
|
15272
|
-
pushWarning(
|
|
15273
|
-
lineNumber,
|
|
15274
|
-
`event-line is horizontal-only in v1; \`direction ${dir}\` (vertical orientation) is a fast-follow.`,
|
|
15275
|
-
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15276
|
-
);
|
|
15277
|
-
}
|
|
15278
|
-
continue;
|
|
15279
|
-
}
|
|
15280
|
-
if (tryParseSharedOption(trimmed, sharedOptions)) continue;
|
|
15281
15248
|
const eraMatch = trimmed.match(ERA_RE);
|
|
15282
15249
|
if (eraMatch) {
|
|
15283
15250
|
contentStarted = true;
|
|
15251
|
+
currentTagGroup = null;
|
|
15284
15252
|
currentEvent = null;
|
|
15285
15253
|
const name = eraMatch[1].trim();
|
|
15286
15254
|
let rest = (eraMatch[2] ?? "").trim();
|
|
@@ -15304,16 +15272,52 @@ function parseEventLine(content, palette) {
|
|
|
15304
15272
|
const era = { name, color, collapsed, lineNumber };
|
|
15305
15273
|
result.eras.push(era);
|
|
15306
15274
|
currentEra = name;
|
|
15275
|
+
eraIndent = indent;
|
|
15307
15276
|
continue;
|
|
15308
15277
|
}
|
|
15309
|
-
if (
|
|
15310
|
-
|
|
15311
|
-
|
|
15312
|
-
|
|
15313
|
-
|
|
15314
|
-
|
|
15315
|
-
|
|
15278
|
+
if (indent === 0) {
|
|
15279
|
+
currentTagGroup = null;
|
|
15280
|
+
if (trimmed.toLowerCase() === "no-scale") {
|
|
15281
|
+
options.scale = false;
|
|
15282
|
+
continue;
|
|
15283
|
+
}
|
|
15284
|
+
const sideMatch = trimmed.match(SIDE_RE);
|
|
15285
|
+
if (sideMatch) {
|
|
15286
|
+
options.side = sideMatch[1].toLowerCase();
|
|
15287
|
+
continue;
|
|
15288
|
+
}
|
|
15289
|
+
if (trimmed.toLowerCase() === "no-box") {
|
|
15290
|
+
options.noBox = true;
|
|
15291
|
+
continue;
|
|
15292
|
+
}
|
|
15293
|
+
if (trimmed.toLowerCase() === "no-legend") {
|
|
15294
|
+
options.noLegend = true;
|
|
15295
|
+
continue;
|
|
15296
|
+
}
|
|
15297
|
+
const dirMatch = trimmed.match(DIRECTION_RE);
|
|
15298
|
+
if (dirMatch) {
|
|
15299
|
+
const dir = dirMatch[1].toUpperCase();
|
|
15300
|
+
if (dir !== "LR") {
|
|
15301
|
+
pushWarning(
|
|
15302
|
+
lineNumber,
|
|
15303
|
+
`event-line is horizontal-only in v1; \`direction ${dir}\` (vertical orientation) is a fast-follow.`,
|
|
15304
|
+
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15305
|
+
);
|
|
15306
|
+
}
|
|
15307
|
+
continue;
|
|
15308
|
+
}
|
|
15309
|
+
if (tryParseSharedOption(trimmed, sharedOptions)) continue;
|
|
15310
|
+
if (SECTION_SEAM_RE.test(trimmed)) {
|
|
15311
|
+
pushWarning(
|
|
15312
|
+
lineNumber,
|
|
15313
|
+
"Group events with `[Name]` era brackets (\xA728.6a), not `section`.",
|
|
15314
|
+
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15315
|
+
);
|
|
15316
|
+
continue;
|
|
15317
|
+
}
|
|
15316
15318
|
}
|
|
15319
|
+
const inEra = currentEra !== null && indent > eraIndent;
|
|
15320
|
+
if (!inEra) currentEra = null;
|
|
15317
15321
|
contentStarted = true;
|
|
15318
15322
|
const event = parseEventHeader(
|
|
15319
15323
|
trimmed,
|
|
@@ -15325,6 +15329,7 @@ function parseEventLine(content, palette) {
|
|
|
15325
15329
|
);
|
|
15326
15330
|
result.events.push(event);
|
|
15327
15331
|
currentEvent = event;
|
|
15332
|
+
currentEventIndent = indent;
|
|
15328
15333
|
}
|
|
15329
15334
|
options.noTitle = sharedOptions["no-title"] === "on";
|
|
15330
15335
|
finalizeAutoTagColors(result.tagGroups, palette);
|
|
@@ -15339,8 +15344,61 @@ function parseEventLine(content, palette) {
|
|
|
15339
15344
|
EVENT_LINE_DIAGNOSTIC_CODES.NO_EVENTS
|
|
15340
15345
|
);
|
|
15341
15346
|
}
|
|
15347
|
+
if (options.scale) {
|
|
15348
|
+
validateEraDateOrder(result.events, result.eras, pushWarning);
|
|
15349
|
+
}
|
|
15342
15350
|
return result;
|
|
15343
15351
|
}
|
|
15352
|
+
function validateEraDateOrder(events, eras, pushWarning) {
|
|
15353
|
+
if (eras.length < 2) return;
|
|
15354
|
+
const order = new Map(eras.map((e, i) => [e.name, i]));
|
|
15355
|
+
const dated = events.filter(
|
|
15356
|
+
(e) => e.dateValue !== null && e.era !== null && order.has(e.era)
|
|
15357
|
+
);
|
|
15358
|
+
if (dated.length === 0) return;
|
|
15359
|
+
const perEra = /* @__PURE__ */ new Map();
|
|
15360
|
+
for (const ev of dated) {
|
|
15361
|
+
const idx = order.get(ev.era);
|
|
15362
|
+
const cur = perEra.get(idx);
|
|
15363
|
+
if (!cur) {
|
|
15364
|
+
perEra.set(idx, { min: ev, max: ev });
|
|
15365
|
+
} else {
|
|
15366
|
+
if (ev.dateValue < cur.min.dateValue) cur.min = ev;
|
|
15367
|
+
if (ev.dateValue > cur.max.dateValue) cur.max = ev;
|
|
15368
|
+
}
|
|
15369
|
+
}
|
|
15370
|
+
const n = eras.length;
|
|
15371
|
+
const prefixMax = new Array(n).fill(null);
|
|
15372
|
+
const suffixMin = new Array(n).fill(null);
|
|
15373
|
+
for (let k = 1; k < n; k++) {
|
|
15374
|
+
const prev = perEra.get(k - 1)?.max ?? null;
|
|
15375
|
+
const carried = prefixMax[k - 1] ?? null;
|
|
15376
|
+
prefixMax[k] = prev && (!carried || prev.dateValue > carried.dateValue) ? prev : carried;
|
|
15377
|
+
}
|
|
15378
|
+
for (let k = n - 2; k >= 0; k--) {
|
|
15379
|
+
const next = perEra.get(k + 1)?.min ?? null;
|
|
15380
|
+
const carried = suffixMin[k + 1] ?? null;
|
|
15381
|
+
suffixMin[k] = next && (!carried || next.dateValue < carried.dateValue) ? next : carried;
|
|
15382
|
+
}
|
|
15383
|
+
for (const ev of dated) {
|
|
15384
|
+
const k = order.get(ev.era);
|
|
15385
|
+
const ahead = suffixMin[k];
|
|
15386
|
+
const behind = prefixMax[k];
|
|
15387
|
+
if (ahead && ev.dateValue > ahead.dateValue) {
|
|
15388
|
+
pushWarning(
|
|
15389
|
+
ev.lineNumber,
|
|
15390
|
+
`"${ev.label}" (${ev.date}) is in era "${ev.era}" but dated after era "${ahead.era}" begins (${ahead.date}). event-line eras run left-to-right by date \u2014 fix the date or move it to the right era, or their brackets will overlap.`,
|
|
15391
|
+
EVENT_LINE_DIAGNOSTIC_CODES.ERA_DATE_ORDER
|
|
15392
|
+
);
|
|
15393
|
+
} else if (behind && ev.dateValue < behind.dateValue) {
|
|
15394
|
+
pushWarning(
|
|
15395
|
+
ev.lineNumber,
|
|
15396
|
+
`"${ev.label}" (${ev.date}) is in era "${ev.era}" but dated before era "${behind.era}" ends (${behind.date}). event-line eras run left-to-right by date \u2014 fix the date or move it to the right era, or their brackets will overlap.`,
|
|
15397
|
+
EVENT_LINE_DIAGNOSTIC_CODES.ERA_DATE_ORDER
|
|
15398
|
+
);
|
|
15399
|
+
}
|
|
15400
|
+
}
|
|
15401
|
+
}
|
|
15344
15402
|
function parseEventHeader(trimmed, lineNumber, era, aliasMap, diagnostics, pushWarning) {
|
|
15345
15403
|
let date = null;
|
|
15346
15404
|
let dateValue = null;
|
|
@@ -15407,7 +15465,8 @@ var init_parser13 = __esm({
|
|
|
15407
15465
|
EVENT_LINE_DIAGNOSTIC_CODES = {
|
|
15408
15466
|
NO_EVENTS: "E_EVENT_LINE_NO_EVENTS",
|
|
15409
15467
|
BAD_DATE: "E_EVENT_LINE_BAD_DATE",
|
|
15410
|
-
UNSUPPORTED: "E_EVENT_LINE_UNSUPPORTED"
|
|
15468
|
+
UNSUPPORTED: "E_EVENT_LINE_UNSUPPORTED",
|
|
15469
|
+
ERA_DATE_ORDER: "E_EVENT_LINE_ERA_DATE_ORDER"
|
|
15411
15470
|
};
|
|
15412
15471
|
NON_ISO_DATE_RE = /^\d{1,4}[/.]\d/;
|
|
15413
15472
|
SIDE_RE = /^side\s+(above|below|alternate)\b/i;
|
|
@@ -26344,9 +26403,6 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26344
26403
|
const hasExpandedEra = parsed.events.some(
|
|
26345
26404
|
(e) => e.era && eraByName.has(e.era) && !collapsedSet.has(e.era)
|
|
26346
26405
|
);
|
|
26347
|
-
const anyCollapsed = parsed.events.some(
|
|
26348
|
-
(e) => e.era && collapsedSet.has(e.era)
|
|
26349
|
-
);
|
|
26350
26406
|
const sideOpt = parsed.options.side;
|
|
26351
26407
|
const alternate = sideOpt === "alternate";
|
|
26352
26408
|
const eraSide = alternate ? "below" : sideOpt === "above" ? "below" : "above";
|
|
@@ -26413,7 +26469,8 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26413
26469
|
x: 0,
|
|
26414
26470
|
side,
|
|
26415
26471
|
lane: 0,
|
|
26416
|
-
left: 0
|
|
26472
|
+
left: 0,
|
|
26473
|
+
spanHalf: 0
|
|
26417
26474
|
};
|
|
26418
26475
|
}
|
|
26419
26476
|
const era = slot.era;
|
|
@@ -26426,19 +26483,19 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26426
26483
|
palette.textOnFillLight,
|
|
26427
26484
|
palette.textOnFillDark
|
|
26428
26485
|
);
|
|
26429
|
-
|
|
26430
|
-
|
|
26431
|
-
const
|
|
26486
|
+
let spanLo = null;
|
|
26487
|
+
let spanHi = null;
|
|
26488
|
+
for (const m of slot.members) {
|
|
26489
|
+
if (m.dateValue === null) continue;
|
|
26490
|
+
if (spanLo === null || m.dateValue < spanLo) spanLo = m.dateValue;
|
|
26491
|
+
if (spanHi === null || m.dateValue > spanHi) spanHi = m.dateValue;
|
|
26492
|
+
}
|
|
26493
|
+
const repDateValue = spanLo !== null && spanHi !== null ? (spanLo + spanHi) / 2 : null;
|
|
26494
|
+
const memberStrs = slot.members.map(
|
|
26432
26495
|
(m) => `\u2022 ${m.date ? `${m.date} ` : ""}${m.label}`
|
|
26433
26496
|
);
|
|
26434
|
-
const bulletColors =
|
|
26497
|
+
const bulletColors = slot.members.map(eventColor);
|
|
26435
26498
|
const lines = wrapDescription(memberStrs, charsPerLine);
|
|
26436
|
-
if (overflow) {
|
|
26437
|
-
lines.push({
|
|
26438
|
-
text: `+${slot.members.length - (ERA_MEMBER_MAX - 1)} more`,
|
|
26439
|
-
kind: "plain"
|
|
26440
|
-
});
|
|
26441
|
-
}
|
|
26442
26499
|
return {
|
|
26443
26500
|
kind: "era",
|
|
26444
26501
|
event: null,
|
|
@@ -26446,7 +26503,7 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26446
26503
|
members: slot.members,
|
|
26447
26504
|
label: era.name,
|
|
26448
26505
|
date: null,
|
|
26449
|
-
dateValue:
|
|
26506
|
+
dateValue: repDateValue,
|
|
26450
26507
|
lineNumber: era.lineNumber,
|
|
26451
26508
|
eraName: era.name,
|
|
26452
26509
|
color: solid,
|
|
@@ -26458,87 +26515,189 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26458
26515
|
x: 0,
|
|
26459
26516
|
side,
|
|
26460
26517
|
lane: 0,
|
|
26461
|
-
left: 0
|
|
26518
|
+
left: 0,
|
|
26519
|
+
spanHalf: 0
|
|
26462
26520
|
};
|
|
26463
26521
|
});
|
|
26464
|
-
const scaled = parsed.options.scale &&
|
|
26522
|
+
const scaled = parsed.options.scale && placed.every((p) => p.dateValue !== null);
|
|
26465
26523
|
const innerW = width - H_MARGIN * 2;
|
|
26466
|
-
|
|
26467
|
-
|
|
26468
|
-
|
|
26469
|
-
|
|
26470
|
-
|
|
26471
|
-
|
|
26524
|
+
const MIN_DOT_GAP = 16;
|
|
26525
|
+
const STRETCH_CAP = 8;
|
|
26526
|
+
const COLLAPSE_W = 64;
|
|
26527
|
+
const SEG_GAP = 16;
|
|
26528
|
+
const segments = [];
|
|
26529
|
+
let run = [];
|
|
26530
|
+
const flushRun = () => {
|
|
26531
|
+
if (!run.length) return;
|
|
26532
|
+
const ds = run.map((e) => e.dateValue);
|
|
26533
|
+
segments.push({
|
|
26534
|
+
kind: "run",
|
|
26535
|
+
events: run,
|
|
26536
|
+
lo: Math.min(...ds),
|
|
26537
|
+
hi: Math.max(...ds)
|
|
26472
26538
|
});
|
|
26473
|
-
|
|
26474
|
-
|
|
26475
|
-
|
|
26476
|
-
|
|
26477
|
-
|
|
26478
|
-
|
|
26479
|
-
|
|
26539
|
+
run = [];
|
|
26540
|
+
};
|
|
26541
|
+
for (const p of placed) {
|
|
26542
|
+
if (p.kind === "era") {
|
|
26543
|
+
flushRun();
|
|
26544
|
+
segments.push({ kind: "capsule", p });
|
|
26545
|
+
} else {
|
|
26546
|
+
run.push(p);
|
|
26547
|
+
}
|
|
26548
|
+
}
|
|
26549
|
+
flushRun();
|
|
26550
|
+
const totalRunTime = segments.reduce(
|
|
26551
|
+
(s, seg) => s + (seg.kind === "run" ? seg.hi - seg.lo : 0),
|
|
26552
|
+
0
|
|
26553
|
+
);
|
|
26554
|
+
const place = (stretch) => {
|
|
26555
|
+
if (scaled) {
|
|
26556
|
+
const pxPerUnit = totalRunTime > 0 ? innerW * stretch / totalRunTime : 0;
|
|
26557
|
+
let cursor = H_MARGIN;
|
|
26558
|
+
for (const seg of segments) {
|
|
26559
|
+
if (seg.kind === "capsule") {
|
|
26560
|
+
seg.p.x = cursor + COLLAPSE_W / 2;
|
|
26561
|
+
seg.p.spanHalf = COLLAPSE_W / 2;
|
|
26562
|
+
cursor += COLLAPSE_W + SEG_GAP;
|
|
26563
|
+
} else {
|
|
26564
|
+
for (const e of seg.events) {
|
|
26565
|
+
e.x = cursor + (e.dateValue - seg.lo) * pxPerUnit;
|
|
26566
|
+
e.spanHalf = 0;
|
|
26567
|
+
}
|
|
26568
|
+
cursor += (seg.hi - seg.lo) * pxPerUnit + SEG_GAP;
|
|
26569
|
+
}
|
|
26570
|
+
}
|
|
26571
|
+
let prevX = -Infinity;
|
|
26572
|
+
let prevVal = null;
|
|
26573
|
+
for (const p of [...placed].sort((a, b) => a.x - b.x)) {
|
|
26574
|
+
if (p.kind === "era") {
|
|
26575
|
+
prevX = p.x + p.spanHalf;
|
|
26576
|
+
prevVal = null;
|
|
26577
|
+
continue;
|
|
26578
|
+
}
|
|
26579
|
+
if (p.dateValue === prevVal) {
|
|
26580
|
+
p.x = prevX;
|
|
26581
|
+
continue;
|
|
26582
|
+
}
|
|
26583
|
+
if (p.x < prevX + MIN_DOT_GAP) p.x = prevX + MIN_DOT_GAP;
|
|
26584
|
+
prevX = p.x;
|
|
26585
|
+
prevVal = p.dateValue;
|
|
26586
|
+
}
|
|
26587
|
+
} else {
|
|
26588
|
+
placed.forEach((p) => {
|
|
26589
|
+
p.spanHalf = 0;
|
|
26590
|
+
});
|
|
26591
|
+
const n = placed.length;
|
|
26592
|
+
const spacing = n > 1 ? Math.max(MIN_SPACING, innerW / (n - 1)) : 0;
|
|
26593
|
+
placed.forEach((p, i) => {
|
|
26594
|
+
p.x = H_MARGIN + i * spacing;
|
|
26595
|
+
});
|
|
26596
|
+
}
|
|
26597
|
+
for (const side of ["above", "below"]) {
|
|
26598
|
+
const arr = placed.filter((p) => p.side === side).sort((a, b) => a.x - b.x);
|
|
26599
|
+
const laneRight = [];
|
|
26600
|
+
for (let i = 0; i < arr.length; i++) {
|
|
26601
|
+
const p = arr[i];
|
|
26602
|
+
const next = arr[i + 1];
|
|
26603
|
+
const crowdedRight = !!next && next.x - p.x < CARD_W + FAN_GAP;
|
|
26604
|
+
const preferred = crowdedRight ? p.x - CARD_W + CARD_INSET : p.x - CARD_W / 2;
|
|
26605
|
+
const maxLeft = p.x - CARD_INSET;
|
|
26606
|
+
const minLeft = p.x - CARD_W + CARD_INSET;
|
|
26607
|
+
let lane = laneRight.length;
|
|
26608
|
+
let left = Math.max(preferred, minLeft);
|
|
26609
|
+
for (let l = 0; l < laneRight.length; l++) {
|
|
26610
|
+
const want = Math.max(preferred, laneRight[l] + FAN_GAP, minLeft);
|
|
26611
|
+
if (want <= maxLeft) {
|
|
26612
|
+
lane = l;
|
|
26613
|
+
left = want;
|
|
26614
|
+
break;
|
|
26615
|
+
}
|
|
26616
|
+
}
|
|
26617
|
+
p.lane = lane;
|
|
26618
|
+
p.left = Math.max(6, left);
|
|
26619
|
+
laneRight[lane] = p.left + CARD_W;
|
|
26480
26620
|
}
|
|
26481
|
-
if (p.x < prevX + MIN_DOT_GAP) p.x = prevX + MIN_DOT_GAP;
|
|
26482
|
-
prevX = p.x;
|
|
26483
|
-
prevVal = p.dateValue;
|
|
26484
26621
|
}
|
|
26622
|
+
};
|
|
26623
|
+
const derive = () => {
|
|
26624
|
+
const contentW2 = Math.max(
|
|
26625
|
+
width,
|
|
26626
|
+
Math.max(...placed.map((p) => p.x + p.spanHalf)) + H_MARGIN,
|
|
26627
|
+
Math.max(...placed.map((p) => p.left + CARD_W)) + 6
|
|
26628
|
+
);
|
|
26629
|
+
const laneOffset = { above: [], below: [] };
|
|
26630
|
+
for (const side of ["above", "below"]) {
|
|
26631
|
+
const laneH = [];
|
|
26632
|
+
for (const p of placed) {
|
|
26633
|
+
if (p.side !== side) continue;
|
|
26634
|
+
laneH[p.lane] = Math.max(laneH[p.lane] ?? 0, p.cardH);
|
|
26635
|
+
}
|
|
26636
|
+
const off = [];
|
|
26637
|
+
let acc = 0;
|
|
26638
|
+
for (let l = 0; l < laneH.length; l++) {
|
|
26639
|
+
off[l] = acc;
|
|
26640
|
+
acc += (laneH[l] ?? 0) + LANE_GAP;
|
|
26641
|
+
}
|
|
26642
|
+
laneOffset[side] = off;
|
|
26643
|
+
}
|
|
26644
|
+
const laneNear2 = (p) => (p.side === "above" ? LEADER_ABOVE : LEADER_BELOW) + (laneOffset[p.side][p.lane] ?? 0);
|
|
26645
|
+
const ext = (side) => Math.max(
|
|
26646
|
+
0,
|
|
26647
|
+
...placed.filter((p) => p.side === side).map((p) => laneNear2(p) + p.cardH)
|
|
26648
|
+
);
|
|
26649
|
+
const dateAbove = placed.some((p) => p.side === "below" && p.date);
|
|
26650
|
+
const dateBelow = placed.some((p) => p.side === "above" && p.date);
|
|
26651
|
+
const contentAbove = Math.max(
|
|
26652
|
+
ext("above"),
|
|
26653
|
+
dateAbove ? DATE_OFFSET + 10 : 0
|
|
26654
|
+
);
|
|
26655
|
+
const contentBelow = Math.max(
|
|
26656
|
+
ext("below"),
|
|
26657
|
+
dateBelow ? DATE_OFFSET + 10 : 0
|
|
26658
|
+
);
|
|
26659
|
+
const aboveExt = contentAbove + (hasExpandedEra && eraSide === "above" ? ERA_BLOCK : 0);
|
|
26660
|
+
const belowExt = contentBelow + (hasExpandedEra && eraSide === "below" ? ERA_BLOCK : 0);
|
|
26661
|
+
const TOP_PAD = 14;
|
|
26662
|
+
const BOT_PAD = 14;
|
|
26663
|
+
const spineY2 = topUsed + TOP_PAD + aboveExt;
|
|
26664
|
+
const eraBaseY2 = eraSide === "above" ? spineY2 - (contentAbove + 14) : spineY2 + (contentBelow + 14);
|
|
26665
|
+
const contentH = spineY2 + belowExt + BOT_PAD;
|
|
26666
|
+
const totalH2 = Math.max(heightHint, contentH);
|
|
26667
|
+
return { contentW: contentW2, contentH, totalH: totalH2, spineY: spineY2, eraBaseY: eraBaseY2, laneNear: laneNear2 };
|
|
26668
|
+
};
|
|
26669
|
+
const envStretch = Number(
|
|
26670
|
+
globalThis.process?.env?.["DGMO_EVT_STRETCH"]
|
|
26671
|
+
);
|
|
26672
|
+
let layout;
|
|
26673
|
+
if (Number.isFinite(envStretch) && envStretch > 0) {
|
|
26674
|
+
place(envStretch);
|
|
26675
|
+
layout = derive();
|
|
26485
26676
|
} else {
|
|
26486
|
-
|
|
26487
|
-
|
|
26488
|
-
|
|
26489
|
-
|
|
26490
|
-
|
|
26491
|
-
|
|
26492
|
-
|
|
26493
|
-
|
|
26494
|
-
|
|
26495
|
-
|
|
26496
|
-
|
|
26497
|
-
|
|
26498
|
-
|
|
26499
|
-
|
|
26500
|
-
|
|
26501
|
-
|
|
26502
|
-
|
|
26503
|
-
let left = Math.max(preferred, minLeft);
|
|
26504
|
-
for (let l = 0; l < laneRight.length; l++) {
|
|
26505
|
-
const want = Math.max(preferred, laneRight[l] + FAN_GAP, minLeft);
|
|
26506
|
-
if (want <= maxLeft) {
|
|
26507
|
-
lane = l;
|
|
26508
|
-
left = want;
|
|
26509
|
-
break;
|
|
26677
|
+
place(1);
|
|
26678
|
+
layout = derive();
|
|
26679
|
+
const panelAspect = width / heightHint;
|
|
26680
|
+
const aspectOf = (l) => l.contentW / l.contentH;
|
|
26681
|
+
if (scaled && layout.contentH > heightHint && aspectOf(layout) < panelAspect) {
|
|
26682
|
+
place(STRETCH_CAP);
|
|
26683
|
+
const capped = derive();
|
|
26684
|
+
if (aspectOf(capped) <= panelAspect) {
|
|
26685
|
+
layout = capped;
|
|
26686
|
+
} else {
|
|
26687
|
+
let loF = 1;
|
|
26688
|
+
let hiF = STRETCH_CAP;
|
|
26689
|
+
for (let it = 0; it < 8; it++) {
|
|
26690
|
+
const mid = (loF + hiF) / 2;
|
|
26691
|
+
place(mid);
|
|
26692
|
+
if (aspectOf(derive()) >= panelAspect) hiF = mid;
|
|
26693
|
+
else loF = mid;
|
|
26510
26694
|
}
|
|
26695
|
+
place(hiF);
|
|
26696
|
+
layout = derive();
|
|
26511
26697
|
}
|
|
26512
|
-
p.lane = lane;
|
|
26513
|
-
p.left = Math.max(6, left);
|
|
26514
|
-
laneRight[lane] = p.left + CARD_W;
|
|
26515
26698
|
}
|
|
26516
26699
|
}
|
|
26517
|
-
const contentW =
|
|
26518
|
-
width,
|
|
26519
|
-
Math.max(...placed.map((p) => p.x)) + H_MARGIN,
|
|
26520
|
-
Math.max(...placed.map((p) => p.left + CARD_W)) + 6
|
|
26521
|
-
);
|
|
26522
|
-
const rowGap = (side) => Math.max(0, ...placed.filter((p) => p.side === side).map((p) => p.cardH)) + LANE_GAP;
|
|
26523
|
-
const rowGapA = rowGap("above");
|
|
26524
|
-
const rowGapB = rowGap("below");
|
|
26525
|
-
const ext = (side) => Math.max(
|
|
26526
|
-
0,
|
|
26527
|
-
...placed.filter((p) => p.side === side).map(
|
|
26528
|
-
(p) => (side === "above" ? LEADER_ABOVE : LEADER_BELOW) + p.lane * (side === "above" ? rowGapA : rowGapB) + p.cardH
|
|
26529
|
-
)
|
|
26530
|
-
);
|
|
26531
|
-
const dateAbove = placed.some((p) => p.side === "below" && p.date);
|
|
26532
|
-
const dateBelow = placed.some((p) => p.side === "above" && p.date);
|
|
26533
|
-
const contentAbove = Math.max(ext("above"), dateAbove ? DATE_OFFSET + 10 : 0);
|
|
26534
|
-
const contentBelow = Math.max(ext("below"), dateBelow ? DATE_OFFSET + 10 : 0);
|
|
26535
|
-
const aboveExt = contentAbove + (hasExpandedEra && eraSide === "above" ? ERA_BLOCK : 0);
|
|
26536
|
-
const belowExt = contentBelow + (hasExpandedEra && eraSide === "below" ? ERA_BLOCK : 0);
|
|
26537
|
-
const TOP_PAD = 14;
|
|
26538
|
-
const BOT_PAD = 14;
|
|
26539
|
-
const spineY = topUsed + TOP_PAD + aboveExt;
|
|
26540
|
-
const eraBaseY = eraSide === "above" ? spineY - (contentAbove + 14) : spineY + (contentBelow + 14);
|
|
26541
|
-
const totalH = Math.max(heightHint, spineY + belowExt + BOT_PAD);
|
|
26700
|
+
const { contentW, totalH, spineY, eraBaseY, laneNear } = layout;
|
|
26542
26701
|
const svg = d3Selection6.select(container).append("svg").attr("width", contentW).attr("height", totalH).attr("viewBox", `0 0 ${contentW} ${totalH}`).attr("preserveAspectRatio", "xMidYMin meet").attr("xmlns", "http://www.w3.org/2000/svg").style("font-family", FONT_FAMILY);
|
|
26543
26702
|
svg.append("rect").attr("width", contentW).attr("height", totalH).attr("fill", palette.bg);
|
|
26544
26703
|
if (showTitle) {
|
|
@@ -26566,12 +26725,11 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26566
26725
|
activeGroup
|
|
26567
26726
|
});
|
|
26568
26727
|
}
|
|
26569
|
-
const
|
|
26570
|
-
const
|
|
26571
|
-
const x1 = Math.max(...xs);
|
|
26728
|
+
const x0 = Math.min(...placed.map((p) => p.x - p.spanHalf));
|
|
26729
|
+
const x1 = Math.max(...placed.map((p) => p.x + p.spanHalf));
|
|
26572
26730
|
svg.append("line").attr("x1", x0 - 20).attr("y1", spineY).attr("x2", x1 + 20).attr("y2", spineY).attr("stroke", palette.text).attr("stroke-width", 2.5).attr("stroke-linecap", "round");
|
|
26573
26731
|
const geo = placed.map((p) => {
|
|
26574
|
-
const near = p.side === "above" ? spineY -
|
|
26732
|
+
const near = p.side === "above" ? spineY - laneNear(p) : spineY + laneNear(p);
|
|
26575
26733
|
const top = p.side === "above" ? near - p.cardH : near;
|
|
26576
26734
|
return { p, near, top };
|
|
26577
26735
|
});
|
|
@@ -26683,7 +26841,7 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26683
26841
|
for (const p of placed) {
|
|
26684
26842
|
if (p.kind === "era") {
|
|
26685
26843
|
const col = p.color;
|
|
26686
|
-
const half = Math.
|
|
26844
|
+
const half = Math.max(16, p.spanHalf);
|
|
26687
26845
|
const spineLeft = x0 - 20;
|
|
26688
26846
|
const spineRight = x1 + 20;
|
|
26689
26847
|
const bx0 = Math.max(spineLeft, p.x - half);
|
|
@@ -26694,6 +26852,11 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26694
26852
|
"d",
|
|
26695
26853
|
`M${bx0},${spineY} L${bx0},${barY} L${bx1},${barY} L${bx1},${spineY}`
|
|
26696
26854
|
).attr("fill", "none").attr("stroke", col).attr("stroke-width", 1.5).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
26855
|
+
const breakCx = (bx0 + bx1) / 2;
|
|
26856
|
+
eg.append("line").attr("x1", breakCx - BREAK_GAP / 2).attr("y1", spineY).attr("x2", breakCx + BREAK_GAP / 2).attr("y2", spineY).attr("stroke", palette.bg).attr("stroke-width", 4).attr("stroke-linecap", "butt");
|
|
26857
|
+
for (const d of axisBreakPaths(breakCx, spineY)) {
|
|
26858
|
+
eg.append("path").attr("d", d).attr("fill", "none").attr("stroke", col).attr("stroke-width", 1.25).attr("stroke-linecap", "round").attr("stroke-linejoin", "round").attr("stroke-opacity", 0.85);
|
|
26859
|
+
}
|
|
26697
26860
|
if (onClickItem) {
|
|
26698
26861
|
const ln = p.lineNumber;
|
|
26699
26862
|
eg.style("cursor", "pointer").on("click", () => onClickItem(ln));
|
|
@@ -26727,13 +26890,23 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26727
26890
|
}
|
|
26728
26891
|
const clampX = (v) => Math.max(4, Math.min(contentW - 4, v));
|
|
26729
26892
|
const cap = eraSide === "above" ? 1 : -1;
|
|
26730
|
-
|
|
26731
|
-
|
|
26893
|
+
const drawn = runs.filter((r) => !r.collapsed).map((r) => ({
|
|
26894
|
+
run: r,
|
|
26895
|
+
x0: clampX(r.firstX - ERA_BRACKET_PAD),
|
|
26896
|
+
x1: clampX(r.lastX + ERA_BRACKET_PAD)
|
|
26897
|
+
})).sort((a, b) => a.run.firstX - b.run.firstX);
|
|
26898
|
+
for (let i = 1; i < drawn.length; i++) {
|
|
26899
|
+
const prev = drawn[i - 1];
|
|
26900
|
+
const cur = drawn[i];
|
|
26901
|
+
if (prev.x1 <= cur.x0) continue;
|
|
26902
|
+
const mid = (prev.run.lastX + cur.run.firstX) / 2;
|
|
26903
|
+
prev.x1 = Math.max(prev.run.lastX, Math.min(prev.x1, mid - ERA_SEAM_GAP));
|
|
26904
|
+
cur.x0 = Math.min(cur.run.firstX, Math.max(cur.x0, mid + ERA_SEAM_GAP));
|
|
26905
|
+
}
|
|
26906
|
+
for (const { run: r, x0: x02, x1: x12 } of drawn) {
|
|
26732
26907
|
const neutral = !r.era.color;
|
|
26733
26908
|
const col = neutral ? palette.text : resolveColor(r.era.color, palette) ?? palette.text;
|
|
26734
26909
|
const op = neutral ? 0.5 : 0.85;
|
|
26735
|
-
const x02 = clampX(r.firstX - 14);
|
|
26736
|
-
const x12 = clampX(r.lastX + 14);
|
|
26737
26910
|
const y = eraBaseY;
|
|
26738
26911
|
const eg = svg.append("g").attr("data-era", r.era.name).attr("data-era-collapsed", String(r.collapsed)).attr("data-line-number", r.era.lineNumber);
|
|
26739
26912
|
eg.append("path").attr(
|
|
@@ -26759,6 +26932,22 @@ function renderEventLineForExport(container, parsed, palette, isDark, exportDims
|
|
|
26759
26932
|
tagOverride
|
|
26760
26933
|
);
|
|
26761
26934
|
}
|
|
26935
|
+
function axisBreakPaths(cx, cy) {
|
|
26936
|
+
const HUMPS = 2;
|
|
26937
|
+
const STEPS = 14;
|
|
26938
|
+
const wave = (x0) => {
|
|
26939
|
+
let d = "";
|
|
26940
|
+
for (let i = 0; i <= STEPS; i++) {
|
|
26941
|
+
const t = i / STEPS;
|
|
26942
|
+
const y = cy - BREAK_HALF_H + t * 2 * BREAK_HALF_H;
|
|
26943
|
+
const x = x0 + BREAK_AMP * Math.sin(t * Math.PI * HUMPS);
|
|
26944
|
+
d += `${i === 0 ? "M" : "L"}${x.toFixed(2)},${y.toFixed(2)}`;
|
|
26945
|
+
if (i < STEPS) d += " ";
|
|
26946
|
+
}
|
|
26947
|
+
return d;
|
|
26948
|
+
};
|
|
26949
|
+
return [wave(cx - BREAK_GAP / 2), wave(cx + BREAK_GAP / 2)];
|
|
26950
|
+
}
|
|
26762
26951
|
function wrapDescription(lines, charsPerLine) {
|
|
26763
26952
|
const out = [];
|
|
26764
26953
|
for (const line11 of lines) {
|
|
@@ -26788,7 +26977,7 @@ function renderBody(cardG, lines, bodyColor, palette, startBaseline = CARD_BODY_
|
|
|
26788
26977
|
y += DESC_LINE_H;
|
|
26789
26978
|
}
|
|
26790
26979
|
}
|
|
26791
|
-
var CARD_W, H_MARGIN, TITLE_AREA, LEGEND_BAND, LEADER_ABOVE, LEADER_BELOW, DESC_FONT, DESC_LINE_H, CARD_PAD, CARD_BODY_TOP, DOT_R, MIN_SPACING, LANE_GAP, NEUTRAL_TAG, CARD_INSET, FAN_GAP, DATE_OFFSET, ERA_BLOCK, ERA_BRACKET_CAP, ERA_LEG, ERA_LABEL_FONT
|
|
26980
|
+
var CARD_W, H_MARGIN, TITLE_AREA, LEGEND_BAND, LEADER_ABOVE, LEADER_BELOW, DESC_FONT, DESC_LINE_H, CARD_PAD, CARD_BODY_TOP, DOT_R, MIN_SPACING, LANE_GAP, NEUTRAL_TAG, CARD_INSET, FAN_GAP, DATE_OFFSET, ERA_BLOCK, ERA_BRACKET_CAP, ERA_BRACKET_PAD, ERA_SEAM_GAP, BREAK_HALF_H, BREAK_AMP, BREAK_GAP, ERA_LEG, ERA_LABEL_FONT;
|
|
26792
26981
|
var init_renderer = __esm({
|
|
26793
26982
|
"src/event-line/renderer.ts"() {
|
|
26794
26983
|
"use strict";
|
|
@@ -26822,9 +27011,13 @@ var init_renderer = __esm({
|
|
|
26822
27011
|
DATE_OFFSET = 28;
|
|
26823
27012
|
ERA_BLOCK = 30;
|
|
26824
27013
|
ERA_BRACKET_CAP = 8;
|
|
27014
|
+
ERA_BRACKET_PAD = 14;
|
|
27015
|
+
ERA_SEAM_GAP = 3;
|
|
27016
|
+
BREAK_HALF_H = 6;
|
|
27017
|
+
BREAK_AMP = 2.2;
|
|
27018
|
+
BREAK_GAP = 5;
|
|
26825
27019
|
ERA_LEG = 13;
|
|
26826
27020
|
ERA_LABEL_FONT = 11.5;
|
|
26827
|
-
ERA_MEMBER_MAX = 6;
|
|
26828
27021
|
}
|
|
26829
27022
|
});
|
|
26830
27023
|
|
|
@@ -53297,6 +53490,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53297
53490
|
y,
|
|
53298
53491
|
score,
|
|
53299
53492
|
palette,
|
|
53493
|
+
isDark,
|
|
53300
53494
|
SCORE_LABEL_R
|
|
53301
53495
|
);
|
|
53302
53496
|
if (!exportDims) {
|
|
@@ -53328,7 +53522,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53328
53522
|
const allSteps = parsed.phases.length > 0 ? parsed.phases.flatMap((p) => p.steps) : parsed.steps;
|
|
53329
53523
|
for (const pt of layout.curvePoints) {
|
|
53330
53524
|
const step = allSteps[pt.stepIndex];
|
|
53331
|
-
const faceG = renderScoreFace(
|
|
53525
|
+
const faceG = renderScoreFace(
|
|
53526
|
+
curveG,
|
|
53527
|
+
pt.x,
|
|
53528
|
+
pt.y,
|
|
53529
|
+
pt.score,
|
|
53530
|
+
palette,
|
|
53531
|
+
isDark
|
|
53532
|
+
);
|
|
53332
53533
|
addEmotionLabel(faceG, pt, palette);
|
|
53333
53534
|
if (step) {
|
|
53334
53535
|
faceG.attr("data-line-number", step.lineNumber);
|
|
@@ -53354,7 +53555,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53354
53555
|
const pt = layout.curvePoints[0];
|
|
53355
53556
|
const allSteps = parsed.phases.length > 0 ? parsed.phases.flatMap((p) => p.steps) : parsed.steps;
|
|
53356
53557
|
const step = allSteps[pt.stepIndex];
|
|
53357
|
-
const faceG = renderScoreFace(
|
|
53558
|
+
const faceG = renderScoreFace(
|
|
53559
|
+
curveG,
|
|
53560
|
+
pt.x,
|
|
53561
|
+
pt.y,
|
|
53562
|
+
pt.score,
|
|
53563
|
+
palette,
|
|
53564
|
+
isDark
|
|
53565
|
+
);
|
|
53358
53566
|
addEmotionLabel(faceG, pt, palette);
|
|
53359
53567
|
if (step) {
|
|
53360
53568
|
faceG.attr("data-line-number", step.lineNumber);
|
|
@@ -53451,6 +53659,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53451
53659
|
faceCy,
|
|
53452
53660
|
step.score,
|
|
53453
53661
|
palette,
|
|
53662
|
+
isDark,
|
|
53454
53663
|
COLLAPSED_FACE_R
|
|
53455
53664
|
);
|
|
53456
53665
|
faceG.attr("data-line-number", step.lineNumber);
|
|
@@ -53554,7 +53763,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53554
53763
|
const fcy = parseFloat(el.attr("data-cy") ?? "0");
|
|
53555
53764
|
el.attr(
|
|
53556
53765
|
"transform",
|
|
53557
|
-
`translate(${fcx},${fcy}) scale(
|
|
53766
|
+
`translate(${fcx},${fcy}) scale(${FACE_HOVER_SCALE}) translate(${-fcx},${-fcy})`
|
|
53558
53767
|
);
|
|
53559
53768
|
} else {
|
|
53560
53769
|
el.attr("transform", null);
|
|
@@ -53600,12 +53809,12 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53600
53809
|
PADDING2,
|
|
53601
53810
|
Math.min(fcx - bw / 2, layout.totalWidth - PADDING2 - bw)
|
|
53602
53811
|
);
|
|
53603
|
-
const by = Math.max(PADDING2, fcy -
|
|
53812
|
+
const by = Math.max(PADDING2, fcy - FACE_HOVER_R - THOUGHT_GAP - bh);
|
|
53604
53813
|
const scoreColor = scoreToColor(score, palette);
|
|
53605
53814
|
const tintedBg = mix(scoreColor, palette.surface, 20);
|
|
53606
53815
|
const g = overlayG.append("g").attr("class", "journey-thought-hover");
|
|
53607
53816
|
g.append("rect").attr("x", bx).attr("y", by).attr("width", bw).attr("height", bh).attr("rx", CARD_RADIUS).attr("fill", tintedBg).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
|
|
53608
|
-
g.append("line").attr("x1", fcx).attr("y1", by + bh).attr("x2", fcx).attr("y2", fcy -
|
|
53817
|
+
g.append("line").attr("x1", fcx).attr("y1", by + bh).attr("x2", fcx).attr("y2", fcy - FACE_HOVER_R - 1).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
|
|
53609
53818
|
const centerX = bx + bw / 2;
|
|
53610
53819
|
for (let i = 0; i < lines.length; i++) {
|
|
53611
53820
|
g.append("text").attr("x", centerX).attr("y", by + THOUGHT_PAD_Y + (i + 1) * THOUGHT_LINE_H - 2).attr("text-anchor", "middle").attr("font-size", THOUGHT_FONT).attr("font-style", "italic").attr("fill", palette.textMuted).text(lines[i]);
|
|
@@ -53848,24 +54057,23 @@ function renderPersonaSilhouette(parent, cx, cy, color, palette, scale = 1) {
|
|
|
53848
54057
|
`M ${cx} ${cy - 12 * s} C ${cx + 10 * s} ${cy - 12 * s}, ${cx + 9 * s} ${cy + 2 * s}, ${cx + 6 * s} ${cy + 6 * s} Q ${cx} ${cy + 9 * s}, ${cx - 6 * s} ${cy + 6 * s} C ${cx - 9 * s} ${cy + 2 * s}, ${cx - 10 * s} ${cy - 12 * s}, ${cx} ${cy - 12 * s} Z`
|
|
53849
54058
|
).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.2);
|
|
53850
54059
|
}
|
|
53851
|
-
function renderScoreFace(parent, cx, cy, score, palette, radius) {
|
|
54060
|
+
function renderScoreFace(parent, cx, cy, score, palette, isDark, radius) {
|
|
53852
54061
|
const r = radius ?? FACE_RADIUS;
|
|
53853
54062
|
const color = scoreToColor(score, palette);
|
|
53854
54063
|
const g = parent.append("g").attr("class", "journey-face").attr("data-cx", cx).attr("data-cy", cy);
|
|
53855
|
-
|
|
53856
|
-
|
|
53857
|
-
|
|
53858
|
-
|
|
53859
|
-
palette.textOnFillDark
|
|
53860
|
-
);
|
|
54064
|
+
const faceFill = shapeFill(palette, color, isDark);
|
|
54065
|
+
g.append("circle").attr("cx", cx).attr("cy", cy).attr("r", r + 1).attr("fill", palette.bg);
|
|
54066
|
+
g.append("circle").attr("cx", cx).attr("cy", cy).attr("r", r).attr("fill", faceFill).attr("stroke", color).attr("stroke-width", 2);
|
|
54067
|
+
const eyeColor = color;
|
|
53861
54068
|
const eyeY = cy - r * 0.15;
|
|
53862
54069
|
const eyeSpacing = r * 0.32;
|
|
53863
54070
|
const eyeR = r * 0.12;
|
|
53864
54071
|
g.append("circle").attr("cx", cx - eyeSpacing).attr("cy", eyeY).attr("r", eyeR).attr("fill", eyeColor);
|
|
53865
54072
|
g.append("circle").attr("cx", cx + eyeSpacing).attr("cy", eyeY).attr("r", eyeR).attr("fill", eyeColor);
|
|
53866
|
-
const
|
|
53867
|
-
const
|
|
53868
|
-
const
|
|
54073
|
+
const mouthW = r * 0.46;
|
|
54074
|
+
const curve = (score - 3) / 2 * r * 0.42;
|
|
54075
|
+
const apexY = cy + r * 0.32;
|
|
54076
|
+
const mouthY = apexY - curve / 2;
|
|
53869
54077
|
g.append("path").attr(
|
|
53870
54078
|
"d",
|
|
53871
54079
|
`M ${cx - mouthW} ${mouthY} Q ${cx} ${mouthY + curve} ${cx + mouthW} ${mouthY}`
|
|
@@ -53936,7 +54144,7 @@ function renderJourneyMapForExport(content, theme, palette) {
|
|
|
53936
54144
|
}
|
|
53937
54145
|
return svgEl.outerHTML;
|
|
53938
54146
|
}
|
|
53939
|
-
var DIAGRAM_PADDING13, PADDING2, CARD_PADDING_X3, CARD_PADDING_Y3, CARD_HEADER_HEIGHT3, CARD_STROKE_WIDTH2, CARD_META_LINE_HEIGHT3, CARD_GAP_INTERNAL, COLUMN_RADIUS2, COLUMN_HEADER_HEIGHT2, COLUMN_PADDING3, FONT_SIZE_TITLE, FONT_SIZE_PHASE, FONT_SIZE_STEP, FONT_SIZE_META, GRID_LINE_OPACITY, CURVE_STROKE_WIDTH, FACE_RADIUS, DIM_HOVER, TITLE_LINE_HEIGHT, EMOTION_LABEL_MAX_WIDTH, EMOTION_LABEL_FONT_SIZE, ICON_THUMBS_DOWN, ICON_THUMBS_UP, ICON_THOUGHT;
|
|
54147
|
+
var DIAGRAM_PADDING13, PADDING2, CARD_PADDING_X3, CARD_PADDING_Y3, CARD_HEADER_HEIGHT3, CARD_STROKE_WIDTH2, CARD_META_LINE_HEIGHT3, CARD_GAP_INTERNAL, COLUMN_RADIUS2, COLUMN_HEADER_HEIGHT2, COLUMN_PADDING3, FONT_SIZE_TITLE, FONT_SIZE_PHASE, FONT_SIZE_STEP, FONT_SIZE_META, GRID_LINE_OPACITY, CURVE_STROKE_WIDTH, FACE_RADIUS, FACE_HOVER_SCALE, FACE_HOVER_R, DIM_HOVER, TITLE_LINE_HEIGHT, EMOTION_LABEL_MAX_WIDTH, EMOTION_LABEL_FONT_SIZE, ICON_THUMBS_DOWN, ICON_THUMBS_UP, ICON_THOUGHT;
|
|
53940
54148
|
var init_renderer17 = __esm({
|
|
53941
54149
|
"src/journey-map/renderer.ts"() {
|
|
53942
54150
|
"use strict";
|
|
@@ -53970,6 +54178,8 @@ var init_renderer17 = __esm({
|
|
|
53970
54178
|
GRID_LINE_OPACITY = 0.15;
|
|
53971
54179
|
CURVE_STROKE_WIDTH = 2.5;
|
|
53972
54180
|
FACE_RADIUS = 14;
|
|
54181
|
+
FACE_HOVER_SCALE = 1.5;
|
|
54182
|
+
FACE_HOVER_R = (FACE_RADIUS + 1) * FACE_HOVER_SCALE;
|
|
53973
54183
|
DIM_HOVER = 0.25;
|
|
53974
54184
|
TITLE_LINE_HEIGHT = 16;
|
|
53975
54185
|
EMOTION_LABEL_MAX_WIDTH = 180;
|