1 簡(jiǎn)介
1.1產(chǎn)品介紹
mxGraph是一系列以不同技術(shù)開發(fā)的工具庫,旨在提供顯示交互式的 圖表和圖形的應(yīng)用程序的功能。 請(qǐng)注意,對(duì)于圖形呼巷,我們是指數(shù)學(xué)圖形, 不一定單單指圖表 (雖然有些圖形是圖表)赎瑰。參見后面的章節(jié):“什么是圖形王悍?”的細(xì)節(jié)描述。
作為一個(gè)開發(fā)庫乡范,mxGraph沒有專門提供了一個(gè)現(xiàn)成的可以使用的應(yīng)用程序配名, 盡管其中的許多例子都接近可以直接使用。 mxGraph提供mxGraph樣式的 所有通常所需的繪畫功能晋辆,互動(dòng)及關(guān)聯(lián)的圖表顯示環(huán)境渠脉。 mxGraph自帶有許多例子, 它們有助于解釋每種技術(shù)是如何被放在一起組成一個(gè)基本的應(yīng)用程序瓶佳,并展示這個(gè) 工具庫的各項(xiàng)功能芋膘。
每本用戶手冊(cè)是針對(duì)某種特定的技術(shù),都具有通用的部分霸饲,如簡(jiǎn)介和布局为朋。開發(fā)人員會(huì)發(fā)現(xiàn),對(duì)于 在不同的技術(shù)實(shí)現(xiàn)厚脉,在產(chǎn)品范圍內(nèi)的每個(gè)工具庫都共享相同的架構(gòu)和API习寸。對(duì)于特定的技術(shù)領(lǐng)域, 事件處理和渲染的實(shí)現(xiàn)略有不同傻工,但是從一個(gè)技術(shù)平臺(tái)整體移植到另一個(gè)平臺(tái)霞溪,mxGraph提供了 盡可能多的通用的接口。
開發(fā)人員在集成此工具庫到他們自己的應(yīng)用程序前中捆,需要應(yīng)該閱讀的使用技術(shù)的先決條件鸯匹。 參見下面的“先決條件”一節(jié)。鑒于mxGraph是您的應(yīng)用程序的組成部分泄伪,你必須了解應(yīng)用程序 使用的技術(shù)殴蓬,以及如何使用該技術(shù)進(jìn)行編程。
mxGraph主要包含一個(gè)JavaScript文件蟋滴,mxGraph的全部函數(shù)都在這個(gè)文件中染厅。它需要被加載到一個(gè)瀏覽器的Web頁面的Javascript中并執(zhí)行在HTML容器中痘绎。它結(jié)構(gòu)簡(jiǎn)單,只要一個(gè)web服務(wù)器來提供html頁面和一個(gè)支持JavaScript的瀏覽器就可以了肖粮。
它的優(yōu)點(diǎn)如下:
- 不需要第三方插件简逮。也就少了對(duì)廠商的依賴。
- 涉及到的技術(shù)都是開源的并且有很多開放的實(shí)現(xiàn)尿赚。這就意味著一個(gè)廠商刪除它的一個(gè)產(chǎn)品或者技術(shù)不會(huì)導(dǎo)致你的程序無法工作。
- 標(biāo)準(zhǔn)化的技術(shù)蕉堰,意味著你的應(yīng)用可以部署在最大數(shù)量的瀏覽器上凌净,用戶不需要在客戶端機(jī)器上添加額外的配置或進(jìn)行安裝。大型企業(yè)的環(huán)境通常不允許個(gè)人安裝瀏覽器插件屋讶,也不允許改變所有機(jī)器的標(biāo)準(zhǔn)配置冰寻。
mxGraph組件關(guān)系
1.2 mxGraph可以被用在什么樣的產(chǎn)品上?
圖形可視化庫的應(yīng)用實(shí)例包括:過程圖皿渗、工作流和BPM的可視化圖表斩芭、流程圖、交通或水流量乐疆、 數(shù)據(jù)庫和WWW的可視化划乖、網(wǎng)絡(luò)和電信顯示、映射應(yīng)用和地理信息系統(tǒng)挤土、UML圖琴庵、電子線路、金融仰美、 超大規(guī)模集成電路和社會(huì)網(wǎng)絡(luò)迷殿、數(shù)據(jù)挖掘、生化咖杂、生態(tài)循環(huán)庆寺、實(shí)體和因果關(guān)系和組織圖表。
1.3 怎樣部署mxGraph诉字?
在典型的瘦客戶端環(huán)境中懦尝,mxGraph分為在客戶端的JavaScript庫和在服務(wù)器端兩種支持的語言之一的.NET或Java庫。 JavaScript庫作為一個(gè)更大的基于瀏覽器的web應(yīng)用程序的一部分奏窑,被一個(gè)標(biāo)準(zhǔn)web服務(wù)器分發(fā)到瀏覽器导披。所有的瀏覽器 需要開啟JavaScript能力才能運(yùn)行這個(gè)應(yīng)用。
在本手冊(cè)的第三部分埃唯,您會(huì)看到一個(gè)嵌入了mxGraph庫的HTML頁面撩匕,以及一個(gè)簡(jiǎn)單的調(diào)用了庫功能的應(yīng)用程序。
1.4 mxGraph的技術(shù)
mxGraph使用在瀏覽器上的客戶端的JavaScript功能墨叛。而在JavaScript代碼層面上止毕,在瀏覽器中使用了基本的矢量圖形語言來顯示圖形模蜡,當(dāng)前SVG技術(shù)已經(jīng)被所有瀏覽器支持。 mxGraph還包括完全只使用HTML來呈現(xiàn)的功能扁凛, 這會(huì)限制可以使用的功能范圍忍疾,但可用于較簡(jiǎn)單的圖表。
作為一名開發(fā)人員谨朝,您并不是被限制在瀏覽器相關(guān)的特定功能卤妒。如前所述,瀏覽器不同字币,所使用的矢量圖形語言也不同则披, 所以mxGraph的功能被抽象成一個(gè)共同的類。同樣洗出,瀏覽器對(duì)于事件處理和DOM士复,兩大瀏覽器實(shí)施的功能也不盡相同。然而翩活, mxGraph通過使用恒定的API來適用于所有瀏覽器阱洪,掩藏不同瀏覽器間的內(nèi)在差異。菠镇、
1.5 mxGraph 授權(quán)
mxGraph的JavaScript客戶端采用了Apache 2.0 license 許可證授權(quán)冗荸,有關(guān)詳細(xì)的許可問題,請(qǐng)務(wù)必咨詢法律專業(yè)人士利耍。
1.6 圖形是什么?
圖形可視化是建立于網(wǎng)絡(luò)俏竞、圖論的數(shù)學(xué)理論基礎(chǔ)上。如果您正在查找JavaScript的條形圖堂竟、餅圖魂毁、甘特圖, 可以參考Google Charts項(xiàng)目,或類似的信息出嘹。
一個(gè)圖是由頂點(diǎn)席楚,也稱為節(jié)點(diǎn),以及邊(節(jié)點(diǎn)之間的連接線)組成税稼。圖論中沒有定義圖究竟如何來視覺呈現(xiàn)烦秩。本手冊(cè)中術(shù)語圖元用來描述圖形的構(gòu)成元素,無論是邊郎仆,節(jié)點(diǎn)或圖元組只祠。
一張簡(jiǎn)單的圖
圖論中有些額外的定義,為圖形處理提供 有用的背景扰肌,如果您感興趣的話抛寝,它們都列在附錄中。
1.6.1 圖形的可視化
可視化是創(chuàng)建一個(gè)有用的圖形可視化展現(xiàn)的過程〉两ⅲ可視化功能的范圍是mxGraphs的主要力量之一晶府。 mxGraph支持范圍廣泛的功能,使圖元顯示僅限于開發(fā)人員的技術(shù)和平臺(tái)可用的功能钻趋。節(jié)點(diǎn)可以是圖形川陆、圖像、矢量繪圖蛮位、動(dòng)畫以及幾乎所有可以在瀏覽器中操作的圖形较沪。您也可以在節(jié)點(diǎn)和邊使用HTML標(biāo)記。
交通系統(tǒng)的可視化圖 (c) Tourizm Maps2003, http://www.world-maps.co.uk
1.6.2 圖形交互
交互是指在一個(gè)使用mxGraph的應(yīng)用程序中失仁,通過WEB應(yīng)用程序的GUI改變圖形模式购对。mxGraph支持拖動(dòng)、復(fù)制圖元陶因、重新調(diào)整大小、重新構(gòu)造垂蜗,連接和斷開楷扬,從外部源的拖放和刪除,編輯圖元標(biāo)簽中的位置等等贴见。 mxGraph的主要好處之一是通過編程來實(shí)現(xiàn)互動(dòng)的靈活性烘苹。
許多復(fù)雜的圖形化Web應(yīng)用程序依賴于與服務(wù)器往返的通訊來顯示圖形,不僅是基本的顯示片部,還包括交互事件镣衡。雖然這就是通常所謂的AJAX功能,這種服務(wù)器的依賴對(duì)交互事件是不合適的档悠。視覺反饋時(shí)間超過0.2秒在應(yīng)用程序中一般嚴(yán)重影響了實(shí)用性廊鸥。mxGraph把所有的交互事件都放置在客戶端,提供了真實(shí)感覺的應(yīng)用程序辖所,而不像一個(gè)啞巴的遠(yuǎn)程終端惰说。它還提供了脫機(jī)使用的可能性。
通過鼠標(biāo)拖動(dòng)選擇一個(gè)區(qū)域時(shí)顯示陰影效果
1.6.3 圖像的布局
圖形圖元可以布置在一個(gè)簡(jiǎn)單的應(yīng)用程序的任何地方缘回,包括在彼此頂部吆视。 某些應(yīng)用程序需要按照一般或特殊的順序結(jié)構(gòu)來顯示出示信息。 這可能涉及到確保圖元不重疊和至少彼此間留有一定的距離酥宴,或出現(xiàn)在相對(duì)于其他圖元的一個(gè)相對(duì) 位置啦吧,圖元通常是通過邊來連接。這個(gè)活動(dòng)拙寡,被稱為布局的應(yīng)用授滓,可以 通過多種方式,來協(xié)助用戶設(shè)置自己的圖形。 對(duì)于非編輯圖形褒墨,布局應(yīng)用是對(duì)圖元進(jìn)行布局算法的過程炫刷。 對(duì)于交互式的圖形,即那些可以通過用戶界面進(jìn)行編輯郁妈,布局應(yīng)用可能只 允許用戶對(duì)特定的圖元進(jìn)行特定位置的修改浑玛,對(duì)每個(gè)修改重新布局,或 編輯完成后噩咪,重新布局顾彰。
使用水平流布局對(duì)工作流進(jìn)行布局
mxGraph支持樹、有機(jī)排列和流向的布局胃碾,來滿足大多數(shù)布局的需求涨享。后面的章節(jié)中會(huì)講述更多布局的信息。
在客戶端-服務(wù)器架構(gòu)中運(yùn)行布局可以有兩個(gè)選項(xiàng)仆百。JavaScript版提供了完全在客戶端布局的能力厕隧,如果需要的話,同樣的布局在服務(wù)器端的Java實(shí)現(xiàn)可以選擇卸載一些服務(wù)器的處理俄周。
1.6.4 圖形的分析
圖形分析涉及到確定有關(guān)的圖形結(jié)構(gòu)的某些細(xì)節(jié)算法的應(yīng)用吁讨,例如, 確定所有路徑或兩個(gè)圖元之間的最短路徑峦朗。有些更復(fù)雜的圖形分析算法建丧,往往被應(yīng)用于 指定域的任務(wù)。有些技術(shù)波势,如聚合翎朱、分解、優(yōu)化等趨向某些針對(duì)性的科學(xué)領(lǐng)域的尺铣,目前包含在核心的mxGraph包中拴曲。
最短路徑分析
1.7 關(guān)于本手冊(cè)
1.7.1 mxGraph先決條件
要從本手冊(cè)中獲益匪淺,您需要對(duì)Web應(yīng)用程序和希望部署的服務(wù)器技術(shù)有一個(gè)合理的了解凛忿。部署的例子可以在每個(gè)服務(wù)器技術(shù)支持得到疗韵,熟悉該服務(wù)器的技術(shù)顯然是必需的。
對(duì)于修改描述顯示和行為方面的編輯器的配置文件侄非,基本的XML知識(shí)是有用的蕉汪。您需要理解和執(zhí)行JavaScript編碼,并熟悉面向?qū)ο缶幊淘砗同F(xiàn)代軟件設(shè)計(jì)逞怨。
您不需要底層的瀏覽器使用的矢量圖形的知識(shí)者疤,如SVG或HTML的canvas。 mxGraph將可視化組件的描述抽象成一個(gè)API叠赦。
2 入門
2.1 mxGraph 包
2.1.1 獲取mxGraph
mxGraph可以從 github 項(xiàng)目上獲得驹马,發(fā)布的版本號(hào)為"va.b.c",其中a,b和c版本號(hào)遵循了語義版本控制
每一個(gè)正式版本的.zip或者.tar.gz包也可以在mxGraph發(fā)布頁面獲得革砸。
2.1.2 項(xiàng)目結(jié)構(gòu)和構(gòu)建選項(xiàng)
解壓縮后,你將在根目錄下獲得的一系列的文件和目錄糯累。
目錄/文件 | 描述 |
---|---|
/doc | 文檔根目錄算利,包含本用戶手冊(cè) |
/docnet | .NET服務(wù)器端代碼 |
/java | Java服務(wù)器端代碼 |
/javascript | JavaScript客戶端功能 |
/javascript/examples | mxGraph的HTML演示例子 |
ChangeLog | 發(fā)布版本間差異詳情 |
index.html | 庫的基本介紹 |
license.txt | 使用庫的許可條款 |
項(xiàng)目目錄結(jié)構(gòu)表
2.1.3 npm
mxGraph同樣可以使用 npm 包管理獲得。使用mxgraph作為依賴泳姐,用 npm 安裝如下:
npm install mxgraph --save
這個(gè)模塊可以使用require()方法進(jìn)行加載效拭。它將返回一個(gè)接受對(duì)象作為選項(xiàng)的工廠函數(shù)。必須將mxBasePath選項(xiàng)提供給工廠函數(shù)胖秒,而不是將其定義為一個(gè)全局變量缎患。
var mxgraph = require("mxgraph")({
mxImageBasePath: "./src/images",
mxBasePath: "./src"
})
工廠函數(shù)返回一個(gè)“命名空間對(duì)象”,通過它可以訪問mxGraph包的所有對(duì)象阎肝。例如挤渔,mxEvent對(duì)象在mxgraph.mxEvent中可用。
var mxEvent = mxgraph.mxEvent;
mxEvent.disableContextMenu(container);
2.2 JavaScript和web應(yīng)用
Web應(yīng)用程序风题,特別是在網(wǎng)頁瀏覽器中使用JavaScript來試圖效仿桌面應(yīng)用程序判导, 仍然是一個(gè)相對(duì)較新的軟件工程領(lǐng)域。障礙JavaScript生產(chǎn)出高質(zhì)量應(yīng)用的主要 有三個(gè)問題:性能沛硅,缺乏原生性的桌面應(yīng)用程序功能以及瀏覽器之間API的不一致性眼刃。
相當(dāng)大的努力已經(jīng)被投入來開發(fā)框架庫,以解決功能和API這兩個(gè)問題稽鞭。許多的開發(fā)庫 的設(shè)計(jì)需求就是由同時(shí)改善網(wǎng)站的設(shè)計(jì)和可用性,以及協(xié)助我們完成一般的應(yīng)用功能 (如菜單引镊、窗口朦蕴、對(duì)話框、持久性弟头、事件處理等)的要求來驅(qū)動(dòng)的吩抓。他們同時(shí)也提供了 某些在JavaScript中找不到的基本功能,如基本的數(shù)學(xué)和集合功能赴恨,而這些功能在桌面 的應(yīng)用程序開發(fā)中是與生俱來的疹娶。
許多這些JavaScript框架,通過原生支持或作為一個(gè)插件的支持伦连,可以用時(shí)下流行IDE來開發(fā)雨饺, 并支持所有的主流包含JavaScript調(diào)試器的瀏覽器。JavaScript沒有編譯過程(它是一種解釋語言)惑淳, 因此额港,除非您的IDE具有語法檢查工具,打字錯(cuò)誤通常只能在運(yùn)行時(shí)刻才可以被捕獲歧焦。因此移斩,世上沒有 一個(gè)能夠包羅萬象的工具包,您往往需要使用好幾個(gè)廠商的獨(dú)立組件,才能提供你開發(fā)JavaScript 應(yīng)用所需要的工具庫向瓷。
2.2.1 第三方JavaScript框架
2.2.1.1 原生JavaScript框架和庫
為了不用列表和比較每一個(gè)框架肠套,請(qǐng)大家參閱維基百科的條目Web應(yīng)用程序框架和JavaScript庫比較。這個(gè)比較表不能被認(rèn)為是最權(quán)威的猖任,而更象說明提供的功能類型你稚,如提供事件處理、動(dòng)畫超升、小工具入宦、支持AJAX請(qǐng)求等。 這個(gè)網(wǎng)站(注:這個(gè)網(wǎng)站內(nèi)容已經(jīng)變了)也是一個(gè)有用的JavaScript庫名單室琢,大多是基于開放/免費(fèi)源許可乾闰。
請(qǐng)注意,很多框架添加了隱式的行為盈滴,使JavaScript的更像是一個(gè)面向?qū)ο蟮恼Z言涯肩, 并增加了語言的基本功能。在寫作的的布局mxGraph部分時(shí)巢钓,我們發(fā)現(xiàn)病苗,這種隱含的行為 使得調(diào)試一個(gè)例子變得非常困難。在選擇一個(gè)框架時(shí)症汹,請(qǐng)留意它引入的隱式的行為阱缓,是否 會(huì)導(dǎo)致任何問題考蕾。
當(dāng)選擇了一個(gè)框架和/或工具庫時(shí),考慮您會(huì)被綁定的某些特定功能,并尋找那些不同的箕肃,可以提供所需功能如動(dòng)畫笋额, 獨(dú)立的模塊淋纲,而無需在總體設(shè)計(jì)上被綁定啄巧。
2.2.1.2 mxGraph與其他JavaScript構(gòu)架的集成
這個(gè)部分經(jīng)常被誤解,簡(jiǎn)單來講胸囱,并不需要集成祷舀。 Web應(yīng)用程序一般包括一個(gè)或多個(gè) div元素, 可以被HTML用來放置包裝應(yīng)用程序的JavaScript烹笔。如果您創(chuàng)建一個(gè)div作為mxGraph的容器裳扯, 這就是一個(gè)可以為mxGraph應(yīng)用程序的獨(dú)立顯示。它可以與任何后端服務(wù)器通信本身谤职,而并不依賴與這個(gè)div和頁面的其余部分嚎朽,除了它們各自占的地方。這包括事件處理柬帕,mxGraph可以處理其容器的事件哟忍, 即便網(wǎng)頁的其余部分用一個(gè)完全不同的事件模型狡门。只要mxGraph和頁面上的其他庫和框架不引入會(huì)打破 一個(gè)頁面作為整體的隱式行為,客戶端集成的問題根本就不需要考慮锅很。
與mxGraph服務(wù)器端集成其馏,我們會(huì)在后面的章節(jié)闡述。
2.2.1.3 mxGraph的JavaScript擴(kuò)展
在JavaScript中爆安,將語言結(jié)構(gòu)映射面向?qū)ο蠓妒接懈鞣N方式叛复。mxGraph在整個(gè)項(xiàng)目中都使用一個(gè)特定的方法, 參見下面的默認(rèn)規(guī)則:
- 不要更改內(nèi)置的原型
- 不要試圖限制JavaScript語言的力量
在mxGraph中扔仓,有兩種類型的“類”:類classes和單例singletons (其中只有一個(gè)存在的類的實(shí)例)褐奥。單例被映射到全局對(duì)象而且變量名同類名是一樣的。 例如翘簇,mxConstants是一個(gè)定義了所有常量字段的對(duì)象實(shí)例撬码。普通類映射到一個(gè)構(gòu)造函數(shù)和 定義了字段和方法的原型。例如版保,mxEditor是一個(gè)函數(shù)而mxEditor.prototype是mxEditor 函數(shù)創(chuàng)建對(duì)象時(shí)的原型呜笑。mx前綴是一種命名習(xí)慣,應(yīng)用于mxGraph包中的所有類彻犁,以避免 與其他對(duì)象在全局命名空間發(fā)生沖突叫胁。
為派生,父類必須提供一個(gè)構(gòu)造函數(shù)汞幢,要么是無參數(shù)或者可以處理不帶參數(shù)的調(diào)用驼鹅。 此外,特殊的構(gòu)造函數(shù)字段派生后的原型必須重新定義森篷。例如输钩,mxEditor派生于mxEventSource。 在JavaScript中疾宏,首先通過分配父類的一個(gè)實(shí)例到子類原型张足,來“繼承”從父類的所有字段和方法:
mxEditor.prototype = new mxEventSource()
并定義構(gòu)造函數(shù)字段:
mxEditor.prototype.constructor = mxEditor
后面的規(guī)則触创,使得可以通過使用構(gòu)造函數(shù)的名稱mxUtils.getFunctionName(obj.constructor)來檢索對(duì)象的類型坎藐。
構(gòu)造函數(shù)
在mxGraph中,對(duì)于派生的子類應(yīng)采用相同的機(jī)制哼绑。例如岩馍,mxGraph的派生子類,首先抖韩, 新類的構(gòu)造函數(shù)必須被定義蛀恩。構(gòu)造函數(shù)調(diào)用的父類的構(gòu)造函數(shù),需要顯式傳入調(diào)用的 mxGraph對(duì)象的每一個(gè)參數(shù):
function MyGraph(container)
{
mxGraph.call(this, container);
}
MyGraph的portotype從mxGraph繼承如下茂浮。像往常一樣双谆,子類的構(gòu)造函數(shù)在繼承后被重新定義:
MyGraph.prototype = new mxGraph();
MyGraph.prototype.constructor = MyGraph;
您可能需要在上述代碼之后定義與該類相關(guān)聯(lián)的編解碼器(參見I/O部分手冊(cè))壳咕。該代碼將在類加載時(shí)執(zhí)行,并確保使用相同的編解碼器來編碼mxGraph和MyGraph的實(shí)例顽馋。
var codec = mxCodecRegistry.getCodec(mxGraph);
codec.template = new MyGraph();
mxCodecRegistry.register(codec);
方法
在MyGraph的prototype中谓厘,mxGraph的方法可如下擴(kuò)展。
MyGraph.prototype.isSelectable = function(cell)
{
var selectable = mxGraph.prototype.isSelectable.apply(this, arguments);
var geo = this.model.getGeometry(cell);
return selectable &&(geo == null || !geo.relative);
}
在第一行中的supercall是可選的寸谜。這是使用apply方法通過傳入this及arguments這個(gè)變量作為參數(shù)竟稳, 到mxGraph的protoype的isSelectable這個(gè)方法上。父類的方法只有在不被覆蓋的時(shí)候才可能被調(diào)用熊痴,這也是JavaScript中另一種“繼承”的方式他爸。
mxGraph.prototype.isSelectable = function(cell)
{
var geo = this.model.getGeometry(cell);
return selectable && (geo == null || !geo.relative);
}
如果方法的定義需要被完全覆蓋,上述方案是有用的果善。
為了增加新的方法和字段诊笤,可以使用如下代碼。在下面的例子岭埠,示范了增加了一個(gè)返回圖模型的XML的新方法:
MyGraph.prototype.getXml = function()
{
var enc = new mxCodec();
return enc.encode(this.getModel());
}
字段
新的字段通過如下方式聲明和定義:
MyGraph.prototype.myField = ‘Hello, World!’;
需要注意的是myField的值只分配了一次盏混,那就是說,所有MyGraph的實(shí)例共享相同的值惜论。 如果您需要每個(gè)實(shí)例擁有自己的值许赃,則該字段必須定義在構(gòu)造函數(shù)中。例如:
function MyGraph(container)
{
mxGraph.call(this, container);
this.myField = [];
}
最后馆类,使用以下代碼將一個(gè)新的MyGraph實(shí)例混聊,其中container是一個(gè)圖形視圖的容器的DOM節(jié)點(diǎn):
var graph = new MyGraph(container);
2.2.2 JavaScript開發(fā)綜述
2.2.2.1 JavaScript混淆
默認(rèn)情況下,當(dāng)你向?yàn)g覽器客戶端發(fā)送JavaScript時(shí)乾巧,發(fā)送都是JavaScript的全部源代碼句喜。然后,JavaScript在瀏覽器上被解析并運(yùn)行沟于。在客戶端運(yùn)行的時(shí)候咳胃,不可能在任何程度上加密JavaScript,因?yàn)镴avaScript解析器必須理解和解釋JavaScript源碼旷太,而且它不具有二進(jìn)制的中間形式展懈。
可以做到的是,在傳輸?shù)倪^程中供璧,將JavaScript加密存崖,在客戶端運(yùn)行前解密,但客戶端仍然能夠訪問解密后的源代碼睡毒。
我們不做混淆来惧,因?yàn)榉椒ǖ拿Q形成的公共的API和I/O,在通信的兩端都需要理解這樣的混淆演顾。
2.2.2.2 命名空間
命名空間的概念在JavaScript中并不存在供搀,所以在創(chuàng)建新的類名稱時(shí)要非常謹(jǐn)慎隅居。 mxGraph中,所有的類都以“mx-”的前綴開始葛虐,以避免無意中沖突或覆蓋掉原型军浆。
2.3 Hello World!
mxGraph中的Hello World,是一個(gè)簡(jiǎn)單的客戶端的例子挡闰,顯示了兩個(gè)相連的“Hello”和“World”的節(jié)點(diǎn)標(biāo)簽乒融。 這個(gè)例子演示了以下幾件事:
- 創(chuàng)建一個(gè)嵌入了mxGraph客戶端JavaScript的HTML頁面
- 創(chuàng)建了一個(gè)容器來裝載mxGraph
- 在圖形中加入了所需的元素
這個(gè)例子的源代碼,helloworld.html摄悯,可以在mxGraph的源代碼的示例目錄下找到赞季。 在HTML源代碼包含兩個(gè)主要部分組成,head和body奢驯。建立一個(gè)基本的mxGraph 應(yīng)用程序的模板應(yīng)包含以下主要內(nèi)容:
mxBasePath: 這是一個(gè)JavaScript變量申钩,用來定義CSS,圖片瘪阁, 資源和js的使用的目錄撒遣。它是一段JavaScript代碼,并需要被放置在 script 標(biāo)簽內(nèi)管跺。 它必須在加載mxClient.js之前义黎,而且不應(yīng)該斜線。
mxClient.js: 這是mxGraph庫的路徑豁跑。如果HTML文件在本地執(zhí)行廉涕, 路徑可能是本地計(jì)算機(jī)路徑或公共互聯(lián)網(wǎng)的路徑。如果HTML頁面是從Web服務(wù)器上下載艇拍,這路徑 通常是一個(gè)公共的因特網(wǎng)路徑狐蜕。
創(chuàng)建容器: 在body元素中底部的代碼,被定義為加載項(xiàng) 的方法(onload事件)卸夕,加載網(wǎng)頁時(shí)會(huì)被調(diào)用层释。它通過在傳遞即下定義的一個(gè)div 容器作為參數(shù)。mxGraph組件將被放置在這個(gè)div容器中快集。在此示例中網(wǎng)格被添加作為背景贡羔, 這在圖表應(yīng)用程序中經(jīng)常用到。在容器創(chuàng)建時(shí)碍讨,其他視覺效果或者其他的背景和以及容器的 寬度和高度都沒有定義治力。
注意蒙秒,如果你想不出現(xiàn)滾動(dòng)條勃黍,overflow:hidden格式應(yīng)該一直被使用。
入口方法: 在這種情況下晕讲,該文件的主要代碼是在頁面加載時(shí)執(zhí)行覆获。 這是JavaScript代碼马澈,還必須在JavaScript的 script 標(biāo)簽當(dāng)中。任何mxGraph 應(yīng)用程序的第一行應(yīng)該檢查瀏覽器的支持弄息,如果不支持應(yīng)該適當(dāng)退出痊班。如果瀏覽器支持, mxGraph將在div容器內(nèi)被創(chuàng)建摹量,在開始/結(jié)束更新調(diào)用之間涤伐,三個(gè)圖元被添加到圖中。
mxGraph的HelloWorld例子
<html>
<head>
<title>Hello, World! example for mxGraph</title>
<!-- Sets the basepath for the library if not in same directory -->
<script type="text/javascript">
mxBasePath = '../src';
</script>
<!-- Loads and initializes the library -->
<script type="text/javascript" src="../src/js/mxClient.js"></script>
<!-- Example code -->
<script type="text/javascript">
// Program starts here. Creates a sample graph in the
// DOM node with the specified ID. This function is invoked
// from the onLoad event handler of the document (see below).
function main(container)
{
// Checks if the browser is supported
if (!mxClient.isBrowserSupported())
{
mxUtils.error('Browser is not supported!', 200, false);
}
else
{
// Creates the graph inside the given container
var graph = new mxGraph(container);
// Enables rubberband selection
new mxRubberband(graph);
// Gets the default parent for inserting new cells. This
// is normally the first child of the root (ie. layer 0).
var parent = graph.getDefaultParent();
// Adds cells to the model in a single step
graph.getModel().beginUpdate();
try
{
var v1 = graph.insertVertex(parent, null,
'Hello,', 20, 20, 80, 30);
var v2 = graph.insertVertex(parent, null,
'World!', 200, 150, 80, 30);
var e1 = graph.insertEdge(parent, null, '', v1, v2);
}
finally
{
// Updates the display
graph.getModel().endUpdate();
}
}
};
</script>
</head>
<!-- Page passes the container for the graph to the program -->
<body onload="main(document.getElementById('graphContainer'))">
<!-- Creates a container for the graph with a grid wallpaper -->
<div id="graphContainer"
style="overflow:hidden;width:321px;height:241px;background:url('editors/images/grid.gif')">
</div>
</body>
</html>
這個(gè)例子中的重要概念有:
- mxClient.js是一個(gè)包含所有的mxGraph源代碼的JavaScript文件缨称。從Web服務(wù)器下載時(shí)凝果, 獲得包含所有的JavaScript的單個(gè)文件,要比分成多個(gè)獨(dú)立文件要快得多睦尽,這是由于每個(gè)文件 都具有獨(dú)立的請(qǐng)求/確認(rèn)開銷器净。無論服務(wù)器對(duì)于一個(gè)客戶的并行接口的能力差異有多大,速度的 提升通常至少是兩倍以上当凡。
- 所有JavaScript代碼及所有的依賴都是放在head元素中
- 默認(rèn)情況下山害,Internet Explorer安全選項(xiàng)是開啟的,將導(dǎo)致試圖從本地文件系統(tǒng)中運(yùn)行 JavaScript得到用戶提示沿量。這可以在選項(xiàng)菜單中禁用浪慌,但請(qǐng)注意,從本地文件系統(tǒng)上運(yùn)行朴则, 不是通常的mxGraph部署場(chǎng)景眷射,這只會(huì)發(fā)生在開發(fā)過程中遇到。
- 您的應(yīng)用程序可以寫在HTML文件中并鏈接到應(yīng)用程序佛掖,也可以寫在另外的JavaScript文件中妖碉,再被鏈接到HTML中,就像在本例中的mxClient.js文件使用的方式芥被。
2.4 mxGraph部署和調(diào)試
mxclient.js文件有兩個(gè)版本欧宜,一個(gè)用于生產(chǎn)用途,另一個(gè)用于的開發(fā)/調(diào)試使用拴魄。javascript/src/js/mxClient.js 的是生產(chǎn)版冗茸, javascript/debug/js/mxClient.js 的是用于開發(fā)。第一個(gè)版本剝離了所有的換行符匹中, 以確保該文件是最可能小的尺寸夏漱。這樣做的副作用,是破壞了JavaScript的調(diào)試器顶捷。在開發(fā)過程中挂绰, 我們建議您使用調(diào)試版本,其中有換行符服赎,支持的在瀏覽器中啟用調(diào)試葵蒂。
兩個(gè)mxClient.js文件是包含整個(gè)mxGraph的JavaScript源代碼交播,為減少文件大小,所有的空格和注釋都被刪除践付。 在調(diào)試過程中秦士,如果您需要調(diào)試到mxGraph庫本身,使用單獨(dú)的源文件更加容易永高。在source.zip的 javascript/devel目錄中隧土,包含完整的源代碼的文件。將它們解壓到mxBasePath命爬,并除去加載完整版 的mxClient.js文件次洼,會(huì)使得調(diào)試mxGraph更加容易。需要注意的是遇骑,源文件的zip文件中的mxclient.js文件, 會(huì)引導(dǎo)加載的所有其他JavaScript源代碼卖毁。
通過壓縮代碼,客戶端的程序的下載速度落萎,可以進(jìn)一步提高亥啦。所有的現(xiàn)代瀏覽器都支持傳輸在服務(wù)器端壓縮過的內(nèi)容, 而所有良好的網(wǎng)絡(luò)服務(wù)器可以檢測(cè)出不支持的瀏覽器练链,并發(fā)送未壓縮版本作為備用翔脱。
例如,在Apache Web服務(wù)器中有一個(gè)mod_deflate模塊媒鼓,通過一個(gè)標(biāo)準(zhǔn)的搜索届吁,可以了解其使用的細(xì)節(jié)。jgraph.com服務(wù)器一直在使用這個(gè)模塊绿鸣,沒有發(fā)現(xiàn)有任何瀏覽器的支持問題疚沐。
通過使用壓縮,mxClient.js文件的大小從約600KB減少到只有130KB左右潮模。對(duì)于使用最先進(jìn)的網(wǎng)絡(luò)用戶而言亮蛔, 區(qū)別并不明顯,但在某些情況下擎厢,傾向于使用較小的版本究流。
3 mxGraph的模型和圖元
3.1 mxGraph的核心架構(gòu)
3.1.1 mxGraph的模型
mxGraph模型是,描述了圖形結(jié)構(gòu)的核心的模型动遭,被稱為mxGraphModel芬探,可以在model包中發(fā)現(xiàn)。 另外厘惦,對(duì)圖形結(jié)構(gòu)的添加偷仿,更改和清除是通過圖模型API來完成的。該模型還提供了方法來確定圖形 的結(jié)構(gòu),以及提供方法來設(shè)置炎疆,如能見度、分組和樣式的視覺狀態(tài)国裳。
然而形入,雖然對(duì)于模型進(jìn)行的處理是被存儲(chǔ)在模型上的,mxGraph被設(shè)計(jì)成一種通過mxGraph類的主要公共API來使用的方式缝左。 “添加該單元格到圖形”的概念亿遂,是一個(gè)比“添加單元到圖形的模型”的更自然的動(dòng)作。它是直觀的渺杉,在模型上和單元上的方法被復(fù)制到了圖形類上蛇数,而這些圖形類上的方法被認(rèn)為是主要的公共API。本手冊(cè)的其余部分是越,這些關(guān)鍵的API方法都被以粉紅色的背景標(biāo)示(注:真實(shí)情況似乎是文字加粗):
anExampleCoreAPIMethod()
因此耳舅,盡管許多的主要API通過mxGraph類來調(diào)用,請(qǐng)注意倚评,mxGraphModel是基本的對(duì)象浦徊,它存儲(chǔ)著圖形的數(shù)據(jù)結(jié)構(gòu)。
mxGraph使用事務(wù)處理系統(tǒng)來更新模型天梧。在HelloWorld的例子里盔性,我們看到如下代碼:
// Adds cells to the model in a single step
graph.getModel().beginUpdate();
try
{
var v1 = graph.insertVertex(parent, null, 'Hello,', 20, 20, 80, 30);
var v2 = graph.insertVertex(parent, null, 'World!', 200, 150, 80, 30);
var e1 = graph.insertEdge(parent, null, '', v1, v2);
}
finally
{
// Updates the display
graph.getModel().endUpdate();
}
執(zhí)行2個(gè)節(jié)點(diǎn)和1條連線的插入。對(duì)于模型的每一個(gè)變化呢岗,請(qǐng)調(diào)用beginUpdate()冕香,作出適當(dāng)?shù)恼{(diào)用更改模型,然后調(diào)用endUpate()方法來完成的變化后豫,通知發(fā)送變化的事件出去悉尾。
關(guān)鍵API方法:
- mxGraphModel.beginUpdate() - 啟動(dòng)一個(gè)事務(wù)或子事務(wù)處理。
- mxGraphModel.endUpdate() - 完成一個(gè)事務(wù)或子事務(wù)處理挫酿。
- mxGraph.addVertex() - 添加一個(gè)新節(jié)點(diǎn)到指定的父單元焕襟。
- mxGraph.addEdge() - 添加一個(gè)連線到指定的父單元。
注意 從技術(shù)上講饭豹,你不必用開始和結(jié)束調(diào)用來包圍著你的更改鸵赖。此更新范圍之外所做的更改會(huì)立即生效,并立即發(fā)出通知拄衰。事實(shí)上它褪,更新范圍內(nèi)的更改會(huì)立即在模型上立即實(shí)現(xiàn),更新范圍是控制事件通知的時(shí)間和連接翘悉。除非更新包裝導(dǎo)致代碼審美問題茫打,否則值得使用它來避免事件和撤消粒度的可能問題。
請(qǐng)注意,這種將模型更改的包裝在try塊中老赤,endUpdate()放在finally塊中的方式轮洋。即使模型的更改有錯(cuò)誤,它依然確保了更新的完整性抬旺。
現(xiàn)在請(qǐng)先忽略parent圖元的引用弊予,在本章節(jié)的后面再做解釋。
3.1.2 事務(wù)模型
以上藍(lán)色塊中的子事務(wù)开财,是指事務(wù)可以被嵌套汉柒。也就是說,在模型中有這樣一個(gè)計(jì)數(shù)器责鳍,每次調(diào)用beginUpdate計(jì)數(shù)遞增碾褂,每次調(diào)用endUpdate計(jì)數(shù)遞減。在計(jì)數(shù)器增加超過1后历葛,當(dāng)該計(jì)數(shù)再次達(dá)到0時(shí)正塌,模型的事務(wù)被認(rèn)為是完成,模型的事件通知被觸發(fā)恤溶。
這意味著传货,每個(gè)子代碼的部分就可以(而且應(yīng)該)被開始/結(jié)束組合來包圍。在mxGraph中宏娄,這創(chuàng)建單獨(dú)的事務(wù)问裕,被用來作為“庫事務(wù)”的能力,能夠?yàn)閯?chuàng)建復(fù)合改動(dòng)孵坚,一系列事件的所有改動(dòng)一起觸發(fā)并且只需要?jiǎng)?chuàng)建一個(gè)撤消粮宛。自動(dòng)布局是說明這個(gè)功能必需性的很好的例子。
在自動(dòng)布局中卖宠,在用戶通常通過用戶界面修改了圖形巍杈,應(yīng)用程序自動(dòng)根據(jù)默認(rèn)規(guī)則定位結(jié)果。自動(dòng)定位即布局扛伍,在開始/結(jié)束調(diào)用之間的獨(dú)立算法筷畦,它并不知道具體的變化內(nèi)容。因?yàn)樗械脑陂_始/結(jié)束變化范圍內(nèi)的更新是由直接作用在圖形模型上刺洒,布局是根據(jù)模型的狀態(tài)的變化來進(jìn)行鳖宾。
需要重點(diǎn)區(qū)分的是,作用在圖形模型上的功能逆航,是作為復(fù)合改動(dòng)的一部分鼎文,還是原子態(tài)圖形的改動(dòng)事件。在第一種情況下因俐,如用于自動(dòng)布局拇惋,該功能將模型就當(dāng)成那樣而作用于它周偎。此方法只用于作為復(fù)合變化的一部分時(shí)使用。應(yīng)用程序的所有的其他部分撑帖,應(yīng)該依據(jù)模型的改變事件而作出反應(yīng)蓉坎。
當(dāng)最后一個(gè)endUpdate調(diào)用將計(jì)數(shù)器還原到0并指示至少發(fā)生了一個(gè)原子圖更改時(shí),會(huì)觸發(fā)模型更改事件胡嘿。改變事件包含著完整的已改變信息(參見后面的部分Events更多詳細(xì)信息)蛉艾。
3.1.2.1 模型改變方法
以下是更改圖形模型并應(yīng)直接或間接放置更新范圍的方法的列表:
add(parent, child, index)
remove(cell)
setCollapsed(cell, collapsed)
setGeometry(cell, geometry)
setRoot(root)
setStyle(cell, style)
setTerminal(cell, terminal, isSource)
setTerminals(edge,source,target)
setValue(cell, value)
setVisible(cell, visible)
最初,我們只關(guān)心添加和刪除灶平,以及幾何和樣式編輯方法伺通。請(qǐng)注意箍土,這些方法不是核心API方法逢享,像往常一樣,這些方法在mxGraph類中是適用的吴藻,他們執(zhí)行的是被封裝的更新瞒爬。
設(shè)計(jì)背景 - 有些人對(duì)可視信息被存儲(chǔ)的模型中感到困惑。這些屬性包括圖元定位沟堡,可見性和折疊狀態(tài)侧但。模型存儲(chǔ)了這些屬性的默認(rèn)值,提供一個(gè)共同的地方對(duì)每個(gè)單元進(jìn)行設(shè)置航罗,以及對(duì)每個(gè)視圖的單獨(dú)設(shè)置禀横。模型是整個(gè)架構(gòu)中,第一個(gè)通用的地方可以以全局的方式設(shè)置這些屬性粥血。請(qǐng)記住柏锄,這是一個(gè)圖形可視化庫,可視化的部分是核心功能复亏。
插入圖元
在HelloWorld應(yīng)用程序中趾娃,創(chuàng)建的三個(gè)圖形單元包括兩個(gè)節(jié)點(diǎn)和一條連線。如果你不熟悉基本圖形理論和術(shù)語缔御,請(qǐng)參閱 維基百科條目 抬闷。
你可以使用add()方法添加節(jié)點(diǎn)和連線到模型中。但是耕突,考慮到日常使用庫的場(chǎng)景笤成,請(qǐng)學(xué)習(xí)mxGrap.insertVertex()和mxGraph.insertEdge()這兩個(gè)添加圖元的核心公共API。
模型功能的要求眷茁,被添加的圖元必須已經(jīng)創(chuàng)建疹启,而mxGraph.insertVertex()為你創(chuàng)建了圖元。
核心API方法:
mxGraph.insertVertex(parent, id, value, x, y, width, height, style) –在調(diào)用開始/結(jié)束更新中蔼卡,創(chuàng)建并插入一個(gè)新的節(jié)點(diǎn)到模型中喊崖。
mxGraph.insertEdge(parent, id, value, source, target, style) –在調(diào)用開始/結(jié)束更新中挣磨,創(chuàng)建并插入一條新的連線到模型中。
mxGraph.insertVertex() 會(huì)創(chuàng)建一個(gè)mxCell對(duì)象并返回荤懂。方法的參數(shù)為:
parent – 組結(jié)構(gòu)中此圖元的直接父圖元茁裙。我們會(huì)很快談?wù)摰浇M結(jié)構(gòu),但現(xiàn)在我們直接使用graph.getDefaultParent();作為默認(rèn)的父圖元节仿,就像在 HelloWorld 這個(gè)例子一樣晤锥。
id – 描述此單元的全局唯一身份號(hào)碼,總是一個(gè)字符串廊宪。主要用于外部對(duì)這單元的引用矾瘾。如果你不想自己維護(hù)這些號(hào)碼,只需要傳入一個(gè)空參數(shù)并確保mxGraphModel.isCreateIds()返回真即可箭启。這樣壕翩,模型就會(huì)管理這些號(hào)碼,并保證它們的唯一性傅寡。
value – 此單元的用戶對(duì)象放妈。用戶對(duì)象只是一些對(duì)象,可以讓您把應(yīng)用程序的商務(wù)邏輯與mxGraph的可視化呈現(xiàn)相關(guān)聯(lián)荐操。在手冊(cè)的后面有詳細(xì)地描述芜抒,這里我們就只用字符 串就好,并把它們顯示成節(jié)點(diǎn)和邊的標(biāo)簽托启。
x, y, width, height – 就像名字提到的宅倒,這是節(jié)點(diǎn)的左上角的 x 和 y 的位置以及它的寬度和高度。
style – 將被應(yīng)用到節(jié)點(diǎn)的樣式描述屯耸。關(guān)于樣式拐迁,很快會(huì)有更詳細(xì)的描述,簡(jiǎn)單來講肩民,就是一個(gè)特定格式的字符串唠亚。這個(gè)字符串有零個(gè)或多個(gè)樣式名字和一些鍵/值配對(duì),用來覆蓋全局設(shè)置或者創(chuàng)立新的樣式持痰。除非我們要?jiǎng)?chuàng)建自己的樣式灶搜,我們可以直接使用這些現(xiàn)有的設(shè)置。
添加連線的方法和添加節(jié)點(diǎn)的方法使用了同樣的參數(shù)工窍。source和target參數(shù)定義了節(jié)點(diǎn)要連接的節(jié)點(diǎn)割卖。注意,源節(jié)點(diǎn) 和目標(biāo)節(jié)點(diǎn)需要已經(jīng)被加入到模型中患雏。
3.1.3 mxCell
mxCell是節(jié)點(diǎn)和連線的圖元對(duì)象鹏溯。mxCell從模型那里復(fù)制了許多的方法。它們的主要差別在于淹仑,使用模型的方法會(huì)創(chuàng)建相關(guān)的事件通知以及撤銷方法丙挽,使用圖元的方法可以發(fā)生改變但不記錄它們肺孵。這對(duì)于臨時(shí)改變視覺效果,如動(dòng)畫或鼠標(biāo)效果颜阐,是非常有用的平窘。作為通用規(guī)則,一般使用模型的編輯API凳怨,除非您遇到什么特殊問題瑰艘。
當(dāng)創(chuàng)建新的圖元時(shí),構(gòu)造函數(shù)需要三部分參數(shù)肤舞,值(用戶數(shù)據(jù))紫新,幾何參數(shù)以及樣式。我們?cè)诨氐接懻搱D元之前李剖,先了解一下這三個(gè)概念芒率。
3.1.3.1 樣式
樣式和樣式表的概念挺像CSS的樣式表,盡管你已經(jīng)注意到mxGraph中事實(shí)上使用的就是CSS,但CSS只是影響HTML的DOM的全局樣式。當(dāng)你使用編輯器打開 util.mxConstants.js 文件并查詢開頭皮匹配“STYLE_”,如果你向下滾動(dòng)鼠標(biāo)顽染,將會(huì)看到很多帶有這個(gè)前綴的各種樣式定義字符串盆耽。一些樣式應(yīng)用到節(jié)點(diǎn)上,一些適用于節(jié)點(diǎn)聪铺,一些適用于連線化焕,一些都適用。正如你所見铃剔,這些視覺屬性定義在它們操作的元素上撒桨。
mxStylesheet包含一個(gè)對(duì)象,樣式键兜,則以一個(gè)散列表映射樣式名稱到一個(gè)樣式數(shù)組凤类。
樣式集合中的樣式列表
上面藍(lán)框里的圖顯示了在mxStyleSheet里面的樣式表。字符串“defaultVertex”是真實(shí)樣式串/值配對(duì)列表中的鍵值普气。請(qǐng)注意谜疤,mxGraph創(chuàng)建兩組默認(rèn)樣式,一個(gè)給節(jié)點(diǎn)现诀,一個(gè)給連線夷磕。如果你看回helloworld這個(gè)例子,作為可選參數(shù)仔沿,沒有任何樣式值傳入insertVertex或insertEdge坐桩。這種情況下,默認(rèn)的樣式會(huì)被使用封锉。
設(shè)置圖元的樣式
如果你希望給一個(gè)圖元指定非默認(rèn)的樣式绵跷,你必須在創(chuàng)建時(shí)傳入(mxGraph的insertVertex和insertEdge都有 為這個(gè)用途的可選參數(shù))膘螟,或者對(duì)這個(gè)圖元用model.setStyle()設(shè)定樣式。
你傳入的樣式有樣式名碾局,請(qǐng)注意萍鲸,樣式名和鍵/值配對(duì)可以按照任何順序排列。下面是這個(gè)概念的示例擦俐,使用我們?cè)趆elloworld中看到的對(duì)insertVertex的調(diào)用:
- 創(chuàng)建一個(gè)叫'ROUNDED'的樣式脊阴,并應(yīng)用到一個(gè)節(jié)點(diǎn)上:
var v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30, 'ROUNDED');
- 用ROUNDED樣式創(chuàng)建一個(gè)新節(jié)點(diǎn),覆蓋筆畫樣式和填充顏色:
var v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30, 'ROUNDED;strokeColor=red;fillColor=green');
- 創(chuàng)建一個(gè)沒有全局樣式蚯瞧,但有本地筆畫樣式和填充顏色:
var v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30, ';strokeColor=red;fillColor=green');
- 用默認(rèn)defaultVertex樣式嘿期,但本地填充顏色的節(jié)點(diǎn):
var v1 = graph.insertVertex(parent, null, 'Hello', 20, 20, 80, 30, 'defaultVertex;fillColor=blue');
請(qǐng)注意,這種情況下埋合,默認(rèn)樣式必須顯式的指明备徐,在分號(hào)起始的字符串之后,沒有指明樣式名這個(gè)圖元即會(huì) 缺失全局樣式甚颂。如果沒有分號(hào)蜜猾,則默認(rèn)樣式會(huì)被使用。
同樣振诬,mxGraph在核心API中提供了工具方法來訪問和修改圖元的樣式:
核心API方法:
mxGraph.setCellStyle(style, cells) – 封裝在開始/結(jié)束的更新中蹭睡,指定一組圖元的樣式。
mxGraph.getCellStyle(cell) – 返回指定單元的樣式赶么,融合了這種單元類型肩豁,任何本地的和默認(rèn)全局的樣式。
創(chuàng)建新的全局樣式
要?jiǎng)?chuàng)建上述ROUNDED全局樣式辫呻,你可以按照這個(gè)模板來創(chuàng)建一個(gè)樣式清钥,并將其注冊(cè)到mxStyleSheet上:
var style = new Object();
style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_RECTANGLE;
style[mxConstants.STYLE_OPACITY] = 50;
style[mxConstants.STYLE_FONTCOLOR]= '#774400';
graph.getStylesheet().putCellStyle('ROUNDED',style);
3.1.3.2 幾何
在helloworld例子中,我們看到在調(diào)用insertVertex方法時(shí)放闺,傳入了節(jié)點(diǎn)的位置及大小信息祟昭。在JavaScript的坐標(biāo)系統(tǒng)中,x是向右為正怖侦,y是向下為正篡悟,而對(duì)圖形而言,是相對(duì)mxGraph放置的容器的絕對(duì)位置础钠。
有專門獨(dú)立的mxGeometry而不是簡(jiǎn)單地用mxRectangle保存這個(gè)信息的原因恰力,是因?yàn)檫B線也有相應(yīng)的幾何信息。
對(duì)于連線而言旗吁,寬帶和高度的值被忽略踩萎,而x和y對(duì)應(yīng)的是連線的標(biāo)簽位置。另外很钓,連線還有控制點(diǎn)的概念香府。它們是沿邊的中間點(diǎn)位置董栽,畫線時(shí)需要經(jīng)過∑蠛ⅲ控制點(diǎn)的使用有時(shí)也被稱為邊緣路由锭碳。
一條由兩個(gè)控制點(diǎn)決定的邊
在幾何里面還有兩個(gè)重要的概念,相對(duì)位置和偏移勿璃。
相對(duì)位置
默認(rèn)情況下擒抛,一個(gè)節(jié)點(diǎn)的x和y位置是圖元本身的邊界矩形的左上角點(diǎn)與父圖元的邊界矩形的左上角點(diǎn)的偏移量。父圖元和組的概念將在本章的后面進(jìn)行討論补疑,這里就不深入細(xì)節(jié)歧沪,如果一個(gè)圖元沒有父圖元, 那么為了定位莲组,圖形容器就是它的父圖元诊胞。
非相對(duì)的節(jié)點(diǎn)位置
對(duì)于一條連線,在默認(rèn)的非相對(duì)模式中锹杈,連線的標(biāo)簽位置是對(duì)圖形原點(diǎn)的絕對(duì)位置撵孤。
非相對(duì)連線的標(biāo)簽位置
對(duì)于相對(duì)模式中的節(jié)點(diǎn),(x,y)是沿父圖元(寬度竭望,高度)的圖元的原點(diǎn)所在的比例邪码。(0,0)是與父圖元 相同的原點(diǎn),(1,1)是原點(diǎn)放在父圖元的右下角市框。兩個(gè)方向上霞扬,相對(duì)位置向0和1以上延伸糕韧。這有助于子圖元保持 對(duì)父圖元整體大小的固定枫振。
相對(duì)節(jié)點(diǎn)位置
最后,在相對(duì)模式下的連線的標(biāo)簽位置萤彩,是根據(jù)連線的中心來確定粪滤。連線的x坐標(biāo)是相對(duì)位置,-1是連線的源端雀扶, 1是邊的目標(biāo)端杖小。連線的y坐標(biāo)是了連線的正交像素偏移量。下圖顯示了在相對(duì)模式下的各種連線標(biāo)簽的x愚墓,y的值予权。 請(qǐng)注意,對(duì)于一條直線浪册,計(jì)算是非常簡(jiǎn)單的扫腺。對(duì)于有多個(gè)控制點(diǎn)的連線,連線是沿要跟蹤段(段結(jié)束點(diǎn)和/或 控制點(diǎn)之間的界線)來找到正確的沿連線的距離村象。 y值是到該段的正交偏移量笆环。
對(duì)于連線的標(biāo)簽攒至,切換到使用相對(duì)位置,是一種常見的應(yīng)用程序的偏好躁劣。導(dǎo)航到mxGraph的mxGraph.insertEdge() 方法中迫吐,你會(huì)看到createEdge()這樣的調(diào)用。在createEdge()中账忘,幾何上設(shè)置為相對(duì)位置志膀,是使用這個(gè)創(chuàng)建每一條連線的。在mxGraph中輔助方法有一定數(shù)量鳖擒,是因?yàn)樗麄兡軌蚝苋菀赘淖兡J(rèn)行為梧却。你應(yīng)該在應(yīng)用程序中, 嘗試盡可能多地使用mxGraph類中API败去,享受這項(xiàng)福利放航。
偏移
在mxGeometry中,偏移量字段是應(yīng)用到圖元標(biāo)簽的絕對(duì)x圆裕,y偏移量广鳍。在連線標(biāo)簽的情況下,該偏移量總是施加在邊標(biāo)簽已根據(jù)上面部分相對(duì)標(biāo)志計(jì)算好之后吓妆。
核心API方法:
- mxGraph.resizeCell(cell, bounds) - 在開始/結(jié)束的更新調(diào)用之間赊时,改變指定圖元的大小到指定的邊框。
- mxGraph.resizeCells(cells, bounds) - 在開始/結(jié)束的更新調(diào)用之間行拢,改變指定隊(duì)列中所有圖元的大小到指定的邊框祖秒。
3.1.3.3 用戶對(duì)象
用戶對(duì)象給了mxGraph一個(gè)環(huán)境,可以把業(yè)務(wù)邏輯與可視圖元相關(guān)聯(lián)舟奠。在HelloWorld的例子里竭缝,用戶對(duì)象只是一個(gè)字符串,只是簡(jiǎn)單地用來呈現(xiàn)單元的標(biāo)簽沼瘫。在更加復(fù)雜的應(yīng)用里抬纸,用戶對(duì)象可以是一個(gè)復(fù)雜的對(duì)象。這個(gè)對(duì)象的一些屬性可以用來作為圖元的顯示使用耿戚,而對(duì)象的其余部分可以用來描述應(yīng)用領(lǐng)域的邏輯關(guān)系湿故。
用一個(gè)簡(jiǎn)單的工作流或過程應(yīng)用程序來做例子,假定我們有以下的圖形(這個(gè)例子已在線膜蛔,在任務(wù)窗口選擇泳道Swimlanes的例子):
一個(gè)簡(jiǎn)單工作流
通常情況下坛猪,該工作流程將存在于某些應(yīng)用服務(wù)器和/或數(shù)據(jù)庫上。瀏覽器端用戶連接到該服務(wù)器皂股,或者一些前端服務(wù)器連接到應(yīng)用程序服務(wù)器和用戶的Web應(yīng)用程序請(qǐng)求“訂購”的工作流墅茉。網(wǎng)站服務(wù)器取得該工作流中的數(shù)據(jù)并將其發(fā)送到客戶端。
mxGraph支持服務(wù)器端填充模型、發(fā)送到客戶端躁锁,然后再返回的過程纷铣。請(qǐng)參閱后面的章節(jié)關(guān)于“I/O和服務(wù)器之間的通信”。
數(shù)據(jù)的發(fā)送在視覺模型(圖中)和以及業(yè)務(wù)邏輯(主要是包含在用戶對(duì)象)都會(huì)發(fā)生战转∷蚜ⅲ客戶端將首先顯示如上圖。如果用戶有權(quán)限編輯工作流程槐秧,他們通常會(huì)做兩件事情:1)編輯圖表啄踊,添加和刪除節(jié)點(diǎn),以及改變的連接刁标,2)編輯圖元的用戶對(duì)象(節(jié)點(diǎn)和/或連線)颠通。
在在線演示中,如果右鍵點(diǎn)擊菱形“Check Inventory”并選擇屬性膀懈,你會(huì)看到如下對(duì)話框:
節(jié)點(diǎn)的屬性
這些屬性展示了幾何數(shù)據(jù)顿锰,標(biāo)簽,ID等启搂,但一個(gè)對(duì)話框可以很容易地圖元的用戶對(duì)象硼控。這有可能是在工作流引擎某個(gè)過程的引用,關(guān)于怎樣檢查庫存清單胳赌。這可能是一個(gè)用于特定應(yīng)用程序的機(jī)制牢撼,在服務(wù)器和客戶端為遠(yuǎn)程方法調(diào)用分配一些識(shí)別標(biāo)志。另一種類型的值可能是調(diào)用過程的返回對(duì)象疑苫,也許是一個(gè)布爾值或整數(shù)(在這種情況下熏版,表示庫存水平)。由于這個(gè)返回類型捍掺,它有可能可以加強(qiáng)對(duì)圖形的約束撼短,并提供視覺化的提示,如乡小,出口連線的決定檢查不符合返回的節(jié)點(diǎn)類型阔加。
接下來,作為一個(gè)示例满钟,發(fā)出的連線的用戶對(duì)象可能包含一個(gè)標(biāo)簽和一個(gè)布爾狀態(tài)。同樣胳喷,基于mxGraph的編輯器可能會(huì)提供更改布爾值的方法湃番。在服務(wù)器端,當(dāng)執(zhí)行到該步驟時(shí)吭露,它可能會(huì)跟隨對(duì)應(yīng)的決策的節(jié)點(diǎn)返回的布爾值的連線吠撮。
請(qǐng)記住,上述示例是非常具體的領(lǐng)域的讲竿,它用來解釋如何將用戶對(duì)象映射到應(yīng)用程序的業(yè)務(wù)邏輯泥兰。它展現(xiàn)了mxGraph如何創(chuàng)建我們所謂的上下文圖弄屡。這上下文是由節(jié)點(diǎn)之間的連接和用戶對(duì)象存儲(chǔ)的業(yè)務(wù)邏輯構(gòu)成的。一個(gè)典型的應(yīng)用程序從服務(wù)器接收可視化部分和業(yè)務(wù)邏輯鞋诗,可能允許編輯它們膀捷,接著發(fā)送到服務(wù)器去持久化和/或執(zhí)行。
3.1.3.4 圖元類型
如前所述削彬,mxGraph是使用這個(gè)庫時(shí)的主要API全庸,同樣圖元也是。在圖上沒有暴露圖元的一個(gè)是節(jié)點(diǎn)還是連線的基本狀態(tài)融痛,這個(gè)調(diào)用可以在圖元上或在模型上找到壶笼。
在mxCell上有兩個(gè)標(biāo)志量,節(jié)點(diǎn)和邊雁刷,在一個(gè)圖元?jiǎng)?chuàng)建時(shí)覆劈,輔助函數(shù)將設(shè)置其中一個(gè)值為true,isVertex(), isEdge() 在 mxGraphModel中用來檢測(cè)一個(gè)圖元的類型沛励,所以這兩種類型沒有分離的對(duì)象墩崩。從技術(shù)上講,在運(yùn)行時(shí)可以隨便改一個(gè)圖元的類型侯勉,但是要注意在改變類型后無效的圖元狀態(tài)鹦筹。同時(shí),要留心幾何對(duì)象方法的參數(shù)在節(jié)點(diǎn)和連線上是不同的址貌。通常铐拐,不建議在運(yùn)行時(shí)修改一個(gè)圖元的類型的。
3.1.4 組結(jié)構(gòu)
在mxGraph中练对,分組的概念就是邏輯上將一個(gè)圖元與另一個(gè)進(jìn)行關(guān)聯(lián)遍蟋。在許多的圖形開發(fā)庫中,這通常被成為子圖螟凭。在圖形模型的數(shù)據(jù)結(jié)構(gòu)中虚青,分組就是把一個(gè)或更多的連線或節(jié)點(diǎn)變成一個(gè)父節(jié)點(diǎn)或連線的子圖元。分組使得mxGraph擁有了更多的有用的特性:
- 子圖 一個(gè)邏輯上獨(dú)立的圖形的概念螺男,在較高的層次圖中顯示為每個(gè)子圖的圖元棒厘。
- 展開和折疊 折疊是這樣的一種能力,它使用父圖元在視覺上來替換一組子圖元下隧。展開則是與其相反的邏輯奢人。通過單擊在線工作流程示例中泳道示例的組單元格左上角的小“ - ”可以看到此行為。這會(huì)在下面的 復(fù)雜性管理 章節(jié)中進(jìn)行講解淆院。
- 分層 層次的概念是指在圖形的顯示中何乎,讓圖元以特定的順序顯示。
- 下鉆,遞升 這兩個(gè)概念是讓子圖可以當(dāng)作完整的圖形一樣可視化和編輯支救。在 用戶對(duì)象 章節(jié)我們看到 “check inventory” (檢查庫存)節(jié)點(diǎn)作為一個(gè)簡(jiǎn)單圖元抢野。舉個(gè)例子來說,一個(gè)開發(fā)人員正在描述流程中每一個(gè)節(jié)點(diǎn)作為軟件流程中執(zhí)行的任務(wù)各墨。應(yīng)用程序中可能會(huì)有一個(gè)選項(xiàng)去下鉆到檢查庫存的節(jié)點(diǎn)指孤。這將導(dǎo)致一個(gè)新的圖形出現(xiàn),詳細(xì)地描述了檢查庫存的細(xì)節(jié)欲主。圖中可能會(huì)有一個(gè)標(biāo)題為“檢查庫存”的節(jié)點(diǎn)用以表示它是一個(gè)子圖邓厕,以及一個(gè)選項(xiàng)去遞升回到上一個(gè)級(jí)別。
在分組中扁瓢,圖元都分配了一個(gè)父圖元详恼。最簡(jiǎn)單的情況是,所有的圖元都有一個(gè)默認(rèn)的父圖元作為他們的父圖元引几。這個(gè)父圖元是一個(gè)不可見的圖元昧互,有著和整張圖相同的界限。這個(gè)圖元在 helloworld 例子中可以通過 graph.getDefaultParent() 返回伟桅。一個(gè)節(jié)點(diǎn)的x,y位置是相對(duì)它的父節(jié)點(diǎn)的敞掘,因此在默認(rèn)分組的情況下(所有的圖元共享默認(rèn)父圖元),圖元的定位也是圖形組件上的絕對(duì)坐標(biāo)楣铁。在所有的圖元都被添加到默認(rèn)根圖元的情況下玖雁,該組的結(jié)構(gòu)邏輯上的模樣,在hello world例子中盖腕,看起來如下圖所示赫冬。
注意添加了0層圖元,這是在組結(jié)構(gòu)中的默認(rèn)間接方式允許根據(jù)附加圖元的要求進(jìn)行圖層的更改溃列。我們將它包含在下面以便正確性劲厌,但在稍后的組圖中它將被省略。
helloworld例子中的組結(jié)構(gòu)
同時(shí)听隐,請(qǐng)注意連線標(biāo)簽的位置(幾何上的x,y)是相對(duì)其父圖元的补鼻。
如果我們回頭去看用戶對(duì)象章節(jié)的簡(jiǎn)單工作流例子,能看到組看起來是什么樣的雅任。在這個(gè)例子中組圖元表示人风范,并且子節(jié)點(diǎn)表示分配給這些人的任務(wù)。在這個(gè)例子中椿访,邏輯組結(jié)構(gòu)如下所示:
工作流示例的邏輯組結(jié)構(gòu)
工作流程操作節(jié)點(diǎn)是黃色的子節(jié)點(diǎn)乌企,泳道組節(jié)點(diǎn)被標(biāo)記為藍(lán)色。
插入圖元的到組結(jié)構(gòu)是通過使用mxGraph類的insertVertex和insertEdge的parent參數(shù)方法成玫。這些函數(shù)相應(yīng)地將父圖元格設(shè)置在子圖元上,而且重點(diǎn)是,會(huì)通知父圖元新子圖元的加入哭当。
通過mxGraph.groupCells()和mxGraph.ungroupCells()函數(shù)來更改組結(jié)構(gòu)猪腕。
核心API方法
- mxGraph.groupCells(group, border, cells) – 添加指定的圖元到指定的組,在一個(gè)begin/end更新結(jié)構(gòu)中钦勘。
- mxGraph.ungroupCells(cells) – 從指定圖元的父圖元中移除它們陋葡,并將其加入到它們的父圖元的父圖元中。任何空的組在這個(gè)操作后將被刪除彻采。這個(gè)操作需要在一個(gè)begin/end更新結(jié)構(gòu)中
3.1.5 復(fù)雜度管理
任何時(shí)候控制顯示圖元的個(gè)數(shù)主要有兩個(gè)原因腐缤。首先是性能,繪制越來越多的圖元在任何平臺(tái)上都將會(huì)在某個(gè)時(shí)間點(diǎn)達(dá)到性能的瓶頸肛响。第二個(gè)原因是易用性岭粤,一個(gè)人只能理解一定量的信息。上面列出的與組相關(guān)的所有概念特笋,能夠用來為用戶降低屏幕上信息的復(fù)雜度剃浇。
3.1.5.1 可折疊
可折疊是我們用來描述組展開和折疊一個(gè)集合名詞。我們可以將令一個(gè)圖元內(nèi)的子圖元不可見稱為折疊猎物。有許多與此特性相關(guān)的方法:
核心API方法
- mxGraph.foldCells(collapse, recurse, cells) – 在一個(gè)begin/end更新結(jié)構(gòu)中虎囚,指定圖元的折疊狀態(tài)。
可折疊相關(guān)方法:
mxGraph.isCellFoldable(cell, collapse) – 對(duì)于有子圖元的圖元而言蔫磨,默認(rèn)為真淘讥。
mxGraph.isCellCollapsed(cell) – 返回圖元的折疊狀態(tài)
當(dāng)一個(gè)組圖元折疊時(shí),默認(rèn)發(fā)生三件事:
- 圖元的子圖變?yōu)椴豢梢?/li>
- 組圖元的邊界被使用堤如。在mxgeometry中有一個(gè)alternativebounds字段蒲列,并且在組圖元中,默認(rèn)地分別存儲(chǔ)了展開和折疊狀態(tài)的邊界煤惩。這些實(shí)例之間的切換由mxgraph.swapbounds()調(diào)用嫉嘀,實(shí)際上這些是foldcells()調(diào)用過程中為你處理的。這允許折疊組能夠被改變大小魄揉,同時(shí)當(dāng)再次展開看起來和折疊前的尺寸一樣剪侮。
- 默認(rèn)情況下會(huì)發(fā)生連線提升。連線提升意味著去展現(xiàn)這樣的連線洛退,它們連著子圖元通過折疊組圖元瓣俯,組圖元同樣連著外面的折疊組圖元,通過使得這些子圖元消失而轉(zhuǎn)去連接折疊的父圖元兵怯。
展開泳道
折疊泳道
以上兩張圖片展示了這三個(gè)概念彩匕。在擴(kuò)展?fàn)顟B(tài)下,上面的組圖元在左上角顯示一個(gè)小框媒区,里面有一個(gè)“ - ”字符驼仪。這表示單擊此框會(huì)折疊組圖元掸犬。點(diǎn)擊后我們將獲得下面的圖片,圖中組圖元使用著它的折疊尺寸绪爸。沒有離開子節(jié)點(diǎn)和邊的圖元都是不可見的湾碎。最后,離開組圖元的連線被提升奠货,表現(xiàn)為連接到折疊的組圖元介褥。點(diǎn)擊框中現(xiàn)在出現(xiàn)的“+”字符展開組圖元,并將其返回到上面的那個(gè)張圖的原始狀態(tài)递惋。
通過調(diào)用mxGraph.foldCells()方法柔滔,你可以通過編程獲得與單擊展開/折疊符號(hào)相同的結(jié)果。一個(gè)常見的用法是這樣的萍虽,當(dāng)應(yīng)用縮放到指定的數(shù)值睛廊,圖元群被分組并且組圖元折疊(往往不帶“-”框,因?yàn)閼?yīng)用程序在控制折疊)贩挣。通過這種方式喉前,用戶可以看到更少,更大的圖元王财,邏輯上每一個(gè)圖元都代表其子圖元卵迂。接著你可以提供一種機(jī)制去放大一個(gè)組,以在該過程中擴(kuò)展它绒净。你也可以提供下鉆/遞升见咒,接下來就解釋一下。
3.1.5.2 子圖, 下鉆 / 遞升
有時(shí)候挂疆,作為一種展開/折疊方案的另一個(gè)選擇改览,或者可能與其結(jié)合使用,你的圖會(huì)由一組圖組成缤言,嵌套到層次結(jié)構(gòu)中宝当,下面我們看一個(gè)簡(jiǎn)單的例子:
一個(gè)頂級(jí)工作流的例子
這個(gè)簡(jiǎn)單的流程由三個(gè)高級(jí)別的步驟組成。顯然胆萧,單個(gè)步驟包含許多子步驟庆揩,我們將查看 Solve Bug 圖元的子圖。
在 Solve Bug 節(jié)點(diǎn)下跌穗,我們創(chuàng)建了一些子節(jié)點(diǎn)來呈現(xiàn)解決一個(gè)問題的流程的細(xì)節(jié)订晌,在這種情況下,解決了在企業(yè)號(hào)星艦(Starship Enterprise)上的一個(gè)問題蚌吸。
在這個(gè)用GraphEditor的例子里锈拨,在上圖顯示的選中的菜單選項(xiàng)調(diào)用了mxGraph.enterGroup(cell),這是子圖相關(guān)的一個(gè)核心的API。
核心API方法:
- mxGraph.enterGroup(cell) – 使指定的圖元成為顯示區(qū)域的根圖元羹唠。
- mxGraph.exitGroup() - 使當(dāng)前圖元的父圖元(如果有)成為新的根圖元奕枢。
- mxGraph.home() - 離開所有組娄昆,使默認(rèn)父圖元成根圖元
到目前為止,圖的根圖元已經(jīng)是所有第一級(jí)圖元的默認(rèn)父節(jié)點(diǎn)验辞。使用這些函數(shù)你能夠?qū)⑷魏谓M結(jié)構(gòu)內(nèi)的組圖元變成根圖元稿黄,這樣父圖元的子圖元就可以作為完整的圖形顯示出來喊衫。
下鉆到Solve Bug節(jié)點(diǎn)的結(jié)果
同樣的圖形如采用折疊方式會(huì)看起來如下:
退出組用 shape->exit group 選項(xiàng)跌造,它會(huì)調(diào)用mxGraph.exitGroup,帶你回到原始的三個(gè)節(jié)點(diǎn)的最高一級(jí)的圖族购。
3.1.5.3 分層和過濾
在mxGraph里, 像其它圖形化應(yīng)用一樣壳贪,它也有z順序的概念。也就是說寝杖,你看向屏幕的方向就是對(duì)象的順序违施。對(duì)象可以位于其他對(duì)象的后面或前方,如果它們重疊且不透明瑟幕,則最后面的對(duì)象將部分或完全遮蓋磕蒲。讓我們回顧一下上面的HelloWorld圖的圖形結(jié)構(gòu)。子圖元以確定的順序被存儲(chǔ)在父圖元下(默認(rèn)情況下只盹,是你添加它們的順序)
如果我們移動(dòng)HelloWorld例子中的圖元辣往,我們將看到如下的結(jié)果:
-重疊的節(jié)點(diǎn)-
可以看到World節(jié)點(diǎn)位于hello節(jié)點(diǎn)的前面。這是因?yàn)閃orld節(jié)點(diǎn)比Hello節(jié)點(diǎn)有一個(gè)更高的子順序殖卑,它們分別在根圖元的有序子圖元集合中的位置1和0位置上站削。
改變順序我們可以用mxGraph.orderCells方法。
核心API方法:
- mxGraph.orderCells(back, cells) – 在開始/結(jié)束的更新調(diào)用之間孵稽,根據(jù)標(biāo)志位许起,移動(dòng)一組圖元到它們的兄弟圖元的前面或者后面。
mxGraph中的兄弟圖元是指任何擁有相同父圖元的圖元菩鲜。因此园细,對(duì)Hello節(jié)點(diǎn)執(zhí)行此方法,會(huì)使其覆蓋World節(jié)點(diǎn)接校。
排序和分組可以擴(kuò)展成邏輯分層組猛频。圖元通過深度優(yōu)先搜索被繪制。再次采用helloworld示例馅笙,設(shè)想一下伦乔,hello和world節(jié)點(diǎn)下面都有一些同層的子圖元。Hello節(jié)點(diǎn)及其子圖元會(huì)比World節(jié)點(diǎn)或其子圖元先繪制董习。如果Hello節(jié)點(diǎn)和World子點(diǎn)是不可見組圖元烈和,那么你就會(huì)有兩個(gè)圖元層次結(jié)構(gòu),一個(gè)完全在另一個(gè)之前繪制皿淋。你還可以通過簡(jiǎn)單地切換不可見組圖元的順序來切換層次結(jié)構(gòu)的順序招刹。
layers.html示例演示了分層的概念恬试。這里按鈕用于設(shè)置組圖層圖元的可見性。這個(gè)例子非常接近過濾的概念疯暑。
篩選具有一些特定的屬性的圖元來顯示训柴。提供過濾功能的一種方法是在渲染圖元之前檢查某個(gè)狀態(tài)。另一種方法妇拯,如果過濾條件簡(jiǎn)單且事先已知幻馁,則按組分配可過濾單元。執(zhí)行這個(gè)過濾操作時(shí)越锈,可以顯示或隱藏這些組仗嗦。
注:如果哪個(gè)地方翻譯的不對(duì)的地方,請(qǐng)以官方文檔為準(zhǔn)甘凭!