https://github.com/ialhashim/topo-blend
Revision 39b13612ebd645a65eda854771b517371f2f858a authored by ennetws on 13 March 2015, 18:17:18 UTC, committed by ennetws on 13 March 2015, 18:17:18 UTC
1 parent c702819
Tip revision: 39b13612ebd645a65eda854771b517371f2f858a authored by ennetws on 13 March 2015, 18:17:18 UTC
Create README.md
Create README.md
Tip revision: 39b1361
ExportDynamicGraph.h
#pragma once
#include "DynamicGraph.h"
#include <QFile>
#include <QXmlStreamWriter>
// Save to XML based graph file
static void toGraphML(DynamicGraphs::DynamicGraph g, QString fileName = "mygraph")
{
QFile file(fileName + ".graphml");
if (!file.open(QFile::WriteOnly | QFile::Text)) return;
QXmlStreamWriter xml(&file);
xml.setAutoFormatting(true);
xml.writeStartDocument();
xml.writeStartElement("graphml");
xml.writeAttribute("xmlns","http://graphml.graphdrawing.org/xmlns");
// Write all graph keys
// Node keys
xml.writeStartElement("key");
xml.writeAttribute("attr.name","label");xml.writeAttribute("attr.type","string");
xml.writeAttribute("for","node");xml.writeAttribute("id","label");
xml.writeEndElement();
xml.writeStartElement("key");
xml.writeAttribute("attr.name","x");xml.writeAttribute("attr.type","double");
xml.writeAttribute("for","node");xml.writeAttribute("id","x");
xml.writeEndElement();
xml.writeStartElement("key");
xml.writeAttribute("attr.name","y");xml.writeAttribute("attr.type","double");
xml.writeAttribute("for","node");xml.writeAttribute("id","y");
xml.writeEndElement();
xml.writeStartElement("key");
xml.writeAttribute("attr.name","size");xml.writeAttribute("attr.type","double");
xml.writeAttribute("for","node");xml.writeAttribute("id","size");
xml.writeEndElement();
// Special node keys
xml.writeStartElement("key");
xml.writeAttribute("attr.name","Original");xml.writeAttribute("attr.type","string");
xml.writeAttribute("for","node");xml.writeAttribute("id","original");
xml.writeEndElement();
xml.writeStartElement("key");
xml.writeAttribute("attr.name","State");xml.writeAttribute("attr.type","int");
xml.writeAttribute("for","node");xml.writeAttribute("id","state");
xml.writeEndElement();
xml.writeStartElement("key");
xml.writeAttribute("attr.name","Correspond");xml.writeAttribute("attr.type","string");
xml.writeAttribute("for","node");xml.writeAttribute("id","correspond");
xml.writeEndElement();
// Edge keys
xml.writeStartElement("key");
xml.writeAttribute("attr.name","Edge Label");xml.writeAttribute("attr.type","string");
xml.writeAttribute("for","edge");xml.writeAttribute("id","edgelabel");
xml.writeEndElement();
xml.writeStartElement("key");
xml.writeAttribute("attr.name","Edge Id");xml.writeAttribute("attr.type","string");
xml.writeAttribute("for","edge");xml.writeAttribute("id","edgeid");
xml.writeEndElement();
xml.writeStartElement("key");
xml.writeAttribute("attr.name","weight");xml.writeAttribute("attr.type","double");
xml.writeAttribute("for","edge");xml.writeAttribute("id","weight");
xml.writeEndElement();
// Write the graph data
xml.writeStartElement("graph");
xml.writeAttribute("edgedefault","undirected");
// Place on a grid
double size = 50;
double spacing = size / 10.0;
double x = 0, y = 0;
double dx = size + spacing;
double dy = dx;
int length = sqrt((double)g.nodes.size());
// Write nodes
foreach(int i, g.nodes.keys())
{
const DynamicGraphs::SimpleNode & n = g.nodes[i];
xml.writeStartElement("node");
xml.writeAttribute("id", QString::number(n.idx));
// Original node label
xml.writeStartElement("data");
xml.writeAttribute("key","label");
xml.writeCharacters(n.property["original"].toString());
xml.writeEndElement();
xml.writeStartElement("data");
xml.writeAttribute("key","original");
xml.writeCharacters(n.property["original"].toString());
xml.writeEndElement();
// Special keys
if(n.property.contains("state"))
{
xml.writeStartElement("data");
xml.writeAttribute("key","state");
xml.writeCharacters(n.property["state"].toString());
xml.writeEndElement();
}
if(n.property.contains("correspond"))
{
xml.writeStartElement("data");
xml.writeAttribute("key","correspond");
xml.writeCharacters(n.property["correspond"].toString());
xml.writeEndElement();
}
// Position
xml.writeStartElement("data");
xml.writeAttribute("key","x");
xml.writeCharacters( QString::number(x) );
xml.writeEndElement();
xml.writeStartElement("data");
xml.writeAttribute("key","y");
xml.writeCharacters( QString::number(y) );
xml.writeEndElement();
xml.writeStartElement("data");
xml.writeAttribute("key","size");
xml.writeCharacters( QString::number(size * 0.5) );
xml.writeEndElement();
// Move virtual cursor
x += dx;
if(i % length == 0){
x = 0;
y += dy;
}
xml.writeEndElement();
}
// Write edges
foreach(int i, g.edges.keys())
{
const SimpleEdge & e = g.edges[i];
xml.writeStartElement("edge");
xml.writeAttribute("source", QString::number(g.nodes[e.n[0]].idx));
xml.writeAttribute("target", QString::number(g.nodes[e.n[1]].idx));
// Edge weight
xml.writeStartElement("data");
xml.writeAttribute("key","weight");
xml.writeCharacters("1.0");
xml.writeEndElement();
xml.writeEndElement();
}
xml.writeEndElement();
xml.writeEndDocument();
file.close();
}
// Convert to Graphviz '.gv' format
static QString toGraphvizFormat(DynamicGraphs::DynamicGraph g, QString subcaption, QString caption)
{
QStringList out;
out << "graph G{\n";
out << "\t" << "node [ fontcolor = black, color = white, style = filled ];" << "\n";
// Place on a grid
double size = 50;
double spacing = size / 10.0;
double x = 0, y = 0;
double dx = size + spacing;
double dy = dx;
int length = sqrt((double)g.nodes.size());
QStringList colors;
colors << "red" << "green" << "blue" << "orangered" << "greenyellow" << "navy";
// Write nodes
foreach(int i, g.nodes.keys())
{
const DynamicGraphs::SimpleNode & n = g.nodes[i];
Structure::Node * node = g.mGraph->getNode(n.property["original"].toString());
QColor color = node->vis_property["color"].value<QColor>();
QString colorHex;
colorHex.sprintf("#%02X%02X%02X", color.red(), color.green(), color.blue());
QString shape = "rectangle";
if(node->id.contains("_null")) shape = "ellipse";
QString nodeName = n.property["original"].toString();
if(nodeName.contains("_null")) nodeName = "# " + nodeName.replace("_null","z");
QString other = "";
if(node->property["articulation"].toBool()) other = ", style=\"bold\"";
out << "\t" << QString("%1 [label = \"%2\", color = \"%3\", shape = %4 %5];").arg(n.idx).arg( nodeName ).arg(colorHex).arg(shape).arg(other) << "\n";
// Move virtual cursor
x += dx;
if(i % length == 0){
x = 0;
y += dy;
}
}
// Write edges
foreach(int i, g.edges.keys())
{
const SimpleEdge & e = g.edges[i];
const DynamicGraphs::SimpleNode & n1 = g.nodes[e.n[0]];
const DynamicGraphs::SimpleNode & n2 = g.nodes[e.n[1]];
Structure::Link * link = g.mGraph->getEdge(n1.property["original"].toString(),n2.property["original"].toString());
QString color = "black", lcolor = "gray";
QString lable = "";
if(link && !link->property.contains("correspond"))
color = "red";
else
{
int uid = -1;
if(link->property.contains("viz_uid")) uid = link->property["viz_uid"].toInt();
lable = QString::number( uid ); // + correspond;
}
out << "\t\"" << QString::number(n1.idx) << "\" -- \"" << QString::number(n2.idx) << "\""
<< QString(" [color=\"%1\",label=\"%2\",fontcolor=\"%3\"] ").arg(color).arg(lable).arg(lcolor) << ";\n";
}
// Labels
out << "label = \"\\n\\n" << caption << "\\n" << subcaption << "\"\n";
out << "fontsize = 20;\n";
out << "}\n";
return out.join("");
}
// Save to XML based graph file
static void toGraphviz(DynamicGraphs::DynamicGraph g, QString fileName = "mygraph", bool isOutputImage = true, QString subcaption="", QString caption = "")
{
QFile file(fileName + ".gv");
if (!file.open(QFile::WriteOnly | QFile::Text)) return;
QTextStream out(&file);
out << toGraphvizFormat(g, subcaption, caption);
file.flush();
file.close();
// Show image of graph (assuming Graphviz is installed)
if(isOutputImage)
{
QString command = QString("dot %1 -Tpng > %2").arg(fileName+".gv").arg(fileName+".png");
qDebug() << "Executing: " << command;
system(qPrintable(command));
}
}
static void visualizeStructureGraph(Structure::Graph * graph, QString filename, QString caption = "")
{
DynamicGraphs::DynamicGraph dg( graph );
toGraphviz(dg, filename, true, QString("V = %1, E = %2").arg(dg.nodes.size()).arg(dg.edges.size()), caption);
}
Computing file changes ...