今天遇到这样一个问题:已知一个图中的节点编号,和途中的边,如何把这个图能够更好的展现出来。算法部分在这个地方不做赘述,有兴趣的可以参看Danny Holten的论文《Force-Directed Edge Bundling for Graph Visualization》。这个算法会根据节点之间的引力和斥力,再考虑到惯性和摩擦力等因素来不断调整节点的坐标。那么现在我们希望把这个调整的过程以动画的形式展现到网页上,而我们的系统又是机遇asp.net开发的,所以我们的选择就很有限了。
首先我做了一个尝试,就是通过GDI+将每一步的结果进行绘制,然后呈现到页面上。但是显然我想多了……这个行不通之后,我又在网上找了一些资料,中间的想法是采用sliverlight或者其他的技术手段进行绘制,然后内嵌到页面里面。这个也不太work。后来我在博文:http://caca.cnblogs.com/archive/2005/09/02/228687.html中找到了一些启示。它的解决方案是把每一帧图片存入gif,然后最后把gif显示出来。但是文中的策略最后是保存到本地,我尝试了将结果写到HttpResponse里面,看页面能否直接用,结果是肯定的。下面是我给出的示例代码:
public void DrawNets(HttpResponse response) { this.CreatGraph(); Bitmap image = new Bitmap(ImageWidth, ImageHeight); Graphics graphics = Graphics.FromImage(image); GifAnimation gif = new GifAnimation(image, GraphicControlExt.Default); gif.Application = ApplicationExt.Default; gif.UseGlobalColorTableOnly = true; try { int timeStep = 0; while (!this.finishedFlag) { this.CalculateNextStep(timeStep++); this.PaintGraph(graphics); graphics.Flush(); gif.AddFrame(image); } } catch (Exception ex) { Log.WriteLog(ex.Message); } finally { graphics.Dispose(); image.Dispose(); } using (MemoryStream memoryStream = new MemoryStream()) { gif.Save(memoryStream); response.BinaryWrite(memoryStream.ToArray()); } }