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

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

5 comments:

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

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

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

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

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

    ReplyDelete
  5. Грибок - является одним из наиболее часто встречающихся заболеваний, которым страдает практически 85% населения планеты. Подцепить эту острозаразную болезнь можно где угодно: в бассейне, на пляже, в сауне а также любом месте, предусматривающем скопление большого количества людей. Несмотря на тот факт, что в продаже сейчас имеется огромное множество разноплановых аптечных мазей и гелей, до появления на рынке препарата Варанга за короткий срок покончить с болезнетворными микробактериями, которые влияют не только на общеэстетический вид кожи ног и ногтей, но и причиняют серьезный ущерб тканям, было очень нелегко. Благодаря этому инновационному крему, с непревзойденным природным составом, ликвидация грибка больше не является трудной задачей. Не требует много сил и времени. Вылечить грибок ногтей и стоп будет возможно после одного курса использования мази. VarangaOfficial - лечит ли варанга грибок ногтей отзывы - исключительно достоверные, проверенные факты. Воспользовавшись услугами нашего ресурса, вы сможете узнать полную, всеисчерпывающую информацию касательно этого натурального лекарственного комплекса. Увидеть данные о клиническом тестировании геля, прочитать реальные отзывы пациентов и медицинского персонала. Ознакомиться с инструкцией по использованию, прочесть об особенностях и методах работы мази, уяснить, как работает крем Варанга, где нужно покупать сертифицированный, оригинальный препарат и, как избежать покупки подделки. Мы очень тщательно проверяем публикуемые данные. Предоставляем посетителям нашего онлайн-ресурса сведения, почерпнутые только из надежных источников. Если вы обнаружили признаки грибкового поражения стоп или уже довольно продолжительное время, без ощутимых результатов стараетесь избавиться от этого досадного недуга, на нашем сайте вы отыщете быстрый и простой способ устранения проблемы. Приобщайтесь и живите здоровой полноценной жизнью. Мы собрали ответы на все вопросы на одном информационном ресурсе.

    ReplyDelete