SDev.Pro - разработка на заказ

http://sdev.pro - это:

1) Разработка программного обеспечения

Мы используем платформы ASP.NET MVC, LAMP, Atmel, Android, iOS, DirectShow и базы данных MS SQL, Oracle, PostgreSQL, а также облака на MS Azure и Amazon AWS для реализации любых Ваших идей.

2)Внедрение программного обеспечения

Мы предлагаем настройку и доработку решений на базе систем электронного документооборота MS SharePoint Server, геоинформационных систем на GeoServer, систем отчетности на MS SQL Reporting Services, а также облачных решений на MS Office 365.

http://sdev.pro

May 1, 2009

Работа с графами и их визуализация (.NET, C#)

Если в вашем проекте возникла потребность в работе с графами, то вам поможет связка QuickGraph + GraphViz.
Алгоритм внедрения в .NET приложение следующий:
1. Используя пространства имен QuickGraph и QuickGraph.GraphViz, формируем граф и записываем его в файл .dot. Также можно отсортировать граф топологически, это полезно для выявления последовательности выполнения связанных процессов, например, у нас в пакете 20 сборок, и нам нужно откомпилировать все, учитывая связи между сборками. Отсортировав топологически, мы можем найти последовательность компиляции всех сборок.
2. С помощью командной утилиты из dot.exe из пакета GraphViz формируем png-файл и отображаем в своем приложении.
Все просто :) В результате получаем изображение графа с автоматической расстановкой связей и элементов.
Добавлю, что с помощью dot.exe можно экспортировать в другие форматы, например, SVG, GIF, JPEG. У себя мы использовали следующую связку PNG + CMAP карта изображения для тега img. Таким образом, мы получали автоматически сформированное интерактивное изображение процесса с подсказками и ссылками в нашем ASP.NET приложении.

