graphviz 雖然很強大,不過有兩個地方不足
- 對中文支援很差,在windows下還可以用utf-8來處理,在linux下面就很麻煩,我嘗試多次也解決不了
- 是graphviz和java之間無法互動,在java中我只能通過新開一個進程來調用graphviz,完全是blackbox,無法控制,也無法確保圖形是否正確繪製。
經過多次嘗試,我發現了幾個解決方案
1,我發現了graphviz還有一個不起眼的子項目grappa,這個項目是完全用java寫的,按照它的文擋說,算是一個簡化版本的graphviz (下載grappa比較麻煩,似乎對方的網頁有錯誤,直接給出的串連是下載不到的,我展轉在maillist上才成功得到,帶原始碼的,如果想要這個的朋友,可以email給我索取) 下載回來一用, 開始是大失所望,原來簡化版居然沒有graphviz最有價值的自動布局功能.直接產生的圖形全部都堆疊在一起, 完全不可用,正打算放棄的時候,發現grappa的的歸類在graphviz的view類別中,突然開竅了, 返回回去查,原來graphviz支援多種輸出,包括輸出.dot檔案,svg檔案等. 這些檔案都是文本的,很好處理,我試了試通過graphviz來產生dot檔案和svg檔案, 很快,而且中文也沒有問題, 經過處理以後的dot檔案比原始的dot檔案大了不少,查看了以下,發現所有的結點,圖形都的是自動布局好了,dot檔案裡面一一標明了座標. 這下用grappa處理很成功. 順利在java中畫出圖形,(效率明顯比graphviz慢不少), 這樣一來,第一個辦法就是通過graphviz來產生dot, 然後通過grappa來顯示. 可以在applet中顯示都沒有問題, grappa支援很老的java1.1,看來ie中是可以用的
2, graphviz原來可以產生svg檔案!,這下就好辦多了, 不需要grappa, 通過jakarta的batik包, 我很順利的通過servlet把svg轉換為jpg圖片, 中文是支援的 如果有問題可以參見(jdk1.5 在linux下字型設定) . 需要注意的是graphviz對中文沒有做特殊處理,在最後產生的xml他會寫encoding="utf-8", 但是實際上的編碼是你系統預設的編碼(我的是gbk) ,所以要手動去調整一下編碼. 如果你夠變態. 可以用batik把svg讀入, 再輸出為svg, 最終的svg相容性就非常好了, 可以通過adobe的svg外掛程式直接在ie中顯示.
ps, 使用graphivz的時候, graphiviz沒有對長行做自動換行處理, 如果有較長的行, 需要你手動換行, 比如寫個程式把12345678換成123\n456\n78,這樣最後的效果是換行. 下面這段代碼就是幹這個事情的
private static String filter(String raw) {
String[] lines = raw.trim().split("\n");
if (lines.length > 0) {
StringBuffer newline = new StringBuffer();
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
newline.append(shortLine(line));
if (i != lines.length - 1)
newline.append("\\n");
}
return newline.toString();
} else {
return shortLine(raw);
}
}
private static String shortLine(String line) {
if (line.length() > 10) {
char[] chars = line.toCharArray();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < chars.length; i++) {
char aChar = chars[i];
if (i != 0 && i % 12 == 0)
sb.append("\\n");
sb.append(aChar);
}
return sb.toString();
} else {
return line;
}
}