조성현

add combobox

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
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 +}
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
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 +}
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();
......