可視化一路走來,體會不少;博客一路寫來,收穫頗豐;代碼一路碼來,思路愈來愈清晰。終究仍是明白了一句古話:紙上得來終覺淺,絕知此事要躬行。html
跌跌撞撞整合了個可視化小tool,零零碎碎結交了衆多的志同道合之人,迷迷糊糊建立了我"可視化/Prefuse"的QQ羣,詳情可查看左側的公告部分。此羣旨在結實更多的可視化領域的同仁,也但願能夠成爲一個開源項目分享與閱讀的平臺。源於開源,開源爲咱們提供了助咱們快速成長的營養,開源的每一行代碼都是前輩們心血的結晶,開源是智慧的濃縮。web
在博客園寫博客也是如此,從起初只是一味的平鋪直敘,直抒胸臆,歷來沒有估計到還要格式調整,也沒有想到要佈局美觀,更不用提什麼言簡意賅、一針見血。總之,看看優秀的博客,就如同接觸到一個開源項目,其開篇佈局、文章內容、文本樣式都是學習的教材。最近體會比較深的就是:寫博客也體現出博客的特性,博客,不是論文,過多或者過於複雜的理論闡述(除非必不可少)會讓大部分讀者兩眼昏花、四肢無力;博客,也不是小學造句子,太短或過少缺少總體的連貫性,剛讀起來有點感受,好吧,還沒高潮就結束了,讓人摸不着頭腦。因此,我發現,但凡得到點贊多的文章除了內容含金量高之外,還贏在表述以及篇幅的控制,真正站在Reader的角度去闡述問題、解決問題,Reader就會控制不住要點個贊。In a Word,路很長,要學的東西不少,慢慢體味。微信
上期回顧:《漫談可視化Prefuse(五)---一款屬於我本身的可視化工具》主要介紹了本身開發的一款可視化工具,包含了可視化工具中一些必不可少的功能,有些網友反應期待web版,其實Prefuse是支持applet版本的,這裏沒有走web的緣由可能仍是根據咱們的需求走。要知道在以js爲堅實後盾的各類可視化庫大行其道的狀況下,相似於Gephi、IBM i2等產品仍然具備不可撼動的地位的緣由,在於需求催生產品,不一樣的需求就會對應着不一樣的產品形態。還有些網友反映披露工具相關細節,下面正文將會有所體現。app
本篇主要立足於Prefuse框架講述:1.可視化工具如何根據需求調整邊的粗細;2.try...catch的巧用框架
1.如何經過邊的粗細來反映邊的權重分佈式
Prefuse框架默認邊的粗細是統一的,都爲1。可是咱們每每面臨的需求是給出數據格式以下函數
Source | Target | Weight |
1 | 2 | 0.5 |
那麼咱們就能夠經過邊的粗細來體現這個Weight屬性,用來代表節點1和節點2之間的親密程度。工具
因此,咱們針對Prefuse的源碼作一下改動,在此以前,咱們先了解有關類的繼承關係:佈局
類LabelRenderer:學習
1
2
3
4
5
6
7
8
9
10
|
public
class
LabelRenderer
extends
AbstractShapeRenderer {
......
public
void
render(Graphics2D g, VisualItem item) {
RectangularShape shape = (RectangularShape) getShape(item);
if
(shape ==
null
)
return
;
......
}
......
}
|
類EdgeRenderer:
1
2
3
4
5
6
7
8
9
|
public
class
EdgeRenderer
extends
AbstractShapeRenderer {
......
public
void
render(Graphics2D g, VisualItem item) {
// render the edge line
super
.render(g, item);
......
}
......
}
|
抽象類AbstractShapeRenderer:
1
2
3
4
5
6
7
8
|
public
abstract
class
AbstractShapeRenderer
implements
Renderer {
......
public
void
render(Graphics2D g, VisualItem item) {
Shape shape = getShape(item);
......
}
......
}
|
從以上三個類能夠發現,類LabelRenderer和EdgeRenderer都是繼承自抽象類AbstractShapeRenderer,而且LabelRenderer和EdgeRenderer類都覆寫了父類 render方法。
兩個類的render方法的最大不一樣之處在於,EdgeRenderer類顯式調用了抽象父類AbstractShapeRenderer的render方法,而且經過在AbstractShapeRenderer類的render方法中加入:
1 | System.out.println( "該item屬於:" + item.getGroup()) |
獲得的打印信息都是"該item屬於:graph.edges",即代表都是對於邊的渲染。
瞭解了類的繼承關係,下面給出修改源碼的步驟以實現經過配置文件實現邊粗細的賦值:
(1)在PrefuseConfig類中添加:
1 | setProperty( "data.edge.weight" , "weight" ); |
用於xml文件中肯定邊粗細的標示,這裏是weight;
(2)在Graph類中添加:
1 | public static final String WEIGHT = PrefuseConfig.get( "data.edge.weight" ); |
用於在GraphMLReader獲取常量;
(3)在GraphMLReader中添加:
1
2
|
public
static
final
String WEIGHT = Graph.WEIGHT;
public
static
final
String WEIGHTID = WEIGHT +
'_'
+ ID;
|
方法startDocument()中添加:
1
2
|
m_esch.addColumn(WEIGHT, String.
class
);
//邊粗細相關
m_esch.addColumn(WEIGHTID, String.
class
);
|
方法startElement()中添加:
1
2
|
m_edges.setString(m_row, WEIGHT, atts.getValue(WEIGHT));
m_edges.setString(m_row, WEIGHTID, atts.getValue(WEIGHTID));
|
(4)在AbstractShapeRenderer中添加:
1
2
3
4
5
6
7
8
9
10
|
EdgeItem edge = (EdgeItem)item;
VisualItem vi = (VisualItem)edge.getSourceNode();
item.setStrokeColor(vi.getFillColor());
String weight =
null
;
try
{
weight = item.get(GraphMLHandler.WEIGHT).toString();
}
catch
(Exception e) {
weight =
"1"
;
}
item.setSize(Double.parseDouble(weight)*
10
);
|
使用的配置文件爲xml格式,內容爲:
最終的圖形顯示爲:
2.try....catch的巧用
巧用之處見1(4)中所寫:
1
2
3
4
5
6
7
8
9
10
|
EdgeItem edge = (EdgeItem)item;
VisualItem vi = (VisualItem)edge.getSourceNode();
item.setStrokeColor(vi.getFillColor());
String weight =
null
;
try
{
weight = item.get(GraphMLHandler.WEIGHT).toString();
}
catch
(Exception e) {
weight =
"1"
;
}
item.setSize(Double.parseDouble(weight)*
10
);
|
由於在實際狀況中,會遇到有些xml文件中沒有weight屬性,或者xml部分邊有部分沒有的狀況,這時就會面臨在AbstractShapeRenderer中沒法獲取weight值的情形,即
1 | item.get(GraphMLHandler.WEIGHT) |
此值不存在或爲空,起初經過添加語句:
1
2
3
4
5
|
if
(item.get(GraphMLHandler.WEIGHT).toString().equals(
""
) || item.get(GraphMLHandler.WEIGHT).toString() ==
null
){
weight =
"1"
;
}
else
{
weight = item.get(GraphMLHandler.WEIGHT).toString();
}
|
等相似手段仍是沒法捕獲item.get()取不到值的全部狀況,後面轉而想到,鑑於要捕獲的是爲空異常,索性使用try...catch直接進行捕獲,捕獲後在進行處理。從而有了上面的處理,即當item.get()函數獲取不到值時就捕獲異常,轉入catch部分執行,在這裏咱們編寫咱們想要實現的功能,也就是獲取爲空時就將weight設置默認值爲1,從而巧妙的解決了考慮全部爲空的狀況。
從該源碼的經歷發現,須要明確本身想要的功能,明確須要觸及哪些類,明確如何保證修改後的源碼運行的完整性,不能由於修改一處而處處報錯;另外,還須要常常思考,靈活運行一些語句的特性爲本身所用。今天就到這吧,若是以爲有用,記得點贊^_^,對可視化(gephi、prefuse、分佈式計算、開源)感興趣的能夠加羣討論。
本文連接:《漫談可視化Prefuse(六)---改動源碼定製邊粗細》
友情贊助
若是你以爲博主的文章對你那麼一點小幫助,恰巧你又有想打賞博主的小衝動,那麼事不宜遲,趕忙掃一掃,小額地贊助下,攢個奶粉錢,也是讓博主有動力繼續努力,寫出更好的文章^^。
1. 支付寶 2. 微信