1. 程式人生 > >HTML5第三彈:亦酷亦萌的網路拓撲圖

HTML5第三彈:亦酷亦萌的網路拓撲圖

前言

前一篇3D機房好像有點火,看來輕量的Web 3D是大勢所趨,當時選擇WebGL而不是U3D真是灰常英明的抉擇。

3D雖然炫酷,但在真正的企業應用裡,資料、關係的呈現還是要回到傳統2D介面,而HTML5是目前的最佳選擇。像HTML5的canvas,雖然已經不是什麼新鮮技術了,但直接在瀏覽器中繪製網路拓撲圖的邏輯關係,而不需要安裝任何外掛,對於很多正在更新換代的OSS系統來說,還是很有吸引力的。

最近忙著給客戶折騰一個複雜的多層巢狀關係,最後的成果還是比較有成就感的。

這裡寫圖片描述

需求描述

先簡單描述下這次客戶的需求。

現實應用中,網路拓撲圖結構可能很簡單,也可能非常複雜。

比如這種節點較多的單層拓撲:

這裡寫圖片描述

稍複雜一些的:

這裡寫圖片描述

在這些拓撲圖中常見的場景是,很多網路節點需要組成一組,這常被稱為“網元組”。一般來說,網元組會有一個形狀,雙擊可以展開/閉合。如下圖:

這裡寫圖片描述

這次客戶的需求中,最大的難點就是需要有五層網元組的巢狀,五層同時展開時,要求清晰美觀。常規的分組形狀有圓形、矩形、平行四邊形等,無論哪種形狀,分組多了後,就會產生審美疲勞。比如,我讓設計師mm簡單地把五層巢狀畫個圖,它看起來會是這樣:

這裡寫圖片描述

我把這個圖給客戶看了以後,客戶表示希望“結構能夠更加清晰”。那天,魔都大雨傾盆,我抓耳撓腮一個下午,終於有了一些靈感。

顏色

怎樣才能使得結構效果更加清晰?我想到的是用顏色。顏色永遠是圖形設計裡面的第一要素。如果分組顏色千篇一律,自然就看不太清楚包含關係。但是顏色太多五顏六色,顯然也不符合電信UI系統的風格。那顏色要如何設定呢?層層巢狀的分組,層層……叮!你有沒有想到一種蔬菜?
這裡寫圖片描述

(此處哼唱“如果你可以一層一層一層地剝開我的心……”一百遍……)

這顆大洋蔥看上去層次分明,是因為它的顏色從內到外有一定規律的變化:漸變。說到漸變,又想起最近GF推薦的一枚遊戲,大概內容是按照顏色的漸變規律來排列一些方塊。(很無聊有沒有?)

這裡寫圖片描述

不過,前端設計中,配色倒是很重要的一個環節。

總之,想好了用漸變的配色來使巢狀組更清晰後,就大膽地嘗試一下:

var group = new twaver.Group();
group.setStyle('group.fill.color', style[3]);
group.setStyle('group.deep', 0);
group.setStyle('group.outline.width'
, style[1]); group.setStyle('group.outline.color', style[0]); group.setStyle('group.shape', 'roundrect'); group.setStyle('select.style', 'none'); group.setStyle('vector.outline.pattern', style[2]); group.setStyle('label.font', '14px "Microsoft Yahei"'); group.setStyle('whole.alpha', 0.8); group.setStyle('group.padding', -10); group.setStyle('label.position', 'topright.topleft'); group.setName(name); group.setLocation(100+150*level, 300); box.add(group);

資料量更大的時候,看看分組是不是會更加清晰?

這裡寫圖片描述

更多顏色

這個圖做出來之後,拿給周圍幾個同事看,大家紛紛表示不錯,但是似乎有一些死板,不夠生動。生動。。那就是要活靈活現的,於是我繼續抓耳撓腮,又想到了一些瓜果蔬菜:

這裡寫圖片描述

大自然鬼斧神工,果然還是我的配色不夠明豔啊。我又讓設計師mm給找了幾個色值調整了一下:

這裡寫圖片描述

