조성현

variable arrange, add topk, get stream input

1 #include "stdafx.h" 1 #include "stdafx.h"
2 #include "GraphItem.h" 2 #include "GraphItem.h"
3 3
4 -GraphItem::GraphItem(ifstream& fin, int numOfLines) 4 +GraphItem::GraphItem(const char *filename)
5 { 5 {
6 - //numOfLines == ifstream에서 읽을 라인의 수 6 + fin.open(filename);
7 -
8 if (!fin) 7 if (!fin)
9 - throw std::exception("graph file input is invalid"); 8 + throw std::exception("graph file is not available");
10 - else if (numOfLines < 1) 9 +
11 - throw std::exception("invalid numOfLines"); 10 + graph = new Graph();
11 + read_more();
12 +}
12 13
14 +GraphItem::~GraphItem()
15 +{
16 + fin.close();
17 +}
18 +
19 +void GraphItem::read_more()
20 +{
13 /** 21 /**
14 - * Parse Paper dataset 22 + * Parse Paper dataset
15 - * - paper_key, [author_list], publish_year 23 + * - paper_key, [author_list], publish_year
16 - * Column Delimiter: || 24 + * Column Delimiter: ||
17 - * Author list Delimiter: && 25 + * Author list Delimiter: &&
18 - */ 26 + */
19 std::string line; 27 std::string line;
20 vector<std::string> tokens; 28 vector<std::string> tokens;
21 vector<std::string> authors; 29 vector<std::string> authors;
22 - vector<pair<string, string>> edges; 30 + /*vector<pair<string, string>> edges;*/
23 - 31 +
24 - //String <--> int 양방향 변환을 위해 bidirectional map 상숑 32 + //vector<simple_edge> edges_indexes;
25 - //map<string, int> -> <vertex label, vertex index> 33 +
26 - /*typedef boost::bimap<string, int> bm_type;*/
27 - /*bm_type node_ids;
28 - vector<simple_edge> edges_indexes*/; //int로 변환된 edge
29 -
30 - int node_cnt = 0;
31 int line_cnt = 0; 34 int line_cnt = 0;
32 qDebug() << "* graph reading start"; 35 qDebug() << "* graph reading start";
33 - 36 +
34 //한 줄씩 읽어서 Parse 37 //한 줄씩 읽어서 Parse
38 + int node_cnt = 0;
35 while (std::getline(fin, line) && !line.empty()) { 39 while (std::getline(fin, line) && !line.empty()) {
36 //boost::split 이용해 문자열 분리 40 //boost::split 이용해 문자열 분리
37 //tokens[0]: Paper-key. ex) conf/iastedCSN/KeimS06 41 //tokens[0]: Paper-key. ex) conf/iastedCSN/KeimS06
...@@ -39,53 +43,72 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines) ...@@ -39,53 +43,72 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
39 //tokens[2]: Published year. 43 //tokens[2]: Published year.
40 boost::split(tokens, line, boost::is_any_of("||"), boost::token_compress_on); 44 boost::split(tokens, line, boost::is_any_of("||"), boost::token_compress_on);
41 boost::split(authors, tokens[1], boost::is_any_of("&&"), boost::token_compress_on); 45 boost::split(authors, tokens[1], boost::is_any_of("&&"), boost::token_compress_on);
42 - 46 +
43 const string& paper_key = tokens[0]; 47 const string& paper_key = tokens[0];
44 if (node_ids.left.find(paper_key) == node_ids.left.end()) { 48 if (node_ids.left.find(paper_key) == node_ids.left.end()) {
45 - node_ids.insert(bm_type::value_type(paper_key, node_cnt++)); 49 + node_ids.insert(bm_type::value_type(paper_key, node_cnt + whole_node_cnt));
50 + ++node_cnt;
46 } 51 }
47 - 52 +
48 for (auto author : authors) { 53 for (auto author : authors) {
49 edges.push_back(pair<string, string>(paper_key, author)); 54 edges.push_back(pair<string, string>(paper_key, author));
50 if (node_ids.left.find(author) == node_ids.left.end()) { 55 if (node_ids.left.find(author) == node_ids.left.end()) {
51 - node_ids.insert(bm_type::value_type(author, node_cnt++)); 56 + node_ids.insert(bm_type::value_type(author, node_cnt + whole_node_cnt));
57 + ++node_cnt;
52 } 58 }
53 } 59 }
54 - 60 +
55 //debug 61 //debug
56 ++line_cnt; 62 ++line_cnt;
57 - if (line_cnt >= numOfLines) break; 63 + if (line_cnt >= READ_LINE_UNIT) break;
58 } 64 }
59 qDebug() << "* graph reading complete"; 65 qDebug() << "* graph reading complete";
60 qDebug() << "* # of read line: " << line_cnt; 66 qDebug() << "* # of read line: " << line_cnt;
61 qDebug() << "* # of nodes: " << node_cnt; 67 qDebug() << "* # of nodes: " << node_cnt;
62 - qDebug() << "* # of edges: " << edges.size(); 68 + //qDebug() << "* # of edges: " << edges.size();
69 +
63 70
71 +
64 //edge conversion 72 //edge conversion
65 //<string, string> to <int, int> 73 //<string, string> to <int, int>
66 //using boost::bimap (bidirectional map) 74 //using boost::bimap (bidirectional map)
75 + edges_indexes.clear();
67 for (auto edge : edges) { 76 for (auto edge : edges) {
68 edges_indexes.push_back({ 77 edges_indexes.push_back({
69 node_ids.left.find(edge.first)->get_right(), 78 node_ids.left.find(edge.first)->get_right(),
70 node_ids.left.find(edge.second)->get_right() 79 node_ids.left.find(edge.second)->get_right()
71 }); 80 });
72 } 81 }
73 - //Graph --> defined in "PaperGraphWidget.h" 82 +
74 //Graph graph(edges_indexes.begin(), edges_indexes.end(), node_ids.size()); 83 //Graph graph(edges_indexes.begin(), edges_indexes.end(), node_ids.size());
84 + //graph = new Graph(edges_indexes.begin(), edges_indexes.end(), node_ids.size());
85 + //for (auto& e: edges_indexes) {
86 + // boost::add_edge(e.first, e.second, graph);
87 + //}
88 +
89 + if (graph) {
90 + delete graph;
91 + graph = nullptr;
92 + }
75 graph = new Graph(edges_indexes.begin(), edges_indexes.end(), node_ids.size()); 93 graph = new Graph(edges_indexes.begin(), edges_indexes.end(), node_ids.size());
94 +
76 95
96 +
77 //set index property 97 //set index property
78 qDebug() << "* set vertex property start"; 98 qDebug() << "* set vertex property start";
79 vertex_iterator vi, vi_end; 99 vertex_iterator vi, vi_end;
80 int i = 0; 100 int i = 0;
81 - for (boost::tie(vi, vi_end)=vertices(*graph); vi!=vi_end; ++vi) { 101 + for (boost::tie(vi, vi_end) = vertices(*graph); vi != vi_end; ++vi) {
82 //Vertex Property 설정 102 //Vertex Property 설정
83 - //index: 0 ~ ... 103 + //index: n ~ ...
84 //name : map의 value(i) 기준으로 찾은 Key 104 //name : map의 value(i) 기준으로 찾은 Key
85 - // map --> map<string, int> (boost bidirectional map) 105 + // map --> map<string, int> (boost bidirectional map)
86 std::string node_label = node_ids.right.find(i)->get_left(); 106 std::string node_label = node_ids.right.find(i)->get_left();
87 boost::put(vertex_index, *graph, *vi, i); 107 boost::put(vertex_index, *graph, *vi, i);
88 boost::put(vertex_name, *graph, *vi, node_label); 108 boost::put(vertex_name, *graph, *vi, node_label);
109 + boost::put(vertex_record, *graph, *vi, 0);
110 +
111 + qDebug() << "** index: " << i << ", name: " << node_label.c_str();
89 112
90 //node type 설정 113 //node type 설정
91 if (boost::regex_match(node_label, paper_reg)) { 114 if (boost::regex_match(node_label, paper_reg)) {
...@@ -99,7 +122,7 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines) ...@@ -99,7 +122,7 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
99 ++i; 122 ++i;
100 } 123 }
101 qDebug() << "* set vertex property end"; 124 qDebug() << "* set vertex property end";
102 - 125 + whole_node_cnt += node_cnt;
103 126
104 //qDebug("* set edges weight start"); 127 //qDebug("* set edges weight start");
105 ////모든 edge의 weight를 1로 설정 128 ////모든 edge의 weight를 1로 설정
...@@ -133,7 +156,7 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines) ...@@ -133,7 +156,7 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
133 //while (current != boost::vertex(start_idx, *graph)) { 156 //while (current != boost::vertex(start_idx, *graph)) {
134 //} 157 //}
135 //qDebug("* path highlighting end"); 158 //qDebug("* path highlighting end");
136 - 159 +
137 160
138 //graph layout calculation 161 //graph layout calculation
139 //using boost::random_graph_layout and boost::kamada_kawai_spring_layout 162 //using boost::random_graph_layout and boost::kamada_kawai_spring_layout
...@@ -148,18 +171,18 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines) ...@@ -148,18 +171,18 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
148 Topology::point_difference_type extent; 171 Topology::point_difference_type extent;
149 extent[0] = extent[1] = (double)SCREEN_SIZE; 172 extent[0] = extent[1] = (double)SCREEN_SIZE;
150 rectangle_topology<> rect_top(gen, 173 rectangle_topology<> rect_top(gen,
151 - -SCREEN_SIZE/2, -SCREEN_SIZE/2, 174 + -SCREEN_SIZE / 2, -SCREEN_SIZE / 2,
152 - SCREEN_SIZE/2, SCREEN_SIZE/2); 175 + SCREEN_SIZE / 2, SCREEN_SIZE / 2);
153 - 176 +
154 switch (LAYOUT_MODE) { 177 switch (LAYOUT_MODE) {
155 case GRAPH_LAYOUT::RANDOM_LAYOUT: 178 case GRAPH_LAYOUT::RANDOM_LAYOUT:
156 random_graph_layout(*graph, get(vertex_position, *graph), rect_top); 179 random_graph_layout(*graph, get(vertex_position, *graph), rect_top);
157 break; 180 break;
158 - 181 +
159 case GRAPH_LAYOUT::CIRCLE_LAYOUT: 182 case GRAPH_LAYOUT::CIRCLE_LAYOUT:
160 - circle_graph_layout(*graph, get(vertex_position, *graph), SCREEN_SIZE/2); 183 + circle_graph_layout(*graph, get(vertex_position, *graph), SCREEN_SIZE / 2);
161 break; 184 break;
162 - 185 +
163 case GRAPH_LAYOUT::FRUCHTERMAN_REINGOLD_LAYOUT: 186 case GRAPH_LAYOUT::FRUCHTERMAN_REINGOLD_LAYOUT:
164 fruchterman_reingold_force_directed_layout(*graph, 187 fruchterman_reingold_force_directed_layout(*graph,
165 get(vertex_position, *graph), 188 get(vertex_position, *graph),
...@@ -172,14 +195,18 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines) ...@@ -172,14 +195,18 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
172 qDebug() << "* make graph layout end"; 195 qDebug() << "* make graph layout end";
173 196
174 197
198 + //clear lists
199 + nodeList.clear();
200 + edgeList.clear();
201 +
175 //add edges 202 //add edges
176 - auto position = get(vertex_position, *graph); 203 + auto position = boost::get(vertex_position, *graph);
177 - auto label = get(vertex_name, *graph); 204 + auto label = boost::get(vertex_name, *graph);
178 - auto nodeType = get(vertex_type, *graph); 205 + auto nodeType = boost::get(vertex_type, *graph);
179 206
180 edge_iterator ei, ei_end; 207 edge_iterator ei, ei_end;
181 vertex_descriptor u, v; 208 vertex_descriptor u, v;
182 - for (boost::tie(ei, ei_end)=boost::edges(*graph); ei!=ei_end; ++ei) { 209 + for (boost::tie(ei, ei_end) = boost::edges(*graph); ei != ei_end; ++ei) {
183 u = source(*ei, *graph); 210 u = source(*ei, *graph);
184 v = target(*ei, *graph); 211 v = target(*ei, *graph);
185 Point p1 = position[u]; 212 Point p1 = position[u];
...@@ -187,14 +214,14 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines) ...@@ -187,14 +214,14 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
187 214
188 //make edge item and push it to list 215 //make edge item and push it to list
189 EdgeItem *edge; 216 EdgeItem *edge;
190 - 217 +
191 edge = new EdgeItem(p1[0], p1[1], p2[0], p2[1], QColor(Qt::black), 0); 218 edge = new EdgeItem(p1[0], p1[1], p2[0], p2[1], QColor(Qt::black), 0);
192 edge->setPos(p1[0], p1[1]); 219 edge->setPos(p1[0], p1[1]);
193 edgeList << edge; 220 edgeList << edge;
194 } 221 }
195 222
196 //add nodes 223 //add nodes
197 - for (boost::tie(vi, vi_end)=vertices(*graph); vi!=vi_end; ++vi) { 224 + for (boost::tie(vi, vi_end) = vertices(*graph); vi != vi_end; ++vi) {
198 Point p = position[*vi]; 225 Point p = position[*vi];
199 auto nt = nodeType[*vi]; 226 auto nt = nodeType[*vi];
200 std::string name = label[*vi]; 227 std::string name = label[*vi];
...@@ -203,7 +230,8 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines) ...@@ -203,7 +230,8 @@ GraphItem::GraphItem(ifstream& fin, int numOfLines)
203 NodeItem *node; 230 NodeItem *node;
204 if (nt == NODE_TYPE::NODE_PAPER) { 231 if (nt == NODE_TYPE::NODE_PAPER) {
205 node = new NodeItem(p[0], p[1], QColor(Qt::darkGreen), QString(name.c_str()), nt); 232 node = new NodeItem(p[0], p[1], QColor(Qt::darkGreen), QString(name.c_str()), nt);
206 - } else { 233 + }
234 + else {
207 node = new NodeItem(p[0], p[1], QColor(Qt::green), QString(name.c_str()), nt); 235 node = new NodeItem(p[0], p[1], QColor(Qt::green), QString(name.c_str()), nt);
208 } 236 }
209 node->setPos(QPointF(p[0], p[1])); 237 node->setPos(QPointF(p[0], p[1]));
...@@ -262,6 +290,63 @@ void GraphItem::reset_color() ...@@ -262,6 +290,63 @@ void GraphItem::reset_color()
262 } 290 }
263 } 291 }
264 292
293 +void GraphItem::topK_highlight()
294 +{
295 + // 저자 노드별 실적 계산
296 + vertex_iterator vi, vi_end;
297 + Graph::adjacency_iterator ai, ai_end;
298 +
299 + auto nodeLabel = boost::get(vertex_name, *graph);
300 + auto nodeType = boost::get(vertex_type, *graph);
301 + auto numOfRecords = boost::get(vertex_record, *graph);
302 +
303 + //실적 count 초기화
304 + //for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi != vi_end; ++vi) {
305 + // if (nodeType[*vi] != NODE_TYPE::NODE_AUTHOR) {
306 + // continue;
307 + // }
308 + // boost::put(vertex_record, *graph, *vi, 0);
309 + //}
310 +
311 + // <record, label>
312 + TopKHeap<pair<int, string>> heap(TOP_K);
313 + for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi != vi_end; ++vi) {
314 + if (nodeType[*vi] != NODE_TYPE::NODE_AUTHOR) {
315 + continue;
316 + }
317 +
318 + int record_cnt = 0;
319 + for (boost::tie(ai, ai_end) = boost::adjacent_vertices(*vi, *graph);
320 + ai != ai_end; ++ai) {
321 + if (nodeType[*vi] == NODE_TYPE::NODE_PAPER) {
322 + ++record_cnt;
323 + }
324 + }
325 +
326 + boost::put(vertex_record, *graph, *vi, record_cnt);
327 + heap.push(make_pair(record_cnt, nodeLabel[*vi]));
328 + }
329 +
330 + //get top K records
331 + pair<int, string> topk_arr[TOP_K];
332 + for (int i = 0; i < TOP_K; ++i) {
333 + topk_arr[i] = heap.pop();
334 + }
335 +
336 + for (auto& n: nodeList) {
337 + auto label = n->getLabel();
338 + n->setColor(QColor(Qt::lightGray));
339 + for (auto& p: topk_arr) {
340 + if (label.toStdString() == p.second) {
341 + n->setColor(QColor(Qt::red));
342 + break;
343 + }
344 + }
345 + }
346 +
347 + //delete[] topk_arr;
348 +}
349 +
265 //event handler 350 //event handler
266 void GraphItem::mousePressEvent(QGraphicsSceneMouseEvent *event) 351 void GraphItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
267 { 352 {
......
...@@ -13,7 +13,12 @@ class GraphItem ...@@ -13,7 +13,12 @@ class GraphItem
13 : public QGraphicsItem 13 : public QGraphicsItem
14 { 14 {
15 public: 15 public:
16 - GraphItem(ifstream& fin, int numOfLines); 16 + //GraphItem(ifstream* pFin);
17 + GraphItem(const char* filename);
18 + virtual ~GraphItem();
19 +
20 + //io
21 + void read_more();
17 22
18 //overrides 23 //overrides
19 QRectF boundingRect() const override; 24 QRectF boundingRect() const override;
...@@ -23,6 +28,7 @@ public: ...@@ -23,6 +28,7 @@ public:
23 //methods 28 //methods
24 void path_highlighting(std::string start, std::string end); 29 void path_highlighting(std::string start, std::string end);
25 void reset_color(); 30 void reset_color();
31 + void topK_highlight();
26 32
27 protected: 33 protected:
28 void mousePressEvent(QGraphicsSceneMouseEvent *event) override; 34 void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
...@@ -30,8 +36,12 @@ protected: ...@@ -30,8 +36,12 @@ protected:
30 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override; 36 void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
31 37
32 private: 38 private:
39 + ifstream fin;
33 bm_type node_ids; 40 bm_type node_ids;
41 + vector<pair<string, string>> edges;
34 vector<simple_edge> edges_indexes; 42 vector<simple_edge> edges_indexes;
43 + int whole_node_cnt = 0;
44 +
35 Graph *graph = nullptr; 45 Graph *graph = nullptr;
36 QList<NodeItem *> nodeList; 46 QList<NodeItem *> nodeList;
37 QList<EdgeItem *> edgeList; 47 QList<EdgeItem *> edgeList;
......
...@@ -25,35 +25,56 @@ MainWindow::~MainWindow() ...@@ -25,35 +25,56 @@ MainWindow::~MainWindow()
25 25
26 } 26 }
27 27
28 -void MainWindow::print_graph(std::ifstream& fin) 28 +void MainWindow::print_graph(const char * filename)
29 { 29 {
30 - graphWidget->print_graph(fin); 30 + graphWidget->print_graph(filename);
31 } 31 }
32 32
33 +//void MainWindow::print_graph(std::ifstream *pFin)
34 +//{
35 +// graphWidget->print_graph(pFin);
36 +//}
37 +
33 ////////////////////////////////////////////////////////////////// 38 //////////////////////////////////////////////////////////////////
34 // private methods 39 // private methods
35 ////////////////////////////////////////////////////////////////// 40 //////////////////////////////////////////////////////////////////
36 void MainWindow::createActions() 41 void MainWindow::createActions()
37 { 42 {
38 - testHighlightAct = new QAction(tr("&Highlight"), this); 43 + readMoreAct = new QAction(tr("Read more"), this);
44 + readMoreAct->setStatusTip(tr("read more lines from file"));
45 + connect(readMoreAct, &QAction::triggered, this, &MainWindow::read_more);
46 +
47 + testHighlightAct = new QAction(tr("Highlight"), this);
39 testHighlightAct->setStatusTip(tr("Highlighting node")); 48 testHighlightAct->setStatusTip(tr("Highlighting node"));
40 connect(testHighlightAct, &QAction::triggered, this, &MainWindow::test_highlighting); 49 connect(testHighlightAct, &QAction::triggered, this, &MainWindow::test_highlighting);
41 - 50 + topkAct = new QAction(tr("topK"), this);
42 - resetColorAct = new QAction(tr("&Reset colors"), this); 51 + topkAct->setStatusTip(tr("highlight who was top k papers"));
52 + connect(topkAct, &QAction::triggered, this, &MainWindow::topk);
53 + resetColorAct = new QAction(tr("Reset colors"), this);
43 resetColorAct->setStatusTip(tr("Reset all node's color")); 54 resetColorAct->setStatusTip(tr("Reset all node's color"));
44 connect(resetColorAct, &QAction::triggered, this, &MainWindow::reset_color); 55 connect(resetColorAct, &QAction::triggered, this, &MainWindow::reset_color);
45 } 56 }
46 57
47 void MainWindow::createMenus() 58 void MainWindow::createMenus()
48 { 59 {
60 + fileMenu = menuBar()->addMenu(tr("&File"));
61 + fileMenu->addAction(readMoreAct);
62 +
49 actionMenu = menuBar()->addMenu(tr("&Actions")); 63 actionMenu = menuBar()->addMenu(tr("&Actions"));
50 actionMenu->addAction(testHighlightAct); 64 actionMenu->addAction(testHighlightAct);
65 + actionMenu->addAction(topkAct);
51 actionMenu->addAction(resetColorAct); 66 actionMenu->addAction(resetColorAct);
52 } 67 }
53 68
54 ////////////////////////////////////////////////////////////////// 69 //////////////////////////////////////////////////////////////////
55 // slots 70 // slots
56 ////////////////////////////////////////////////////////////////// 71 //////////////////////////////////////////////////////////////////
72 +void MainWindow::read_more()
73 +{
74 + qDebug("* MainWindow::read_more");
75 + graphWidget->read_more();
76 +}
77 +
57 void MainWindow::test_highlighting() 78 void MainWindow::test_highlighting()
58 { 79 {
59 /*QMessageBox::information(this, "test", 80 /*QMessageBox::information(this, "test",
...@@ -62,7 +83,12 @@ void MainWindow::test_highlighting() ...@@ -62,7 +83,12 @@ void MainWindow::test_highlighting()
62 //graphWidget->update(); 83 //graphWidget->update();
63 } 84 }
64 85
86 +void MainWindow::topk()
87 +{
88 + graphWidget->topk();
89 +}
90 +
65 void MainWindow::reset_color() 91 void MainWindow::reset_color()
66 { 92 {
67 graphWidget->reset_color(); 93 graphWidget->reset_color();
68 -}
...\ No newline at end of file ...\ No newline at end of file
94 +}
......
...@@ -12,14 +12,18 @@ public: ...@@ -12,14 +12,18 @@ public:
12 MainWindow(QWidget *parent = 0); 12 MainWindow(QWidget *parent = 0);
13 ~MainWindow(); 13 ~MainWindow();
14 14
15 - void print_graph(std::ifstream& fin); 15 + //void print_graph(std::ifstream *pFin);
16 - /*void test_highlighting();*/ 16 + void print_graph(const char* filename);
17 +
17 18
18 private: 19 private:
19 PaperGraphWidget *graphWidget; 20 PaperGraphWidget *graphWidget;
20 21
22 + QMenu *fileMenu;
23 + QAction *readMoreAct;
21 QMenu *actionMenu; 24 QMenu *actionMenu;
22 QAction *testHighlightAct; 25 QAction *testHighlightAct;
26 + QAction *topkAct;
23 QAction *resetColorAct; 27 QAction *resetColorAct;
24 28
25 private: 29 private:
...@@ -27,7 +31,9 @@ private: ...@@ -27,7 +31,9 @@ private:
27 void createMenus(); 31 void createMenus();
28 32
29 private slots: 33 private slots:
34 + void read_more();
30 void test_highlighting(); 35 void test_highlighting();
36 + void topk();
31 void reset_color(); 37 void reset_color();
32 }; 38 };
33 39
......
...@@ -25,23 +25,47 @@ PaperGraphWidget::PaperGraphWidget(QWidget *parent) ...@@ -25,23 +25,47 @@ PaperGraphWidget::PaperGraphWidget(QWidget *parent)
25 setWindowTitle(tr("dblp paper graph visualization")); 25 setWindowTitle(tr("dblp paper graph visualization"));
26 } 26 }
27 27
28 -void PaperGraphWidget::print_graph(ifstream& fin) 28 +//void PaperGraphWidget::print_graph(ifstream* pFin)
29 +//{
30 +// qDebug("* PaperGraphWidget::print_graph");
31 +// //QGraphicsItem *graph_item = new GraphItem(fin);
32 +// if (graphItem)
33 +// throw std::exception("already have graph item");
34 +//
35 +// graphItem = new GraphItem(pFin);
36 +// graphItem->setPos(0, 0);
37 +// scene->addItem(graphItem);
38 +//}
39 +
40 +void PaperGraphWidget::print_graph(const char * filename)
29 { 41 {
30 - //QGraphicsItem *graph_item = new GraphItem(fin);
31 if (graphItem) 42 if (graphItem)
32 throw std::exception("already have graph item"); 43 throw std::exception("already have graph item");
33 44
34 - graphItem = new GraphItem(fin, READ_LINE_UNIT); 45 + graphItem = new GraphItem(filename);
35 graphItem->setPos(0, 0); 46 graphItem->setPos(0, 0);
36 scene->addItem(graphItem); 47 scene->addItem(graphItem);
37 } 48 }
38 49
50 +void PaperGraphWidget::read_more()
51 +{
52 + qDebug("* PaperGraphWidget::read_more");
53 + graphItem->read_more();
54 + scene->update();
55 +}
56 +
39 void PaperGraphWidget::path_highlight() 57 void PaperGraphWidget::path_highlight()
40 { 58 {
41 graphItem->path_highlighting(std::string(""), std::string("")); 59 graphItem->path_highlighting(std::string(""), std::string(""));
42 scene->update(); 60 scene->update();
43 } 61 }
44 62
63 +void PaperGraphWidget::topk()
64 +{
65 + graphItem->topK_highlight();
66 + scene->update();
67 +}
68 +
45 void PaperGraphWidget::reset_color() 69 void PaperGraphWidget::reset_color()
46 { 70 {
47 graphItem->reset_color(); 71 graphItem->reset_color();
......
...@@ -11,9 +11,13 @@ class PaperGraphWidget : public QWidget ...@@ -11,9 +11,13 @@ class PaperGraphWidget : public QWidget
11 11
12 public: 12 public:
13 PaperGraphWidget(QWidget *parent = 0); 13 PaperGraphWidget(QWidget *parent = 0);
14 - void print_graph(ifstream& fin); 14 + //void print_graph(ifstream* pFin);
15 + void print_graph(const char* filename);
15 16
17 +//main window slots
18 + void read_more();
16 void path_highlight(); 19 void path_highlight();
20 + void topk();
17 void reset_color(); 21 void reset_color();
18 22
19 private slots: 23 private slots:
......
...@@ -9,9 +9,9 @@ int main(int argc, char *argv[]) ...@@ -9,9 +9,9 @@ int main(int argc, char *argv[])
9 MainWindow m; 9 MainWindow m;
10 10
11 try { 11 try {
12 - ifstream fin(PAPER_FILENAME); 12 + //ifstream fin(PAPER_FILENAME);
13 - m.print_graph(fin); 13 + m.print_graph(PAPER_FILENAME);
14 - fin.close(); 14 + //fin.close();
15 } catch (const std::exception& e) { 15 } catch (const std::exception& e) {
16 qDebug() << "Error: " << e.what(); 16 qDebug() << "Error: " << e.what();
17 return EXIT_FAILURE; 17 return EXIT_FAILURE;
......
...@@ -28,13 +28,20 @@ ...@@ -28,13 +28,20 @@
28 #include <boost/graph/topology.hpp> 28 #include <boost/graph/topology.hpp>
29 #include <boost/regex.hpp> 29 #include <boost/regex.hpp>
30 30
31 +#include <cstdio>
32 +#include <cstdlib>
33 +#include <cstring>
34 +
31 #include <algorithm> 35 #include <algorithm>
32 #include <exception> 36 #include <exception>
33 #include <fstream> 37 #include <fstream>
34 #include <iostream> 38 #include <iostream>
35 #include <iterator> 39 #include <iterator>
40 +#include <limits>
36 #include <map> 41 #include <map>
42 +#include <queue>
37 #include <string> 43 #include <string>
44 +#include <utility>
38 #include <vector> 45 #include <vector>
39 46
40 using namespace boost; 47 using namespace boost;
...@@ -43,9 +50,11 @@ using namespace std; ...@@ -43,9 +50,11 @@ using namespace std;
43 /* enums */ 50 /* enums */
44 enum vertex_position_t { vertex_position }; 51 enum vertex_position_t { vertex_position };
45 enum vertex_type_t { vertex_type }; 52 enum vertex_type_t { vertex_type };
53 +enum vertex_record_t { vertex_record };
46 namespace boost { 54 namespace boost {
47 BOOST_INSTALL_PROPERTY(vertex, position); 55 BOOST_INSTALL_PROPERTY(vertex, position);
48 BOOST_INSTALL_PROPERTY(vertex, type); 56 BOOST_INSTALL_PROPERTY(vertex, type);
57 + BOOST_INSTALL_PROPERTY(vertex, record);
49 } 58 }
50 enum NODE_TYPE { 59 enum NODE_TYPE {
51 NODE_PAPER, 60 NODE_PAPER,
...@@ -64,7 +73,8 @@ typedef square_topology<>::point_type point; ...@@ -64,7 +73,8 @@ typedef square_topology<>::point_type point;
64 typedef boost::property<vertex_index_t, int, 73 typedef boost::property<vertex_index_t, int,
65 boost::property<vertex_name_t, std::string, 74 boost::property<vertex_name_t, std::string,
66 boost::property<vertex_position_t, point, 75 boost::property<vertex_position_t, point,
67 - boost::property<vertex_type_t, int>>> 76 + boost::property<vertex_type_t, int,
77 + boost::property<vertex_record_t, int>>>>
68 > VertexProperties; 78 > VertexProperties;
69 typedef boost::adjacency_list< 79 typedef boost::adjacency_list<
70 listS, //outEdgeList 80 listS, //outEdgeList
...@@ -77,6 +87,7 @@ typedef boost::adjacency_list< ...@@ -77,6 +87,7 @@ typedef boost::adjacency_list<
77 > Graph; 87 > Graph;
78 typedef typename graph_traits<Graph>::edge_iterator edge_iterator; 88 typedef typename graph_traits<Graph>::edge_iterator edge_iterator;
79 typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator; 89 typedef typename graph_traits<Graph>::vertex_iterator vertex_iterator;
90 +//typedef boost::graph_traits<Graph>::adjacency_iterator adjacency_iterator;
80 typedef boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor; 91 typedef boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
81 typedef square_topology<> Topology; 92 typedef square_topology<> Topology;
82 typedef typename Topology::point_type Point; 93 typedef typename Topology::point_type Point;
...@@ -95,14 +106,98 @@ namespace { ...@@ -95,14 +106,98 @@ namespace {
95 const int NODE_SIZE = 4; 106 const int NODE_SIZE = 4;
96 const int LAYOUT_MODE = GRAPH_LAYOUT::RANDOM_LAYOUT; 107 const int LAYOUT_MODE = GRAPH_LAYOUT::RANDOM_LAYOUT;
97 const int SCREEN_SIZE = 1000; 108 const int SCREEN_SIZE = 1000;
98 - const int READ_LINE_UNIT = 100; //한 번에 몇 라인을 읽을지 109 + const int READ_LINE_UNIT = 5; //한 번에 몇 라인을 읽을지
99 110
100 /* topK */ 111 /* topK */
101 - const int TOP_K = 10; //상위 몇 개 아이템에 대해 할 지 112 + const int TOP_K = 10; //상위 몇 개 아이템에 대해 highlight 할 지
102 113
103 } 114 }
104 115
105 - 116 +/* boost */
106 namespace boost { 117 namespace boost {
107 const boost::regex paper_reg("(conf|journals).*"); 118 const boost::regex paper_reg("(conf|journals).*");
108 -}
...\ No newline at end of file ...\ No newline at end of file
119 +}
120 +
121 +/* topK heap */
122 +template <typename T>
123 +class TopKHeap {
124 +private:
125 + int k; //max size
126 + int size; //current size
127 + T *heap;
128 +
129 +private:
130 + void reHeapDown(int root) {
131 + //after pop
132 + int minIdx, left, right;
133 +
134 + left = root * 2 + 1;
135 + right = root * 2 + 2;
136 +
137 + if (left <= (size - 1)) {
138 + if (left == (size - 1))
139 + minIdx = left;
140 + else {
141 + minIdx = ((heap[left] <= heap[right]) ? left : right);
142 + }
143 +
144 + if (heap[root] > heap[minIdx]) {
145 + swap(heap[root], heap[minIdx]);
146 + reHeapDown(minIdx);
147 + }
148 + }
149 + }
150 + void reHeapUp(int root, int bottom) {
151 + //bottom: 위로 올릴 노드 idx
152 + //after push
153 + if (root > bottom) {
154 + int parent = (bottom - 1) / 2;
155 + if (heap[parent] < heap[bottom]) {
156 + swap(heap[parent], heap[bottom]);
157 + reHeapUp(root, parent);
158 + }
159 + }
160 + }
161 +
162 +public:
163 + TopKHeap(int _k) : k(_k), size(0) {
164 + if (_k <= 0) abort();
165 + heap = new T[_k];
166 + memset(heap, 0, sizeof(heap));
167 + }
168 + ~TopKHeap() {
169 + if (heap) delete[] heap;
170 + }
171 +
172 +public:
173 + void push(T elem) {
174 + if (size < k) {
175 + heap[size++] = elem;
176 + }
177 + else {
178 + if (elem < heap[0]) {
179 + //less than minimum
180 + }
181 + else {
182 + pop();
183 + heap[size++] = elem;
184 + }
185 + }
186 +
187 + reHeapUp(0, size - 1);
188 + }
189 + T pop() {
190 + if (size <= 0)
191 + abort();
192 + else if (size == 1) {
193 + T ret = heap[--size];
194 + return ret;
195 + }
196 + else {
197 + T ret = heap[0];
198 + heap[0] = heap[--size];
199 + reHeapDown(0);
200 + return ret;
201 + }
202 + }
203 +};
...\ No newline at end of file ...\ No newline at end of file
......