参考资料:
点击打开链接
————————————————————————————————————————————————————————
1. 安装Graphviz 2.28, 安装目录不要修改,C:\Program Files\Graphviz 2.28\bin\dot.exe;
2. 在Web.config中,添加节点:
<appSettings>
<!-- Graphviz 执行文件路径 -->
<add key="dotExePath" value="C:\Program Files\Graphviz 2.28\bin\dot.exe" />
</appSettings>
3. 建立帮助类
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Web;
using System.IO;
using System.Diagnostics;
using System.Text;
using System.Net;
using System.Drawing.Imaging;
using System.Drawing;
namespace Module.Common
{
/// <summary>
/// 拓扑图
/// </summary>
public class GraphvizHelper
{
public static void SaveWebImgToLocal(string url)
{
string path=GetImgSavePath();
if(path=="" || url.IndexOf('/')== -1 )
return;
path += url.Substring(url.LastIndexOf('/'));
WebClient my=new WebClient();
byte[] mybyte;
mybyte=my.DownloadData(url);
MemoryStream ms = new MemoryStream(mybyte);
System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
img.Save(path, ImageFormat.Png); //保存
switch (Path.GetExtension(path))
{
case ".gif":
img.Save(path, ImageFormat.Gif);
break;
case ".jpg":
case ".jpeg":
img.Save(path, ImageFormat.Jpeg);
break;
case ".png":
img.Save(path, ImageFormat.Png);
break;
case ".icon":
img.Save(path, ImageFormat.Icon);
break;
case ".bmp":
img.Save(path, ImageFormat.Bmp);
break;
default:
img.Save(path, ImageFormat.Png);
break;
}
img.Dispose();
ms.Dispose();
CompressJpeg(path, 64);
}
public static void CompressJpeg(string strPath, int intWidth)
{
var img = Image.FromFile(strPath); // 如果不是图片会出错。
if (img.Width <= intWidth)
{
img.Dispose();
return;
}
var intHeight = img.Height * intWidth / img.Width;
// 创建位图及相关联的图形处理工具,在位图上画缩略图
var thm = new Bitmap(intWidth, intHeight);
var grp = Graphics.FromImage(thm);
//设置高质量插值法
grp.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
//设置高质量,低速度呈现平滑程度
grp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
grp.Clear(System.Drawing.Color.Transparent);//清空画布以透明填充
grp.DrawImage(img, 0, 0, intWidth, intHeight);
// 释放占用的图片文件
img.Dispose();
grp.Dispose();
// 保存缩略图
thm.Save(strPath); // 如果不设置图片质量,可直接保存
thm.Dispose();
}
public static string GetNodeMap(string strData)
{
StringBuilder sb = new StringBuilder();
if (String.IsNullOrEmpty(strData))
{
sb.Append("subgraph cluster_app1 {label=应用系统1 app1[image=\"../../images/Topology/app.png\"];}");
sb.Append("subgraph cluster_vm1 {label=虚拟机1 vm1[image=\"../../images/Topology/vm.png\"];}");
sb.Append("subgraph cluster_vm2 {label=虚拟机2 vm2[image=\"../../images/Topology/vm.png\"];}");
sb.Append("subgraph cluster_svr1 {label=服务器1 svr1[image=\"../../images/Topology/svr.png\"];}");
sb.Append("subgraph cluster_sw1 {label=交换机1 sw1[image=\"../../images/Topology/sw.png\"];}");
sb.Append("subgraph cluster_tap1 {label=磁带机1 tap1[image=\"../../images/Topology/tape.png\"];}");
sb.Append("app1 -> vm1 [label=安装于]");
sb.Append("app1 -> vm2 [label=安装于]");
sb.Append("vm1 -> svr1 [label=承载于]");
sb.Append("vm2 -> svr1 [label=承载于]");
sb.Append("svr1 -> sw1 [label=连接]");
sb.Append("svr1 -> tap1 [label=连接]");
}
else {
sb.Append(strData);
}
//前面一段字符
StringBuilder sb2 = new StringBuilder();
sb2.Append("digraph G {\n");
sb2.Append("compound=true;\n");
sb2.Append("ranksep=0.5;\n");
sb2.Append("nodesep=0.5;\n");
sb2.Append("rankdir=LR;\n");
sb2.Append("graph [penwidth=0, labelloc=\"b\", fontname=simsun, fontcolor=dodgerblue3, fontsize=10]\n");
sb2.Append("node [shape=plaintext, label=\"\"]\n");
sb2.Append("edge [color=brown, fontname=simsun, fontcolor=brown1, fontsize=10, weight=1.2];\n");
//string dotSource_temp = sb2.ToString() + strData; //sb.ToString();
string dotSource_temp = sb2.ToString() + sb.ToString();
string dotFileName_temp = Path.GetRandomFileName();
string dirPath = GetTempDirPath();
if (dirPath == "") {
return "";
}
string dotFileName = Path.ChangeExtension(Path.Combine(dirPath , Path.GetFileName(dotFileName_temp)), ".dot");
string pngFile = Path.ChangeExtension(dotFileName, ".png");
//string pngFile_temp=
using (StreamWriter writer = new StreamWriter(dotFileName))
{
writer.Write(dotSource_temp);
}
string dotExePath_temp = System.Configuration.ConfigurationManager.AppSettings["dotExePath"] as string;
//调用服务器端exe进程
ProcessStartInfo info = new ProcessStartInfo()
{
FileName = dotExePath_temp,
WorkingDirectory = Path.GetDirectoryName(dotFileName),
Arguments = string.Concat("-Tpng -o ", pngFile, " ", dotFileName),
RedirectStandardInput = false,
RedirectStandardOutput = false,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
try
{
using (Process exe = Process.Start(info))
{
exe.WaitForExit();
if (0 == exe.ExitCode)
{
System.Web.HttpContext.Current.Response.Write(pngFile);
}
else
{
string errMsg;
using (StreamReader stdErr = exe.StandardError)
{
errMsg = stdErr.ReadToEnd();
}
//System.Web.HttpContext.Current.Response.Write(errMsg);
}
}
}
catch(Exception ex)
{
return "";
}
String path="~/TempFile/Graphviz/"+Path.GetFileName(pngFile);
return path;
}//---- end of GetNodeMap ----
/// <summary>
/// 取得临时文件夹路径
/// </summary>
/// <returns></returns>
private static string GetTempDirPath()
{
string path = System.Web.HttpContext.Current.Server.MapPath("~")+"\\TempFile\\Graphviz";
if (!Function.CreateDir(path))
{
return "";
}
return path;
}
/// <summary>
/// 取得图片保存路径
/// </summary>
/// <returns></returns>
private static string GetImgSavePath()
{
string path = System.Web.HttpContext.Current.Server.MapPath("~") + "\\images\\Topology";
if (!Function.CreateDir(path))
{
return "";
}
return path;
}
}//end of class
public class Function
{
/// <summary>
/// 根据目录创建文件夹,如果存在就不创建
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static bool CreateDir(string path)
{
bool result = true;
DirectoryInfo dir = new DirectoryInfo(path);
//目录不存在
if (!dir.Exists)
{
try
{
dir.Create();
}
catch (Exception e)
{
result = false;
}
}
return result;
}
}//end of class
}//end of namespace
4. 加测试数据
CREATE TABLE Graph(
ID CHAR(4) PRIMARY KEY,
PID CHAR(4) NOT NULL,
Title NVARCHAR(20) NOT NULL,
RelationShip NVARCHAR(10) NOT NULL,
Img VARCHAR(200) NOT NULL
)
GO
--填充数据
INSERT INTO Graph(ID,PID,Title,RelationShip,Img) VALUES('1000','','应用系统','安装于','../../images/Topology/app.png')
INSERT INTO Graph(ID,PID,Title,RelationShip,Img) VALUES('2001','1000','虚拟机1','承载于','../../images/Topology/vm.png')
INSERT INTO Graph(ID,PID,Title,RelationShip,Img) VALUES('2002','1000','虚拟机2','承载于','../../images/Topology/vm.png')
INSERT INTO Graph(ID,PID,Title,RelationShip,Img) VALUES('2003','1000','虚拟机1','承载于','../../images/Topology/vm.png')
INSERT INTO Graph(ID,PID,Title,RelationShip,Img) VALUES('3001','2001','服务器1','连接','../../images/Topology/svr.png')
INSERT INTO Graph(ID,PID,Title,RelationShip,Img) VALUES('3002','2001','服务器2','连接','../../images/Topology/svr.png')
INSERT INTO Graph(ID,PID,Title,RelationShip,Img) VALUES('3003','2002','服务器3','连接','../../images/Topology/svr.png')
INSERT INTO Graph(ID,PID,Title,RelationShip,Img) VALUES('4001','3001','交换机1','连接','../../images/Topology/sw.png')
INSERT INTO Graph(ID,PID,Title,RelationShip,Img) VALUES('4002','3002','磁带机2','连接','../../images/Topology/tape.png')
5. 页面调用:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>无标题页</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Image ID="Image1" runat="server" />
</div>
</form>
</body>
</html>
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using Module.Common;
using System.Text;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack) {
LoadInfo();
}
}
private void LoadInfo()
{
string sql = "SELECT * FROM Graph";
DataTable dt = DBHelper.GetDataTableBySql(sql);
StringBuilder sb = new StringBuilder();
if (dt == null || dt.Rows.Count == 0)
return;
BuildGraphNodes(sb,dt,"",1,5);
String imgUrl = GraphvizHelper.GetNodeMap(sb.ToString());
this.Image1.ImageUrl = imgUrl;
GraphvizHelper.SaveWebImgToLocal("http://hiphotos.baidu.com/yuangengqiang/pic/item/f9eb16e8007ae310b90e2dc3.jpg");
}
private void BuildGraphNodes(StringBuilder sb, DataTable dt, string pid, int depth, int maxDepth)
{
if(dt==null || dt.Rows.Count==0 || depth > maxDepth )
return;
DataRow[] drArr = dt.Select( String.Format("PID='{0}'",pid) );
if ( drArr == null || drArr.Length == 0)
return;
foreach (DataRow dr in drArr) {
sb.AppendFormat("subgraph cluster_id{0} {{label=\"{1}\" id{0}[image=\"{2}\"];}}\n",
dr["ID"] as string, ((dr["Title"] as string)??"").Replace("\"","'"), dr["Img"] as string);
DataRow[] drSubArr = dt.Select(string.Format("PID='{0}'", dr["ID"] as String));
if (depth < maxDepth)
{
foreach (DataRow drSub in drSubArr)
{
sb.AppendFormat("id{0} -> id{1} [label=\"{2}\"]\n", ((dr["ID"] as string) ?? "").Replace("\"", "'"), ((drSub["ID"] as string) ?? "").Replace("\"", "'"), dr["RelationShip"] as string);
}
}
BuildGraphNodes(sb, dt, dr["ID"] as String, depth + 1, maxDepth);
}
}
}
|