Graphviz 拓扑图

参考资料:

点击打开链接

————————————————————————————————————————————————————————

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);
        }
    }
}


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值