看起來明朗多了。

折角

有了寫花瓣層疊的感覺,是不是舒服多了?不過,方方正正的組的形狀,還是太死板,缺乏立體感。看到桌子上的一張折了角的白紙,突然有了靈感。

給方形的組做一個折角效果,不知效果如何。要做這個效果,就要重寫group的繪製,自己接管2d繪製了。Group的形狀將不再是一個矩形,而是一個切角的矩形。

//draw round rect body.
var roundRadius=10;
ctx.save();
ctx.beginPath();
ctx.moveTo(rect.x+roundRadius, rect.y);
ctx.lineTo(rect.x+rect.width-60, rect.y);
ctx.lineTo(rect.x+rect.width, rect.y+28);
ctx.lineTo(rect.x+rect.width, rect.y+rect.height-roundRadius);
ctx.quadraticCurveTo(rect.x+rect.width, rect.y+rect.height, rect.x+rect.width-roundRadius, rect.y+rect.height);
ctx.lineTo(rect.x+roundRadius, rect.y+rect.height);
ctx.quadraticCurveTo(rect.x, rect.y+rect.height, rect.x, rect.y+rect.height-roundRadius);
ctx.lineTo(rect.x, rect.y+roundRadius);
ctx.quadraticCurveTo(rect.x, rect.y, rect.x+roundRadius, rect.y);
ctx.save();
ctx.shadowOffsetX = 4;
ctx.shadowOffsetY = 4;
ctx.shadowBlur = 4;
ctx.shadowColor ="#555555";
ctx.fill();
ctx.restore();
ctx.lineWidth=node.getStyle('group.outline.width');
ctx.strokeStyle=node.getStyle('group.outline.color');
ctx.stroke();       
ctx.restore();

通過繪製一個帶圓角的矩形並切掉一個角,stroke到畫布上。看看效果:

這裡寫圖片描述

再通過增加圓角、切角、增加陰影、設定不同的邊框線寬,讓分組進一步產生“層層遞進”的感覺。現在就剩下畫折角的細節了。

折角這裡,需要畫一個被折下來的直角三角形。三角形的顏色,應該是“紙”的背面顏色。這裡小心定義三角形的形狀,並進行填充:

//draw corlor.
ctx.fillStyle=node.getStyle('group.outline.color');             
ctx.lineWidth=node.getStyle('group.outline.width');
ctx.lineJoin='bevel';
ctx.beginPath();
ctx.moveTo(rect.x+rect.width-60, rect.y);
ctx.lineTo(rect.x+rect.width-23-10, rect.y+47-10);
ctx.quadraticCurveTo(rect.x+rect.width-23, rect.y+46, rect.x+rect.width-23+10, rect.y+47-10);
ctx.lineTo(rect.x+rect.width, rect.y+28);
ctx.closePath();
ctx.save();
ctx.shadowOffsetX = 4;
ctx.shadowOffsetY = 4;
ctx.shadowBlur = 4;
ctx.shadowColor ="#777777";
ctx.fill();                         
ctx.restore();
ctx.strokeStyle=node.getStyle('group.outline.color');
ctx.stroke();   

效果如下,立體感出來以後,是不是生動了很多?

這裡寫圖片描述

這裡要注意的是,折角的陰影也要設定,並且填充要使用和邊框相同的顏色,增加“摺紙”的立體感。

小細節

摺紙效果有了,不過左側上方略顯空曠,於是利用canvas的2d來練練手,畫個path看看:

ctx.save();
ctx.strokeStyle='#27A3DA';
ctx.lineWidth=2;
ctx.beginPath();
ctx.moveTo(rect.x+31, rect.y+5);
ctx.lineTo(rect.x+25, rect.y+20);
ctx.bezierCurveTo(rect.x+25, rect.y+26, rect.x+28, rect.y+28, rect.x+32, rect.y+23);
ctx.lineTo(rect.x+42, rect.y-2);
ctx.bezierCurveTo(rect.x+42, rect.y-12, rect.x+32, rect.y-10, rect.x+32, rect.y-5);
ctx.lineTo(rect.x+29, rect.y-1);

ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 1;
ctx.shadowBlur = 1;
ctx.shadowColor ="#aaaaaa";
ctx.stroke();
ctx.restore();

