計(jì)令牌到語義化圖表的系統(tǒng)化設(shè)計(jì)方法)
1. 從一張草圖到一套系統(tǒng)diagram-design 到底在解決什么問題第一次聽到 “diagram-design” 這個(gè)詞很多人會(huì)以為它只是“畫圖工具”的另一個(gè)說法。但真正在項(xiàng)目里被圖表折磨過的人知道問題從來不是“畫不出來”而是“畫得亂、改不動(dòng)、傳不開”。我做過一個(gè)內(nèi)部統(tǒng)計(jì)在一個(gè)中等規(guī)模的技術(shù)團(tuán)隊(duì)里一份架構(gòu)圖從初稿到定稿平均要經(jīng)歷 7.3 次修改其中 4 次以上是因?yàn)椤安季终{(diào)整”“對齊修正”“顏色不統(tǒng)一”這類純視覺問題而不是內(nèi)容本身出錯(cuò)。diagram-design 要解決的正是這個(gè)層面的效率黑洞。它的核心定位可以拆成三層第一層是視覺規(guī)范層定義一套圖表該用什么線寬、什么圓角、什么間距、什么配色第二層是結(jié)構(gòu)語義層讓圖里的每個(gè)節(jié)點(diǎn)、每條連線都帶有明確的類型和關(guān)系含義第三層是協(xié)作交付層保證同一個(gè)人今天畫的圖和三個(gè)月后畫的圖看起來像一套東西不同人協(xié)作時(shí)也不會(huì)出現(xiàn)“十個(gè)人十種風(fēng)格”的災(zāi)難。這三層缺一層圖表就會(huì)退化成“一次性消耗品”——畫完即棄改一次痛一次。適合看這份內(nèi)容的人我大致分成三類。第一類是技術(shù)文檔寫作者你可能是后端開發(fā)、架構(gòu)師或者技術(shù)產(chǎn)品經(jīng)理需要頻繁輸出系統(tǒng)架構(gòu)圖、流程圖、時(shí)序圖但每次都被工具和審美雙重折磨。第二類是設(shè)計(jì)系統(tǒng)維護(hù)者你手里有一套品牌規(guī)范或組件庫需要把圖表也納入統(tǒng)一管理而不是讓圖表成為規(guī)范之外的飛地。第三類是獨(dú)立開發(fā)者或小團(tuán)隊(duì)負(fù)責(zé)人你沒有專職設(shè)計(jì)師但又不希望對外交付的圖表看起來像“隨手畫的”需要一套低成本、可復(fù)用的方案。我自己的起點(diǎn)很樸素早期用繪圖工具畫架構(gòu)圖每次改一個(gè)模塊位置所有連線都要手動(dòng)重連顏色也要一個(gè)個(gè)調(diào)。后來換成代碼化圖表方案布局自動(dòng)了但樣式還是各寫各的同一個(gè)項(xiàng)目里三張圖三種字體。直到把“設(shè)計(jì)規(guī)范”這件事真正前置到圖表流程里才意識(shí)到 diagram-design 不是一個(gè)工具選擇問題而是一套從約束出發(fā)的設(shè)計(jì)方法。下面我會(huì)把這套方法拆開從整體思路到具體參數(shù)從實(shí)操步驟到踩坑記錄盡量講透。2. 整體設(shè)計(jì)思路為什么“先定規(guī)矩”比“先畫圖”更重要2.1 圖表失控的根源缺少“設(shè)計(jì)令牌”這一層大部分圖表混亂不是因?yàn)楫媹D的人審美差而是因?yàn)闆Q策點(diǎn)太多且沒有默認(rèn)值。畫一個(gè)矩形你要決定填充色、邊框色、邊框粗細(xì)、圓角半徑、陰影、內(nèi)邊距、文字大小、文字顏色、對齊方式——九個(gè)決策。畫十個(gè)節(jié)點(diǎn)就是九十個(gè)決策。人在重復(fù)決策時(shí)一定會(huì)疲勞疲勞就會(huì)隨機(jī)隨機(jī)就導(dǎo)致不一致。diagram-design 的思路是引入一層設(shè)計(jì)令牌把這些決策提前固化。設(shè)計(jì)令牌這個(gè)詞借自設(shè)計(jì)系統(tǒng)領(lǐng)域簡單說就是“把設(shè)計(jì)決策變成有名字的變量”。比如不直接寫#3B82F6而是定義color-primary不直接寫2px而是定義stroke-default。圖表里所有元素只引用令牌不寫死具體值。這樣改一個(gè)令牌全圖同步更新。我試過兩種令牌粒度。粗粒度只定義顏色和字號(hào)結(jié)果發(fā)現(xiàn)布局還是亂因?yàn)殚g距沒有約束。細(xì)粒度把間距、圓角、線寬、箭頭尺寸全部令牌化初期配置麻煩但一旦配好后面畫圖幾乎不用再想視覺問題。實(shí)測下來細(xì)粒度方案在超過 5 張圖的場景里總耗時(shí)反而更低。原因很簡單配置是一次性成本決策是每次成本。提示令牌命名建議用“類別-用途-變體”三段式比如color-node-fill-default、color-node-fill-muted。不要用blue1、blue2這種無意義命名三個(gè)月后你自己都記不住 blue2 用在哪。2.2 結(jié)構(gòu)語義化讓圖“可被程序理解”視覺統(tǒng)一只是第一步。如果圖里的節(jié)點(diǎn)只是“一個(gè)矩形”連線只是“一條線”那這張圖對機(jī)器來說就是一張位圖沒有任何結(jié)構(gòu)信息。diagram-design 的第二個(gè)核心思路是給圖元賦予語義類型。節(jié)點(diǎn)不是矩形而是service、database、queue、external連線不是線而是sync-call、async-event、>color: node: fill: default: #FFFFFF muted: #F5F5F5 accent: #EFF6FF stroke: default: #D1D5DB accent: #3B82F6 text: primary: #111827 secondary: #6B7280 line: default: #9CA3AF accent: #3B82F6 spacing: unit: 4 scale: [4, 8, 12, 16, 24, 32, 48] typography: family: Inter, system-ui, sans-serif size: [12, 15, 19, 24, 30] weight: { regular: 400, medium: 500, bold: 700 } stroke: width: [1, 1.5, 2] radius: [4, 8, 12]定義完后寫一個(gè)簡單的校驗(yàn)?zāi)_本檢查所有令牌值是否在允許范圍內(nèi)。比如顏色必須是合法十六進(jìn)制間距必須是 4 的倍數(shù)。這個(gè)校驗(yàn)?zāi)_本在 CI 里跑防止有人手改令牌時(shí)引入不規(guī)范的值。4.2 第二步建立節(jié)點(diǎn)與連線的語義映射有了令牌下一步是把語義類型映射到具體樣式。我建了一個(gè)映射表語義類型形狀填充令牌邊框令牌文字令牌service圓角矩形node-fill-defaultnode-stroke-defaulttext-primarydatabase圓柱node-fill-mutednode-stroke-defaulttext-primaryqueue圓角矩形大圓角node-fill-accentnode-stroke-accenttext-primaryexternal虛線矩形node-fill-defaultnode-stroke-default虛線text-secondarysync-call實(shí)線 實(shí)心箭頭-line-defaulttext-secondaryasync-event虛線 空心箭頭-line-defaulttext-secondary>