agentic-mermaid 0.1.0 → 0.1.2
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/CHANGELOG.md +149 -4
- package/LICENSES/Apache-2.0.txt +202 -0
- package/README.md +25 -32
- package/THIRD_PARTY_NOTICES.md +29 -0
- package/assets/fonts/FONT-LICENSES.md +9 -5
- package/assets/fonts/Inter-Bold.ttf +0 -0
- package/assets/fonts/Inter-Medium.ttf +0 -0
- package/assets/fonts/Inter-Regular.ttf +0 -0
- package/assets/fonts/Inter-SemiBold.ttf +0 -0
- package/dist/agent-core.d.ts +463 -0
- package/dist/agent-core.js +397 -0
- package/dist/agent.d.ts +81 -1822
- package/dist/agent.js +336 -36839
- package/dist/agentic-mermaid-mcp.js +7 -37908
- package/dist/am.js +33638 -36261
- package/dist/chunk-4QECACIA.js +4702 -0
- package/dist/chunk-CDPKJ2BQ.js +37 -0
- package/dist/chunk-QKDLMOJJ.js +3487 -0
- package/dist/chunk-WI35L7IR.js +615 -0
- package/dist/chunk-WN3YDOBG.js +149 -0
- package/dist/chunk-ZYMMKQ3I.js +62637 -0
- package/dist/index-D54dqSdC.d.ts +6777 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +310 -32836
- package/dist/mcp-cli-SBQSTJFC.js +17 -0
- package/docs/README.md +14 -6
- package/docs/schemas/style-spec.schema.json +1221 -30
- package/examples/styles/catalog.json +54 -0
- package/examples/styles/cloudflare-workers-inspired-prototype.mmd +9 -0
- package/examples/styles/cloudflare-workers-inspired-prototype.style.json +110 -0
- package/examples/styles/cupertino-prototype.mmd +10 -0
- package/examples/styles/cupertino-prototype.style.json +63 -0
- package/examples/styles/mid-century-report.style.json +2 -2
- package/examples/styles/star-chart-atlas.style.json +2 -1
- package/examples/styles/transit-route-map.style.json +2 -2
- package/examples/styles/vercel-inspired-prototype.mmd +6 -0
- package/examples/styles/vercel-inspired-prototype.style.json +87 -0
- package/package.json +70 -43
- package/server.json +41 -0
- package/skills/agentic-mermaid-diagram-workflow/SKILL.md +17 -36
- package/skills/agentic-mermaid-diagram-workflow/references/cli.md +4 -5
- package/skills/agentic-mermaid-diagram-workflow/references/code-mode.md +15 -31
- package/skills/agentic-mermaid-diagram-workflow/references/sequence.md +10 -14
- package/skills/agentic-mermaid-live-editor/SKILL.md +100 -206
- package/AGENT_NATIVE.md +0 -602
- package/Instructions_for_agents.md +0 -83
- package/TODO.md +0 -662
- package/assets/hero.png +0 -0
- package/dist/index-x2Cj1dVv.d.ts +0 -1089
- package/docs/agent-api-cookbook.md +0 -308
- package/docs/agent-mutation-policy.md +0 -104
- package/docs/agent-workflow-examples.md +0 -46
- package/docs/api.md +0 -203
- package/docs/ascii.md +0 -103
- package/docs/assets/improvements/box-start-connector.png +0 -0
- package/docs/assets/improvements/comment-dropped-lint.png +0 -0
- package/docs/assets/improvements/er-content-loss.png +0 -0
- package/docs/assets/improvements/fan-in-trunks.png +0 -0
- package/docs/assets/improvements/gantt-family.png +0 -0
- package/docs/assets/improvements/gantt-milestone-clamp.png +0 -0
- package/docs/assets/improvements/gantt-verify-seam.png +0 -0
- package/docs/assets/improvements/subgraph-container-edges.png +0 -0
- package/docs/assets/improvements/wrapper-frontmatter.png +0 -0
- package/docs/assets/improvements/wrapper-init-directive.png +0 -0
- package/docs/assets/improvements/wrapper-leading-comment.png +0 -0
- package/docs/assets/style-cookbook/mid-century-report.png +0 -0
- package/docs/assets/style-cookbook/star-chart-atlas.png +0 -0
- package/docs/assets/style-cookbook/transit-route-map.png +0 -0
- package/docs/comparison.md +0 -94
- package/docs/config.md +0 -105
- package/docs/contributing/adding-diagram-types.md +0 -144
- package/docs/contributing/diagram-family-citizenship.matrix.json +0 -2127
- package/docs/contributing/diagram-family-citizenship.md +0 -82
- package/docs/contributing/harvesting-upstream-tests.md +0 -126
- package/docs/contributing/lessons-learned.md +0 -276
- package/docs/contributing/releasing.md +0 -71
- package/docs/contributing/visual-review-evidence.md +0 -53
- package/docs/custom-style-cookbook.md +0 -154
- package/docs/design/families/README.md +0 -26
- package/docs/design/families/architecture-beta.md +0 -48
- package/docs/design/families/flowchart-parser-conformance.md +0 -22
- package/docs/design/families/gantt-research.md +0 -137
- package/docs/design/families/gantt.md +0 -329
- package/docs/design/families/journey-agentic-cards-before.png +0 -0
- package/docs/design/families/journey-mermaid-classic-implementation.png +0 -0
- package/docs/design/families/journey-mermaid-classic-prototype.png +0 -0
- package/docs/design/families/journey-mermaid-classic-prototype.svg +0 -163
- package/docs/design/families/journey-mermaid-classic-prototype.svg.png +0 -0
- package/docs/design/families/journey-migration-parity.md +0 -433
- package/docs/design/families/journey-usage-research.md +0 -423
- package/docs/design/families/journey.md +0 -125
- package/docs/design/families/xychart.md +0 -85
- package/docs/design/system/README.md +0 -45
- package/docs/design/system/abstraction-audit.md +0 -224
- package/docs/design/system/abstraction-recommendations.md +0 -655
- package/docs/design/system/architecture.mmd +0 -29
- package/docs/design/system/architecture.svg +0 -137
- package/docs/design/system/layout-guarantees-and-robustness.md +0 -351
- package/docs/design/system/layout-rubric.md +0 -138
- package/docs/design/system/route-contracts.md +0 -848
- package/docs/design/system/source-preservation-ladder.md +0 -52
- package/docs/design/system/styles-rollout.md +0 -216
- package/docs/design/system/ugly-layouts.md +0 -119
- package/docs/diagram-families.md +0 -193
- package/docs/features.md +0 -147
- package/docs/fork-differences.md +0 -130
- package/docs/getting-started.md +0 -175
- package/docs/issue-derived-test-cases.md +0 -156
- package/docs/layout-characterization/README.md +0 -245
- package/docs/layout-characterization/contact-sheet-families.md +0 -496
- package/docs/layout-characterization/contact-sheet.md +0 -638
- package/docs/layout-characterization/properties.md +0 -281
- package/docs/layout-characterization/visual-quality.md +0 -160
- package/docs/layout-characterization/visual-snapshots/architecture.svg +0 -79
- package/docs/layout-characterization/visual-snapshots/class.svg +0 -60
- package/docs/layout-characterization/visual-snapshots/er.svg +0 -61
- package/docs/layout-characterization/visual-snapshots/flowchart.svg +0 -58
- package/docs/layout-characterization/visual-snapshots/gantt.svg +0 -52
- package/docs/layout-characterization/visual-snapshots/journey.svg +0 -118
- package/docs/layout-characterization/visual-snapshots/pie.svg +0 -36
- package/docs/layout-characterization/visual-snapshots/quadrant.svg +0 -47
- package/docs/layout-characterization/visual-snapshots/sequence.svg +0 -59
- package/docs/layout-characterization/visual-snapshots/state.svg +0 -52
- package/docs/layout-characterization/visual-snapshots/timeline.svg +0 -64
- package/docs/layout-characterization/visual-snapshots/xychart.svg +0 -97
- package/docs/mcp-code-mode-rationale.md +0 -101
- package/docs/mcp-http-transport.md +0 -223
- package/docs/mermaid-layout-complaints.md +0 -837
- package/docs/mutation-testing.md +0 -206
- package/docs/project/divergences.md +0 -98
- package/docs/project/dogfooding-docs-strategy.md +0 -66
- package/docs/project/hosted-mcp-cloudflare-plan.md +0 -338
- package/docs/project/lessons-learned.md +0 -1019
- package/docs/project/remove-role-styling-plan.md +0 -176
- package/docs/quality.md +0 -212
- package/docs/react.md +0 -97
- package/docs/style-authoring.md +0 -133
- package/docs/testing-strategy.md +0 -335
- package/docs/theming.md +0 -162
- package/examples/agent-improve-auth-flow.ts +0 -206
- package/examples/agent-loop.ts +0 -53
- package/examples/mcp-vs-cli-complex-diagrams.ts +0 -133
- package/llms.txt +0 -104
- package/skill-evals/README.md +0 -77
- package/skill-evals/fixtures/architecture-cache/input.mmd +0 -5
- package/skill-evals/fixtures/class-payment/input.mmd +0 -4
- package/skill-evals/fixtures/er-orders/input.mmd +0 -10
- package/skill-evals/fixtures/flowchart-cache/input.mmd +0 -3
- package/skill-evals/fixtures/gantt-release/input.mmd +0 -7
- package/skill-evals/fixtures/journey-checkout/input.mmd +0 -6
- package/skill-evals/fixtures/pie-exports/input.mmd +0 -5
- package/skill-evals/fixtures/quadrant-priorities/input.mmd +0 -11
- package/skill-evals/fixtures/sequence-retry/input.mmd +0 -8
- package/skill-evals/fixtures/state-lifecycle/input.mmd +0 -5
- package/skill-evals/fixtures/timeline-release/input.mmd +0 -6
- package/skill-evals/fixtures/xychart-growth/input.mmd +0 -5
- package/skill-evals/shared-benchmark.json +0 -510
- package/src/agent/analyze.ts +0 -157
- package/src/agent/apply.ts +0 -146
- package/src/agent/architecture-body.ts +0 -458
- package/src/agent/certificates.ts +0 -110
- package/src/agent/class-body.ts +0 -319
- package/src/agent/core.ts +0 -207
- package/src/agent/create.ts +0 -106
- package/src/agent/describe.ts +0 -364
- package/src/agent/er-body.ts +0 -224
- package/src/agent/facts.ts +0 -337
- package/src/agent/families-builtin.ts +0 -934
- package/src/agent/families.ts +0 -232
- package/src/agent/family-layouts.ts +0 -826
- package/src/agent/flowchart-body.ts +0 -372
- package/src/agent/flowchart-unsupported.ts +0 -243
- package/src/agent/gantt-body.ts +0 -495
- package/src/agent/index.ts +0 -10
- package/src/agent/journey-body.ts +0 -414
- package/src/agent/label-metrics.ts +0 -28
- package/src/agent/layout-to-rendered.ts +0 -63
- package/src/agent/mutate.ts +0 -97
- package/src/agent/mutation-ops.ts +0 -51
- package/src/agent/op-schema.ts +0 -439
- package/src/agent/parse.ts +0 -223
- package/src/agent/pie-body.ts +0 -270
- package/src/agent/png.ts +0 -117
- package/src/agent/quadrant-body.ts +0 -336
- package/src/agent/quality.ts +0 -363
- package/src/agent/readability-audit.ts +0 -92
- package/src/agent/rendered-route-audit.ts +0 -61
- package/src/agent/sequence-body.ts +0 -345
- package/src/agent/serialize.ts +0 -214
- package/src/agent/state-body.ts +0 -589
- package/src/agent/structural-count.ts +0 -150
- package/src/agent/timeline-body.ts +0 -280
- package/src/agent/trace-log.ts +0 -43
- package/src/agent/types.ts +0 -979
- package/src/agent/verify.ts +0 -571
- package/src/agent/xychart-body.ts +0 -472
- package/src/architecture/config.ts +0 -282
- package/src/architecture/layout.ts +0 -496
- package/src/architecture/parser.ts +0 -375
- package/src/architecture/renderer.ts +0 -611
- package/src/architecture/types.ts +0 -113
- package/src/ascii/ansi.ts +0 -423
- package/src/ascii/architecture.ts +0 -210
- package/src/ascii/canvas.ts +0 -443
- package/src/ascii/class-diagram.ts +0 -697
- package/src/ascii/converter.ts +0 -475
- package/src/ascii/draw.ts +0 -1693
- package/src/ascii/edge-bundling.ts +0 -328
- package/src/ascii/edge-routing.ts +0 -330
- package/src/ascii/er-diagram.ts +0 -439
- package/src/ascii/gantt.ts +0 -276
- package/src/ascii/grid.ts +0 -747
- package/src/ascii/index.ts +0 -196
- package/src/ascii/journey.ts +0 -189
- package/src/ascii/meta.ts +0 -244
- package/src/ascii/multiline-utils.ts +0 -80
- package/src/ascii/pathfinder.ts +0 -301
- package/src/ascii/pie.ts +0 -67
- package/src/ascii/quadrant.ts +0 -158
- package/src/ascii/reverse.ts +0 -216
- package/src/ascii/sequence.ts +0 -499
- package/src/ascii/shapes/circle.ts +0 -27
- package/src/ascii/shapes/corners.ts +0 -143
- package/src/ascii/shapes/diamond.ts +0 -27
- package/src/ascii/shapes/hexagon.ts +0 -27
- package/src/ascii/shapes/index.ts +0 -106
- package/src/ascii/shapes/rectangle.ts +0 -168
- package/src/ascii/shapes/rounded.ts +0 -27
- package/src/ascii/shapes/special.ts +0 -332
- package/src/ascii/shapes/stadium.ts +0 -110
- package/src/ascii/shapes/state.ts +0 -192
- package/src/ascii/shapes/types.ts +0 -73
- package/src/ascii/timeline.ts +0 -128
- package/src/ascii/types.ts +0 -312
- package/src/ascii/validate.ts +0 -120
- package/src/ascii/width.ts +0 -81
- package/src/ascii/xychart.ts +0 -919
- package/src/browser.ts +0 -29
- package/src/class/layout.ts +0 -240
- package/src/class/parser.ts +0 -332
- package/src/class/renderer.ts +0 -638
- package/src/class/types.ts +0 -129
- package/src/cli/agent-instructions.ts +0 -1
- package/src/cli/am-bin.ts +0 -6
- package/src/cli/exit-codes.ts +0 -18
- package/src/cli/index.ts +0 -1117
- package/src/cli/init-agent.ts +0 -147
- package/src/color-resolver.ts +0 -152
- package/src/elk-instance.ts +0 -114
- package/src/er/layout.ts +0 -187
- package/src/er/parser.ts +0 -226
- package/src/er/renderer.ts +0 -792
- package/src/er/types.ts +0 -99
- package/src/font-manifest.ts +0 -27
- package/src/gantt/layout.ts +0 -365
- package/src/gantt/parser.ts +0 -282
- package/src/gantt/pipeline.ts +0 -27
- package/src/gantt/renderer.ts +0 -414
- package/src/gantt/schedule.ts +0 -513
- package/src/gantt/types.ts +0 -255
- package/src/index.ts +0 -368
- package/src/journey/layout.ts +0 -520
- package/src/journey/parser.ts +0 -218
- package/src/journey/renderer.ts +0 -811
- package/src/journey/types.ts +0 -144
- package/src/layout/geometry.ts +0 -182
- package/src/layout/pass.ts +0 -142
- package/src/layout/passes/index.ts +0 -3916
- package/src/layout-engine.ts +0 -1565
- package/src/layout-rubric.ts +0 -659
- package/src/mcp/artifacts.ts +0 -137
- package/src/mcp/dynamic-harness.ts +0 -31
- package/src/mcp/dynamic-modules.d.ts +0 -7
- package/src/mcp/facade.ts +0 -608
- package/src/mcp/harness-runtime.ts +0 -203
- package/src/mcp/hosted-server.ts +0 -468
- package/src/mcp/mcp-bin.ts +0 -3
- package/src/mcp/mcp-cli.ts +0 -82
- package/src/mcp/protocol.ts +0 -13
- package/src/mcp/sandbox.ts +0 -195
- package/src/mcp/sdk-decl.ts +0 -387
- package/src/mcp/server.ts +0 -362
- package/src/mcp/tool-surface.ts +0 -146
- package/src/mermaid-source.ts +0 -655
- package/src/multiline-utils.ts +0 -228
- package/src/parser.ts +0 -1031
- package/src/pie/layout.ts +0 -168
- package/src/pie/parser.ts +0 -136
- package/src/pie/renderer.ts +0 -234
- package/src/pie/types.ts +0 -82
- package/src/quadrant/layout.ts +0 -191
- package/src/quadrant/parser.ts +0 -183
- package/src/quadrant/renderer.ts +0 -322
- package/src/quadrant/types.ts +0 -113
- package/src/render-family-hooks.ts +0 -244
- package/src/renderer.ts +0 -1099
- package/src/route-contracts.ts +0 -2723
- package/src/scene/backend.ts +0 -76
- package/src/scene/fidelity.ts +0 -183
- package/src/scene/hybrid-backend.ts +0 -174
- package/src/scene/ir.ts +0 -181
- package/src/scene/marks.ts +0 -127
- package/src/scene/rough-backend.ts +0 -378
- package/src/scene/seed.ts +0 -46
- package/src/scene/style-registry.ts +0 -556
- package/src/sequence/layout.ts +0 -456
- package/src/sequence/parser.ts +0 -255
- package/src/sequence/renderer.ts +0 -604
- package/src/sequence/types.ts +0 -154
- package/src/shape-clipping.ts +0 -351
- package/src/shared/accessibility-directives.ts +0 -22
- package/src/shared/batched.ts +0 -61
- package/src/shared/color-math.ts +0 -72
- package/src/shared/svg-a11y.ts +0 -29
- package/src/shared/syntax-error.ts +0 -17
- package/src/shared/unicode-ranges.ts +0 -135
- package/src/styles.ts +0 -318
- package/src/svg-paths.ts +0 -28
- package/src/text-metrics.ts +0 -248
- package/src/theme.ts +0 -639
- package/src/timeline/layout.ts +0 -381
- package/src/timeline/parser.ts +0 -215
- package/src/timeline/renderer.ts +0 -538
- package/src/timeline/types.ts +0 -105
- package/src/types.ts +0 -454
- package/src/website-worker-modules.d.ts +0 -18
- package/src/xychart/axis-utils.ts +0 -109
- package/src/xychart/colors.ts +0 -124
- package/src/xychart/config.ts +0 -88
- package/src/xychart/layout.ts +0 -656
- package/src/xychart/parser.ts +0 -504
- package/src/xychart/renderer.ts +0 -640
- package/src/xychart/types.ts +0 -282
package/src/types.ts
DELETED
|
@@ -1,454 +0,0 @@
|
|
|
1
|
-
import type { MermaidRuntimeConfig } from './mermaid-source.ts'
|
|
2
|
-
import type { DiagramColors } from './theme.ts'
|
|
3
|
-
import type { ArchitectureVisualConfig } from './architecture/config.ts'
|
|
4
|
-
import type { StyleInput } from './scene/style-registry.ts'
|
|
5
|
-
|
|
6
|
-
// ============================================================================
|
|
7
|
-
// Parsed graph — logical structure extracted from Mermaid text
|
|
8
|
-
// ============================================================================
|
|
9
|
-
|
|
10
|
-
export interface MermaidGraph {
|
|
11
|
-
direction: Direction
|
|
12
|
-
nodes: Map<string, MermaidNode>
|
|
13
|
-
edges: MermaidEdge[]
|
|
14
|
-
subgraphs: MermaidSubgraph[]
|
|
15
|
-
classDefs: Map<string, Record<string, string>>
|
|
16
|
-
/** Maps node IDs to their class names (from `class X className` or `:::className` shorthand) */
|
|
17
|
-
classAssignments: Map<string, string>
|
|
18
|
-
/** Maps node IDs to inline styles (from `style X fill:#f00,stroke:#333`) */
|
|
19
|
-
nodeStyles: Map<string, Record<string, string>>
|
|
20
|
-
/** Maps edge indices (or 'default') to inline styles from `linkStyle` directives */
|
|
21
|
-
linkStyles: Map<number | 'default', Record<string, string>>
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export type Direction = 'TD' | 'TB' | 'LR' | 'BT' | 'RL'
|
|
25
|
-
|
|
26
|
-
export interface MermaidNode {
|
|
27
|
-
id: string
|
|
28
|
-
label: string
|
|
29
|
-
shape: NodeShape
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export type NodeShape =
|
|
33
|
-
| 'rectangle'
|
|
34
|
-
| 'service'
|
|
35
|
-
| 'rounded'
|
|
36
|
-
| 'diamond'
|
|
37
|
-
| 'stadium'
|
|
38
|
-
| 'circle'
|
|
39
|
-
// Batch 1 additions
|
|
40
|
-
| 'subroutine' // [[text]] — double-bordered rectangle
|
|
41
|
-
| 'doublecircle' // (((text))) — concentric circles
|
|
42
|
-
| 'hexagon' // {{text}} — six-sided polygon
|
|
43
|
-
// Batch 2 additions
|
|
44
|
-
| 'cylinder' // [(text)] — database cylinder
|
|
45
|
-
| 'asymmetric' // >text] — flag/banner shape
|
|
46
|
-
| 'trapezoid' // [/text\] — wider bottom
|
|
47
|
-
| 'trapezoid-alt' // [\text/] — wider top
|
|
48
|
-
// Parallelograms (Mermaid lean_right / lean_left — the flowchart I/O symbol)
|
|
49
|
-
| 'lean-r' // [/text/] — leans right
|
|
50
|
-
| 'lean-l' // [\text\] — leans left
|
|
51
|
-
// Batch 3 state diagram pseudostates
|
|
52
|
-
| 'state-start' // filled circle (start pseudostate)
|
|
53
|
-
| 'state-end' // bullseye circle (end pseudostate)
|
|
54
|
-
|
|
55
|
-
export interface MermaidEdge {
|
|
56
|
-
source: string
|
|
57
|
-
target: string
|
|
58
|
-
label?: string
|
|
59
|
-
style: EdgeStyle
|
|
60
|
-
/** Whether to render a marker at the start (source end) of the edge */
|
|
61
|
-
hasArrowStart: boolean
|
|
62
|
-
/** Whether to render a marker at the end (target end) of the edge */
|
|
63
|
-
hasArrowEnd: boolean
|
|
64
|
-
/** Marker shape at start when hasArrowStart=true. Defaults to 'arrow' if undefined. */
|
|
65
|
-
startMarker?: EdgeMarker
|
|
66
|
-
/** Marker shape at end when hasArrowEnd=true. Defaults to 'arrow' if undefined. */
|
|
67
|
-
endMarker?: EdgeMarker
|
|
68
|
-
/** Mermaid link length (rank-distance intent): 1 = base operator, 2 = one
|
|
69
|
-
* extra shaft unit (`--->`, `-..->`, `====>`, `~~~~`), etc. Undefined ≡ 1,
|
|
70
|
-
* so base-form edges serialize byte-identically. Preserved through
|
|
71
|
-
* round-trip; layout honors this conservatively for simple primary-forward
|
|
72
|
-
* no-subgraph DAGs and leaves grouped/cyclic cases to ELK. */
|
|
73
|
-
length?: number
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/** 'invisible' is Mermaid's `~~~` link: it participates in layout ordering
|
|
77
|
-
* but draws no stroke. */
|
|
78
|
-
export type EdgeStyle = 'solid' | 'dotted' | 'thick' | 'invisible'
|
|
79
|
-
export type EdgeMarker = 'arrow' | 'circle' | 'cross'
|
|
80
|
-
|
|
81
|
-
export interface MermaidSubgraph {
|
|
82
|
-
id: string
|
|
83
|
-
label: string
|
|
84
|
-
nodeIds: string[]
|
|
85
|
-
children: MermaidSubgraph[]
|
|
86
|
-
/** Optional direction override for this subgraph's internal layout */
|
|
87
|
-
direction?: Direction
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// ============================================================================
|
|
91
|
-
// Positioned graph — after ELK layout, ready for SVG rendering
|
|
92
|
-
// ============================================================================
|
|
93
|
-
|
|
94
|
-
export interface PositionedDiagram {
|
|
95
|
-
width: number
|
|
96
|
-
height: number
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export interface RenderContext<TPositioned extends PositionedDiagram = PositionedDiagram> {
|
|
100
|
-
positioned: TPositioned
|
|
101
|
-
colors: DiagramColors
|
|
102
|
-
options: RenderOptions
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export interface PositionedGraph extends PositionedDiagram {
|
|
106
|
-
width: number
|
|
107
|
-
height: number
|
|
108
|
-
nodes: PositionedNode[]
|
|
109
|
-
edges: PositionedEdge[]
|
|
110
|
-
groups: PositionedGroup[]
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export interface PositionedNode {
|
|
114
|
-
id: string
|
|
115
|
-
label: string
|
|
116
|
-
shape: NodeShape
|
|
117
|
-
x: number
|
|
118
|
-
y: number
|
|
119
|
-
width: number
|
|
120
|
-
height: number
|
|
121
|
-
/** Inline styles resolved from classDef + explicit `style` statements — override theme defaults */
|
|
122
|
-
inlineStyle?: Record<string, string>
|
|
123
|
-
/** User-assigned Mermaid class names (from `class X myClass` / `:::myClass`). Emitted as SVG CSS classes so external stylesheets can target them. */
|
|
124
|
-
classNames?: string[]
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface PositionedEdge {
|
|
128
|
-
source: string
|
|
129
|
-
target: string
|
|
130
|
-
label?: string
|
|
131
|
-
style: EdgeStyle
|
|
132
|
-
hasArrowStart: boolean
|
|
133
|
-
hasArrowEnd: boolean
|
|
134
|
-
/** Marker shape at start when hasArrowStart=true. Defaults to 'arrow' if undefined. */
|
|
135
|
-
startMarker?: EdgeMarker
|
|
136
|
-
/** Marker shape at end when hasArrowEnd=true. Defaults to 'arrow' if undefined. */
|
|
137
|
-
endMarker?: EdgeMarker
|
|
138
|
-
/** Full path including bends — array of {x, y} points */
|
|
139
|
-
points: Point[]
|
|
140
|
-
/** Layout-computed label center position (avoids label-label collisions) */
|
|
141
|
-
labelPosition?: Point
|
|
142
|
-
/** Inline styles resolved from `linkStyle` directives — override theme defaults */
|
|
143
|
-
inlineStyle?: Record<string, string>
|
|
144
|
-
/** Index into MermaidGraph.edges this positioned edge was extracted from */
|
|
145
|
-
edgeIndex?: number
|
|
146
|
-
/** Route contract certificate attached by the layout pipeline (docs/design/system/route-contracts.md) */
|
|
147
|
-
routeCertificate?: RouteCertificate
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// ============================================================================
|
|
151
|
-
// Route contracts — semantic routing intent and per-edge certificates
|
|
152
|
-
// (docs/design/system/route-contracts.md)
|
|
153
|
-
// ============================================================================
|
|
154
|
-
|
|
155
|
-
export type RouteClass =
|
|
156
|
-
| 'primary-forward' // added in author order without creating a cycle; owns the straight lane
|
|
157
|
-
| 'feedback' // would create a cycle; may straighten onto its own reverse lane, never the forward edge's lane
|
|
158
|
-
| 'self-loop'
|
|
159
|
-
| 'container' // endpoint is a subgraph id
|
|
160
|
-
| 'cross-hierarchy' // endpoints live in different subgraph scopes
|
|
161
|
-
|
|
162
|
-
export type LayoutRouteClass = RouteClass | 'family-layout'
|
|
163
|
-
|
|
164
|
-
/** The four canonical connection points of a shape (Visio connection-point /
|
|
165
|
-
* yFiles port-candidate model). For every Mermaid shape these lie at the
|
|
166
|
-
* bbox side midpoints: the diamond's vertices, the rectangle's side
|
|
167
|
-
* midpoints, and the boundary extremes of circles, stadiums, hexagons and
|
|
168
|
-
* cylinders are the same four points, because each shape is symmetric and
|
|
169
|
-
* inscribed in its bbox. */
|
|
170
|
-
export type PortSide = 'N' | 'E' | 'S' | 'W'
|
|
171
|
-
|
|
172
|
-
/** Diamond facet-midpoints: the four points halfway along each slanted edge
|
|
173
|
-
* (NE/SE/SW/NW). They lie exactly on the diamond outline and serve as
|
|
174
|
-
* designated attachment points alongside the four cardinal vertices, but are
|
|
175
|
-
* diamond-only — shapePorts() stays four-cardinal for every shape. */
|
|
176
|
-
export type DiamondFacet = 'NE' | 'SE' | 'SW' | 'NW'
|
|
177
|
-
|
|
178
|
-
/** A port an endpoint may sit on: a cardinal vertex/side-midpoint, or — on a
|
|
179
|
-
* diamond — a facet-midpoint. */
|
|
180
|
-
export type AnyPort = PortSide | DiamondFacet
|
|
181
|
-
|
|
182
|
-
export type PortSemanticRole =
|
|
183
|
-
| 'flow-source'
|
|
184
|
-
| 'flow-target'
|
|
185
|
-
| 'feedback-source'
|
|
186
|
-
| 'feedback-target'
|
|
187
|
-
| 'self-loop-source'
|
|
188
|
-
| 'self-loop-target'
|
|
189
|
-
| 'container-source'
|
|
190
|
-
| 'container-target'
|
|
191
|
-
| 'cross-hierarchy-source'
|
|
192
|
-
| 'cross-hierarchy-target'
|
|
193
|
-
|
|
194
|
-
/** Dynamic port allocation metadata: which side an endpoint semantically uses,
|
|
195
|
-
* its deterministic order among the endpoints on that side, and why it is
|
|
196
|
-
* there. This extends `sourcePort`/`targetPort` without changing their V1
|
|
197
|
-
* vocabulary: exact endpoint ports remain `AnyPort`, while the allocation
|
|
198
|
-
* records side-level slot/role intent for pre-layout and debugging. */
|
|
199
|
-
export interface RoutePortAssignment {
|
|
200
|
-
side: PortSide
|
|
201
|
-
/** 0-based deterministic order along the side (N/S: left→right; E/W: top→bottom). */
|
|
202
|
-
slotIndex: number
|
|
203
|
-
/** Number of endpoints allocated to this node side. */
|
|
204
|
-
slotCount: number
|
|
205
|
-
role: PortSemanticRole
|
|
206
|
-
/** Exact designated port when the final endpoint landed on one. */
|
|
207
|
-
port?: AnyPort
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
export interface RouteBlocker {
|
|
211
|
-
kind: 'node' | 'label' | 'channel' | 'span' | 'crossing' | 'port'
|
|
212
|
-
id: string
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
export type RouteInvariant =
|
|
216
|
-
| 'straight' // exactly two points, axis-aligned with the flow
|
|
217
|
-
| 'explained-detour' // bends, and directLaneBlockedBy says why
|
|
218
|
-
| 'bundle' // path owned by the fan-out/fan-in bundler
|
|
219
|
-
| 'outer-feedback' // feedback routed around the nodes through an outer channel (ELK feedbackEdges)
|
|
220
|
-
| 'feedback-detour' // feedback that neither straightened nor reached an outer channel
|
|
221
|
-
| 'self-loop'
|
|
222
|
-
| 'container-attach'
|
|
223
|
-
| 'unverified-shape' // endpoint shape has no straight attachment side
|
|
224
|
-
|
|
225
|
-
interface RouteCertificateBase {
|
|
226
|
-
/** Index into MermaidGraph.edges */
|
|
227
|
-
edgeIndex: number
|
|
228
|
-
routeClass: RouteClass
|
|
229
|
-
bendCount: number
|
|
230
|
-
directLaneClear?: boolean
|
|
231
|
-
directLaneBlockedBy?: RouteBlocker[]
|
|
232
|
-
/** Set when the endpoint sits exactly on a port: a cardinal side-midpoint
|
|
233
|
-
* for every shape, or a diamond facet-midpoint (NE/SE/SW/NW). */
|
|
234
|
-
sourcePort?: AnyPort
|
|
235
|
-
/** Set when the endpoint sits exactly on a port: a cardinal side-midpoint
|
|
236
|
-
* for every shape, or a diamond facet-midpoint (NE/SE/SW/NW). */
|
|
237
|
-
targetPort?: AnyPort
|
|
238
|
-
/** Dynamic side/slot/role allocation for the source endpoint. */
|
|
239
|
-
sourcePortAssignment?: RoutePortAssignment
|
|
240
|
-
/** Dynamic side/slot/role allocation for the target endpoint. */
|
|
241
|
-
targetPortAssignment?: RoutePortAssignment
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
export type StraightRouteCertificate = RouteCertificateBase & {
|
|
245
|
-
invariant: 'straight'
|
|
246
|
-
/** True when the certifying straightener collapsed this route */
|
|
247
|
-
straightened?: true
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
export type NonStraightRouteCertificate = RouteCertificateBase & {
|
|
251
|
-
invariant: Exclude<RouteInvariant, 'straight'>
|
|
252
|
-
/** Non-straight certificates cannot claim a straightening happened. */
|
|
253
|
-
straightened?: never
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
export type RouteCertificate = StraightRouteCertificate | NonStraightRouteCertificate
|
|
257
|
-
|
|
258
|
-
export type FamilyEdgeRouteCertificate =
|
|
259
|
-
| {
|
|
260
|
-
family: 'class' | 'er'
|
|
261
|
-
edgeIndex: number
|
|
262
|
-
routeClass: 'family-layout'
|
|
263
|
-
invariant: 'orthogonal-box' | 'unverified-family-route'
|
|
264
|
-
bendCount: number
|
|
265
|
-
orthogonal: boolean
|
|
266
|
-
sourceBoundary: boolean
|
|
267
|
-
targetBoundary: boolean
|
|
268
|
-
}
|
|
269
|
-
| {
|
|
270
|
-
family: 'architecture'
|
|
271
|
-
edgeIndex: number
|
|
272
|
-
routeClass: 'family-layout'
|
|
273
|
-
invariant: 'side-anchored' | 'unverified-family-route'
|
|
274
|
-
bendCount: number
|
|
275
|
-
orthogonal: boolean
|
|
276
|
-
sourceSide: 'L' | 'R' | 'T' | 'B'
|
|
277
|
-
targetSide: 'L' | 'R' | 'T' | 'B'
|
|
278
|
-
sourceBoundary: 'item' | 'group'
|
|
279
|
-
targetBoundary: 'item' | 'group'
|
|
280
|
-
sourceAnchored: boolean
|
|
281
|
-
targetAnchored: boolean
|
|
282
|
-
}
|
|
283
|
-
| {
|
|
284
|
-
family: 'sequence'
|
|
285
|
-
edgeIndex: number
|
|
286
|
-
routeClass: 'family-layout'
|
|
287
|
-
invariant: 'lifeline-message' | 'self-message' | 'unverified-family-route'
|
|
288
|
-
bendCount: number
|
|
289
|
-
horizontal: boolean
|
|
290
|
-
sourceLifeline: boolean
|
|
291
|
-
targetLifeline: boolean
|
|
292
|
-
selfMessage: boolean
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
export type RegionContainmentCertificate = {
|
|
296
|
-
family: 'timeline' | 'xychart' | 'pie' | 'quadrant' | 'gantt'
|
|
297
|
-
elementId: string
|
|
298
|
-
routeClass: 'family-layout'
|
|
299
|
-
invariant: 'timeline-interval' | 'plot-contained' | 'legend-contained' | 'section-contained' | 'unverified-family-layout'
|
|
300
|
-
/** Node/mark box in layout coordinates; included so cert consumers do not have to join back to nodes. */
|
|
301
|
-
bounds: { x: number; y: number; w: number; h: number }
|
|
302
|
-
/** Center point used by plot/region-mark containment certs. */
|
|
303
|
-
center: { x: number; y: number }
|
|
304
|
-
/** Whether the cert proves the full box or the semantic mark center is contained. */
|
|
305
|
-
containment: 'bounds' | 'center'
|
|
306
|
-
withinBounds: boolean
|
|
307
|
-
groupId?: string
|
|
308
|
-
withinGroup?: boolean
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
export type EdgeRouteCertificate = RouteCertificate | FamilyEdgeRouteCertificate
|
|
312
|
-
export type FamilyRouteCertificate = FamilyEdgeRouteCertificate | RegionContainmentCertificate
|
|
313
|
-
export type LayoutRouteCertificate = EdgeRouteCertificate | RegionContainmentCertificate
|
|
314
|
-
|
|
315
|
-
export interface Point {
|
|
316
|
-
x: number
|
|
317
|
-
y: number
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
export interface PositionedGroup {
|
|
321
|
-
id: string
|
|
322
|
-
label: string
|
|
323
|
-
x: number
|
|
324
|
-
y: number
|
|
325
|
-
width: number
|
|
326
|
-
height: number
|
|
327
|
-
children: PositionedGroup[]
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// ============================================================================
|
|
331
|
-
// Render options — user-facing configuration
|
|
332
|
-
//
|
|
333
|
-
// Color theming uses CSS custom properties: --bg and --fg are required,
|
|
334
|
-
// optional enrichment variables (--line, --accent, --muted, --surface,
|
|
335
|
-
// --border) add richer color from Shiki themes or custom palettes.
|
|
336
|
-
// See src/theme.ts for the full variable system.
|
|
337
|
-
// ============================================================================
|
|
338
|
-
|
|
339
|
-
export type TextTransform = 'uppercase' | 'lowercase' | 'capitalize'
|
|
340
|
-
|
|
341
|
-
export interface RenderOptions {
|
|
342
|
-
/** Background color → CSS variable --bg. Default: '#FFFFFF' */
|
|
343
|
-
bg?: string
|
|
344
|
-
/** Foreground / primary text color → CSS variable --fg. Default: '#27272A' */
|
|
345
|
-
fg?: string
|
|
346
|
-
|
|
347
|
-
// -- Optional enrichment colors (fall back to color-mix from bg/fg) --
|
|
348
|
-
|
|
349
|
-
/** Edge/connector color → CSS variable --line */
|
|
350
|
-
line?: string
|
|
351
|
-
/** Arrow heads, highlights → CSS variable --accent */
|
|
352
|
-
accent?: string
|
|
353
|
-
/** Secondary text, edge labels → CSS variable --muted */
|
|
354
|
-
muted?: string
|
|
355
|
-
/** Node/box fill tint → CSS variable --surface */
|
|
356
|
-
surface?: string
|
|
357
|
-
/** Node/group stroke color → CSS variable --border */
|
|
358
|
-
border?: string
|
|
359
|
-
|
|
360
|
-
/** Font family for all text. Default: 'Inter' */
|
|
361
|
-
font?: string
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* How the diagram looks: a registered style name ('hand-drawn', 'tufte',
|
|
365
|
-
* any THEMES palette name like 'dracula'), an inline StyleSpec, or a STACK
|
|
366
|
-
* of either merged left-to-right ({ style: ['hand-drawn', 'dracula'] } is
|
|
367
|
-
* hand-drawn geometry with the dracula palette). A colors-only style is a
|
|
368
|
-
* palette.
|
|
369
|
-
* Precedence: defaults < style stack < themeVariables < explicit color
|
|
370
|
-
* options. Unknown names throw. Unset (or 'crisp') = the default renderer,
|
|
371
|
-
* byte-identical to previous releases.
|
|
372
|
-
*/
|
|
373
|
-
style?: StyleInput | StyleInput[]
|
|
374
|
-
|
|
375
|
-
/** Canvas padding in px. Default: 40 */
|
|
376
|
-
padding?: number
|
|
377
|
-
/** Horizontal spacing between sibling nodes. Default: 24 */
|
|
378
|
-
nodeSpacing?: number
|
|
379
|
-
/** Vertical spacing between layers. Default: 40 */
|
|
380
|
-
layerSpacing?: number
|
|
381
|
-
/** Spacing between disconnected components. Default: nodeSpacing (24) */
|
|
382
|
-
componentSpacing?: number
|
|
383
|
-
/** Render with transparent background (no background style on SVG). Default: false */
|
|
384
|
-
transparent?: boolean
|
|
385
|
-
/** Enable hover tooltips on chart data points (xychart only). Default: false */
|
|
386
|
-
interactive?: boolean
|
|
387
|
-
/** Optional explicit drop shadows on node shapes. Default: false */
|
|
388
|
-
shadow?: boolean
|
|
389
|
-
/** Family-specific SVG renderer options for architecture-beta diagrams. */
|
|
390
|
-
architecture?: {
|
|
391
|
-
visual?: ArchitectureVisualConfig
|
|
392
|
-
}
|
|
393
|
-
/** Optional Mermaid-style runtime config (analogous to initialize/frontmatter config). */
|
|
394
|
-
mermaidConfig?: MermaidRuntimeConfig
|
|
395
|
-
/**
|
|
396
|
-
* Whether to embed the Google Fonts `@import` line in the SVG `<style>` block.
|
|
397
|
-
* Default: `true` (preserves wire compatibility with all existing consumers).
|
|
398
|
-
*
|
|
399
|
-
* CLI / PNG paths set `false` explicitly to render offline / CSP-friendly.
|
|
400
|
-
* The CSS variable `--font` is always emitted on the SVG root regardless,
|
|
401
|
-
* so the family stays overridable post-render even when the @import is gone.
|
|
402
|
-
*/
|
|
403
|
-
embedFontImport?: boolean
|
|
404
|
-
|
|
405
|
-
/**
|
|
406
|
-
* Compact SVG output. Default `false`. When true:
|
|
407
|
-
* - Numeric coords with 3+ fractional digits are rounded (via `roundCoord`).
|
|
408
|
-
* - Newlines between SVG elements are collapsed (whitespace inside `<style>`
|
|
409
|
-
* is preserved so CSS declarations don't break).
|
|
410
|
-
* - `data-*` and `class=` attributes are preserved (agent inspection hooks).
|
|
411
|
-
*
|
|
412
|
-
* Typical reduction: 30-40% of bytes on flowchart graphs. Useful for the
|
|
413
|
-
* PNG render path (no need for human-readable SVG) and for bandwidth-
|
|
414
|
-
* sensitive consumers.
|
|
415
|
-
*/
|
|
416
|
-
compact?: boolean
|
|
417
|
-
/**
|
|
418
|
-
* Namespace prefix for all generated SVG def ids (markers, filters) and
|
|
419
|
-
* their `url(#…)` references. Default '' = current behavior (back-compat,
|
|
420
|
-
* zero snapshot churn). Set a distinct prefix per diagram when rendering
|
|
421
|
-
* multiple diagrams onto one HTML page so their `<defs>` don't collide
|
|
422
|
-
* (e.g. two `arrowhead` markers — the browser dedupes by id and the second
|
|
423
|
-
* diagram's arrows break). `am batch` auto-assigns per-line prefixes.
|
|
424
|
-
* Must be deterministic per call site to preserve render determinism.
|
|
425
|
-
*/
|
|
426
|
-
idPrefix?: string
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Security posture for the rendered output. Default `'default'`.
|
|
430
|
-
* `'strict'` (agent / untrusted-diagram mode): guarantees no external-fetch
|
|
431
|
-
* references in the SVG — forces `embedFontImport` off (no Google Fonts
|
|
432
|
-
* `@import`), so the SVG renders with no network calls. The `--font` CSS
|
|
433
|
-
* variable still declares the family. Use `verifyNoExternalRefs(svg)` to
|
|
434
|
-
* assert the guarantee. Agent/untrusted SVG callers should opt into strict
|
|
435
|
-
* mode explicitly. See SECURITY.md.
|
|
436
|
-
*/
|
|
437
|
-
security?: 'default' | 'strict'
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* Explicit "today" for the Gantt `todayMarker` (a date in the diagram's
|
|
441
|
-
* `dateFormat`, or ISO `YYYY-MM-DD`). Gantt rendering never reads the wall
|
|
442
|
-
* clock; without this value the today marker is simply not drawn, and
|
|
443
|
-
* `todayMarker off` disables it even when a clock is supplied.
|
|
444
|
-
*/
|
|
445
|
-
ganttToday?: string
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* Deterministic re-roll seed for stochastic styles.
|
|
449
|
-
* The same source + options + seed always produces identical bytes; it
|
|
450
|
-
* re-rolls ink wobble only — layout never moves. The crisp path ignores
|
|
451
|
-
* it. Default 0.
|
|
452
|
-
*/
|
|
453
|
-
seed?: number
|
|
454
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// Ambient module declarations so the website Worker — imported by
|
|
2
|
-
// src/__tests__/website-build.test.ts to exercise host/path routing — also
|
|
3
|
-
// type-checks under the ROOT tsconfig. These mirror the module rules in
|
|
4
|
-
// website/src/worker-env.d.ts (wrangler Text/Data/Wasm imports); the worker
|
|
5
|
-
// casts the `caches` global itself, so no Cache API declaration is needed here
|
|
6
|
-
// (declaring one would clash with the DOM `CacheStorage` in the root lib set).
|
|
7
|
-
declare module '*.js.txt' {
|
|
8
|
-
const text: string
|
|
9
|
-
export default text
|
|
10
|
-
}
|
|
11
|
-
declare module '*.ttf' {
|
|
12
|
-
const data: ArrayBuffer
|
|
13
|
-
export default data
|
|
14
|
-
}
|
|
15
|
-
declare module '*.wasm' {
|
|
16
|
-
const mod: WebAssembly.Module
|
|
17
|
-
export default mod
|
|
18
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import type { XYChart } from './types.ts'
|
|
2
|
-
|
|
3
|
-
export function getDataCount(chart: Pick<XYChart, 'xAxis' | 'series'>): number {
|
|
4
|
-
const seriesCount = Math.max(0, ...chart.series.map(series => series.data.length))
|
|
5
|
-
if (chart.xAxis.categories) return Math.max(1, chart.xAxis.categories.length, seriesCount)
|
|
6
|
-
return Math.max(1, seriesCount)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function getDataXValues(chart: Pick<XYChart, 'xAxis' | 'series'>, count = getDataCount(chart)): number[] {
|
|
10
|
-
if (chart.xAxis.range) {
|
|
11
|
-
const { min, max } = chart.xAxis.range
|
|
12
|
-
const step = count > 1 ? (max - min) / (count - 1) : 0
|
|
13
|
-
return Array.from({ length: count }, (_, index) => min + step * index)
|
|
14
|
-
}
|
|
15
|
-
return Array.from({ length: count }, (_, index) => index)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function getCategoryLabels(chart: Pick<XYChart, 'xAxis' | 'series'>, count = getDataCount(chart)): string[] {
|
|
19
|
-
if (chart.xAxis.categories) return Array.from({ length: count }, (_, index) => chart.xAxis.categories![index] ?? String(index + 1))
|
|
20
|
-
if (chart.xAxis.range) return getDataXValues(chart, count).map(value => formatTickValue(value))
|
|
21
|
-
return Array.from({ length: count }, (_, index) => String(index + 1))
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function getPointSpacing(values: number[], scale: (value: number) => number, fallback: number): number {
|
|
25
|
-
if (values.length < 2) return fallback
|
|
26
|
-
let minSpacing = Number.POSITIVE_INFINITY
|
|
27
|
-
for (let i = 1; i < values.length; i++) {
|
|
28
|
-
minSpacing = Math.min(minSpacing, Math.abs(scale(values[i]!) - scale(values[i - 1]!)))
|
|
29
|
-
}
|
|
30
|
-
return Number.isFinite(minSpacing) && minSpacing > 0 ? minSpacing : fallback
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function linearTicks(min: number, max: number, count = 10): number[] {
|
|
34
|
-
if (!(count > 0)) return []
|
|
35
|
-
if (min === max) return [min]
|
|
36
|
-
|
|
37
|
-
const reverse = max < min
|
|
38
|
-
const start = reverse ? max : min
|
|
39
|
-
const stop = reverse ? min : max
|
|
40
|
-
const [indexStart, indexStop, increment] = tickSpec(start, stop, count)
|
|
41
|
-
if (!(indexStop >= indexStart)) return []
|
|
42
|
-
|
|
43
|
-
const tickCount = indexStop - indexStart + 1
|
|
44
|
-
const ticks = new Array<number>(tickCount)
|
|
45
|
-
if (reverse) {
|
|
46
|
-
if (increment < 0) {
|
|
47
|
-
for (let i = 0; i < tickCount; i++) ticks[i] = (indexStop - i) / -increment
|
|
48
|
-
} else {
|
|
49
|
-
for (let i = 0; i < tickCount; i++) ticks[i] = (indexStop - i) * increment
|
|
50
|
-
}
|
|
51
|
-
} else if (increment < 0) {
|
|
52
|
-
for (let i = 0; i < tickCount; i++) ticks[i] = (indexStart + i) / -increment
|
|
53
|
-
} else {
|
|
54
|
-
for (let i = 0; i < tickCount; i++) ticks[i] = (indexStart + i) * increment
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return ticks.map(roundTick)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function formatTickValue(value: number): string {
|
|
61
|
-
if (!Number.isFinite(value)) return String(value)
|
|
62
|
-
if (Number.isInteger(value)) return String(value)
|
|
63
|
-
|
|
64
|
-
const abs = Math.abs(value)
|
|
65
|
-
if (abs >= 1000 || abs === 0) return roundTick(value).toString()
|
|
66
|
-
|
|
67
|
-
const precision = abs < 1 ? 2 : abs < 10 ? 1 : 0
|
|
68
|
-
return stripTrailingZeros(value.toFixed(precision))
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function tickSpec(start: number, stop: number, count: number): [number, number, number] {
|
|
72
|
-
const step = (stop - start) / Math.max(0, count)
|
|
73
|
-
const power = Math.floor(Math.log10(step))
|
|
74
|
-
const error = step / Math.pow(10, power)
|
|
75
|
-
const factor = error >= Math.sqrt(50) ? 10 : error >= Math.sqrt(10) ? 5 : error >= Math.sqrt(2) ? 2 : 1
|
|
76
|
-
|
|
77
|
-
let indexStart: number
|
|
78
|
-
let indexStop: number
|
|
79
|
-
let increment: number
|
|
80
|
-
|
|
81
|
-
if (power < 0) {
|
|
82
|
-
increment = Math.pow(10, -power) / factor
|
|
83
|
-
indexStart = Math.round(start * increment)
|
|
84
|
-
indexStop = Math.round(stop * increment)
|
|
85
|
-
if (indexStart / increment < start) indexStart++
|
|
86
|
-
if (indexStop / increment > stop) indexStop--
|
|
87
|
-
increment = -increment
|
|
88
|
-
} else {
|
|
89
|
-
increment = Math.pow(10, power) * factor
|
|
90
|
-
indexStart = Math.round(start / increment)
|
|
91
|
-
indexStop = Math.round(stop / increment)
|
|
92
|
-
if (indexStart * increment < start) indexStart++
|
|
93
|
-
if (indexStop * increment > stop) indexStop--
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (indexStop < indexStart && 0.5 <= count && count < 2) {
|
|
97
|
-
return tickSpec(start, stop, count * 2)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return [indexStart, indexStop, increment]
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function roundTick(value: number): number {
|
|
104
|
-
return Math.round(value * 1e12) / 1e12
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function stripTrailingZeros(value: string): string {
|
|
108
|
-
return value.replace(/\.0+$|(\.\d*?[1-9])0+$/, '$1')
|
|
109
|
-
}
|