執行一下,你猜是神馬?

這裡寫圖片描述

哈哈,一個小回形針瞬間躍然紙上了,感覺萌萌噠!為了增加立體感,回形針也是要設定陰影的,不過偏移不要太大、顏色要淡一些,像這樣:

這裡寫圖片描述

適當明豔的色彩,加上折角、陰影和小回形針,這回這個層層巢狀總算是清晰又好看了吧?

執行一下,拖拖拽拽,因為之前已經做了不少圖示、線條的樣式,所以總體效果還是很不錯的!

這裡寫圖片描述

這裡寫圖片描述

後記

之前也說,HTML5的canvas,雖然已經不是什麼新鮮技術了,但當技術本身不再有壁壘,我們更應該注重的是實際業務中應用,比如在畫這種組織結構關係非常複雜的拓撲圖時,如何讓圖形更加清晰、易懂,讓技術真正落到實處。如果你有更加好的這類拓撲圖的解決方案,也可以和我聯絡交流:[email protected]

相關推薦

HTML5網路拓撲圖

前言 前一篇3D機房好像有點火,看來輕量的Web 3D是大勢所趨,當時選擇WebGL而不是U3D真是灰常英明的抉擇。 3D雖然炫酷,但在真正的企業應用裡,資料、關係的呈現還是要回到傳統2D介面,而HTML5是目前的最佳選擇。像HTML5的canvas,雖然已

老鼠屎地理資訊視覺化Plotly+Pyecharts繪製地理座標系線圖

    由於最近老鼠屎做的東西和地圖上的線型圖相關,因此在這裡做一點簡單總結。很多地方都除錯得很不理想,希望成功的地方可以給大家帶來一點點啟發,不理想的地方也歡迎大神們賜教。 1 Plotly 1.1 地圖上繪製線     有關pyplot的相關在老鼠屎的博文使用plo

scala學習scala實戰

需要安裝的軟體jdk scala sbt repl sbt(simple build tools)為scala而設計 scala的互動式介面叫做repl介面 進入互動介面:命令列輸入scala 退出互

圖神經網路概述來自IEEE Fellow的GNN綜述

選自 arXiv,作者:Zonghan Wu等,機器之心編譯。 圖神經網路(GNN)熱度持續上升,之前我們曾介紹了清華兩篇綜述論文,參見:深度學習時代的圖模型,清華髮文綜述圖網路,和清華大學圖神經網路綜述:模型與應用。最近,IEEE Fellow、Senior Member 和 Member Zon

JDK1.8 API翻譯(Number)

下面開始翻譯。 Class Number java.lang.Object     java.lang.Number All Implemented Interfaces: Serializable Direct Known Subclasses

github管理自己的學習計劃

最近使用了github後有了將自己近 半年的學習情況在上面進行記錄的想 法,就是建立一個自己的repo,裡 面存放一些自己做過的或者看過的一 些工作,這樣豈不是很方便還高大 上,於是說幹就幹! 先放個整體效果圖鎮樓 現在,我

Java併發必知必會用積木講解ABA原理

# Java併發必知必會第三彈:用積木講解ABA原理 ![封面圖](http://cdn.jayh.club/blog/20200825/f0IhlK4RmutQ.png?imageslim) 可落地的 Spring Cloud專案:[PassJava](https://github.com/Jackso

【轉】LLVM——幾維安全CTO劉柏江IoT時代LLVM編譯器防護的藝術

      「隨著物聯網時代的開啟,需要解決的安全問題會愈來愈多,而程式碼安全是其他安全方案的底層支撐。面對晶片架構繁多,執行環境複雜的嵌入式物聯網裝置,傳統的程式碼安全方案都將會失效,LLVM編譯器為我們帶來了終極程式碼安全解決方案。」        日前,幾維安全C

