Conversation
- network.ts: replace fixed BASE_R+WEIGHT_STEP formula with linear mapping from actual [min_weight, max_weight] to [MIN_NODE_R=20, MAX_NODE_R=56]; add edge stroke-width linear mapping from [min_edge_weight, max_edge_weight] to [MIN_EDGE_W=1, MAX_EDGE_W=6] - types.ts: remove [1-5] restriction on NetworkNode.weight; add weight field to NetworkEdge - parse.ts: remove clamp(1,5) on node weight; add edge weight parsing (syntax: `A --> B: label: 3` or `A --> B: 3`) - bubble.ts: replace area-proportional formula with linear radius mapping from actual [minVal, maxVal] to [MIN_R, MAX_R] - Update all affected SVG snapshots
…a, fixed edge width - bubble.ts: revert to original area-proportional radius formula (r = sqrt(MIN_R² + value/maxVal * (MAX_R² − MIN_R²))) - network.ts: replace linear mapping with the same area-proportional formula (weight plays the role of value, maxWeight as denominator) - network.ts: restore fixed theme.edgeWidth for all edges; remove MIN_EDGE_W/MAX_EDGE_W constants and linearMap helper - Update all affected SVG snapshots
…meline and Network
|
官网首页图表数量。 |
Done in the latest commit. Changes made:
|
There was a problem hiding this comment.
Pull request overview
This PR introduces and documents a new network diagram type in ai-figure, including a force-directed renderer, figmd parsing support, updated public types/exports, and refreshed docs/site/gallery content to reflect the 14th diagram type.
Changes:
- Added
networkdiagram implementation (createNetworkDiagram) and wired it intofig()dispatch + public types. - Added figmd parsing support for
figure network, plus multiple new snapshot tests and regenerated SVG snapshots/assets. - Updated README/SKILL/AGENT + site docs/gallery content to include
networkand reflect “14 diagram types”.
Reviewed changes
Copilot reviewed 19 out of 26 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/snapshots/network-tech-stack-antv.svg | New snapshot for antv palette network example |
| tests/snapshots/network-social-figma-dark.svg | New snapshot for figma dark network example |
| tests/snapshots/network-parse-characters.svg | New snapshot for figmd-parsed (Chinese) network example |
| tests/snapshots/network-org-drawio-dark.svg | New snapshot for drawio dark org network example |
| tests/snapshots/network-knowledge-mono-purple.svg | New snapshot for mono-purple knowledge graph example |
| tests/snapshots/network-characters-default.svg | New snapshot for default palette Three Kingdoms example |
| tests/network-tech-stack-antv.test.ts | Adds snapshot test for tech stack network |
| tests/network-social-figma-dark.test.ts | Adds snapshot test for social graph dark network |
| tests/network-parse-characters.test.ts | Adds snapshot test exercising figmd parsing for network |
| tests/network-org-drawio-dark.test.ts | Adds snapshot test for org chart (drawio dark) network |
| tests/network-knowledge-mono-purple.test.ts | Adds snapshot test for ML knowledge graph network |
| tests/network-characters-default.test.ts | Adds snapshot test for default palette characters network |
| src/types.ts | Adds Network* public types and extends FigOptions union |
| src/parse.ts | Adds parseNetwork() and updates “unknown figure type” error message to include network |
| src/network.ts | New network renderer + force layout implementation |
| src/index.ts | Wires network into dispatcher and re-exports Network* types |
| src/bubble.ts | Minor comment wording change |
| SKILL.md | Updates skill metadata + adds network documentation and examples |
| site/src/lib/diagrams.ts | Adds network examples to gallery data |
| site/src/app/page.tsx | Updates homepage copy from 13 → 14 diagram types |
| site/src/app/gallery/page.tsx | Updates gallery page metadata to include network |
| site/src/app/docs/page.tsx | Adds network section to docs sidebar + content |
| site/src/app/ai/page.tsx | Updates AI playground system prompt and examples to include network |
| README.md | Restructures showcase table + adds network docs section and usage snippets |
| assets/network.svg | Adds representative network SVG asset referenced by README |
| AGENT.md | Updates contributor guidance to mention network behavior/constants |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!nodeMap.has(id) || nodeExpr.trim() !== id) { | ||
| const node: NetworkNode = { id, label }; | ||
| if (currentGroup) node.group = currentGroup; | ||
| if (weight !== undefined) node.weight = weight; | ||
| nodeMap.set(id, node); | ||
| nodes.push(node); | ||
| } else if (weight !== undefined) { | ||
| // Update weight if node was auto-created by an edge | ||
| const existing = nodeMap.get(id)!; | ||
| existing.weight = weight; | ||
| } |
| // ── Compute node radii (area-proportional, same formula as bubble chart) ─ | ||
| // Area ∝ weight: r = sqrt(MIN_R² + weight/maxWeight * (MAX_R² − MIN_R²)) | ||
| const nodeWeights = rawNodes.map(n => Math.max(0, n.weight ?? 1)); | ||
| const maxNodeW = Math.max(...(nodeWeights.length ? nodeWeights : [1])); | ||
| const radii = nodeWeights.map(w => | ||
| maxNodeW > 0 | ||
| ? Math.round(Math.sqrt(MIN_NODE_R * MIN_NODE_R + (w / maxNodeW) * (MAX_NODE_R * MAX_NODE_R - MIN_NODE_R * MIN_NODE_R))) | ||
| : MIN_NODE_R, | ||
| ); |
| // Collect unique groups in order of first appearance | ||
| const groupOrder: string[] = []; | ||
| const groupSeen = new Set<string>(); | ||
| for (const n of rawNodes) { | ||
| const g = n.group ?? ''; | ||
| if (!groupSeen.has(g)) { groupSeen.add(g); groupOrder.push(g); } | ||
| } |
| const x1 = px(si), y1 = py(si); | ||
| const x2 = px(ti), y2 = py(ti); | ||
| const r2 = radii[ti]; | ||
|
|
||
| // Shorten line so it ends at the target node's boundary (arrowhead sits at border) | ||
| const dx = x2 - x1, dy = y2 - y1; | ||
| const dist = Math.sqrt(dx * dx + dy * dy) || 1; | ||
| const ex2 = Math.round(x2 - (dx / dist) * (r2 + 2)); | ||
| const ey2 = Math.round(y2 - (dy / dist) * (r2 + 2)); | ||
|
|
||
| parts.push( | ||
| `<line x1="${x1}" y1="${y1}" x2="${ex2}" y2="${ey2}" ` + | ||
| `stroke="${escapeXml(theme.edgeColor)}" stroke-width="${theme.edgeWidth}" ` + | ||
| `marker-end="url(#${uid}-arr)" class="${uid}-edge"/>`, | ||
| ); | ||
|
|
||
| // Optional edge label (centred) | ||
| if (e.label) { | ||
| const lx = Math.round((x1 + ex2) / 2); | ||
| const ly = Math.round((y1 + ey2) / 2); |
| const dx = nodes[i].x - nodes[j].x; | ||
| const dy = nodes[i].y - nodes[j].y; | ||
| const d2 = dx * dx + dy * dy || 0.01; | ||
| const d = Math.sqrt(d2); | ||
| const f = k2 / d; |
| parts.push( | ||
| `<line x1="${x1}" y1="${y1}" x2="${ex2}" y2="${ey2}" ` + | ||
| `stroke="${escapeXml(theme.edgeColor)}" stroke-width="${theme.edgeWidth}" ` + | ||
| `marker-end="url(#${uid}-arr)" class="${uid}-edge"/>`, | ||
| ); |
| * Optional numeric weight (any positive number). | ||
| * Controls the node circle radius via linear mapping across all node weights: | ||
| * the node with the lowest weight gets the minimum radius, the highest gets | ||
| * the maximum radius. Defaults to 1. | ||
| */ | ||
| weight?: number; |
| - **Sequence**: `TOP_PAD=24`, `BOTTOM_PAD=32`, actor `W=120 H=44`, spacing `180` px center-to-center, message spacing `56` px. | ||
| - **Quadrant**: `PAD_LEFT=56` (Y-axis label), `PAD_RIGHT=24`, `PAD_TOP=32`, `PAD_BOTTOM=52` (X-axis label). | ||
| - **Radar**: `W=560`, `CX=280`, `R=180`, `LABEL_PAD=38`, `LEVELS=5`; legend: `LEGEND_ITEM_H=22`, `LEGEND_PAD_TOP=18`, `LEGEND_PAD_BTOM=14`; max 4 legend columns. | ||
| - **Network**: `BASE_R=28`, `WEIGHT_STEP=6`, `PAD=48`, `IDEAL_LEN=120`, `ITERATIONS=300`; node radius = `BASE_R + (weight−1)×WEIGHT_STEP` (weight clamped to [1,5]). |
| import { fig } from '../src/index'; | ||
| import { matchSvgSnapshot } from './helpers'; | ||
|
|
||
| it('network diagram — tech stack dependencies, antv palette', () => { |
|
@copilot code review 的问题帮忙看看~ |
已处理 code review 提到的问题,修复已在提交 |
|
@copilot 如果图形的直径小于 18, 则把文字放在图形外面,做一下简单的文字碰撞处理。 |
已处理,已在提交 |
|
@copilot 为什么节点大小差距这么大了,是修改了 最大最小范围吗? |
是的,范围改过:当前节点半径从之前的 |
|
@copilot 调整到 16-56 吧,别轻易修改。如果没有指定 value 也默认大小 36 |
已按要求调整,提交 |
Several UX and quality improvements to the network diagram type, plus README showcase table restructuring and site content updates.
Network rendering changes
MIN=20/MAX=56→MIN=16/MAX=56weight/valueis not specified, node radius now defaults to36[1,5]and mapped linearly from min→max weighted node toMIN_NODE_R..MAX_NODE_R14→10, edge labels12→10…), purely by char count — no width-based secondary clippingNetworkEdge.weightnow affects rendered edge stroke widthTests
network-knowledge-mono-purple— ML concepts knowledge graph, mono-purple palettenetwork-org-drawio-dark— R&D org chart (Chinese labels), drawio dark palettetests/parse/network.test.ts(duplicate-node refinement, ungrouped type behavior, edge weight parsing/rendering behavior)tests/network-rendering.test.ts(radius min/max mapping, edge boundary anchoring, ungrouped type assignment, default radius behavior when weight/value is omitted, and label placement assertions)assets/network.svgsynced to the Three Kingdoms characters caseREADME showcase table
Site & gallery updates
networkto the sidebar TOC and a full diagram section with live preview, config table, and markdown syntax notesnetworkexamples todiagrams.ts(matching all other types), covering: Three Kingdoms characters (default), Frontend tech stack (antv), Social network (figma dark), ML knowledge graph (mono-purple), Microservices (drawio), City transport (vega), Movie universe (mono-orange dark), R&D org chart in Chinese (drawio dark)networkadded to the valid types list with a working markdown example