@diagrammo/dgmo 0.8.25 → 0.8.27

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/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@diagrammo/dgmo",
3
- "version": "0.8.25",
3
+ "version": "0.8.27",
4
4
  "description": "DGMO diagram markup language — parser, renderer, and color system",
5
5
  "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/diagrammo/dgmo.git"
9
+ },
10
+ "homepage": "https://github.com/diagrammo/dgmo#readme",
6
11
  "type": "module",
7
12
  "bin": {
8
13
  "dgmo": "dist/cli.cjs"
@@ -84,7 +89,7 @@
84
89
  "check:deadcode": "knip",
85
90
  "check:spelling": "cspell \"src/**/*.ts\" \"tests/**/*.ts\"",
86
91
  "check:all": "pnpm check:deadcode && pnpm check:spelling && pnpm check:duplication && pnpm check:circular && pnpm check:deps && pnpm check:security && pnpm build && pnpm check:publish && pnpm check:types",
87
- "check:circular": "madge --circular --extensions ts src/ --json | node -e \"const c=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); const n=c.length; if(n>7){console.error('New circular deps found ('+n+' > 7 known type-only cycles)');process.exit(1)}else if(n>0){console.log(n+' known type-only/dynamic cycles (safe)')}else{console.log('No circular dependencies')}\"",
92
+ "check:circular": "madge --circular --extensions ts src/ --json | node -e \"const c=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); const n=c.length; if(n>10){console.error('New circular deps found ('+n+' > 10 known type-only cycles)');process.exit(1)}else if(n>0){console.log(n+' known type-only/dynamic cycles (safe)')}else{console.log('No circular dependencies')}\"",
88
93
  "check:deps": "depcheck --ignores='@codemirror/language,@lezer/*,husky,lint-staged,tsup'",
89
94
  "check:security": "pnpm audit --prod",
90
95
  "check:publish": "publint",
package/src/d3.ts CHANGED
@@ -2681,8 +2681,10 @@ function renderEras(
2681
2681
  eras.forEach((era, i) => {
2682
2682
  const startVal = parseTimelineDate(era.startDate);
2683
2683
  const endVal = parseTimelineDate(era.endDate);
2684
+ if (!Number.isFinite(startVal) || !Number.isFinite(endVal)) return;
2684
2685
  const start = scale(startVal);
2685
2686
  const end = scale(endVal);
2687
+ if (!Number.isFinite(start) || !Number.isFinite(end)) return;
2686
2688
  const color = era.color || eraColors[i % eraColors.length];
2687
2689
 
2688
2690
  const eraG = g
@@ -2772,7 +2774,9 @@ function renderMarkers(
2772
2774
 
2773
2775
  markers.forEach((marker) => {
2774
2776
  const dateVal = parseTimelineDate(marker.date);
2777
+ if (!Number.isFinite(dateVal)) return;
2775
2778
  const pos = scale(dateVal);
2779
+ if (!Number.isFinite(pos)) return;
2776
2780
  const color = marker.color || defaultColor;
2777
2781
  const lineOpacity = 0.5;
2778
2782
  const diamondSize = 5;
@@ -3480,6 +3484,33 @@ export function renderTimeline(
3480
3484
  latestEndDateStr = ev.endDate ?? ev.date;
3481
3485
  }
3482
3486
  }
3487
+
3488
+ // Eras and markers anchor the time axis — fold their dates into the
3489
+ // domain so out-of-range items still render within the chart.
3490
+ for (const era of timelineEras) {
3491
+ const eraStartNum = parseTimelineDate(era.startDate);
3492
+ const eraEndNum = parseTimelineDate(era.endDate);
3493
+ if (Number.isFinite(eraStartNum) && eraStartNum < minDate) {
3494
+ minDate = eraStartNum;
3495
+ earliestStartDateStr = era.startDate;
3496
+ }
3497
+ if (Number.isFinite(eraEndNum) && eraEndNum > maxDate) {
3498
+ maxDate = eraEndNum;
3499
+ latestEndDateStr = era.endDate;
3500
+ }
3501
+ }
3502
+ for (const marker of timelineMarkers) {
3503
+ const markerNum = parseTimelineDate(marker.date);
3504
+ if (!Number.isFinite(markerNum)) continue;
3505
+ if (markerNum < minDate) {
3506
+ minDate = markerNum;
3507
+ earliestStartDateStr = marker.date;
3508
+ }
3509
+ if (markerNum > maxDate) {
3510
+ maxDate = markerNum;
3511
+ latestEndDateStr = marker.date;
3512
+ }
3513
+ }
3483
3514
  const datePadding = (maxDate - minDate) * 0.05 || 0.5;
3484
3515
 
3485
3516
  const FADE_OPACITY = 0.1;
@@ -27,7 +27,7 @@ export interface StepLayout {
27
27
  color: string;
28
28
  }
29
29
 
30
- export interface PhaseLayout {
30
+ interface PhaseLayout {
31
31
  x: number;
32
32
  y: number;
33
33
  width: number;
@@ -88,8 +88,6 @@ export function scoreToColor(score: number, palette: PaletteColors): string {
88
88
  // Layout Engine
89
89
  // ============================================================
90
90
 
91
- export const COLLAPSED_PHASE_WIDTH = 60;
92
-
93
91
  export function layoutJourneyMap(
94
92
  parsed: ParsedJourneyMap,
95
93
  palette: PaletteColors,
@@ -186,5 +186,4 @@ export function getRadarGeometry(
186
186
  return { cx, cy, maxRadius, ringBandWidth: maxRadius / ringCount };
187
187
  }
188
188
 
189
- /** Exported for testing. */
190
- export { POSITION_ORDER, getQuadrantArc, BASE_BLIP_RADIUS, MIN_BLIP_RADIUS };
189
+ export { POSITION_ORDER, getQuadrantArc };
@@ -33,7 +33,7 @@ const POSITION_ORDER: readonly QuadrantPosition[] = [
33
33
  /** Known tech-radar options (key-value). */
34
34
  const KNOWN_OPTIONS = new Set<string>([]);
35
35
  /** Known tech-radar boolean options (bare keyword). */
36
- const KNOWN_BOOLEANS = new Set<string>([]);
36
+ const KNOWN_BOOLEANS = new Set<string>(['show-blip-legend']);
37
37
 
38
38
  export function parseTechRadar(content: string): ParsedTechRadar {
39
39
  const result: ParsedTechRadar = {
@@ -111,8 +111,10 @@ export function renderTechRadar(
111
111
  return;
112
112
  }
113
113
 
114
- // Determine if listing is visible — always show for export (blip legend is essential)
115
- const showListing = exportDims ? true : (options?.showListing ?? false);
114
+ // Determine if listing is visible — always show for export (blip legend is essential).
115
+ // Otherwise: runtime option wins; falls back to the `show-blip-legend` directive in source.
116
+ const directiveOn = parsed.options['show-blip-legend'] === 'on';
117
+ const showListing = exportDims ? true : (options?.showListing ?? directiveOn);
116
118
  const listingHeight = showListing ? estimateListingHeight(parsed) : 0;
117
119
 
118
120
  const init = initRadarSvg(container, palette, exportDims);
@@ -4,7 +4,7 @@ import type { PaletteColors } from '../palettes';
4
4
  import type { QuadrantPosition, BlipTrend } from './types';
5
5
 
6
6
  /** Default quadrant colors by position when not overridden. */
7
- export const DEFAULT_QUADRANT_COLORS: Record<QuadrantPosition, string> = {
7
+ const DEFAULT_QUADRANT_COLORS: Record<QuadrantPosition, string> = {
8
8
  'top-left': 'blue',
9
9
  'top-right': 'green',
10
10
  'bottom-left': 'red',
@@ -101,20 +101,6 @@ function renderCrescent(
101
101
  .attr('stroke-linecap', 'round');
102
102
  }
103
103
 
104
- /** Trend indicator character for text listings. */
105
- export function getTrendChar(trend: BlipTrend | null): string {
106
- switch (trend) {
107
- case 'new':
108
- return ' ★';
109
- case 'up':
110
- return ' ▲';
111
- case 'down':
112
- return ' ▼';
113
- default:
114
- return '';
115
- }
116
- }
117
-
118
104
  // ============================================================
119
105
  // Shared Constants
120
106
  // ============================================================
@@ -163,25 +149,3 @@ export function createTooltip(
163
149
  container.appendChild(tip);
164
150
  return tip;
165
151
  }
166
-
167
- export function showTooltip(
168
- tooltip: HTMLDivElement,
169
- text: string,
170
- event: MouseEvent
171
- ): void {
172
- tooltip.textContent = text;
173
- tooltip.style.display = 'block';
174
- const container = tooltip.parentElement!;
175
- const rect = container.getBoundingClientRect();
176
- let left = event.clientX - rect.left + 12;
177
- let top = event.clientY - rect.top - 28;
178
- const tipW = tooltip.offsetWidth;
179
- if (left + tipW > rect.width) left = rect.width - tipW - 4;
180
- if (top < 0) top = event.clientY - rect.top + 16;
181
- tooltip.style.left = `${left}px`;
182
- tooltip.style.top = `${top}px`;
183
- }
184
-
185
- export function hideTooltip(tooltip: HTMLDivElement): void {
186
- tooltip.style.display = 'none';
187
- }
@@ -1,14 +0,0 @@
1
- export { parseTechRadar } from './parser';
2
- export { computeRadarLayout, getRadarGeometry } from './layout';
3
- export { renderTechRadar, renderTechRadarForExport } from './renderer';
4
- export { renderQuadrantFocus } from './interactive';
5
- export type {
6
- ParsedTechRadar,
7
- TechRadarRing,
8
- TechRadarQuadrant,
9
- TechRadarBlip,
10
- TechRadarLayoutPoint,
11
- QuadrantPosition,
12
- BlipTrend,
13
- TechRadarRenderOptions,
14
- } from './types';