Tighten architecture nodes by label length
This commit is contained in:
1 parent
f8233d9f20
commit
ab23e48f4f
4 files changed
+47
-5
No files matched your search
@@ -174,6 +174,7 @@ import { api } from "@/lib/api";
|
||||
import { EDITOR_LOCAL_SAVE_DELAY_MS, formatShortcutBinding, getNotebookMoveOptions, type ShortcutSettings } from "@/lib/app-helpers";
|
||||
import { copyTextToClipboard } from "@/lib/clipboard";
|
||||
import {
|
||||
architectureNodeHeight,
|
||||
compactArchitectureNodeSize,
|
||||
compactFlowchartNodeSize,
|
||||
flowchartNodePresentation,
|
||||
@@ -1114,7 +1115,14 @@ const diagramNodePresentation = (
|
||||
fontSize, 'font-size': fontSize, 'font-weight': kind === "architecture" ? ARCHITECTURE_NODE_FONT_WEIGHT : !node.parentId ? 650 : 500,
|
||||
lineHeight,
|
||||
});
|
||||
return { ...size, height: Math.max(size.height, text.split("\n").length * lineHeight + 16), text };
|
||||
const lineCount = text.split("\n").length;
|
||||
return {
|
||||
...size,
|
||||
height: kind === "architecture"
|
||||
? architectureNodeHeight(node.shape, lineCount)
|
||||
: Math.max(size.height, lineCount * lineHeight + 16),
|
||||
text,
|
||||
};
|
||||
};
|
||||
|
||||
const diagramNodeSize = (node: DiagramDocument["nodes"][number], kind: DiagramDocument["kind"], structure?: DiagramStructure) => {
|
||||
|
||||
@@ -180,6 +180,22 @@ describe("diagram auto layout", () => {
|
||||
expect(compactArchitectureNodeSize("boundary", { width: 640, height: 360 })).toEqual({ width: 640, height: 360 });
|
||||
});
|
||||
|
||||
test("reserves height for wrapped architecture labels while shortening compact nodes", () => {
|
||||
const document = compileDiagramIr({
|
||||
kind: "architecture",
|
||||
nodes: [
|
||||
{ id: "short", type: "service", label: "API" },
|
||||
{ id: "medium", type: "service", label: "商品与库存查询服务" },
|
||||
{ id: "long", type: "service", label: "商品与库存查询服务及活动规则配置中心" },
|
||||
],
|
||||
edges: [],
|
||||
});
|
||||
const heights = Object.fromEntries(document.nodes.map((node) => [node.id, node.height]));
|
||||
expect(heights.short).toBe(56);
|
||||
expect(heights.medium).toBe(60);
|
||||
expect(heights.long).toBeGreaterThan(heights.medium);
|
||||
});
|
||||
|
||||
test("turns a long ungrouped architecture pipeline downward on creation and auto layout", () => {
|
||||
const nodes = Array.from({ length: 17 }, (_, index) => ({
|
||||
id: `service-${index}`,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export {
|
||||
compileDiagramIr,
|
||||
architectureNodeHeight,
|
||||
compactArchitectureNodeSize,
|
||||
compactFlowchartNodeSize,
|
||||
flowchartNodePresentation,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { compactFlowchartNodeSize, flowchartNodePresentation } from "./diagram-node-presentation";
|
||||
import { compactFlowchartNodeSize, flowchartNodePresentation, visualTextUnits } from "./diagram-node-presentation";
|
||||
export { compactFlowchartNodeSize, flowchartNodePresentation } from "./diagram-node-presentation";
|
||||
import { DIAGRAM_READABLE_MIN_SCALE, FLOWCHART_LAYOUT_SPACING } from "./diagram-flowchart-style";
|
||||
export {
|
||||
@@ -131,8 +131,25 @@ export const compactArchitectureNodeSize = (
|
||||
if (shape === "boundary") return authored ?? { width: 560, height: 320 };
|
||||
if (shape === "database") return { width: 150, height: 72 };
|
||||
if (shape === "queue") return { width: 156, height: 60 };
|
||||
if (shape === "security") return { width: 148, height: 68 };
|
||||
return { width: 156, height: 64 };
|
||||
if (shape === "security") return { width: 148, height: 60 };
|
||||
return { width: 156, height: 56 };
|
||||
};
|
||||
|
||||
export const architectureNodeHeight = (shape: DiagramNodeShape, lineCount: number) => {
|
||||
const baseHeight = compactArchitectureNodeSize(shape).height;
|
||||
return Math.max(baseHeight, lineCount <= 1 ? 56 : lineCount === 2 ? 60 : lineCount * 17 + 20);
|
||||
};
|
||||
|
||||
const architectureNodeSizeForLabel = (shape: DiagramNodeShape, label: string) => {
|
||||
const { width } = compactArchitectureNodeSize(shape);
|
||||
if (shape === "boundary") return compactArchitectureNodeSize(shape);
|
||||
// Reserve space during semantic layout before the browser measures the final wrapping.
|
||||
const capacity = (width - 66) / 12;
|
||||
const lineCount = label.split("\n").reduce(
|
||||
(count, paragraph) => count + Math.max(1, Math.ceil(visualTextUnits(paragraph) / capacity)),
|
||||
0,
|
||||
);
|
||||
return { width, height: architectureNodeHeight(shape, lineCount) };
|
||||
};
|
||||
|
||||
const computeMindMapLayout = (
|
||||
@@ -1115,7 +1132,7 @@ export const compileDiagramIr = (ir: DiagramIr): DiagramDocument => {
|
||||
const size = ir.kind === "mind-map"
|
||||
? mindMapNodePresentation(node.label, mindMapNodeRole(ir.nodes, node.id), ir.structure)
|
||||
: ir.kind === "architecture"
|
||||
? compactArchitectureNodeSize(shape)
|
||||
? architectureNodeSizeForLabel(shape, node.label)
|
||||
: flowchartNodePresentation(shape, node.label);
|
||||
return {
|
||||
id: node.id,
|
||||
|
||||
Reference in new issue
Block a user