程式設計師表白程式,開放原始碼,不斷更新(第二

首先感謝hackerzhou同志,是他給了我激情和想法,感謝他的開源精神,造福大家。這一波主要內容集中在網頁這裡,我一直想找一個通用或簡易辦法,能使大部分人都能使用“表白”這份禮物,如果使用網頁,那麼就要會建站,要伺服器,要域名,除了程式碼還需要配置,有點麻煩,我這裡使用的都

[Python3] 011 字串給你們看看我的內建方法

目錄 少廢話,上例子 1. encode(encoding='utf-8', errors='strict') 2. expandtabs([tabsize=8]) 藉此機會簡單地說一說 print() 3. format_map()

[Python3] 011 字符串給你們看看我的內置方法

its 文件的 所有 ive utf-8 示例 orm ror windows 目錄 少廢話,上例子 1. encode(encoding=‘utf-8‘, errors=‘strict‘) 2. expandtabs([tabsize=8]) 借此機會簡單地說一說 pr

機器學習為慈善機構尋找捐助者

alt earch .get 變量 照相 標簽 log 比較 random 這個任務同樣是在Jupyter Notebook中完成, 項目目的是通過前面的所有特征列,當然去掉序號列,然後預測最後一列,收入‘income‘,究竟是大於50K,還是小於等於50K. 第一

【Linux探索之旅】第一部分測試並安裝Ubuntu

u盤 nco 過程 sans ubunt windows u盤啟動盤 系統 .com 內容簡單介紹 1、第一部分第三課:測試並安裝Ubuntu 2、第一部分第四課預告:磁盤分區 測試並安裝Ubuntu 大家好,經過前兩個比較偏理論(是否

讀構建之法 軟件工程師的成長

知識點 可維護 vid -s 評估 不同 fun 可靠 科研 本章理論和知識點:評價軟件工程師水平的主要方法 軟件工程把相關的技術和過程統一到一個體系中,叫“軟件開發流程”,軟件開發流程的目的是為了提高軟件開發、運營、維護的效率,以及提升用戶滿意度、軟件的可靠性和可維護性。

linux設備驅動寫一個簡單的字符設備驅動

提示 copy flags 驅動程序 相關 clas open ugo param 在linux設備驅動第一篇:設備驅動程序簡介中簡單介紹了字符驅動,本篇簡單介紹如何寫一個簡單的字符設備驅動。本篇借鑒LDD中的源碼,實現一個與硬件設備無關的字符設備驅動,僅僅操

Python基礎函數

turn 說明 代碼 名稱 維護 span 大小寫 div 邏輯 一、Python函數介紹 1.函數的作用 規範代碼使代碼變得邏輯性更強 提高可讀性,方便管理,降低維護成本,以及降低代碼冗余 函數是組織好的,可重復使用的,用來實現單一,或相關聯功能的代碼段。 2.函

爬蟲框架 - Scrapy

工程 講解 爬取 turn 本體 爬蟲框架 sel 傳遞 使用 前言 Python提供了一個比較實用的爬蟲框架 - Scrapy。在這個框架下只要定制好指定的幾個模塊,就能實現一個爬蟲。 本文將講解Scrapy框架的基本體系結構,以及使用這

數據可視化 - ggplot2

strong 保存 轉換成 特征 散點圖 說明 pdf格式 ota 目的 前言 R語言的強大之處在於統計和作圖。其中統計部分的內容很多很強大,因此會在以後的實例中逐步介紹;而作圖部分的套路相對來說是比較固定的,現在可以先對它做一個總體的認識。

開發中的問題及解決方式

.text cat 彈窗 ret 如何 配置 中項 新的 顯示 1.texarea 如何保存空格、換行? 答:var content1= $("#content").val(); var content =content1.replace(/\n|\r\n/g,"&

python學習之路—— (作業篇第一題)

image 操作 啟動程序 代碼 color 鎖定文件 文件 文件內容 數據 作業一:編寫登錄接口1.輸入用戶名密碼2.認證成功後顯示歡迎信息3.輸錯三次後鎖定。 所需知識點 文件基本讀寫操作,循環,列表,字典 上面的作業題是在學習完數據類型和簡單的文件操作之後布置的,