@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.cjs
CHANGED
|
@@ -105,7 +105,7 @@ function vennAliasKeywordRemovedMessage(args) {
|
|
|
105
105
|
return `Venn 'alias' keyword was removed. Use 'as' instead \u2014 '${args.name} as ${args.alias}'.`;
|
|
106
106
|
}
|
|
107
107
|
function pipeOperatorRemovedMessage() {
|
|
108
|
-
return `'|'
|
|
108
|
+
return `'|' is no longer metadata syntax \u2014 write metadata inline as 'key: value' (e.g. "Name color: red"), or remove the '|'.`;
|
|
109
109
|
}
|
|
110
110
|
function ganttBarePercentRemovedMessage(percent) {
|
|
111
111
|
return `Bare-percent progress shorthand '| ${percent}' was removed. Use 'progress: ${percent.replace(/%$/, "")}' (integer 0\u2013100, no '%').`;
|
|
@@ -13658,7 +13658,8 @@ function buildScatterOption(parsed, palette, isDark, textColor, axisLineColor, g
|
|
|
13658
13658
|
solid: parsed.solidFill === true
|
|
13659
13659
|
}),
|
|
13660
13660
|
borderColor: catColor,
|
|
13661
|
-
borderWidth: CHART_BORDER_WIDTH
|
|
13661
|
+
borderWidth: CHART_BORDER_WIDTH,
|
|
13662
|
+
opacity: SCATTER_FILL_OPACITY
|
|
13662
13663
|
},
|
|
13663
13664
|
label: labelConfig,
|
|
13664
13665
|
emphasis: emphasisConfig,
|
|
@@ -13685,6 +13686,7 @@ function buildScatterOption(parsed, palette, isDark, textColor, axisLineColor, g
|
|
|
13685
13686
|
{
|
|
13686
13687
|
type: "scatter",
|
|
13687
13688
|
data,
|
|
13689
|
+
itemStyle: { opacity: SCATTER_FILL_OPACITY },
|
|
13688
13690
|
label: labelConfig,
|
|
13689
13691
|
emphasis: emphasisConfig,
|
|
13690
13692
|
blur: blurConfig
|
|
@@ -14990,7 +14992,7 @@ async function renderExtendedChartForExport(content, theme, palette) {
|
|
|
14990
14992
|
chart.dispose();
|
|
14991
14993
|
}
|
|
14992
14994
|
}
|
|
14993
|
-
var echarts, import_charts, import_components, import_renderers, 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;
|
|
14995
|
+
var echarts, import_charts, import_components, import_renderers, 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;
|
|
14994
14996
|
var init_echarts = __esm({
|
|
14995
14997
|
"src/echarts.ts"() {
|
|
14996
14998
|
"use strict";
|
|
@@ -15048,6 +15050,7 @@ var init_echarts = __esm({
|
|
|
15048
15050
|
tooltip: { show: false }
|
|
15049
15051
|
};
|
|
15050
15052
|
CHART_BORDER_WIDTH = 2;
|
|
15053
|
+
SCATTER_FILL_OPACITY = 0.65;
|
|
15051
15054
|
VALID_EXTENDED_TYPES = /* @__PURE__ */ new Set([
|
|
15052
15055
|
"sankey",
|
|
15053
15056
|
"chord",
|
|
@@ -15145,6 +15148,8 @@ function parseEventLine(content, palette) {
|
|
|
15145
15148
|
let currentTagGroup = null;
|
|
15146
15149
|
let currentEvent = null;
|
|
15147
15150
|
let currentEra = null;
|
|
15151
|
+
let eraIndent = -1;
|
|
15152
|
+
let currentEventIndent = 0;
|
|
15148
15153
|
const aliasMap = /* @__PURE__ */ new Map();
|
|
15149
15154
|
for (let i = 0; i < lines.length; i++) {
|
|
15150
15155
|
const line11 = lines[i];
|
|
@@ -15219,52 +15224,15 @@ function parseEventLine(content, palette) {
|
|
|
15219
15224
|
});
|
|
15220
15225
|
continue;
|
|
15221
15226
|
}
|
|
15222
|
-
if (indent >
|
|
15223
|
-
if (!currentEvent) {
|
|
15224
|
-
pushWarning(
|
|
15225
|
-
lineNumber,
|
|
15226
|
-
`Indented description "${trimmed}" has no event above it \u2014 add an event line first. (\xA728)`
|
|
15227
|
-
);
|
|
15228
|
-
continue;
|
|
15229
|
-
}
|
|
15227
|
+
if (currentEvent && indent > currentEventIndent) {
|
|
15230
15228
|
const descLine = trimmed.startsWith("- ") ? `\u2022 ${trimmed.substring(2)}` : trimmed;
|
|
15231
15229
|
currentEvent.description.push(descLine);
|
|
15232
15230
|
continue;
|
|
15233
15231
|
}
|
|
15234
|
-
currentTagGroup = null;
|
|
15235
|
-
if (trimmed.toLowerCase() === "no-scale") {
|
|
15236
|
-
options.scale = false;
|
|
15237
|
-
continue;
|
|
15238
|
-
}
|
|
15239
|
-
const sideMatch = trimmed.match(SIDE_RE);
|
|
15240
|
-
if (sideMatch) {
|
|
15241
|
-
options.side = sideMatch[1].toLowerCase();
|
|
15242
|
-
continue;
|
|
15243
|
-
}
|
|
15244
|
-
if (trimmed.toLowerCase() === "no-box") {
|
|
15245
|
-
options.noBox = true;
|
|
15246
|
-
continue;
|
|
15247
|
-
}
|
|
15248
|
-
if (trimmed.toLowerCase() === "no-legend") {
|
|
15249
|
-
options.noLegend = true;
|
|
15250
|
-
continue;
|
|
15251
|
-
}
|
|
15252
|
-
const dirMatch = trimmed.match(DIRECTION_RE);
|
|
15253
|
-
if (dirMatch) {
|
|
15254
|
-
const dir = dirMatch[1].toUpperCase();
|
|
15255
|
-
if (dir !== "LR") {
|
|
15256
|
-
pushWarning(
|
|
15257
|
-
lineNumber,
|
|
15258
|
-
`event-line is horizontal-only in v1; \`direction ${dir}\` (vertical orientation) is a fast-follow.`,
|
|
15259
|
-
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15260
|
-
);
|
|
15261
|
-
}
|
|
15262
|
-
continue;
|
|
15263
|
-
}
|
|
15264
|
-
if (tryParseSharedOption(trimmed, sharedOptions)) continue;
|
|
15265
15232
|
const eraMatch = trimmed.match(ERA_RE);
|
|
15266
15233
|
if (eraMatch) {
|
|
15267
15234
|
contentStarted = true;
|
|
15235
|
+
currentTagGroup = null;
|
|
15268
15236
|
currentEvent = null;
|
|
15269
15237
|
const name = eraMatch[1].trim();
|
|
15270
15238
|
let rest = (eraMatch[2] ?? "").trim();
|
|
@@ -15288,16 +15256,52 @@ function parseEventLine(content, palette) {
|
|
|
15288
15256
|
const era = { name, color, collapsed, lineNumber };
|
|
15289
15257
|
result.eras.push(era);
|
|
15290
15258
|
currentEra = name;
|
|
15259
|
+
eraIndent = indent;
|
|
15291
15260
|
continue;
|
|
15292
15261
|
}
|
|
15293
|
-
if (
|
|
15294
|
-
|
|
15295
|
-
|
|
15296
|
-
|
|
15297
|
-
|
|
15298
|
-
|
|
15299
|
-
|
|
15262
|
+
if (indent === 0) {
|
|
15263
|
+
currentTagGroup = null;
|
|
15264
|
+
if (trimmed.toLowerCase() === "no-scale") {
|
|
15265
|
+
options.scale = false;
|
|
15266
|
+
continue;
|
|
15267
|
+
}
|
|
15268
|
+
const sideMatch = trimmed.match(SIDE_RE);
|
|
15269
|
+
if (sideMatch) {
|
|
15270
|
+
options.side = sideMatch[1].toLowerCase();
|
|
15271
|
+
continue;
|
|
15272
|
+
}
|
|
15273
|
+
if (trimmed.toLowerCase() === "no-box") {
|
|
15274
|
+
options.noBox = true;
|
|
15275
|
+
continue;
|
|
15276
|
+
}
|
|
15277
|
+
if (trimmed.toLowerCase() === "no-legend") {
|
|
15278
|
+
options.noLegend = true;
|
|
15279
|
+
continue;
|
|
15280
|
+
}
|
|
15281
|
+
const dirMatch = trimmed.match(DIRECTION_RE);
|
|
15282
|
+
if (dirMatch) {
|
|
15283
|
+
const dir = dirMatch[1].toUpperCase();
|
|
15284
|
+
if (dir !== "LR") {
|
|
15285
|
+
pushWarning(
|
|
15286
|
+
lineNumber,
|
|
15287
|
+
`event-line is horizontal-only in v1; \`direction ${dir}\` (vertical orientation) is a fast-follow.`,
|
|
15288
|
+
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15289
|
+
);
|
|
15290
|
+
}
|
|
15291
|
+
continue;
|
|
15292
|
+
}
|
|
15293
|
+
if (tryParseSharedOption(trimmed, sharedOptions)) continue;
|
|
15294
|
+
if (SECTION_SEAM_RE.test(trimmed)) {
|
|
15295
|
+
pushWarning(
|
|
15296
|
+
lineNumber,
|
|
15297
|
+
"Group events with `[Name]` era brackets (\xA728.6a), not `section`.",
|
|
15298
|
+
EVENT_LINE_DIAGNOSTIC_CODES.UNSUPPORTED
|
|
15299
|
+
);
|
|
15300
|
+
continue;
|
|
15301
|
+
}
|
|
15300
15302
|
}
|
|
15303
|
+
const inEra = currentEra !== null && indent > eraIndent;
|
|
15304
|
+
if (!inEra) currentEra = null;
|
|
15301
15305
|
contentStarted = true;
|
|
15302
15306
|
const event = parseEventHeader(
|
|
15303
15307
|
trimmed,
|
|
@@ -15309,6 +15313,7 @@ function parseEventLine(content, palette) {
|
|
|
15309
15313
|
);
|
|
15310
15314
|
result.events.push(event);
|
|
15311
15315
|
currentEvent = event;
|
|
15316
|
+
currentEventIndent = indent;
|
|
15312
15317
|
}
|
|
15313
15318
|
options.noTitle = sharedOptions["no-title"] === "on";
|
|
15314
15319
|
finalizeAutoTagColors(result.tagGroups, palette);
|
|
@@ -15323,8 +15328,61 @@ function parseEventLine(content, palette) {
|
|
|
15323
15328
|
EVENT_LINE_DIAGNOSTIC_CODES.NO_EVENTS
|
|
15324
15329
|
);
|
|
15325
15330
|
}
|
|
15331
|
+
if (options.scale) {
|
|
15332
|
+
validateEraDateOrder(result.events, result.eras, pushWarning);
|
|
15333
|
+
}
|
|
15326
15334
|
return result;
|
|
15327
15335
|
}
|
|
15336
|
+
function validateEraDateOrder(events, eras, pushWarning) {
|
|
15337
|
+
if (eras.length < 2) return;
|
|
15338
|
+
const order = new Map(eras.map((e, i) => [e.name, i]));
|
|
15339
|
+
const dated = events.filter(
|
|
15340
|
+
(e) => e.dateValue !== null && e.era !== null && order.has(e.era)
|
|
15341
|
+
);
|
|
15342
|
+
if (dated.length === 0) return;
|
|
15343
|
+
const perEra = /* @__PURE__ */ new Map();
|
|
15344
|
+
for (const ev of dated) {
|
|
15345
|
+
const idx = order.get(ev.era);
|
|
15346
|
+
const cur = perEra.get(idx);
|
|
15347
|
+
if (!cur) {
|
|
15348
|
+
perEra.set(idx, { min: ev, max: ev });
|
|
15349
|
+
} else {
|
|
15350
|
+
if (ev.dateValue < cur.min.dateValue) cur.min = ev;
|
|
15351
|
+
if (ev.dateValue > cur.max.dateValue) cur.max = ev;
|
|
15352
|
+
}
|
|
15353
|
+
}
|
|
15354
|
+
const n = eras.length;
|
|
15355
|
+
const prefixMax = new Array(n).fill(null);
|
|
15356
|
+
const suffixMin = new Array(n).fill(null);
|
|
15357
|
+
for (let k = 1; k < n; k++) {
|
|
15358
|
+
const prev = perEra.get(k - 1)?.max ?? null;
|
|
15359
|
+
const carried = prefixMax[k - 1] ?? null;
|
|
15360
|
+
prefixMax[k] = prev && (!carried || prev.dateValue > carried.dateValue) ? prev : carried;
|
|
15361
|
+
}
|
|
15362
|
+
for (let k = n - 2; k >= 0; k--) {
|
|
15363
|
+
const next = perEra.get(k + 1)?.min ?? null;
|
|
15364
|
+
const carried = suffixMin[k + 1] ?? null;
|
|
15365
|
+
suffixMin[k] = next && (!carried || next.dateValue < carried.dateValue) ? next : carried;
|
|
15366
|
+
}
|
|
15367
|
+
for (const ev of dated) {
|
|
15368
|
+
const k = order.get(ev.era);
|
|
15369
|
+
const ahead = suffixMin[k];
|
|
15370
|
+
const behind = prefixMax[k];
|
|
15371
|
+
if (ahead && ev.dateValue > ahead.dateValue) {
|
|
15372
|
+
pushWarning(
|
|
15373
|
+
ev.lineNumber,
|
|
15374
|
+
`"${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.`,
|
|
15375
|
+
EVENT_LINE_DIAGNOSTIC_CODES.ERA_DATE_ORDER
|
|
15376
|
+
);
|
|
15377
|
+
} else if (behind && ev.dateValue < behind.dateValue) {
|
|
15378
|
+
pushWarning(
|
|
15379
|
+
ev.lineNumber,
|
|
15380
|
+
`"${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.`,
|
|
15381
|
+
EVENT_LINE_DIAGNOSTIC_CODES.ERA_DATE_ORDER
|
|
15382
|
+
);
|
|
15383
|
+
}
|
|
15384
|
+
}
|
|
15385
|
+
}
|
|
15328
15386
|
function parseEventHeader(trimmed, lineNumber, era, aliasMap, diagnostics, pushWarning) {
|
|
15329
15387
|
let date = null;
|
|
15330
15388
|
let dateValue = null;
|
|
@@ -15391,7 +15449,8 @@ var init_parser13 = __esm({
|
|
|
15391
15449
|
EVENT_LINE_DIAGNOSTIC_CODES = {
|
|
15392
15450
|
NO_EVENTS: "E_EVENT_LINE_NO_EVENTS",
|
|
15393
15451
|
BAD_DATE: "E_EVENT_LINE_BAD_DATE",
|
|
15394
|
-
UNSUPPORTED: "E_EVENT_LINE_UNSUPPORTED"
|
|
15452
|
+
UNSUPPORTED: "E_EVENT_LINE_UNSUPPORTED",
|
|
15453
|
+
ERA_DATE_ORDER: "E_EVENT_LINE_ERA_DATE_ORDER"
|
|
15395
15454
|
};
|
|
15396
15455
|
NON_ISO_DATE_RE = /^\d{1,4}[/.]\d/;
|
|
15397
15456
|
SIDE_RE = /^side\s+(above|below|alternate)\b/i;
|
|
@@ -26327,9 +26386,6 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26327
26386
|
const hasExpandedEra = parsed.events.some(
|
|
26328
26387
|
(e) => e.era && eraByName.has(e.era) && !collapsedSet.has(e.era)
|
|
26329
26388
|
);
|
|
26330
|
-
const anyCollapsed = parsed.events.some(
|
|
26331
|
-
(e) => e.era && collapsedSet.has(e.era)
|
|
26332
|
-
);
|
|
26333
26389
|
const sideOpt = parsed.options.side;
|
|
26334
26390
|
const alternate = sideOpt === "alternate";
|
|
26335
26391
|
const eraSide = alternate ? "below" : sideOpt === "above" ? "below" : "above";
|
|
@@ -26396,7 +26452,8 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26396
26452
|
x: 0,
|
|
26397
26453
|
side,
|
|
26398
26454
|
lane: 0,
|
|
26399
|
-
left: 0
|
|
26455
|
+
left: 0,
|
|
26456
|
+
spanHalf: 0
|
|
26400
26457
|
};
|
|
26401
26458
|
}
|
|
26402
26459
|
const era = slot.era;
|
|
@@ -26409,19 +26466,19 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26409
26466
|
palette.textOnFillLight,
|
|
26410
26467
|
palette.textOnFillDark
|
|
26411
26468
|
);
|
|
26412
|
-
|
|
26413
|
-
|
|
26414
|
-
const
|
|
26469
|
+
let spanLo = null;
|
|
26470
|
+
let spanHi = null;
|
|
26471
|
+
for (const m of slot.members) {
|
|
26472
|
+
if (m.dateValue === null) continue;
|
|
26473
|
+
if (spanLo === null || m.dateValue < spanLo) spanLo = m.dateValue;
|
|
26474
|
+
if (spanHi === null || m.dateValue > spanHi) spanHi = m.dateValue;
|
|
26475
|
+
}
|
|
26476
|
+
const repDateValue = spanLo !== null && spanHi !== null ? (spanLo + spanHi) / 2 : null;
|
|
26477
|
+
const memberStrs = slot.members.map(
|
|
26415
26478
|
(m) => `\u2022 ${m.date ? `${m.date} ` : ""}${m.label}`
|
|
26416
26479
|
);
|
|
26417
|
-
const bulletColors =
|
|
26480
|
+
const bulletColors = slot.members.map(eventColor);
|
|
26418
26481
|
const lines = wrapDescription(memberStrs, charsPerLine);
|
|
26419
|
-
if (overflow) {
|
|
26420
|
-
lines.push({
|
|
26421
|
-
text: `+${slot.members.length - (ERA_MEMBER_MAX - 1)} more`,
|
|
26422
|
-
kind: "plain"
|
|
26423
|
-
});
|
|
26424
|
-
}
|
|
26425
26482
|
return {
|
|
26426
26483
|
kind: "era",
|
|
26427
26484
|
event: null,
|
|
@@ -26429,7 +26486,7 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26429
26486
|
members: slot.members,
|
|
26430
26487
|
label: era.name,
|
|
26431
26488
|
date: null,
|
|
26432
|
-
dateValue:
|
|
26489
|
+
dateValue: repDateValue,
|
|
26433
26490
|
lineNumber: era.lineNumber,
|
|
26434
26491
|
eraName: era.name,
|
|
26435
26492
|
color: solid,
|
|
@@ -26441,87 +26498,189 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26441
26498
|
x: 0,
|
|
26442
26499
|
side,
|
|
26443
26500
|
lane: 0,
|
|
26444
|
-
left: 0
|
|
26501
|
+
left: 0,
|
|
26502
|
+
spanHalf: 0
|
|
26445
26503
|
};
|
|
26446
26504
|
});
|
|
26447
|
-
const scaled = parsed.options.scale &&
|
|
26505
|
+
const scaled = parsed.options.scale && placed.every((p) => p.dateValue !== null);
|
|
26448
26506
|
const innerW = width - H_MARGIN * 2;
|
|
26449
|
-
|
|
26450
|
-
|
|
26451
|
-
|
|
26452
|
-
|
|
26453
|
-
|
|
26454
|
-
|
|
26507
|
+
const MIN_DOT_GAP = 16;
|
|
26508
|
+
const STRETCH_CAP = 8;
|
|
26509
|
+
const COLLAPSE_W = 64;
|
|
26510
|
+
const SEG_GAP = 16;
|
|
26511
|
+
const segments = [];
|
|
26512
|
+
let run = [];
|
|
26513
|
+
const flushRun = () => {
|
|
26514
|
+
if (!run.length) return;
|
|
26515
|
+
const ds = run.map((e) => e.dateValue);
|
|
26516
|
+
segments.push({
|
|
26517
|
+
kind: "run",
|
|
26518
|
+
events: run,
|
|
26519
|
+
lo: Math.min(...ds),
|
|
26520
|
+
hi: Math.max(...ds)
|
|
26455
26521
|
});
|
|
26456
|
-
|
|
26457
|
-
|
|
26458
|
-
|
|
26459
|
-
|
|
26460
|
-
|
|
26461
|
-
|
|
26462
|
-
|
|
26522
|
+
run = [];
|
|
26523
|
+
};
|
|
26524
|
+
for (const p of placed) {
|
|
26525
|
+
if (p.kind === "era") {
|
|
26526
|
+
flushRun();
|
|
26527
|
+
segments.push({ kind: "capsule", p });
|
|
26528
|
+
} else {
|
|
26529
|
+
run.push(p);
|
|
26530
|
+
}
|
|
26531
|
+
}
|
|
26532
|
+
flushRun();
|
|
26533
|
+
const totalRunTime = segments.reduce(
|
|
26534
|
+
(s, seg) => s + (seg.kind === "run" ? seg.hi - seg.lo : 0),
|
|
26535
|
+
0
|
|
26536
|
+
);
|
|
26537
|
+
const place = (stretch) => {
|
|
26538
|
+
if (scaled) {
|
|
26539
|
+
const pxPerUnit = totalRunTime > 0 ? innerW * stretch / totalRunTime : 0;
|
|
26540
|
+
let cursor = H_MARGIN;
|
|
26541
|
+
for (const seg of segments) {
|
|
26542
|
+
if (seg.kind === "capsule") {
|
|
26543
|
+
seg.p.x = cursor + COLLAPSE_W / 2;
|
|
26544
|
+
seg.p.spanHalf = COLLAPSE_W / 2;
|
|
26545
|
+
cursor += COLLAPSE_W + SEG_GAP;
|
|
26546
|
+
} else {
|
|
26547
|
+
for (const e of seg.events) {
|
|
26548
|
+
e.x = cursor + (e.dateValue - seg.lo) * pxPerUnit;
|
|
26549
|
+
e.spanHalf = 0;
|
|
26550
|
+
}
|
|
26551
|
+
cursor += (seg.hi - seg.lo) * pxPerUnit + SEG_GAP;
|
|
26552
|
+
}
|
|
26553
|
+
}
|
|
26554
|
+
let prevX = -Infinity;
|
|
26555
|
+
let prevVal = null;
|
|
26556
|
+
for (const p of [...placed].sort((a, b) => a.x - b.x)) {
|
|
26557
|
+
if (p.kind === "era") {
|
|
26558
|
+
prevX = p.x + p.spanHalf;
|
|
26559
|
+
prevVal = null;
|
|
26560
|
+
continue;
|
|
26561
|
+
}
|
|
26562
|
+
if (p.dateValue === prevVal) {
|
|
26563
|
+
p.x = prevX;
|
|
26564
|
+
continue;
|
|
26565
|
+
}
|
|
26566
|
+
if (p.x < prevX + MIN_DOT_GAP) p.x = prevX + MIN_DOT_GAP;
|
|
26567
|
+
prevX = p.x;
|
|
26568
|
+
prevVal = p.dateValue;
|
|
26569
|
+
}
|
|
26570
|
+
} else {
|
|
26571
|
+
placed.forEach((p) => {
|
|
26572
|
+
p.spanHalf = 0;
|
|
26573
|
+
});
|
|
26574
|
+
const n = placed.length;
|
|
26575
|
+
const spacing = n > 1 ? Math.max(MIN_SPACING, innerW / (n - 1)) : 0;
|
|
26576
|
+
placed.forEach((p, i) => {
|
|
26577
|
+
p.x = H_MARGIN + i * spacing;
|
|
26578
|
+
});
|
|
26579
|
+
}
|
|
26580
|
+
for (const side of ["above", "below"]) {
|
|
26581
|
+
const arr = placed.filter((p) => p.side === side).sort((a, b) => a.x - b.x);
|
|
26582
|
+
const laneRight = [];
|
|
26583
|
+
for (let i = 0; i < arr.length; i++) {
|
|
26584
|
+
const p = arr[i];
|
|
26585
|
+
const next = arr[i + 1];
|
|
26586
|
+
const crowdedRight = !!next && next.x - p.x < CARD_W + FAN_GAP;
|
|
26587
|
+
const preferred = crowdedRight ? p.x - CARD_W + CARD_INSET : p.x - CARD_W / 2;
|
|
26588
|
+
const maxLeft = p.x - CARD_INSET;
|
|
26589
|
+
const minLeft = p.x - CARD_W + CARD_INSET;
|
|
26590
|
+
let lane = laneRight.length;
|
|
26591
|
+
let left = Math.max(preferred, minLeft);
|
|
26592
|
+
for (let l = 0; l < laneRight.length; l++) {
|
|
26593
|
+
const want = Math.max(preferred, laneRight[l] + FAN_GAP, minLeft);
|
|
26594
|
+
if (want <= maxLeft) {
|
|
26595
|
+
lane = l;
|
|
26596
|
+
left = want;
|
|
26597
|
+
break;
|
|
26598
|
+
}
|
|
26599
|
+
}
|
|
26600
|
+
p.lane = lane;
|
|
26601
|
+
p.left = Math.max(6, left);
|
|
26602
|
+
laneRight[lane] = p.left + CARD_W;
|
|
26463
26603
|
}
|
|
26464
|
-
if (p.x < prevX + MIN_DOT_GAP) p.x = prevX + MIN_DOT_GAP;
|
|
26465
|
-
prevX = p.x;
|
|
26466
|
-
prevVal = p.dateValue;
|
|
26467
26604
|
}
|
|
26605
|
+
};
|
|
26606
|
+
const derive = () => {
|
|
26607
|
+
const contentW2 = Math.max(
|
|
26608
|
+
width,
|
|
26609
|
+
Math.max(...placed.map((p) => p.x + p.spanHalf)) + H_MARGIN,
|
|
26610
|
+
Math.max(...placed.map((p) => p.left + CARD_W)) + 6
|
|
26611
|
+
);
|
|
26612
|
+
const laneOffset = { above: [], below: [] };
|
|
26613
|
+
for (const side of ["above", "below"]) {
|
|
26614
|
+
const laneH = [];
|
|
26615
|
+
for (const p of placed) {
|
|
26616
|
+
if (p.side !== side) continue;
|
|
26617
|
+
laneH[p.lane] = Math.max(laneH[p.lane] ?? 0, p.cardH);
|
|
26618
|
+
}
|
|
26619
|
+
const off = [];
|
|
26620
|
+
let acc = 0;
|
|
26621
|
+
for (let l = 0; l < laneH.length; l++) {
|
|
26622
|
+
off[l] = acc;
|
|
26623
|
+
acc += (laneH[l] ?? 0) + LANE_GAP;
|
|
26624
|
+
}
|
|
26625
|
+
laneOffset[side] = off;
|
|
26626
|
+
}
|
|
26627
|
+
const laneNear2 = (p) => (p.side === "above" ? LEADER_ABOVE : LEADER_BELOW) + (laneOffset[p.side][p.lane] ?? 0);
|
|
26628
|
+
const ext = (side) => Math.max(
|
|
26629
|
+
0,
|
|
26630
|
+
...placed.filter((p) => p.side === side).map((p) => laneNear2(p) + p.cardH)
|
|
26631
|
+
);
|
|
26632
|
+
const dateAbove = placed.some((p) => p.side === "below" && p.date);
|
|
26633
|
+
const dateBelow = placed.some((p) => p.side === "above" && p.date);
|
|
26634
|
+
const contentAbove = Math.max(
|
|
26635
|
+
ext("above"),
|
|
26636
|
+
dateAbove ? DATE_OFFSET + 10 : 0
|
|
26637
|
+
);
|
|
26638
|
+
const contentBelow = Math.max(
|
|
26639
|
+
ext("below"),
|
|
26640
|
+
dateBelow ? DATE_OFFSET + 10 : 0
|
|
26641
|
+
);
|
|
26642
|
+
const aboveExt = contentAbove + (hasExpandedEra && eraSide === "above" ? ERA_BLOCK : 0);
|
|
26643
|
+
const belowExt = contentBelow + (hasExpandedEra && eraSide === "below" ? ERA_BLOCK : 0);
|
|
26644
|
+
const TOP_PAD = 14;
|
|
26645
|
+
const BOT_PAD = 14;
|
|
26646
|
+
const spineY2 = topUsed + TOP_PAD + aboveExt;
|
|
26647
|
+
const eraBaseY2 = eraSide === "above" ? spineY2 - (contentAbove + 14) : spineY2 + (contentBelow + 14);
|
|
26648
|
+
const contentH = spineY2 + belowExt + BOT_PAD;
|
|
26649
|
+
const totalH2 = Math.max(heightHint, contentH);
|
|
26650
|
+
return { contentW: contentW2, contentH, totalH: totalH2, spineY: spineY2, eraBaseY: eraBaseY2, laneNear: laneNear2 };
|
|
26651
|
+
};
|
|
26652
|
+
const envStretch = Number(
|
|
26653
|
+
globalThis.process?.env?.["DGMO_EVT_STRETCH"]
|
|
26654
|
+
);
|
|
26655
|
+
let layout;
|
|
26656
|
+
if (Number.isFinite(envStretch) && envStretch > 0) {
|
|
26657
|
+
place(envStretch);
|
|
26658
|
+
layout = derive();
|
|
26468
26659
|
} else {
|
|
26469
|
-
|
|
26470
|
-
|
|
26471
|
-
|
|
26472
|
-
|
|
26473
|
-
|
|
26474
|
-
|
|
26475
|
-
|
|
26476
|
-
|
|
26477
|
-
|
|
26478
|
-
|
|
26479
|
-
|
|
26480
|
-
|
|
26481
|
-
|
|
26482
|
-
|
|
26483
|
-
|
|
26484
|
-
|
|
26485
|
-
|
|
26486
|
-
let left = Math.max(preferred, minLeft);
|
|
26487
|
-
for (let l = 0; l < laneRight.length; l++) {
|
|
26488
|
-
const want = Math.max(preferred, laneRight[l] + FAN_GAP, minLeft);
|
|
26489
|
-
if (want <= maxLeft) {
|
|
26490
|
-
lane = l;
|
|
26491
|
-
left = want;
|
|
26492
|
-
break;
|
|
26660
|
+
place(1);
|
|
26661
|
+
layout = derive();
|
|
26662
|
+
const panelAspect = width / heightHint;
|
|
26663
|
+
const aspectOf = (l) => l.contentW / l.contentH;
|
|
26664
|
+
if (scaled && layout.contentH > heightHint && aspectOf(layout) < panelAspect) {
|
|
26665
|
+
place(STRETCH_CAP);
|
|
26666
|
+
const capped = derive();
|
|
26667
|
+
if (aspectOf(capped) <= panelAspect) {
|
|
26668
|
+
layout = capped;
|
|
26669
|
+
} else {
|
|
26670
|
+
let loF = 1;
|
|
26671
|
+
let hiF = STRETCH_CAP;
|
|
26672
|
+
for (let it = 0; it < 8; it++) {
|
|
26673
|
+
const mid = (loF + hiF) / 2;
|
|
26674
|
+
place(mid);
|
|
26675
|
+
if (aspectOf(derive()) >= panelAspect) hiF = mid;
|
|
26676
|
+
else loF = mid;
|
|
26493
26677
|
}
|
|
26678
|
+
place(hiF);
|
|
26679
|
+
layout = derive();
|
|
26494
26680
|
}
|
|
26495
|
-
p.lane = lane;
|
|
26496
|
-
p.left = Math.max(6, left);
|
|
26497
|
-
laneRight[lane] = p.left + CARD_W;
|
|
26498
26681
|
}
|
|
26499
26682
|
}
|
|
26500
|
-
const contentW =
|
|
26501
|
-
width,
|
|
26502
|
-
Math.max(...placed.map((p) => p.x)) + H_MARGIN,
|
|
26503
|
-
Math.max(...placed.map((p) => p.left + CARD_W)) + 6
|
|
26504
|
-
);
|
|
26505
|
-
const rowGap = (side) => Math.max(0, ...placed.filter((p) => p.side === side).map((p) => p.cardH)) + LANE_GAP;
|
|
26506
|
-
const rowGapA = rowGap("above");
|
|
26507
|
-
const rowGapB = rowGap("below");
|
|
26508
|
-
const ext = (side) => Math.max(
|
|
26509
|
-
0,
|
|
26510
|
-
...placed.filter((p) => p.side === side).map(
|
|
26511
|
-
(p) => (side === "above" ? LEADER_ABOVE : LEADER_BELOW) + p.lane * (side === "above" ? rowGapA : rowGapB) + p.cardH
|
|
26512
|
-
)
|
|
26513
|
-
);
|
|
26514
|
-
const dateAbove = placed.some((p) => p.side === "below" && p.date);
|
|
26515
|
-
const dateBelow = placed.some((p) => p.side === "above" && p.date);
|
|
26516
|
-
const contentAbove = Math.max(ext("above"), dateAbove ? DATE_OFFSET + 10 : 0);
|
|
26517
|
-
const contentBelow = Math.max(ext("below"), dateBelow ? DATE_OFFSET + 10 : 0);
|
|
26518
|
-
const aboveExt = contentAbove + (hasExpandedEra && eraSide === "above" ? ERA_BLOCK : 0);
|
|
26519
|
-
const belowExt = contentBelow + (hasExpandedEra && eraSide === "below" ? ERA_BLOCK : 0);
|
|
26520
|
-
const TOP_PAD = 14;
|
|
26521
|
-
const BOT_PAD = 14;
|
|
26522
|
-
const spineY = topUsed + TOP_PAD + aboveExt;
|
|
26523
|
-
const eraBaseY = eraSide === "above" ? spineY - (contentAbove + 14) : spineY + (contentBelow + 14);
|
|
26524
|
-
const totalH = Math.max(heightHint, spineY + belowExt + BOT_PAD);
|
|
26683
|
+
const { contentW, totalH, spineY, eraBaseY, laneNear } = layout;
|
|
26525
26684
|
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);
|
|
26526
26685
|
svg.append("rect").attr("width", contentW).attr("height", totalH).attr("fill", palette.bg);
|
|
26527
26686
|
if (showTitle) {
|
|
@@ -26549,12 +26708,11 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26549
26708
|
activeGroup
|
|
26550
26709
|
});
|
|
26551
26710
|
}
|
|
26552
|
-
const
|
|
26553
|
-
const
|
|
26554
|
-
const x1 = Math.max(...xs);
|
|
26711
|
+
const x0 = Math.min(...placed.map((p) => p.x - p.spanHalf));
|
|
26712
|
+
const x1 = Math.max(...placed.map((p) => p.x + p.spanHalf));
|
|
26555
26713
|
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");
|
|
26556
26714
|
const geo = placed.map((p) => {
|
|
26557
|
-
const near = p.side === "above" ? spineY -
|
|
26715
|
+
const near = p.side === "above" ? spineY - laneNear(p) : spineY + laneNear(p);
|
|
26558
26716
|
const top = p.side === "above" ? near - p.cardH : near;
|
|
26559
26717
|
return { p, near, top };
|
|
26560
26718
|
});
|
|
@@ -26666,7 +26824,7 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26666
26824
|
for (const p of placed) {
|
|
26667
26825
|
if (p.kind === "era") {
|
|
26668
26826
|
const col = p.color;
|
|
26669
|
-
const half = Math.
|
|
26827
|
+
const half = Math.max(16, p.spanHalf);
|
|
26670
26828
|
const spineLeft = x0 - 20;
|
|
26671
26829
|
const spineRight = x1 + 20;
|
|
26672
26830
|
const bx0 = Math.max(spineLeft, p.x - half);
|
|
@@ -26677,6 +26835,11 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26677
26835
|
"d",
|
|
26678
26836
|
`M${bx0},${spineY} L${bx0},${barY} L${bx1},${barY} L${bx1},${spineY}`
|
|
26679
26837
|
).attr("fill", "none").attr("stroke", col).attr("stroke-width", 1.5).attr("stroke-linecap", "round").attr("stroke-linejoin", "round");
|
|
26838
|
+
const breakCx = (bx0 + bx1) / 2;
|
|
26839
|
+
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");
|
|
26840
|
+
for (const d of axisBreakPaths(breakCx, spineY)) {
|
|
26841
|
+
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);
|
|
26842
|
+
}
|
|
26680
26843
|
if (onClickItem) {
|
|
26681
26844
|
const ln = p.lineNumber;
|
|
26682
26845
|
eg.style("cursor", "pointer").on("click", () => onClickItem(ln));
|
|
@@ -26710,13 +26873,23 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
|
|
|
26710
26873
|
}
|
|
26711
26874
|
const clampX = (v) => Math.max(4, Math.min(contentW - 4, v));
|
|
26712
26875
|
const cap = eraSide === "above" ? 1 : -1;
|
|
26713
|
-
|
|
26714
|
-
|
|
26876
|
+
const drawn = runs.filter((r) => !r.collapsed).map((r) => ({
|
|
26877
|
+
run: r,
|
|
26878
|
+
x0: clampX(r.firstX - ERA_BRACKET_PAD),
|
|
26879
|
+
x1: clampX(r.lastX + ERA_BRACKET_PAD)
|
|
26880
|
+
})).sort((a, b) => a.run.firstX - b.run.firstX);
|
|
26881
|
+
for (let i = 1; i < drawn.length; i++) {
|
|
26882
|
+
const prev = drawn[i - 1];
|
|
26883
|
+
const cur = drawn[i];
|
|
26884
|
+
if (prev.x1 <= cur.x0) continue;
|
|
26885
|
+
const mid = (prev.run.lastX + cur.run.firstX) / 2;
|
|
26886
|
+
prev.x1 = Math.max(prev.run.lastX, Math.min(prev.x1, mid - ERA_SEAM_GAP));
|
|
26887
|
+
cur.x0 = Math.min(cur.run.firstX, Math.max(cur.x0, mid + ERA_SEAM_GAP));
|
|
26888
|
+
}
|
|
26889
|
+
for (const { run: r, x0: x02, x1: x12 } of drawn) {
|
|
26715
26890
|
const neutral = !r.era.color;
|
|
26716
26891
|
const col = neutral ? palette.text : resolveColor(r.era.color, palette) ?? palette.text;
|
|
26717
26892
|
const op = neutral ? 0.5 : 0.85;
|
|
26718
|
-
const x02 = clampX(r.firstX - 14);
|
|
26719
|
-
const x12 = clampX(r.lastX + 14);
|
|
26720
26893
|
const y = eraBaseY;
|
|
26721
26894
|
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);
|
|
26722
26895
|
eg.append("path").attr(
|
|
@@ -26742,6 +26915,22 @@ function renderEventLineForExport(container, parsed, palette, isDark, exportDims
|
|
|
26742
26915
|
tagOverride
|
|
26743
26916
|
);
|
|
26744
26917
|
}
|
|
26918
|
+
function axisBreakPaths(cx, cy) {
|
|
26919
|
+
const HUMPS = 2;
|
|
26920
|
+
const STEPS = 14;
|
|
26921
|
+
const wave = (x0) => {
|
|
26922
|
+
let d = "";
|
|
26923
|
+
for (let i = 0; i <= STEPS; i++) {
|
|
26924
|
+
const t = i / STEPS;
|
|
26925
|
+
const y = cy - BREAK_HALF_H + t * 2 * BREAK_HALF_H;
|
|
26926
|
+
const x = x0 + BREAK_AMP * Math.sin(t * Math.PI * HUMPS);
|
|
26927
|
+
d += `${i === 0 ? "M" : "L"}${x.toFixed(2)},${y.toFixed(2)}`;
|
|
26928
|
+
if (i < STEPS) d += " ";
|
|
26929
|
+
}
|
|
26930
|
+
return d;
|
|
26931
|
+
};
|
|
26932
|
+
return [wave(cx - BREAK_GAP / 2), wave(cx + BREAK_GAP / 2)];
|
|
26933
|
+
}
|
|
26745
26934
|
function wrapDescription(lines, charsPerLine) {
|
|
26746
26935
|
const out = [];
|
|
26747
26936
|
for (const line11 of lines) {
|
|
@@ -26771,7 +26960,7 @@ function renderBody(cardG, lines, bodyColor, palette, startBaseline = CARD_BODY_
|
|
|
26771
26960
|
y += DESC_LINE_H;
|
|
26772
26961
|
}
|
|
26773
26962
|
}
|
|
26774
|
-
var d3Selection6, 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
|
|
26963
|
+
var d3Selection6, 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;
|
|
26775
26964
|
var init_renderer = __esm({
|
|
26776
26965
|
"src/event-line/renderer.ts"() {
|
|
26777
26966
|
"use strict";
|
|
@@ -26806,9 +26995,13 @@ var init_renderer = __esm({
|
|
|
26806
26995
|
DATE_OFFSET = 28;
|
|
26807
26996
|
ERA_BLOCK = 30;
|
|
26808
26997
|
ERA_BRACKET_CAP = 8;
|
|
26998
|
+
ERA_BRACKET_PAD = 14;
|
|
26999
|
+
ERA_SEAM_GAP = 3;
|
|
27000
|
+
BREAK_HALF_H = 6;
|
|
27001
|
+
BREAK_AMP = 2.2;
|
|
27002
|
+
BREAK_GAP = 5;
|
|
26809
27003
|
ERA_LEG = 13;
|
|
26810
27004
|
ERA_LABEL_FONT = 11.5;
|
|
26811
|
-
ERA_MEMBER_MAX = 6;
|
|
26812
27005
|
}
|
|
26813
27006
|
});
|
|
26814
27007
|
|
|
@@ -53279,6 +53472,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53279
53472
|
y,
|
|
53280
53473
|
score,
|
|
53281
53474
|
palette,
|
|
53475
|
+
isDark,
|
|
53282
53476
|
SCORE_LABEL_R
|
|
53283
53477
|
);
|
|
53284
53478
|
if (!exportDims) {
|
|
@@ -53310,7 +53504,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53310
53504
|
const allSteps = parsed.phases.length > 0 ? parsed.phases.flatMap((p) => p.steps) : parsed.steps;
|
|
53311
53505
|
for (const pt of layout.curvePoints) {
|
|
53312
53506
|
const step = allSteps[pt.stepIndex];
|
|
53313
|
-
const faceG = renderScoreFace(
|
|
53507
|
+
const faceG = renderScoreFace(
|
|
53508
|
+
curveG,
|
|
53509
|
+
pt.x,
|
|
53510
|
+
pt.y,
|
|
53511
|
+
pt.score,
|
|
53512
|
+
palette,
|
|
53513
|
+
isDark
|
|
53514
|
+
);
|
|
53314
53515
|
addEmotionLabel(faceG, pt, palette);
|
|
53315
53516
|
if (step) {
|
|
53316
53517
|
faceG.attr("data-line-number", step.lineNumber);
|
|
@@ -53336,7 +53537,14 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53336
53537
|
const pt = layout.curvePoints[0];
|
|
53337
53538
|
const allSteps = parsed.phases.length > 0 ? parsed.phases.flatMap((p) => p.steps) : parsed.steps;
|
|
53338
53539
|
const step = allSteps[pt.stepIndex];
|
|
53339
|
-
const faceG = renderScoreFace(
|
|
53540
|
+
const faceG = renderScoreFace(
|
|
53541
|
+
curveG,
|
|
53542
|
+
pt.x,
|
|
53543
|
+
pt.y,
|
|
53544
|
+
pt.score,
|
|
53545
|
+
palette,
|
|
53546
|
+
isDark
|
|
53547
|
+
);
|
|
53340
53548
|
addEmotionLabel(faceG, pt, palette);
|
|
53341
53549
|
if (step) {
|
|
53342
53550
|
faceG.attr("data-line-number", step.lineNumber);
|
|
@@ -53433,6 +53641,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53433
53641
|
faceCy,
|
|
53434
53642
|
step.score,
|
|
53435
53643
|
palette,
|
|
53644
|
+
isDark,
|
|
53436
53645
|
COLLAPSED_FACE_R
|
|
53437
53646
|
);
|
|
53438
53647
|
faceG.attr("data-line-number", step.lineNumber);
|
|
@@ -53536,7 +53745,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53536
53745
|
const fcy = parseFloat(el.attr("data-cy") ?? "0");
|
|
53537
53746
|
el.attr(
|
|
53538
53747
|
"transform",
|
|
53539
|
-
`translate(${fcx},${fcy}) scale(
|
|
53748
|
+
`translate(${fcx},${fcy}) scale(${FACE_HOVER_SCALE}) translate(${-fcx},${-fcy})`
|
|
53540
53749
|
);
|
|
53541
53750
|
} else {
|
|
53542
53751
|
el.attr("transform", null);
|
|
@@ -53582,12 +53791,12 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
|
|
|
53582
53791
|
PADDING2,
|
|
53583
53792
|
Math.min(fcx - bw / 2, layout.totalWidth - PADDING2 - bw)
|
|
53584
53793
|
);
|
|
53585
|
-
const by = Math.max(PADDING2, fcy -
|
|
53794
|
+
const by = Math.max(PADDING2, fcy - FACE_HOVER_R - THOUGHT_GAP - bh);
|
|
53586
53795
|
const scoreColor = scoreToColor(score, palette);
|
|
53587
53796
|
const tintedBg = mix(scoreColor, palette.surface, 20);
|
|
53588
53797
|
const g = overlayG.append("g").attr("class", "journey-thought-hover");
|
|
53589
53798
|
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);
|
|
53590
|
-
g.append("line").attr("x1", fcx).attr("y1", by + bh).attr("x2", fcx).attr("y2", fcy -
|
|
53799
|
+
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);
|
|
53591
53800
|
const centerX = bx + bw / 2;
|
|
53592
53801
|
for (let i = 0; i < lines.length; i++) {
|
|
53593
53802
|
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]);
|
|
@@ -53830,24 +54039,23 @@ function renderPersonaSilhouette(parent, cx, cy, color, palette, scale = 1) {
|
|
|
53830
54039
|
`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`
|
|
53831
54040
|
).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.2);
|
|
53832
54041
|
}
|
|
53833
|
-
function renderScoreFace(parent, cx, cy, score, palette, radius) {
|
|
54042
|
+
function renderScoreFace(parent, cx, cy, score, palette, isDark, radius) {
|
|
53834
54043
|
const r = radius ?? FACE_RADIUS;
|
|
53835
54044
|
const color = scoreToColor(score, palette);
|
|
53836
54045
|
const g = parent.append("g").attr("class", "journey-face").attr("data-cx", cx).attr("data-cy", cy);
|
|
53837
|
-
|
|
53838
|
-
|
|
53839
|
-
|
|
53840
|
-
|
|
53841
|
-
palette.textOnFillDark
|
|
53842
|
-
);
|
|
54046
|
+
const faceFill = shapeFill(palette, color, isDark);
|
|
54047
|
+
g.append("circle").attr("cx", cx).attr("cy", cy).attr("r", r + 1).attr("fill", palette.bg);
|
|
54048
|
+
g.append("circle").attr("cx", cx).attr("cy", cy).attr("r", r).attr("fill", faceFill).attr("stroke", color).attr("stroke-width", 2);
|
|
54049
|
+
const eyeColor = color;
|
|
53843
54050
|
const eyeY = cy - r * 0.15;
|
|
53844
54051
|
const eyeSpacing = r * 0.32;
|
|
53845
54052
|
const eyeR = r * 0.12;
|
|
53846
54053
|
g.append("circle").attr("cx", cx - eyeSpacing).attr("cy", eyeY).attr("r", eyeR).attr("fill", eyeColor);
|
|
53847
54054
|
g.append("circle").attr("cx", cx + eyeSpacing).attr("cy", eyeY).attr("r", eyeR).attr("fill", eyeColor);
|
|
53848
|
-
const
|
|
53849
|
-
const
|
|
53850
|
-
const
|
|
54055
|
+
const mouthW = r * 0.46;
|
|
54056
|
+
const curve = (score - 3) / 2 * r * 0.42;
|
|
54057
|
+
const apexY = cy + r * 0.32;
|
|
54058
|
+
const mouthY = apexY - curve / 2;
|
|
53851
54059
|
g.append("path").attr(
|
|
53852
54060
|
"d",
|
|
53853
54061
|
`M ${cx - mouthW} ${mouthY} Q ${cx} ${mouthY + curve} ${cx + mouthW} ${mouthY}`
|
|
@@ -53918,7 +54126,7 @@ function renderJourneyMapForExport(content, theme, palette) {
|
|
|
53918
54126
|
}
|
|
53919
54127
|
return svgEl.outerHTML;
|
|
53920
54128
|
}
|
|
53921
|
-
var d3, d3Shape10, 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;
|
|
54129
|
+
var d3, d3Shape10, 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;
|
|
53922
54130
|
var init_renderer17 = __esm({
|
|
53923
54131
|
"src/journey-map/renderer.ts"() {
|
|
53924
54132
|
"use strict";
|
|
@@ -53954,6 +54162,8 @@ var init_renderer17 = __esm({
|
|
|
53954
54162
|
GRID_LINE_OPACITY = 0.15;
|
|
53955
54163
|
CURVE_STROKE_WIDTH = 2.5;
|
|
53956
54164
|
FACE_RADIUS = 14;
|
|
54165
|
+
FACE_HOVER_SCALE = 1.5;
|
|
54166
|
+
FACE_HOVER_R = (FACE_RADIUS + 1) * FACE_HOVER_SCALE;
|
|
53957
54167
|
DIM_HOVER = 0.25;
|
|
53958
54168
|
TITLE_LINE_HEIGHT = 16;
|
|
53959
54169
|
EMOTION_LABEL_MAX_WIDTH = 180;
|