Ниже пример построения графа последовательности одевания человека (C#):

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using QuickGraph;

using QuickGraph.Algorithms;

using QuickGraph.Graphviz;

using System.Drawing;

using System.Diagnostics;

namespace gr

{

class Program

{

static void Main(string[] args)

{

var g = new AdjacencyGraph<string, TaggedEdge<string, string>>();

g.AddVertex("Часы");

g.AddVertex("Носки");

g.AddVertex("Туфли");

g.AddVertex("Трусы");

g.AddVertex("Брюки");

g.AddVertex("Рубашка");

g.AddVertex("Ремень");

g.AddVertex("Галстук");

g.AddVertex("Пиджак");

g.AddEdge(new TaggedEdge<string, string>("Носки", "Туфли", "a"));

g.AddEdge(new TaggedEdge<string, string>("Трусы", "Туфли", "s"));

g.AddEdge(new TaggedEdge<string, string>("Трусы", "Брюки", "d"));

g.AddEdge(new TaggedEdge<string, string>("Брюки", "Туфли", "f"));

g.AddEdge(new TaggedEdge<string, string>("Брюки", "Ремень", "g"));

g.AddEdge(new TaggedEdge<string, string>("Рубашка", "Ремень", "h"));

g.AddEdge(new TaggedEdge<string, string>("Рубашка", "Галстук", "j"));

g.AddEdge(new TaggedEdge<string, string>("Галстук", "Пиджак", "k"));

g.AddEdge(new TaggedEdge<string, string>("Ремень", "Пиджак", "l"));

foreach (var elem in g.TopologicalSort<string, TaggedEdge<string, string>>())

{

Console.WriteLine(elem);

}

var graphViz = new GraphvizAlgorithm<string, TaggedEdge<string, string>>(g, @".\", QuickGraph.Graphviz.Dot.GraphvizImageType.Png);

graphViz.FormatVertex += FormatVertex;

graphViz.FormatEdge += FormatEdge;

graphViz.Generate(new FileDotEngine(), "ww");

Console.ReadLine();

}

private static void FormatVertex(object sender, FormatVertexEventArgs<string> e)

{

e.VertexFormatter.Label = e.Vertex;

e.VertexFormatter.Shape = QuickGraph.Graphviz.Dot.GraphvizVertexShape.Box;

e.VertexFormatter.StrokeColor = Color.Yellow;

e.VertexFormatter.Font = new Font(FontFamily.GenericSansSerif, 12);

}

private static void FormatEdge(object sender, FormatEdgeEventArgs<string, TaggedEdge<string, string>> e)

{

e.EdgeFormatter.Head.Label = e.Edge.Target;

e.EdgeFormatter.Tail.Label = e.Edge.Source;

e.EdgeFormatter.Font = new Font(FontFamily.GenericSansSerif, 8);

e.EdgeFormatter.FontColor = Color.Red;

e.EdgeFormatter.StrokeColor = Color.Gray;

}

}

}

После выполнения приложения получаем файл ww.dot:
digraph G { 0 [color="#FFFF00FF", fontsize=12, label="Часы", shape=box, fontname="Microsoft Sans Serif"]; 1 [color="#FFFF00FF", fontsize=12, label="Носки", shape=box, fontname="Microsoft Sans Serif"]; 2 [color="#FFFF00FF", fontsize=12, label="Туфли", shape=box, fontname="Microsoft Sans Serif"]; 3 [color="#FFFF00FF", fontsize=12, label="Трусы", shape=box, fontname="Microsoft Sans Serif"]; 4 [color="#FFFF00FF", fontsize=12, label="Брюки", shape=box, fontname="Microsoft Sans Serif"]; 5 [color="#FFFF00FF", fontsize=12, label="Рубашка", shape=box, fontname="Microsoft Sans Serif"]; 6 [color="#FFFF00FF", fontsize=12, label="Ремень", shape=box, fontname="Microsoft Sans Serif"]; 7 [color="#FFFF00FF", fontsize=12, label="Галстук", shape=box, fontname="Microsoft Sans Serif"]; 8 [color="#FFFF00FF", fontsize=12, label="Пиджак", shape=box, fontname="Microsoft Sans Serif"]; 1 -> 2 [ fontsize=8, fontcolor="#FF0000FF", color="#808080FF", taillabel="Носки", fontname="Microsoft Sans Serif", headlabel="Туфли"]; 3 -> 2 [ fontsize=8, fontcolor="#FF0000FF", color="#808080FF", taillabel="Трусы", fontname="Microsoft Sans Serif", headlabel="Туфли"]; 3 -> 4 [ fontsize=8, fontcolor="#FF0000FF", color="#808080FF", taillabel="Трусы", fontname="Microsoft Sans Serif", headlabel="Брюки"]; 4 -> 2 [ fontsize=8, fontcolor="#FF0000FF", color="#808080FF", taillabel="Брюки", fontname="Microsoft Sans Serif", headlabel="Туфли"]; 4 -> 6 [ fontsize=8, fontcolor="#FF0000FF", color="#808080FF", taillabel="Брюки", fontname="Microsoft Sans Serif", headlabel="Ремень"]; 5 -> 6 [ fontsize=8, fontcolor="#FF0000FF", color="#808080FF", taillabel="Рубашка", fontname="Microsoft Sans Serif", headlabel="Ремень"]; 5 -> 7 [ fontsize=8, fontcolor="#FF0000FF", color="#808080FF", taillabel="Рубашка", fontname="Microsoft Sans Serif", headlabel="Галстук"]; 6 -> 8 [ fontsize=8, fontcolor="#FF0000FF", color="#808080FF", taillabel="Ремень", fontname="Microsoft Sans Serif", headlabel="Пиджак"]; 7 -> 8 [ fontsize=8, fontcolor="#FF0000FF", color="#808080FF", taillabel="Галстук", fontname="Microsoft Sans Serif", headlabel="Пиджак"]; }

Формируем изображение с помощью dot.exe:
dot -T png ww.dot > ww.png

Итоговое изображение:

4 comments:

  1. А как построить граф с помощью QuickGraph на Window форме? Чтобы он сразу отображал его на форме без запуска сторонних файлов?

    ReplyDelete
  2. Добрый день,

    Посмотрите на компоненты:
    1. http://wingraphviz.sourceforge.net/wingraphviz/.
    2. http://graphsharp.codeplex.com/

    ReplyDelete
  3. Спасибо)))

    ReplyDelete
  4. Доброго времени суток!
    Не подскажите, с помощью каких библиотек можно реализовать на С# редактор графов с возможностью последующего сохранения графа?

    ReplyDelete