Showing
14 changed files
with
873 additions
and
278 deletions
.gitignore
0 → 100644
| 1 | +## Ignore Visual Studio temporary files, build results, and | ||
| 2 | +## files generated by popular Visual Studio add-ons. | ||
| 3 | +## | ||
| 4 | +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore | ||
| 5 | + | ||
| 6 | +# User-specific files | ||
| 7 | +*.suo | ||
| 8 | +*.user | ||
| 9 | +*.userosscache | ||
| 10 | +*.sln.docstates | ||
| 11 | + | ||
| 12 | +# User-specific files (MonoDevelop/Xamarin Studio) | ||
| 13 | +*.userprefs | ||
| 14 | + | ||
| 15 | +# Build results | ||
| 16 | +[Dd]ebug/ | ||
| 17 | +[Dd]ebugPublic/ | ||
| 18 | +[Rr]elease/ | ||
| 19 | +[Rr]eleases/ | ||
| 20 | +x64/ | ||
| 21 | +x86/ | ||
| 22 | +bld/ | ||
| 23 | +[Bb]in/ | ||
| 24 | +[Oo]bj/ | ||
| 25 | +[Ll]og/ | ||
| 26 | + | ||
| 27 | +# Visual Studio 2015 cache/options directory | ||
| 28 | +.vs/ | ||
| 29 | +# Uncomment if you have tasks that create the project's static files in wwwroot | ||
| 30 | +#wwwroot/ | ||
| 31 | + | ||
| 32 | +# MSTest test Results | ||
| 33 | +[Tt]est[Rr]esult*/ | ||
| 34 | +[Bb]uild[Ll]og.* | ||
| 35 | + | ||
| 36 | +# NUNIT | ||
| 37 | +*.VisualState.xml | ||
| 38 | +TestResult.xml | ||
| 39 | + | ||
| 40 | +# Build Results of an ATL Project | ||
| 41 | +[Dd]ebugPS/ | ||
| 42 | +[Rr]eleasePS/ | ||
| 43 | +dlldata.c | ||
| 44 | + | ||
| 45 | +# .NET Core | ||
| 46 | +project.lock.json | ||
| 47 | +project.fragment.lock.json | ||
| 48 | +artifacts/ | ||
| 49 | +**/Properties/launchSettings.json | ||
| 50 | + | ||
| 51 | +*_i.c | ||
| 52 | +*_p.c | ||
| 53 | +*_i.h | ||
| 54 | +*.ilk | ||
| 55 | +*.meta | ||
| 56 | +*.obj | ||
| 57 | +*.pch | ||
| 58 | +*.pdb | ||
| 59 | +*.pgc | ||
| 60 | +*.pgd | ||
| 61 | +*.rsp | ||
| 62 | +*.sbr | ||
| 63 | +*.tlb | ||
| 64 | +*.tli | ||
| 65 | +*.tlh | ||
| 66 | +*.tmp | ||
| 67 | +*.tmp_proj | ||
| 68 | +*.log | ||
| 69 | +*.vspscc | ||
| 70 | +*.vssscc | ||
| 71 | +.builds | ||
| 72 | +*.pidb | ||
| 73 | +*.svclog | ||
| 74 | +*.scc | ||
| 75 | + | ||
| 76 | +# Chutzpah Test files | ||
| 77 | +_Chutzpah* | ||
| 78 | + | ||
| 79 | +# Visual C++ cache files | ||
| 80 | +ipch/ | ||
| 81 | +*.aps | ||
| 82 | +*.ncb | ||
| 83 | +*.opendb | ||
| 84 | +*.opensdf | ||
| 85 | +*.sdf | ||
| 86 | +*.cachefile | ||
| 87 | +*.VC.db | ||
| 88 | +*.VC.VC.opendb | ||
| 89 | + | ||
| 90 | +# Visual Studio profiler | ||
| 91 | +*.psess | ||
| 92 | +*.vsp | ||
| 93 | +*.vspx | ||
| 94 | +*.sap | ||
| 95 | + | ||
| 96 | +# TFS 2012 Local Workspace | ||
| 97 | +$tf/ | ||
| 98 | + | ||
| 99 | +# Guidance Automation Toolkit | ||
| 100 | +*.gpState | ||
| 101 | + | ||
| 102 | +# ReSharper is a .NET coding add-in | ||
| 103 | +_ReSharper*/ | ||
| 104 | +*.[Rr]e[Ss]harper | ||
| 105 | +*.DotSettings.user | ||
| 106 | + | ||
| 107 | +# JustCode is a .NET coding add-in | ||
| 108 | +.JustCode | ||
| 109 | + | ||
| 110 | +# TeamCity is a build add-in | ||
| 111 | +_TeamCity* | ||
| 112 | + | ||
| 113 | +# DotCover is a Code Coverage Tool | ||
| 114 | +*.dotCover | ||
| 115 | + | ||
| 116 | +# Visual Studio code coverage results | ||
| 117 | +*.coverage | ||
| 118 | +*.coveragexml | ||
| 119 | + | ||
| 120 | +# NCrunch | ||
| 121 | +_NCrunch_* | ||
| 122 | +.*crunch*.local.xml | ||
| 123 | +nCrunchTemp_* | ||
| 124 | + | ||
| 125 | +# MightyMoose | ||
| 126 | +*.mm.* | ||
| 127 | +AutoTest.Net/ | ||
| 128 | + | ||
| 129 | +# Web workbench (sass) | ||
| 130 | +.sass-cache/ | ||
| 131 | + | ||
| 132 | +# Installshield output folder | ||
| 133 | +[Ee]xpress/ | ||
| 134 | + | ||
| 135 | +# DocProject is a documentation generator add-in | ||
| 136 | +DocProject/buildhelp/ | ||
| 137 | +DocProject/Help/*.HxT | ||
| 138 | +DocProject/Help/*.HxC | ||
| 139 | +DocProject/Help/*.hhc | ||
| 140 | +DocProject/Help/*.hhk | ||
| 141 | +DocProject/Help/*.hhp | ||
| 142 | +DocProject/Help/Html2 | ||
| 143 | +DocProject/Help/html | ||
| 144 | + | ||
| 145 | +# Click-Once directory | ||
| 146 | +publish/ | ||
| 147 | + | ||
| 148 | +# Publish Web Output | ||
| 149 | +*.[Pp]ublish.xml | ||
| 150 | +*.azurePubxml | ||
| 151 | +# TODO: Comment the next line if you want to checkin your web deploy settings | ||
| 152 | +# but database connection strings (with potential passwords) will be unencrypted | ||
| 153 | +*.pubxml | ||
| 154 | +*.publishproj | ||
| 155 | + | ||
| 156 | +# Microsoft Azure Web App publish settings. Comment the next line if you want to | ||
| 157 | +# checkin your Azure Web App publish settings, but sensitive information contained | ||
| 158 | +# in these scripts will be unencrypted | ||
| 159 | +PublishScripts/ | ||
| 160 | + | ||
| 161 | +# NuGet Packages | ||
| 162 | +*.nupkg | ||
| 163 | +# The packages folder can be ignored because of Package Restore | ||
| 164 | +**/packages/* | ||
| 165 | +# except build/, which is used as an MSBuild target. | ||
| 166 | +!**/packages/build/ | ||
| 167 | +# Uncomment if necessary however generally it will be regenerated when needed | ||
| 168 | +#!**/packages/repositories.config | ||
| 169 | +# NuGet v3's project.json files produces more ignorable files | ||
| 170 | +*.nuget.props | ||
| 171 | +*.nuget.targets | ||
| 172 | + | ||
| 173 | +# Microsoft Azure Build Output | ||
| 174 | +csx/ | ||
| 175 | +*.build.csdef | ||
| 176 | + | ||
| 177 | +# Microsoft Azure Emulator | ||
| 178 | +ecf/ | ||
| 179 | +rcf/ | ||
| 180 | + | ||
| 181 | +# Windows Store app package directories and files | ||
| 182 | +AppPackages/ | ||
| 183 | +BundleArtifacts/ | ||
| 184 | +Package.StoreAssociation.xml | ||
| 185 | +_pkginfo.txt | ||
| 186 | + | ||
| 187 | +# Visual Studio cache files | ||
| 188 | +# files ending in .cache can be ignored | ||
| 189 | +*.[Cc]ache | ||
| 190 | +# but keep track of directories ending in .cache | ||
| 191 | +!*.[Cc]ache/ | ||
| 192 | + | ||
| 193 | +# Others | ||
| 194 | +ClientBin/ | ||
| 195 | +~$* | ||
| 196 | +*~ | ||
| 197 | +*.dbmdl | ||
| 198 | +*.dbproj.schemaview | ||
| 199 | +*.jfm | ||
| 200 | +*.pfx | ||
| 201 | +*.publishsettings | ||
| 202 | +orleans.codegen.cs | ||
| 203 | + | ||
| 204 | +# Since there are multiple workflows, uncomment next line to ignore bower_components | ||
| 205 | +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) | ||
| 206 | +#bower_components/ | ||
| 207 | + | ||
| 208 | +# RIA/Silverlight projects | ||
| 209 | +Generated_Code/ | ||
| 210 | + | ||
| 211 | +# Backup & report files from converting an old project file | ||
| 212 | +# to a newer Visual Studio version. Backup files are not needed, | ||
| 213 | +# because we have git ;-) | ||
| 214 | +_UpgradeReport_Files/ | ||
| 215 | +Backup*/ | ||
| 216 | +UpgradeLog*.XML | ||
| 217 | +UpgradeLog*.htm | ||
| 218 | + | ||
| 219 | +# SQL Server files | ||
| 220 | +*.mdf | ||
| 221 | +*.ldf | ||
| 222 | +*.ndf | ||
| 223 | + | ||
| 224 | +# Business Intelligence projects | ||
| 225 | +*.rdl.data | ||
| 226 | +*.bim.layout | ||
| 227 | +*.bim_*.settings | ||
| 228 | + | ||
| 229 | +# Microsoft Fakes | ||
| 230 | +FakesAssemblies/ | ||
| 231 | + | ||
| 232 | +# GhostDoc plugin setting file | ||
| 233 | +*.GhostDoc.xml | ||
| 234 | + | ||
| 235 | +# Node.js Tools for Visual Studio | ||
| 236 | +.ntvs_analysis.dat | ||
| 237 | +node_modules/ | ||
| 238 | + | ||
| 239 | +# Typescript v1 declaration files | ||
| 240 | +typings/ | ||
| 241 | + | ||
| 242 | +# Visual Studio 6 build log | ||
| 243 | +*.plg | ||
| 244 | + | ||
| 245 | +# Visual Studio 6 workspace options file | ||
| 246 | +*.opt | ||
| 247 | + | ||
| 248 | +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) | ||
| 249 | +*.vbw | ||
| 250 | + | ||
| 251 | +# Visual Studio LightSwitch build output | ||
| 252 | +**/*.HTMLClient/GeneratedArtifacts | ||
| 253 | +**/*.DesktopClient/GeneratedArtifacts | ||
| 254 | +**/*.DesktopClient/ModelManifest.xml | ||
| 255 | +**/*.Server/GeneratedArtifacts | ||
| 256 | +**/*.Server/ModelManifest.xml | ||
| 257 | +_Pvt_Extensions | ||
| 258 | + | ||
| 259 | +# Paket dependency manager | ||
| 260 | +.paket/paket.exe | ||
| 261 | +paket-files/ | ||
| 262 | + | ||
| 263 | +# FAKE - F# Make | ||
| 264 | +.fake/ | ||
| 265 | + | ||
| 266 | +# JetBrains Rider | ||
| 267 | +.idea/ | ||
| 268 | +*.sln.iml | ||
| 269 | + | ||
| 270 | +# CodeRush | ||
| 271 | +.cr/ | ||
| 272 | + | ||
| 273 | +# Python Tools for Visual Studio (PTVS) | ||
| 274 | +__pycache__/ | ||
| 275 | +*.pyc | ||
| 276 | + | ||
| 277 | +# Cake - Uncomment if you are using it | ||
| 278 | +# tools/** | ||
| 279 | +# !tools/packages.config | ||
| 280 | + | ||
| 281 | +# Telerik's JustMock configuration file | ||
| 282 | +*.jmconfig | ||
| 283 | + | ||
| 284 | +# BizTalk build output | ||
| 285 | +*.btp.cs | ||
| 286 | +*.btm.cs | ||
| 287 | +*.odx.cs | ||
| 288 | +*.xsd.cs | ||
| 289 | + | ||
| 290 | +# C++ objects and libs | ||
| 291 | + | ||
| 292 | +*.slo | ||
| 293 | +*.lo | ||
| 294 | +*.o | ||
| 295 | +*.a | ||
| 296 | +*.la | ||
| 297 | +*.lai | ||
| 298 | +*.so | ||
| 299 | +*.dll | ||
| 300 | +*.dylib | ||
| 301 | + | ||
| 302 | +# Qt-es | ||
| 303 | + | ||
| 304 | +/.qmake.cache | ||
| 305 | +/.qmake.stash | ||
| 306 | +*.pro.user | ||
| 307 | +*.pro.user.* | ||
| 308 | +*.qbs.user | ||
| 309 | +*.qbs.user.* | ||
| 310 | +*.moc | ||
| 311 | +moc_*.cpp | ||
| 312 | +qrc_*.cpp | ||
| 313 | +ui_*.h | ||
| 314 | +Makefile* | ||
| 315 | +*build-* | ||
| 316 | + | ||
| 317 | +# QtCreator | ||
| 318 | + | ||
| 319 | +*.autosave | ||
| 320 | + | ||
| 321 | +# QtCtreator Qml | ||
| 322 | +*.qmlproject.user | ||
| 323 | +*.qmlproject.user.* | ||
| 324 | + | ||
| 325 | +# QtCtreator CMake | ||
| 326 | +CMakeLists.txt.user* | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
PaperGraph/EdgeItem.cpp
0 → 100644
| 1 | +#include "EdgeItem.h" | ||
| 2 | +#include <QtWidgets> | ||
| 3 | + | ||
| 4 | +void EdgeItem::mousePressEvent(QGraphicsSceneMouseEvent * event) | ||
| 5 | +{ | ||
| 6 | +} | ||
| 7 | + | ||
| 8 | +void EdgeItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) | ||
| 9 | +{ | ||
| 10 | +} | ||
| 11 | + | ||
| 12 | +void EdgeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) | ||
| 13 | +{ | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +EdgeItem::EdgeItem(double x1, double y1, double x2, double y2, QColor color, int width) | ||
| 17 | +{ | ||
| 18 | + this->x1 = x1; | ||
| 19 | + this->y1 = y1; | ||
| 20 | + this->x2 = x2; | ||
| 21 | + this->y2 = y2; | ||
| 22 | + | ||
| 23 | + this->color = color; | ||
| 24 | + this->width = width; | ||
| 25 | + setZValue(0); //노드 앞 가리지 않도록 ZValue 설정 | ||
| 26 | + | ||
| 27 | + /*setFlags(ItemIsSelectable | ItemIsMovable); | ||
| 28 | + setAcceptHoverEvents(true);*/ | ||
| 29 | +} | ||
| 30 | + | ||
| 31 | +QRectF EdgeItem::boundingRect() const | ||
| 32 | +{ | ||
| 33 | + return QRectF(0,0,0,0); | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +QPainterPath EdgeItem::shape() const | ||
| 37 | +{ | ||
| 38 | + QPainterPath path; | ||
| 39 | + return path; | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +void EdgeItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) | ||
| 43 | +{ | ||
| 44 | + Q_UNUSED(widget); | ||
| 45 | + | ||
| 46 | + QPen oldPen = painter->pen(); | ||
| 47 | + QPen pen = oldPen; | ||
| 48 | + pen.setWidth(width); | ||
| 49 | + pen.setColor(color); | ||
| 50 | + painter->setPen(pen); | ||
| 51 | + painter->drawLine(QLineF(x1, y1, x2, y2)); | ||
| 52 | +} |
PaperGraph/EdgeItem.h
0 → 100644
| 1 | +#ifndef EDGEITEM_H | ||
| 2 | +#define EDGEITEM_H | ||
| 3 | + | ||
| 4 | +#include <QColor> | ||
| 5 | +#include <QGraphicsItem> | ||
| 6 | + | ||
| 7 | + | ||
| 8 | +class EdgeItem | ||
| 9 | + : public QGraphicsItem | ||
| 10 | +{ | ||
| 11 | +private: | ||
| 12 | + double x1, y1, x2, y2; | ||
| 13 | + int width; | ||
| 14 | + QColor color; | ||
| 15 | + | ||
| 16 | +protected: | ||
| 17 | + void mousePressEvent(QGraphicsSceneMouseEvent *event) override; | ||
| 18 | + void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; | ||
| 19 | + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; | ||
| 20 | + | ||
| 21 | +public: | ||
| 22 | + EdgeItem(double x1, double y1, double x2, double y2, QColor color, int width); | ||
| 23 | + | ||
| 24 | + QRectF boundingRect() const override; | ||
| 25 | + QPainterPath shape() const override; | ||
| 26 | + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; | ||
| 27 | +}; | ||
| 28 | + | ||
| 29 | +#endif // EDGEITEM_H | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
PaperGraph/GraphItem.cpp
0 → 100644
| 1 | +#include "GraphItem.h" | ||
| 2 | + | ||
| 3 | +#include <boost/graph/fruchterman_reingold.hpp> | ||
| 4 | +#include <boost/graph/random_layout.hpp> | ||
| 5 | +#include <boost/graph/circle_layout.hpp> | ||
| 6 | +#include <boost/graph/dijkstra_shortest_paths.hpp> | ||
| 7 | +#include <boost/algorithm/string.hpp> //boost::split | ||
| 8 | +#include <boost/bimap.hpp> | ||
| 9 | +#include <boost/regex.hpp> | ||
| 10 | + | ||
| 11 | +#include <exception> | ||
| 12 | +#include <iterator> | ||
| 13 | +#include <string> | ||
| 14 | +#include <map> | ||
| 15 | +#include <vector> | ||
| 16 | + | ||
| 17 | +#include <QDebug> | ||
| 18 | +#include <QtWidgets> | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +GraphItem::GraphItem(ifstream& fin) | ||
| 22 | +{ | ||
| 23 | + if (!fin) | ||
| 24 | + throw std::exception("graph file input is invalid"); | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * Parse Paper dataset | ||
| 28 | + * - paper_key, [author_list], publish_year | ||
| 29 | + * Column Delimiter: || | ||
| 30 | + * Author list Delimiter: && | ||
| 31 | + */ | ||
| 32 | + std::string line; | ||
| 33 | + vector<std::string> tokens; | ||
| 34 | + vector<std::string> authors; | ||
| 35 | + vector<pair<string, string>> edges; | ||
| 36 | + | ||
| 37 | + //String <--> int 양방향 변환을 위해 bidirectional map 상숑 | ||
| 38 | + //map<string, int> -> <vertex label, vertex index> | ||
| 39 | + typedef boost::bimap<string, int> bm_type; | ||
| 40 | + bm_type node_ids; | ||
| 41 | + vector<simple_edge> edges_indexes; //int로 변환된 edge | ||
| 42 | + | ||
| 43 | + int node_cnt = 0; | ||
| 44 | + qDebug() << "* graph reading start"; | ||
| 45 | + | ||
| 46 | + //한 줄씩 읽어서 Parse | ||
| 47 | + while (std::getline(fin, line) && !line.empty()) { | ||
| 48 | + //boost::split 이용해 문자열 분리 | ||
| 49 | + //tokens[0]: Paper-key. ex) conf/iastedCSN/KeimS06 | ||
| 50 | + //tokens[1]: Authors. ex) Werner Keim&&Arpad L. Scholtz | ||
| 51 | + //tokens[2]: Published year. | ||
| 52 | + boost::split(tokens, line, boost::is_any_of("||"), boost::token_compress_on); | ||
| 53 | + boost::split(authors, tokens[1], boost::is_any_of("&&"), boost::token_compress_on); | ||
| 54 | + | ||
| 55 | + const string& paper_key = tokens[0]; | ||
| 56 | + if (node_ids.left.find(paper_key) == node_ids.left.end()) { | ||
| 57 | + node_ids.insert(bm_type::value_type(paper_key, node_cnt++)); | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + for (auto author : authors) { | ||
| 61 | + edges.push_back(pair<string, string>(paper_key, author)); | ||
| 62 | + if (node_ids.left.find(author) == node_ids.left.end()) { | ||
| 63 | + node_ids.insert(bm_type::value_type(author, node_cnt++)); | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + //debug | ||
| 68 | + if (node_cnt > NODE_LIMIT) break; | ||
| 69 | + } | ||
| 70 | + qDebug() << "* graph reading complete"; | ||
| 71 | + qDebug() << "* # of nodes: " << node_cnt; | ||
| 72 | + qDebug() << "* # of edges: " << edges.size(); | ||
| 73 | + | ||
| 74 | + //edge conversion | ||
| 75 | + //<string, string> to <int, int> | ||
| 76 | + //using boost::bimap (bidirectional map) | ||
| 77 | + for (auto edge : edges) { | ||
| 78 | + edges_indexes.push_back({ | ||
| 79 | + node_ids.left.find(edge.first)->get_right(), | ||
| 80 | + node_ids.left.find(edge.second)->get_right() | ||
| 81 | + }); | ||
| 82 | + } | ||
| 83 | + //Graph --> defined in "PaperGraphWidget.h" | ||
| 84 | + //Graph graph(edges_indexes.begin(), edges_indexes.end(), node_ids.size()); | ||
| 85 | + graph = new Graph(edges_indexes.begin(), edges_indexes.end(), node_ids.size()); | ||
| 86 | + | ||
| 87 | + //set index property | ||
| 88 | + qDebug() << "* set vertex property start"; | ||
| 89 | + typedef typename graph_traits<Graph>::edge_iterator edge_iterator; | ||
| 90 | + typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator; | ||
| 91 | + vertex_iterator vi, vi_end; | ||
| 92 | + int i = 0; | ||
| 93 | + for (boost::tie(vi, vi_end)=vertices(*graph); vi!=vi_end; ++vi) { | ||
| 94 | + //Vertex Property 설정 | ||
| 95 | + //index: 0 ~ ... | ||
| 96 | + //name : map의 value(i) 기준으로 찾은 Key | ||
| 97 | + // map --> map<string, int> (boost bidirectional map) | ||
| 98 | + boost::put(vertex_index, *graph, *vi, i); | ||
| 99 | + boost::put(vertex_name, *graph, *vi, | ||
| 100 | + node_ids.right.find(i)->get_left()); | ||
| 101 | + | ||
| 102 | + ++i; | ||
| 103 | + } | ||
| 104 | + qDebug() << "* set vertex property end"; | ||
| 105 | + | ||
| 106 | + | ||
| 107 | + //qDebug("* set edges weight start"); | ||
| 108 | + ////모든 edge의 weight를 1로 설정 | ||
| 109 | + //typename graph_traits<Graph>::edge_iterator ei, ei_end; | ||
| 110 | + //for (boost::tie(ei, ei_end)=boost::edges(*graph); ei!=ei_end; ++ei) { | ||
| 111 | + // boost::put(edge_weight, *graph, *ei, 1); | ||
| 112 | + //} | ||
| 113 | + //qDebug("* set edges weight end"); | ||
| 114 | + // | ||
| 115 | + // | ||
| 116 | + //qDebug("* path highlighting start"); | ||
| 117 | + ////find start, end node's id | ||
| 118 | + //int start_idx, end_idx; | ||
| 119 | + //for (boost::tie(vi, vi_end)=vertices(*graph); vi!=vi_end; ++vi) { | ||
| 120 | + // string node_name = boost::get(vertex_name, *graph, *vi); | ||
| 121 | + // if (node_name == "Seong Chul Cho") { | ||
| 122 | + // start_idx = boost::get(vertex_index, *graph, *vi); | ||
| 123 | + // } else if (node_name == "Hyung Jin Kim") { | ||
| 124 | + // end_idx = boost::get(vertex_index, *graph, *vi); | ||
| 125 | + // } | ||
| 126 | + //} | ||
| 127 | + | ||
| 128 | + //typedef boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor; | ||
| 129 | + //vector<vertex_descriptor> parents(num_vertices(*graph)); | ||
| 130 | + //vector<int> distances(num_vertices(*graph)); | ||
| 131 | + //vertex_descriptor start_vertex = vertex(start_idx, *graph); | ||
| 132 | + //dijkstra_shortest_paths(*graph, start_vertex, | ||
| 133 | + // predecessor_map(&parents[0]).distance_map(&distances[0])); | ||
| 134 | + ////path finding | ||
| 135 | + //vertex_descriptor current = boost::vertex(end_idx, *graph); | ||
| 136 | + //while (current != boost::vertex(start_idx, *graph)) { | ||
| 137 | + //} | ||
| 138 | + //qDebug("* path highlighting end"); | ||
| 139 | + | ||
| 140 | + | ||
| 141 | + //graph layout calculation | ||
| 142 | + //using boost::random_graph_layout and boost::kamada_kawai_spring_layout | ||
| 143 | + //vertex마다 계산된 좌표를 property에 적용 | ||
| 144 | + //예제 코드: http://www.boost.org/doc/libs/1_63_0/libs/graph/test/layout_test.cpp | ||
| 145 | + //(-> 콘솔 기반) | ||
| 146 | + qDebug() << "* make graph layout start"; | ||
| 147 | + typedef square_topology<> Topology; | ||
| 148 | + minstd_rand gen; | ||
| 149 | + Topology topology(gen, (double)SCREEN_SIZE); | ||
| 150 | + Topology::point_type origin; | ||
| 151 | + origin[0] = origin[1] = (double)SCREEN_SIZE; | ||
| 152 | + Topology::point_difference_type extent; | ||
| 153 | + extent[0] = extent[1] = (double)SCREEN_SIZE; | ||
| 154 | + rectangle_topology<> rect_top(gen, | ||
| 155 | + -SCREEN_SIZE/2, -SCREEN_SIZE/2, | ||
| 156 | + SCREEN_SIZE/2, SCREEN_SIZE/2); | ||
| 157 | + | ||
| 158 | + switch (LAYOUT_MODE) { | ||
| 159 | + case GRAPH_LAYOUT::RANDOM_LAYOUT: | ||
| 160 | + random_graph_layout(*graph, get(vertex_position, *graph), rect_top); | ||
| 161 | + break; | ||
| 162 | + | ||
| 163 | + case GRAPH_LAYOUT::CIRCLE_LAYOUT: | ||
| 164 | + circle_graph_layout(*graph, get(vertex_position, *graph), SCREEN_SIZE/2); | ||
| 165 | + break; | ||
| 166 | + | ||
| 167 | + case GRAPH_LAYOUT::FRUCHTERMAN_REINGOLD_LAYOUT: | ||
| 168 | + fruchterman_reingold_force_directed_layout(*graph, | ||
| 169 | + get(vertex_position, *graph), | ||
| 170 | + topology, | ||
| 171 | + attractive_force(square_distance_attractive_force()) | ||
| 172 | + .cooling(linear_cooling<double>(50)) | ||
| 173 | + ); | ||
| 174 | + break; | ||
| 175 | + } | ||
| 176 | + qDebug() << "* make graph layout end"; | ||
| 177 | + | ||
| 178 | + | ||
| 179 | + //add edges | ||
| 180 | + typedef square_topology<> Topology; | ||
| 181 | + typedef typename Topology::point_type Point; | ||
| 182 | + auto position = get(vertex_position, *graph); | ||
| 183 | + auto label = get(vertex_name, *graph); | ||
| 184 | + | ||
| 185 | + typedef boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor; | ||
| 186 | + typename graph_traits<Graph>::edge_iterator ei, ei_end; | ||
| 187 | + vertex_descriptor u, v; | ||
| 188 | + for (boost::tie(ei, ei_end)=boost::edges(*graph); ei!=ei_end; ++ei) { | ||
| 189 | + u = source(*ei, *graph); | ||
| 190 | + v = target(*ei, *graph); | ||
| 191 | + Point p1 = position[u]; | ||
| 192 | + Point p2 = position[v]; | ||
| 193 | + | ||
| 194 | + //make edge item and push it to list | ||
| 195 | + EdgeItem *edge; | ||
| 196 | + | ||
| 197 | + //if (label[u] == "conf/sbrn/GomesPSRC10" || | ||
| 198 | + // label[u] == "conf/iastedCSN/KeimS06" || | ||
| 199 | + // label[v] == "conf/sbrn/GomesPSRC10" || | ||
| 200 | + // label[v] == "conf/iastedCSN/KeimS06") { | ||
| 201 | + // //highlight | ||
| 202 | + // edge = new EdgeItem(p1[0], p1[1], p2[0], p2[1], QColor(Qt::blue), 3); | ||
| 203 | + //} else { | ||
| 204 | + // edge = new EdgeItem(p1[0], p1[1], p2[0], p2[1], QColor(Qt::black), 0); | ||
| 205 | + //} | ||
| 206 | + edge = new EdgeItem(p1[0], p1[1], p2[0], p2[1], QColor(Qt::black), 0); | ||
| 207 | + edge->setPos(p1[0], p1[1]); | ||
| 208 | + edgeList << edge; | ||
| 209 | + } | ||
| 210 | + | ||
| 211 | + //add nodes | ||
| 212 | + for (boost::tie(vi, vi_end)=vertices(*graph); vi!=vi_end; ++vi) { | ||
| 213 | + Point p = position[*vi]; | ||
| 214 | + std::string name = label[*vi]; | ||
| 215 | + | ||
| 216 | + //make node item and push it to list | ||
| 217 | + NodeItem *node; | ||
| 218 | + //if (name == "conf/sbrn/GomesPSRC10" || | ||
| 219 | + // name == "conf/iastedCSN/KeimS06") { | ||
| 220 | + // //highlight | ||
| 221 | + // node = new NodeItem(p[0], p[1], QColor(Qt::blue), QString(name.c_str())); | ||
| 222 | + //} else { | ||
| 223 | + // node = new NodeItem(p[0], p[1], QColor(Qt::green), QString(name.c_str())); | ||
| 224 | + //} | ||
| 225 | + node = new NodeItem(p[0], p[1], QColor(Qt::green), QString(name.c_str())); | ||
| 226 | + node->setPos(QPointF(p[0], p[1])); | ||
| 227 | + nodeList << node; | ||
| 228 | + } | ||
| 229 | +} | ||
| 230 | + | ||
| 231 | +//override | ||
| 232 | +QRectF GraphItem::boundingRect() const | ||
| 233 | +{ | ||
| 234 | + //TODO | ||
| 235 | + return QRectF(-SCREEN_SIZE/2, -SCREEN_SIZE/2, SCREEN_SIZE, SCREEN_SIZE); | ||
| 236 | +} | ||
| 237 | + | ||
| 238 | +QPainterPath GraphItem::shape() const | ||
| 239 | +{ | ||
| 240 | + QPainterPath path; | ||
| 241 | + return path; | ||
| 242 | +} | ||
| 243 | + | ||
| 244 | +void GraphItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) | ||
| 245 | +{ | ||
| 246 | + if (!graph) | ||
| 247 | + return; | ||
| 248 | + | ||
| 249 | + //debug | ||
| 250 | + //-> x, y, w, h | ||
| 251 | + //현재 Graph의 bounding rect 출력 | ||
| 252 | + /*QPen oldPen = painter->pen(); | ||
| 253 | + QPen pen = oldPen; | ||
| 254 | + pen.setColor(Qt::red); | ||
| 255 | + painter->setPen(pen); | ||
| 256 | + painter->drawRect(QRectF(-SCREEN_SIZE/2, -SCREEN_SIZE/2, SCREEN_SIZE, SCREEN_SIZE));*/ | ||
| 257 | + | ||
| 258 | + //print edges | ||
| 259 | + for (auto edge: edgeList) { | ||
| 260 | + edge->paint(painter, option, widget); | ||
| 261 | + } | ||
| 262 | + | ||
| 263 | + //print nodes | ||
| 264 | + for (auto node: nodeList) { | ||
| 265 | + node->paint(painter, option, widget); | ||
| 266 | + } | ||
| 267 | +} | ||
| 268 | + | ||
| 269 | +//event handler | ||
| 270 | +void GraphItem::mousePressEvent(QGraphicsSceneMouseEvent *event) | ||
| 271 | +{ | ||
| 272 | +} | ||
| 273 | + | ||
| 274 | +void GraphItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) | ||
| 275 | +{ | ||
| 276 | +} | ||
| 277 | + | ||
| 278 | +void GraphItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) | ||
| 279 | +{ | ||
| 280 | +} |
PaperGraph/GraphItem.h
0 → 100644
| 1 | +#ifndef GRAPHITEM_H | ||
| 2 | +#define GRAPHITEM_H | ||
| 3 | + | ||
| 4 | +#include <QGraphicsItem> | ||
| 5 | +#include <QList> | ||
| 6 | +#include <QColor> | ||
| 7 | + | ||
| 8 | +#include <boost/graph/adjacency_list.hpp> | ||
| 9 | +#include <boost/graph/topology.hpp> | ||
| 10 | +#include <boost/graph/graph_traits.hpp> | ||
| 11 | + | ||
| 12 | +#include <fstream> | ||
| 13 | + | ||
| 14 | +#include "NodeItem.h" | ||
| 15 | +#include "EdgeItem.h" | ||
| 16 | + | ||
| 17 | +using namespace std; | ||
| 18 | +using namespace boost; | ||
| 19 | + | ||
| 20 | + | ||
| 21 | +enum GRAPH_LAYOUT { | ||
| 22 | + RANDOM_LAYOUT, | ||
| 23 | + CIRCLE_LAYOUT, | ||
| 24 | + //KAMADA_KAWAI_LAYOUT, | ||
| 25 | + FRUCHTERMAN_REINGOLD_LAYOUT //slow | ||
| 26 | +}; | ||
| 27 | +/** | ||
| 28 | + * Constants | ||
| 29 | + */ | ||
| 30 | +const int LAYOUT_MODE = GRAPH_LAYOUT::RANDOM_LAYOUT; | ||
| 31 | +const int SCREEN_SIZE = 300; | ||
| 32 | +const int NODE_LIMIT = 100; | ||
| 33 | + | ||
| 34 | + | ||
| 35 | +enum vertex_position_t { vertex_position }; | ||
| 36 | +namespace boost { | ||
| 37 | + BOOST_INSTALL_PROPERTY(vertex, position); | ||
| 38 | +} | ||
| 39 | +typedef square_topology<>::point_type point; | ||
| 40 | +struct simple_edge { | ||
| 41 | + int first, second; | ||
| 42 | +}; | ||
| 43 | +typedef boost::property<vertex_index_t, int, | ||
| 44 | + boost::property<vertex_name_t, std::string, | ||
| 45 | + boost::property<vertex_position_t, point>> | ||
| 46 | +> VertexProperties; | ||
| 47 | +typedef adjacency_list< | ||
| 48 | + listS, //outEdgeList | ||
| 49 | + listS, //VertexList | ||
| 50 | + undirectedS, | ||
| 51 | + //vertex properties | ||
| 52 | + VertexProperties, | ||
| 53 | + //edge properties | ||
| 54 | + boost::property<edge_weight_t, double> | ||
| 55 | +> Graph; | ||
| 56 | + | ||
| 57 | + | ||
| 58 | +class GraphItem | ||
| 59 | + : public QGraphicsItem | ||
| 60 | +{ | ||
| 61 | +public: | ||
| 62 | + GraphItem(ifstream& fin); | ||
| 63 | + | ||
| 64 | + //overrides | ||
| 65 | + QRectF boundingRect() const override; | ||
| 66 | + QPainterPath shape() const override; | ||
| 67 | + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; | ||
| 68 | + | ||
| 69 | + //methods | ||
| 70 | + void path_highlighting(std::string start, std::string end); | ||
| 71 | + // | ||
| 72 | + | ||
| 73 | +protected: | ||
| 74 | + void mousePressEvent(QGraphicsSceneMouseEvent *event) override; | ||
| 75 | + void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override; | ||
| 76 | + void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; | ||
| 77 | + | ||
| 78 | +private: | ||
| 79 | + Graph *graph = nullptr; | ||
| 80 | + QList<NodeItem *> nodeList; | ||
| 81 | + QList<EdgeItem *> edgeList; | ||
| 82 | +}; | ||
| 83 | + | ||
| 84 | +#endif // GRAPHITEM_H |
| 1 | #include "GraphicsView.h" | 1 | #include "GraphicsView.h" |
| 2 | #include <qmath.h> | 2 | #include <qmath.h> |
| 3 | +#include <QKeyEvent> | ||
| 3 | 4 | ||
| 4 | //View | 5 | //View |
| 5 | View::View(const QString& name, QWidget *parent) | 6 | View::View(const QString& name, QWidget *parent) |
| ... | @@ -12,8 +13,6 @@ View::View(const QString& name, QWidget *parent) | ... | @@ -12,8 +13,6 @@ View::View(const QString& name, QWidget *parent) |
| 12 | graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); | 13 | graphicsView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); |
| 13 | graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); | 14 | graphicsView->setTransformationAnchor(QGraphicsView::AnchorUnderMouse); |
| 14 | 15 | ||
| 15 | - //connect | ||
| 16 | - | ||
| 17 | //layout | 16 | //layout |
| 18 | QGridLayout *topLayout = new QGridLayout; | 17 | QGridLayout *topLayout = new QGridLayout; |
| 19 | topLayout->addWidget(graphicsView, 0, 0); | 18 | topLayout->addWidget(graphicsView, 0, 0); |
| ... | @@ -29,11 +28,27 @@ QGraphicsView* View::view() const | ... | @@ -29,11 +28,27 @@ QGraphicsView* View::view() const |
| 29 | 28 | ||
| 30 | void View::setupMatrix() | 29 | void View::setupMatrix() |
| 31 | { | 30 | { |
| 32 | - qreal scale = qPow(qreal(2), qreal(2)); | 31 | + qreal scale = qPow(qreal(1), qreal(1)); |
| 33 | 32 | ||
| 34 | QMatrix matrix; | 33 | QMatrix matrix; |
| 35 | matrix.scale(scale, scale); | 34 | matrix.scale(scale, scale); |
| 36 | matrix.rotate(qreal(0)); | 35 | matrix.rotate(qreal(0)); |
| 37 | 36 | ||
| 38 | graphicsView->setMatrix(matrix); | 37 | graphicsView->setMatrix(matrix); |
| 39 | -} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| 38 | +} | ||
| 39 | + | ||
| 40 | +#ifndef QT_NO_WHEELEVENT | ||
| 41 | +void GraphicsView::wheelEvent(QWheelEvent * event) | ||
| 42 | +{ | ||
| 43 | + scaleView(pow((double)2, event->delta() / 240.0)); | ||
| 44 | +} | ||
| 45 | +#endif | ||
| 46 | + | ||
| 47 | +void GraphicsView::scaleView(qreal scaleFactor) | ||
| 48 | +{ | ||
| 49 | + qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); | ||
| 50 | + if (factor < 0.07 || factor > 100) | ||
| 51 | + return; | ||
| 52 | + | ||
| 53 | + scale(scaleFactor, scaleFactor); | ||
| 54 | +} | ... | ... |
| ... | @@ -16,6 +16,12 @@ class GraphicsView | ... | @@ -16,6 +16,12 @@ class GraphicsView |
| 16 | private: | 16 | private: |
| 17 | View* view; | 17 | View* view; |
| 18 | 18 | ||
| 19 | +protected: | ||
| 20 | +#ifndef QT_NO_WHEELEVENT | ||
| 21 | + void wheelEvent(QWheelEvent *event) override; | ||
| 22 | +#endif | ||
| 23 | + void scaleView(qreal scaleFactor); | ||
| 24 | + | ||
| 19 | public: | 25 | public: |
| 20 | GraphicsView(View *v): QGraphicsView(), view(v) {}; | 26 | GraphicsView(View *v): QGraphicsView(), view(v) {}; |
| 21 | }; | 27 | }; | ... | ... |
| 1 | #include "NodeItem.h" | 1 | #include "NodeItem.h" |
| 2 | #include <QtWidgets> | 2 | #include <QtWidgets> |
| 3 | +#include <QMessageBox> | ||
| 3 | 4 | ||
| 4 | void NodeItem::mousePressEvent(QGraphicsSceneMouseEvent * event) | 5 | void NodeItem::mousePressEvent(QGraphicsSceneMouseEvent * event) |
| 5 | { | 6 | { |
| 7 | + /*if (event->button() == Qt::LeftButton) { | ||
| 8 | + QMessageBox msgbox; | ||
| 9 | + msgbox.setText("hi"); | ||
| 10 | + msgbox.setInformativeText("hi2"); | ||
| 11 | + msgbox.setStandardButtons(QMessageBox::Ok); | ||
| 12 | + msgbox.setDefaultButton(QMessageBox::Ok); | ||
| 13 | + | ||
| 14 | + msgbox.exec(); | ||
| 15 | + }*/ | ||
| 6 | } | 16 | } |
| 7 | 17 | ||
| 8 | void NodeItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) | 18 | void NodeItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event) |
| ... | @@ -13,16 +23,17 @@ void NodeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) | ... | @@ -13,16 +23,17 @@ void NodeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event) |
| 13 | { | 23 | { |
| 14 | } | 24 | } |
| 15 | 25 | ||
| 16 | -NodeItem::NodeItem(int x, int y, QString label) | 26 | +NodeItem::NodeItem(double x, double y, QColor color, QString label) |
| 17 | { | 27 | { |
| 28 | + //node constructor | ||
| 18 | this->x = x; | 29 | this->x = x; |
| 19 | this->y = y; | 30 | this->y = y; |
| 20 | - this->color = QColor(Qt::green); | 31 | + this->color = color; |
| 21 | this->label = label; | 32 | this->label = label; |
| 22 | setZValue(1); | 33 | setZValue(1); |
| 23 | 34 | ||
| 24 | - setFlags(ItemIsSelectable | ItemIsMovable); | 35 | + //setFlags(ItemIsSelectable | ItemIsMovable); |
| 25 | - setAcceptHoverEvents(true); | 36 | + //setAcceptHoverEvents(true); |
| 26 | } | 37 | } |
| 27 | 38 | ||
| 28 | QRectF NodeItem::boundingRect() const | 39 | QRectF NodeItem::boundingRect() const |
| ... | @@ -33,7 +44,6 @@ QRectF NodeItem::boundingRect() const | ... | @@ -33,7 +44,6 @@ QRectF NodeItem::boundingRect() const |
| 33 | QPainterPath NodeItem::shape() const | 44 | QPainterPath NodeItem::shape() const |
| 34 | { | 45 | { |
| 35 | QPainterPath path; | 46 | QPainterPath path; |
| 36 | - //path.addRect(14, 14, 82, 42); | ||
| 37 | path.addRect(0, 0, NODE_SIZE, NODE_SIZE); | 47 | path.addRect(0, 0, NODE_SIZE, NODE_SIZE); |
| 38 | return path; | 48 | return path; |
| 39 | } | 49 | } |
| ... | @@ -42,23 +52,24 @@ void NodeItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option | ... | @@ -42,23 +52,24 @@ void NodeItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option |
| 42 | { | 52 | { |
| 43 | Q_UNUSED(widget); | 53 | Q_UNUSED(widget); |
| 44 | 54 | ||
| 55 | + //set node pen style | ||
| 56 | + QPen oldPen = painter->pen(); | ||
| 57 | + QPen pen = oldPen; | ||
| 58 | + pen.setWidth(0); | ||
| 59 | + pen.setColor(QColor(Qt::black)); | ||
| 60 | + painter->setPen(pen); | ||
| 61 | + | ||
| 45 | //label | 62 | //label |
| 46 | - QFont font("Gulim", 10); | 63 | + QFont font("Gulim", 3); //set font, font size |
| 47 | - font.setStyleStrategy(QFont::ForceOutline); | ||
| 48 | painter->setFont(font); | 64 | painter->setFont(font); |
| 49 | painter->save(); | 65 | painter->save(); |
| 50 | - painter->scale(0.3, 0.3); | 66 | + painter->drawText(x, y, label); |
| 51 | - painter->drawText(0, 0, label); | ||
| 52 | painter->restore(); | 67 | painter->restore(); |
| 53 | 68 | ||
| 54 | 69 | ||
| 55 | - //Rectangle | 70 | + //node rectangle |
| 56 | QColor fillColor = (option->state & QStyle::State_Selected) ? color.dark(150) : color; | 71 | QColor fillColor = (option->state & QStyle::State_Selected) ? color.dark(150) : color; |
| 57 | if (option->state & QStyle::State_MouseOver) fillColor = fillColor.light(125); | 72 | if (option->state & QStyle::State_MouseOver) fillColor = fillColor.light(125); |
| 58 | - QPen pen = painter->pen(); | ||
| 59 | - pen.setWidth(0); | ||
| 60 | - pen.setColor(QColor(Qt::black)); | ||
| 61 | - painter->setPen(pen); | ||
| 62 | painter->setBrush(QBrush(fillColor)); | 73 | painter->setBrush(QBrush(fillColor)); |
| 63 | - painter->drawRect(0, 0, NODE_SIZE, NODE_SIZE); | 74 | + painter->drawRect(x, y, NODE_SIZE, NODE_SIZE); |
| 64 | } | 75 | } | ... | ... |
| ... | @@ -11,8 +11,8 @@ class NodeItem | ... | @@ -11,8 +11,8 @@ class NodeItem |
| 11 | : public QGraphicsItem | 11 | : public QGraphicsItem |
| 12 | { | 12 | { |
| 13 | private: | 13 | private: |
| 14 | - int x; | 14 | + double x; |
| 15 | - int y; | 15 | + double y; |
| 16 | QColor color; | 16 | QColor color; |
| 17 | QString label; | 17 | QString label; |
| 18 | 18 | ||
| ... | @@ -22,7 +22,7 @@ protected: | ... | @@ -22,7 +22,7 @@ protected: |
| 22 | void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; | 22 | void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; |
| 23 | 23 | ||
| 24 | public: | 24 | public: |
| 25 | - NodeItem(int x, int y, QString label); | 25 | + NodeItem(double x, double y, QColor color, QString label); |
| 26 | 26 | ||
| 27 | QRectF boundingRect() const override; | 27 | QRectF boundingRect() const override; |
| 28 | QPainterPath shape() const override; | 28 | QPainterPath shape() const override; | ... | ... |
| ... | @@ -145,6 +145,7 @@ | ... | @@ -145,6 +145,7 @@ |
| 145 | </Link> | 145 | </Link> |
| 146 | </ItemDefinitionGroup> | 146 | </ItemDefinitionGroup> |
| 147 | <ItemGroup> | 147 | <ItemGroup> |
| 148 | + <ClCompile Include="EdgeItem.cpp" /> | ||
| 148 | <ClCompile Include="GeneratedFiles\Debug\moc_GraphicsView.cpp"> | 149 | <ClCompile Include="GeneratedFiles\Debug\moc_GraphicsView.cpp"> |
| 149 | <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> | 150 | <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> |
| 150 | <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> | 151 | <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> |
| ... | @@ -172,6 +173,7 @@ | ... | @@ -172,6 +173,7 @@ |
| 172 | <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> | 173 | <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> |
| 173 | </ClCompile> | 174 | </ClCompile> |
| 174 | <ClCompile Include="GraphicsView.cpp" /> | 175 | <ClCompile Include="GraphicsView.cpp" /> |
| 176 | + <ClCompile Include="GraphItem.cpp" /> | ||
| 175 | <ClCompile Include="main.cpp" /> | 177 | <ClCompile Include="main.cpp" /> |
| 176 | <ClCompile Include="NodeItem.cpp" /> | 178 | <ClCompile Include="NodeItem.cpp" /> |
| 177 | <ClCompile Include="PaperGraphWidget.cpp" /> | 179 | <ClCompile Include="PaperGraphWidget.cpp" /> |
| ... | @@ -217,6 +219,7 @@ | ... | @@ -217,6 +219,7 @@ |
| 217 | </CustomBuild> | 219 | </CustomBuild> |
| 218 | </ItemGroup> | 220 | </ItemGroup> |
| 219 | <ItemGroup> | 221 | <ItemGroup> |
| 222 | + <ClInclude Include="EdgeItem.h" /> | ||
| 220 | <ClInclude Include="GeneratedFiles\ui_PaperGraphWidget.h" /> | 223 | <ClInclude Include="GeneratedFiles\ui_PaperGraphWidget.h" /> |
| 221 | <CustomBuild Include="GraphicsView.h"> | 224 | <CustomBuild Include="GraphicsView.h"> |
| 222 | <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs> | 225 | <AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs> |
| ... | @@ -236,6 +239,7 @@ | ... | @@ -236,6 +239,7 @@ |
| 236 | <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs> | 239 | <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs> |
| 237 | <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"</Command> | 240 | <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DUNICODE -DWIN32 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB "-I.\GeneratedFiles" "-I." "-I$(QTDIR)\include" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include\QtCore" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtWidgets"</Command> |
| 238 | </CustomBuild> | 241 | </CustomBuild> |
| 242 | + <ClInclude Include="GraphItem.h" /> | ||
| 239 | <ClInclude Include="NodeItem.h" /> | 243 | <ClInclude Include="NodeItem.h" /> |
| 240 | </ItemGroup> | 244 | </ItemGroup> |
| 241 | <ItemGroup> | 245 | <ItemGroup> | ... | ... |
| ... | @@ -62,6 +62,12 @@ | ... | @@ -62,6 +62,12 @@ |
| 62 | <ClCompile Include="GeneratedFiles\Release\moc_GraphicsView.cpp"> | 62 | <ClCompile Include="GeneratedFiles\Release\moc_GraphicsView.cpp"> |
| 63 | <Filter>Generated Files\Release</Filter> | 63 | <Filter>Generated Files\Release</Filter> |
| 64 | </ClCompile> | 64 | </ClCompile> |
| 65 | + <ClCompile Include="GraphItem.cpp"> | ||
| 66 | + <Filter>Source Files</Filter> | ||
| 67 | + </ClCompile> | ||
| 68 | + <ClCompile Include="EdgeItem.cpp"> | ||
| 69 | + <Filter>Source Files</Filter> | ||
| 70 | + </ClCompile> | ||
| 65 | </ItemGroup> | 71 | </ItemGroup> |
| 66 | <ItemGroup> | 72 | <ItemGroup> |
| 67 | <CustomBuild Include="PaperGraphWidget.h"> | 73 | <CustomBuild Include="PaperGraphWidget.h"> |
| ... | @@ -84,5 +90,11 @@ | ... | @@ -84,5 +90,11 @@ |
| 84 | <ClInclude Include="NodeItem.h"> | 90 | <ClInclude Include="NodeItem.h"> |
| 85 | <Filter>Header Files</Filter> | 91 | <Filter>Header Files</Filter> |
| 86 | </ClInclude> | 92 | </ClInclude> |
| 93 | + <ClInclude Include="GraphItem.h"> | ||
| 94 | + <Filter>Header Files</Filter> | ||
| 95 | + </ClInclude> | ||
| 96 | + <ClInclude Include="EdgeItem.h"> | ||
| 97 | + <Filter>Header Files</Filter> | ||
| 98 | + </ClInclude> | ||
| 87 | </ItemGroup> | 99 | </ItemGroup> |
| 88 | </Project> | 100 | </Project> |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -3,6 +3,9 @@ | ... | @@ -3,6 +3,9 @@ |
| 3 | #include "GraphicsView.h" | 3 | #include "GraphicsView.h" |
| 4 | 4 | ||
| 5 | #include <string> | 5 | #include <string> |
| 6 | +#include <QComboBox> | ||
| 7 | +#include <QMessageBox> | ||
| 8 | +#include <QtGui> | ||
| 6 | 9 | ||
| 7 | PaperGraphWidget::PaperGraphWidget(QWidget *parent) | 10 | PaperGraphWidget::PaperGraphWidget(QWidget *parent) |
| 8 | : QWidget(parent) | 11 | : QWidget(parent) |
| ... | @@ -12,77 +15,40 @@ PaperGraphWidget::PaperGraphWidget(QWidget *parent) | ... | @@ -12,77 +15,40 @@ PaperGraphWidget::PaperGraphWidget(QWidget *parent) |
| 12 | 15 | ||
| 13 | View *view = new View("temp view"); | 16 | View *view = new View("temp view"); |
| 14 | view->view()->setScene(scene); | 17 | view->view()->setScene(scene); |
| 15 | - QHBoxLayout *layout = new QHBoxLayout; | 18 | + |
| 19 | + QVBoxLayout *layout = new QVBoxLayout; | ||
| 20 | + QComboBox *combo = new QComboBox; | ||
| 21 | + combo->addItem("conf/iastedCSN/KeimS06"); | ||
| 22 | + combo->addItem("conf/iastedCSN/Mojumdar06"); | ||
| 23 | + combo->addItem("conf/iastedCSN/PourKKI06"); | ||
| 24 | + connect(combo, SIGNAL(currentIndexChanged(int)), | ||
| 25 | + this, SLOT(handleSelectionChanged(int))); | ||
| 26 | + | ||
| 27 | + layout->addWidget(combo); | ||
| 16 | layout->addWidget(view); | 28 | layout->addWidget(view); |
| 17 | setLayout(layout); | 29 | setLayout(layout); |
| 18 | 30 | ||
| 19 | setWindowTitle(tr("dblp paper graph visualization")); | 31 | setWindowTitle(tr("dblp paper graph visualization")); |
| 20 | } | 32 | } |
| 21 | 33 | ||
| 22 | -void PaperGraphWidget::print_graph(const Graph & graph) | 34 | +void PaperGraphWidget::print_graph(ifstream& fin) |
| 23 | { | 35 | { |
| 24 | - //print graph | 36 | + QGraphicsItem *graph_item = new GraphItem(fin); |
| 25 | - typedef square_topology<> Topology; | 37 | + graph_item->setPos(0, 0); |
| 26 | - typedef typename Topology::point_type Point; | 38 | + scene->addItem(graph_item); |
| 27 | - const int rect_sz = 4; | 39 | +} |
| 28 | - auto position = get(vertex_position, graph); | ||
| 29 | - auto label = get(vertex_name, graph); | ||
| 30 | - | ||
| 31 | - | ||
| 32 | - | ||
| 33 | - //print edges | ||
| 34 | - typename graph_traits<Graph>::edge_iterator ei, ei_end; | ||
| 35 | - typedef boost::graph_traits<Graph>::vertex_descriptor VertexDescriptor; | ||
| 36 | - VertexDescriptor u, v; | ||
| 37 | - for (boost::tie(ei, ei_end)=edges(graph); ei!=ei_end; ++ei) { | ||
| 38 | - u = source(*ei, graph); | ||
| 39 | - v = target(*ei, graph); | ||
| 40 | - | ||
| 41 | - Point p1 = position[u]; | ||
| 42 | - Point p2 = position[v]; | ||
| 43 | - | ||
| 44 | - /*line = scene->addLine( | ||
| 45 | - p1[0], p1[1], | ||
| 46 | - p2[0], p2[1], | ||
| 47 | - QPen(Qt::black) | ||
| 48 | - );*/ | ||
| 49 | - //QGraphicsItem *edge = | ||
| 50 | - // new EdgeItem(p1[0], p1[1], p2[0], p2[1]); | ||
| 51 | - //edge->setPos(QPointF(p1[0], p1[1])); | ||
| 52 | - //scene->addItem(edge); | ||
| 53 | - | ||
| 54 | - scene->addLine(p1[0], p1[1], p2[0], p2[1], QPen(Qt::black, 0)); | ||
| 55 | - } | ||
| 56 | 40 | ||
| 57 | - //print nodes | 41 | +void PaperGraphWidget::handleSelectionChanged(int idx) |
| 58 | - typename graph_traits<Graph>::vertex_iterator vi, vi_end; | 42 | +{ |
| 59 | - for (boost::tie(vi, vi_end)=vertices(graph); vi!=vi_end; ++vi) { | 43 | + /*QMessageBox::information(this, "QCombobox", |
| 60 | - //Point p = position[*vi]; | 44 | + "idx: "+QString::number(idx));*/ |
| 61 | - //rectangle = scene->addRect( | 45 | + if (idx==0) { |
| 62 | - // p[0], p[1], rect_sz, rect_sz, | 46 | + } else if (idx==1) { |
| 63 | - // QPen(Qt::black), | 47 | + } else { |
| 64 | - // QBrush(Qt::green)); | ||
| 65 | - Point p = position[*vi]; | ||
| 66 | - std::string name = label[*vi]; | ||
| 67 | - QGraphicsItem *node = new NodeItem(p[0], p[1], QString(name.c_str())); | ||
| 68 | - node->setPos(QPointF(p[0], p[1])); | ||
| 69 | - scene->addItem(node); | ||
| 70 | } | 48 | } |
| 71 | } | 49 | } |
| 72 | 50 | ||
| 73 | void PaperGraphWidget::initscene() | 51 | void PaperGraphWidget::initscene() |
| 74 | { | 52 | { |
| 75 | scene = new QGraphicsScene(this); | 53 | scene = new QGraphicsScene(this); |
| 76 | - | ||
| 77 | - //int x = 0, y; | ||
| 78 | - //for (int i=-11000; i<11000; i+=110) { | ||
| 79 | - // ++x; | ||
| 80 | - // y = 0; | ||
| 81 | - // for (int j=-7000; j<7000; j+=70) { | ||
| 82 | - // ++y; | ||
| 83 | - // QGraphicsItem *item = new NodeItem(x, y); | ||
| 84 | - // item->setPos(QPointF(i, j)); | ||
| 85 | - // scene->addItem(item); | ||
| 86 | - // } | ||
| 87 | - //} | ||
| 88 | } | 54 | } | ... | ... |
| ... | @@ -4,46 +4,22 @@ | ... | @@ -4,46 +4,22 @@ |
| 4 | #include <QtWidgets/QWidget> | 4 | #include <QtWidgets/QWidget> |
| 5 | #include <QGraphicsScene> | 5 | #include <QGraphicsScene> |
| 6 | 6 | ||
| 7 | -#include <boost/graph/adjacency_list.hpp> | 7 | +#include <fstream> |
| 8 | -#include <boost/graph/topology.hpp> | ||
| 9 | -#include <boost/graph/graph_traits.hpp> | ||
| 10 | 8 | ||
| 9 | +#include "GraphItem.h" | ||
| 11 | #include "ui_PaperGraphWidget.h" | 10 | #include "ui_PaperGraphWidget.h" |
| 12 | 11 | ||
| 13 | 12 | ||
| 14 | -using namespace boost; | ||
| 15 | - | ||
| 16 | - | ||
| 17 | -enum vertex_position_t { vertex_position }; | ||
| 18 | -namespace boost { | ||
| 19 | - BOOST_INSTALL_PROPERTY(vertex, position); | ||
| 20 | -} | ||
| 21 | -typedef square_topology<>::point_type point; | ||
| 22 | -struct simple_edge { | ||
| 23 | - int first, second; | ||
| 24 | -}; | ||
| 25 | -typedef boost::property<vertex_index_t, int, | ||
| 26 | - boost::property<vertex_name_t, std::string, | ||
| 27 | - boost::property<vertex_position_t, point>> | ||
| 28 | -> VertexProperties; | ||
| 29 | -typedef adjacency_list< | ||
| 30 | - listS, //outEdgeList | ||
| 31 | - listS, //VertexList | ||
| 32 | - undirectedS, | ||
| 33 | - //vertex properties | ||
| 34 | - VertexProperties, | ||
| 35 | - //edge properties | ||
| 36 | - boost::property<edge_weight_t, double> | ||
| 37 | -> Graph; | ||
| 38 | - | ||
| 39 | - | ||
| 40 | class PaperGraphWidget : public QWidget | 13 | class PaperGraphWidget : public QWidget |
| 41 | { | 14 | { |
| 42 | Q_OBJECT | 15 | Q_OBJECT |
| 43 | 16 | ||
| 44 | public: | 17 | public: |
| 45 | PaperGraphWidget(QWidget *parent = 0); | 18 | PaperGraphWidget(QWidget *parent = 0); |
| 46 | - void print_graph(const Graph& graph); | 19 | + void print_graph(ifstream& fin); |
| 20 | + | ||
| 21 | +private slots: | ||
| 22 | + void handleSelectionChanged(int idx); | ||
| 47 | 23 | ||
| 48 | private: | 24 | private: |
| 49 | void initscene(); | 25 | void initscene(); | ... | ... |
| ... | @@ -14,7 +14,6 @@ | ... | @@ -14,7 +14,6 @@ |
| 14 | //#include <boost/graph/kamada_kawai_spring_layout.hpp> | 14 | //#include <boost/graph/kamada_kawai_spring_layout.hpp> |
| 15 | #include <boost/graph/random_layout.hpp> | 15 | #include <boost/graph/random_layout.hpp> |
| 16 | #include <boost/graph/circle_layout.hpp> | 16 | #include <boost/graph/circle_layout.hpp> |
| 17 | -#include <boost/graph/dijkstra_shortest_paths.hpp> | ||
| 18 | #include <boost/algorithm/string.hpp> //boost::split | 17 | #include <boost/algorithm/string.hpp> //boost::split |
| 19 | #include <boost/bimap.hpp> | 18 | #include <boost/bimap.hpp> |
| 20 | 19 | ||
| ... | @@ -24,187 +23,22 @@ using namespace std; | ... | @@ -24,187 +23,22 @@ using namespace std; |
| 24 | * Constants | 23 | * Constants |
| 25 | */ | 24 | */ |
| 26 | const char* PAPER_FILENAME = "dblp-paper.txt"; | 25 | const char* PAPER_FILENAME = "dblp-paper.txt"; |
| 27 | -enum GRAPH_LAYOUT { | ||
| 28 | - RANDOM_LAYOUT, | ||
| 29 | - CIRCLE_LAYOUT, | ||
| 30 | - //KAMADA_KAWAI_LAYOUT, | ||
| 31 | - FRUCHTERMAN_REINGOLD_LAYOUT //slow | ||
| 32 | -}; | ||
| 33 | -const int LAYOUT_MODE = GRAPH_LAYOUT::RANDOM_LAYOUT; | ||
| 34 | -const int SCREEN_SIZE = 500; | ||
| 35 | -const int NODE_LIMIT = 100; | ||
| 36 | - | ||
| 37 | -Graph read_graph(ifstream& in) throw(std::exception) { | ||
| 38 | - /** | ||
| 39 | - * Parse Paper dataset | ||
| 40 | - * - paper_key, [author_list], publish_year | ||
| 41 | - * Column Delimiter: || | ||
| 42 | - * Author list Delimiter: && | ||
| 43 | - */ | ||
| 44 | - std::string line; | ||
| 45 | - vector<std::string> tokens; | ||
| 46 | - vector<std::string> authors; | ||
| 47 | - vector<pair<string, string>> edges; | ||
| 48 | - | ||
| 49 | - //String <--> int 양방향 변환을 위해 bidirectional map 상숑 | ||
| 50 | - //map<string, int> -> <vertex label, vertex index> | ||
| 51 | - typedef boost::bimap<string, int> bm_type; | ||
| 52 | - bm_type node_ids; | ||
| 53 | - vector<simple_edge> edges_indexes; //int로 변환된 edge | ||
| 54 | - | ||
| 55 | - int node_cnt = 0; | ||
| 56 | - qDebug() << "* graph reading start"; | ||
| 57 | - | ||
| 58 | - //한 줄씩 읽어서 Parse | ||
| 59 | - while (std::getline(in, line) && !line.empty()) { | ||
| 60 | - //boost::split 이용해 문자열 분리 | ||
| 61 | - //tokens[0]: Paper-key. ex) conf/iastedCSN/KeimS06 | ||
| 62 | - //tokens[1]: Authors. ex) Werner Keim&&Arpad L. Scholtz | ||
| 63 | - //tokens[2]: Published year. | ||
| 64 | - boost::split(tokens, line, boost::is_any_of("||"), boost::token_compress_on); | ||
| 65 | - boost::split(authors, tokens[1], boost::is_any_of("&&"), boost::token_compress_on); | ||
| 66 | - | ||
| 67 | - const string& paper_key = tokens[0]; | ||
| 68 | - if (node_ids.left.find(paper_key) == node_ids.left.end()) { | ||
| 69 | - node_ids.insert(bm_type::value_type(paper_key, node_cnt++)); | ||
| 70 | - } | ||
| 71 | - | ||
| 72 | - for (auto author : authors) { | ||
| 73 | - edges.push_back(pair<string, string>(paper_key, author)); | ||
| 74 | - if (node_ids.left.find(author) == node_ids.left.end()) { | ||
| 75 | - node_ids.insert(bm_type::value_type(author, node_cnt++)); | ||
| 76 | - } | ||
| 77 | - } | ||
| 78 | - | ||
| 79 | - //debug | ||
| 80 | - if (node_cnt > NODE_LIMIT) break; | ||
| 81 | - } | ||
| 82 | - qDebug() << "* graph reading complete"; | ||
| 83 | - qDebug() << "* # of nodes: " << node_cnt; | ||
| 84 | - qDebug() << "* # of edges: " << edges.size(); | ||
| 85 | - | ||
| 86 | - //edge conversion | ||
| 87 | - //<string, string> to <int, int> | ||
| 88 | - //using boost::bimap (bidirectional map) | ||
| 89 | - for (auto edge : edges) { | ||
| 90 | - edges_indexes.push_back({ | ||
| 91 | - node_ids.left.find(edge.first)->get_right(), | ||
| 92 | - node_ids.left.find(edge.second)->get_right() | ||
| 93 | - }); | ||
| 94 | - } | ||
| 95 | - //Graph --> defined in "PaperGraphWidget.h" | ||
| 96 | - Graph graph(edges_indexes.begin(), edges_indexes.end(), node_ids.size()); | ||
| 97 | - | ||
| 98 | - //set index property | ||
| 99 | - qDebug() << "* set vertex property start"; | ||
| 100 | - typedef typename graph_traits<Graph>::edge_iterator edge_iterator; | ||
| 101 | - typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator; | ||
| 102 | - vertex_iterator vi, vi_end; | ||
| 103 | - int i = 0; | ||
| 104 | - for (boost::tie(vi, vi_end)=vertices(graph); vi!=vi_end; ++vi) { | ||
| 105 | - //Vertex Property 설정 | ||
| 106 | - //index: 0 ~ ... | ||
| 107 | - //name : map의 value(i) 기준으로 찾은 Key | ||
| 108 | - // map --> map<string, int> (boost bidirectional map) | ||
| 109 | - boost::put(vertex_index, graph, *vi, i); | ||
| 110 | - boost::put(vertex_name, graph, *vi, | ||
| 111 | - node_ids.right.find(i)->get_left()); | ||
| 112 | - | ||
| 113 | - ++i; | ||
| 114 | - } | ||
| 115 | - qDebug() << "* set vertex property end"; | ||
| 116 | - | ||
| 117 | - | ||
| 118 | - //모든 edge weight 1로 만들기 | ||
| 119 | - //edge_iterator ei, ei_end; | ||
| 120 | - //for (boost::tie(ei, ei_end)=boost::edges(graph); ei!=ei_end; ++ei) { | ||
| 121 | - // boost::put(edge_weight, graph, *ei, 1); | ||
| 122 | - //} | ||
| 123 | - ////path finding between two vertices | ||
| 124 | - ////using dijkstra algorithm | ||
| 125 | - ////ex) "Werner Keim" ---> "Arpad L. Scholtz" (in dataset 2nd line) | ||
| 126 | - //qDebug() << "* path finding start"; | ||
| 127 | - //typedef graph_traits<Graph>::vertex_descriptor vertex_descriptor; | ||
| 128 | - //std::vector<vertex_descriptor> parent(num_vertices(graph)); | ||
| 129 | - //std::vector<int> distance(num_vertices(graph)); | ||
| 130 | - //int start_idx = node_ids.left.find("Werner Keim")->get_right(); | ||
| 131 | - //vertex_descriptor start_v = vertex(start_idx, graph); | ||
| 132 | - //dijkstra_shortest_paths( | ||
| 133 | - // graph, | ||
| 134 | - // start_v, | ||
| 135 | - // predecessor_map( | ||
| 136 | - // boost::make_iterator_property_map(parent.begin(), get(boost::vertex_index, graph)) | ||
| 137 | - // ).distance_map(boost::make_iterator_property_map(distance.begin(), get(boost::vertex_index, graph))) | ||
| 138 | - //); | ||
| 139 | - //qDebug() << "* path finding end"; | ||
| 140 | - | ||
| 141 | - | ||
| 142 | - //graph layout calculation | ||
| 143 | - //using boost::random_graph_layout and boost::kamada_kawai_spring_layout | ||
| 144 | - //vertex마다 계산된 좌표를 property에 적용 | ||
| 145 | - //예제 코드: http://www.boost.org/doc/libs/1_63_0/libs/graph/test/layout_test.cpp | ||
| 146 | - //(-> 콘솔 기반) | ||
| 147 | - qDebug() << "* make graph layout start"; | ||
| 148 | - typedef square_topology<> Topology; | ||
| 149 | - minstd_rand gen; | ||
| 150 | - Topology topology(gen, (double)SCREEN_SIZE); | ||
| 151 | - Topology::point_type origin; | ||
| 152 | - origin[0] = origin[1] = (double)SCREEN_SIZE; | ||
| 153 | - Topology::point_difference_type extent; | ||
| 154 | - extent[0] = extent[1] = (double)SCREEN_SIZE; | ||
| 155 | - rectangle_topology<> rect_top(gen, | ||
| 156 | - -SCREEN_SIZE/2, -SCREEN_SIZE/2, | ||
| 157 | - SCREEN_SIZE/2, SCREEN_SIZE/2); | ||
| 158 | - | ||
| 159 | - switch (LAYOUT_MODE) { | ||
| 160 | - case GRAPH_LAYOUT::RANDOM_LAYOUT: | ||
| 161 | - random_graph_layout(graph, get(vertex_position, graph), rect_top); | ||
| 162 | - break; | ||
| 163 | - | ||
| 164 | - case GRAPH_LAYOUT::CIRCLE_LAYOUT: | ||
| 165 | - circle_graph_layout(graph, get(vertex_position, graph), SCREEN_SIZE/2); | ||
| 166 | - break; | ||
| 167 | - | ||
| 168 | - //case GRAPH_LAYOUT::KAMADA_KAWAI_LAYOUT: | ||
| 169 | - // kamada_kawai_spring_layout(graph, | ||
| 170 | - // get(vertex_position, graph), | ||
| 171 | - // get(edge_weight, graph), | ||
| 172 | - // topology, | ||
| 173 | - // side_length((double)SCREEN_SIZE) | ||
| 174 | - // ); | ||
| 175 | - // break; | ||
| 176 | - | ||
| 177 | - case GRAPH_LAYOUT::FRUCHTERMAN_REINGOLD_LAYOUT: | ||
| 178 | - fruchterman_reingold_force_directed_layout(graph, | ||
| 179 | - get(vertex_position, graph), | ||
| 180 | - topology, | ||
| 181 | - attractive_force(square_distance_attractive_force()) | ||
| 182 | - .cooling(linear_cooling<double>(50)) | ||
| 183 | - ); | ||
| 184 | - break; | ||
| 185 | - } | ||
| 186 | - qDebug() << "* make graph layout end"; | ||
| 187 | - | ||
| 188 | - return graph; | ||
| 189 | -} | ||
| 190 | 26 | ||
| 191 | int main(int argc, char *argv[]) | 27 | int main(int argc, char *argv[]) |
| 192 | { | 28 | { |
| 193 | QApplication app(argc, argv); | 29 | QApplication app(argc, argv); |
| 194 | - //app.setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); | ||
| 195 | 30 | ||
| 196 | PaperGraphWidget w; | 31 | PaperGraphWidget w; |
| 197 | 32 | ||
| 198 | try { | 33 | try { |
| 199 | ifstream fin(PAPER_FILENAME); | 34 | ifstream fin(PAPER_FILENAME); |
| 200 | - w.print_graph(read_graph(fin)); | 35 | + w.print_graph(fin); |
| 201 | fin.close(); | 36 | fin.close(); |
| 202 | } catch (const std::exception& e) { | 37 | } catch (const std::exception& e) { |
| 203 | qDebug() << "Error: " << e.what(); | 38 | qDebug() << "Error: " << e.what(); |
| 204 | return EXIT_FAILURE; | 39 | return EXIT_FAILURE; |
| 205 | } | 40 | } |
| 206 | 41 | ||
| 207 | - | ||
| 208 | w.show(); | 42 | w.show(); |
| 209 | 43 | ||
| 210 | return app.exec(); | 44 | return app.exec(); | ... | ... |
-
Please register or login to post a comment