现在的位置: 首页 > 综合 > 正文

用Graphviz来画图 2

2012年01月25日 ⁄ 综合 ⁄ 共 2144字 ⁄ 字号 评论关闭

graphviz 虽然很强大,不过有两个地方不足

  1. 对中文支持很差,在windows下还可以用utf-8来处理,在linux下面就很麻烦,我尝试多次也解决不了
  2. 是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;
        }


    }

抱歉!评论已关闭.