Toggle navigation
Toggle navigation
This project
Loading...
Sign in
조성현
/
graph-visualization
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Snippets
Network
Create a new issue
Builds
Commits
Issue Boards
Authored by
조성현
2017-06-21 21:51:39 +0900
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
02cb0a376969e3f6b702cb6e649a4429e05cf026
02cb0a37
1 parent
a30dd054
중간저장
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
260 additions
and
120 deletions
PaperGraph/ChartDialog.cpp
PaperGraph/ChartDialog.h
PaperGraph/GraphItem.cpp
PaperGraph/GraphItem.h
PaperGraph/MainWindow.cpp
PaperGraph/MainWindow.h
PaperGraph/PaperGraph.vcxproj.filters
PaperGraph/PaperGraphWidget.cpp
PaperGraph/PaperGraphWidget.h
PaperGraph/main.cpp
PaperGraph/stdafx.h
PaperGraph/ChartDialog.cpp
0 → 100644
View file @
02cb0a3
#include "stdafx.h"
#include "ChartDialog.h"
ChartDialog
::
ChartDialog
()
{
}
ChartDialog
::~
ChartDialog
()
{
}
PaperGraph/ChartDialog.h
0 → 100644
View file @
02cb0a3
#pragma once
#include "stdafx.h"
class
ChartDialog
:
public
QDialog
{
private
:
public
:
ChartDialog
();
virtual
~
ChartDialog
();
};
PaperGraph/GraphItem.cpp
View file @
02cb0a3
...
...
@@ -36,6 +36,11 @@ void GraphItem::read_more()
auto
node_label_map
=
boost
::
get
(
vertex_name
,
*
graph
);
auto
node_type_map
=
boost
::
get
(
vertex_type
,
*
graph
);
auto
node_citation_map
=
boost
::
get
(
vertex_citation
,
*
graph
);
auto
node_pagerank_map
=
boost
::
get
(
vertex_pagerank
,
*
graph
);
auto
node_category_map
=
boost
::
get
(
vertex_category
,
*
graph
);
auto
node_title_map
=
boost
::
get
(
vertex_title
,
*
graph
);
auto
node_year_map
=
boost
::
get
(
vertex_year
,
*
graph
);
auto
node_category_accuracy_map
=
boost
::
get
(
vertex_category_accuracy
,
*
graph
);
int
line_cnt
=
0
;
qDebug
()
<<
"* graph reading start"
;
...
...
@@ -116,8 +121,7 @@ void GraphItem::read_more()
//Paper일 경우
//vertex type 설정
boost
::
put
(
vertex_type
,
*
graph
,
*
vi
,
NODE_TYPE
::
NODE_PAPER
);
//citation counting
#ifdef CITATION_COUNT
//bibtex 다운로드
std
::
string
dblp_url
=
std
::
string
(
"http://dblp.uni-trier.de/rec/bib1/"
)
+
node_label
;
_curl_processor
.
set_url
(
dblp_url
.
c_str
());
...
...
@@ -137,6 +141,7 @@ void GraphItem::read_more()
_curl_processor
.
set_url
(
json_address
.
c_str
());
_curl_processor
.
perform
();
//citation 카운트
_json_processor
.
read_json
(
_curl_processor
.
get_buffer
());
if
(
!
_json_processor
.
is_ok
())
{
node_citation_map
[
*
vi
]
=
0
;
...
...
@@ -145,6 +150,20 @@ void GraphItem::read_more()
node_citation_map
[
*
vi
]
=
_json_processor
.
get_citation_count
();
}
}
//논문제목(title), year 등 기타정보 받아오기
std
::
string
title
,
year_str
;
int
year
;
_bibtex_processor
.
get_value
(
"title"
,
title
);
_bibtex_processor
.
get_value
(
"year"
,
year_str
);
year
=
stoi
(
year_str
);
node_title_map
[
*
vi
]
=
title
;
node_year_map
[
*
vi
]
=
year
;
#endif // CITATION_COUNT
//카테고리 계산 및 accuracy 계산
//--> case insensitive
}
else
{
//Author
boost
::
put
(
vertex_type
,
*
graph
,
*
vi
,
NODE_TYPE
::
NODE_AUTHOR
);
...
...
@@ -699,75 +718,75 @@ void GraphItem::topK_highlight_with_target()
delete
[]
topk_arr
;
}
void
GraphItem
::
topK_using_custom_score
()
{
// 전체 그래프 기준 topK highlight
// 저자 노드별 실적 계산
vertex_iterator
vi
,
vi_end
;
Graph
::
adjacency_iterator
ai
,
ai_end
;
auto
node_label_map
=
boost
::
get
(
vertex_name
,
*
graph
);
auto
node_type_map
=
boost
::
get
(
vertex_type
,
*
graph
);
auto
node_records_map
=
boost
::
get
(
vertex_record
,
*
graph
);
//k 입력
bool
isok
=
false
;
QInputDialog
*
inputDialog
=
new
QInputDialog
();
//int inputK = inputDialog->getText(nullptr, "Enter target's name", "Start node's name:",
// QLineEdit::Normal, "Akira Idoue", &isok).toStdString();
int
inputK
=
inputDialog
->
getInt
(
nullptr
,
"Enter K"
,
"K:"
,
3
,
1
,
whole_node_cnt
,
1
,
&
isok
);
if
(
!
isok
)
{
qDebug
(
"input cancelled"
);
return
;
}
//저자별 논문 수 계산 + TopK Heap 사용
//pair -> <num_of_record, label>
TopKHeap
<
pair
<
int
,
string
>>
heap
(
inputK
);
for
(
boost
::
tie
(
vi
,
vi_end
)
=
boost
::
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
if
(
node_type_map
[
*
vi
]
!=
NODE_TYPE
::
NODE_AUTHOR
)
{
continue
;
}
int
record_cnt
=
0
;
for
(
boost
::
tie
(
ai
,
ai_end
)
=
boost
::
adjacent_vertices
(
*
vi
,
*
graph
);
ai
!=
ai_end
;
++
ai
)
{
if
(
node_type_map
[
*
ai
]
==
NODE_TYPE
::
NODE_PAPER
)
{
++
record_cnt
;
}
}
boost
::
put
(
vertex_record
,
*
graph
,
*
vi
,
record_cnt
);
heap
.
push
(
make_pair
(
record_cnt
,
node_label_map
[
*
vi
]));
//qDebug() << record_cnt;
}
//get top K records
//pair<int, string> topk_arr[inputK];
pair
<
int
,
string
>
*
topk_arr
=
new
pair
<
int
,
string
>
[
inputK
];
for
(
int
i
=
0
;
i
<
inputK
;
++
i
)
{
topk_arr
[
i
]
=
heap
.
pop
();
qDebug
()
<<
"topk["
<<
i
<<
"] = "
<<
topk_arr
[
i
].
first
<<
", "
<<
QString
::
fromStdString
(
topk_arr
[
i
].
second
);
}
for
(
auto
&
n
:
nodeList
)
{
auto
label
=
n
->
getLabel
();
n
->
setColor
(
QColor
(
Qt
::
lightGray
));
for
(
int
i
=
0
;
i
<
inputK
;
++
i
)
{
auto
&
p
=
topk_arr
[
i
];
if
(
label
.
toStdString
()
==
p
.
second
)
{
n
->
setColor
(
QColor
(
Qt
::
red
));
break
;
}
}
}
delete
[]
topk_arr
;
}
//
void GraphItem::topK_using_custom_score()
//
{
//
// 전체 그래프 기준 topK highlight
//
//
// 저자 노드별 실적 계산
//
vertex_iterator vi, vi_end;
//
Graph::adjacency_iterator ai, ai_end;
//
//
auto node_label_map = boost::get(vertex_name, *graph);
//
auto node_type_map = boost::get(vertex_type, *graph);
//
auto node_records_map = boost::get(vertex_record, *graph);
//
//
//k 입력
//
bool isok = false;
//
//
QInputDialog *inputDialog = new QInputDialog();
//
//int inputK = inputDialog->getText(nullptr, "Enter target's name", "Start node's name:",
//
// QLineEdit::Normal, "Akira Idoue", &isok).toStdString();
//
int inputK = inputDialog->getInt(nullptr, "Enter K", "K:", 3,
//
1, whole_node_cnt, 1, &isok);
//
if (!isok) {
//
qDebug("input cancelled");
//
return;
//
}
//
//
//저자별 논문 수 계산 + TopK Heap 사용
//
//pair -> <num_of_record, label>
//
TopKHeap<pair<int, string>> heap(inputK);
//
for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi != vi_end; ++vi) {
//
if (node_type_map[*vi] != NODE_TYPE::NODE_AUTHOR) {
//
continue;
//
}
//
//
int record_cnt = 0;
//
for (boost::tie(ai, ai_end) = boost::adjacent_vertices(*vi, *graph);
//
ai != ai_end; ++ai) {
//
if (node_type_map[*ai] == NODE_TYPE::NODE_PAPER) {
//
++record_cnt;
//
}
//
}
//
//
boost::put(vertex_record, *graph, *vi, record_cnt);
//
heap.push(make_pair(record_cnt, node_label_map[*vi]));
//
//
//qDebug() << record_cnt;
//
}
//
//
//get top K records
//
//pair<int, string> topk_arr[inputK];
//
pair<int, string> *topk_arr = new pair<int, string>[inputK];
//
for (int i = 0; i < inputK; ++i) {
//
topk_arr[i] = heap.pop();
//
qDebug() << "topk[" << i << "] = " << topk_arr[i].first << ", " << QString::fromStdString(topk_arr[i].second);
//
}
//
//
//
for (auto& n : nodeList) {
//
auto label = n->getLabel();
//
n->setColor(QColor(Qt::lightGray));
//
for (int i = 0; i < inputK; ++i) {
//
auto& p = topk_arr[i];
//
if (label.toStdString() == p.second) {
//
n->setColor(QColor(Qt::red));
//
break;
//
}
//
}
//
}
//
delete[] topk_arr;
//
}
void
GraphItem
::
find_shortest_path
()
{
...
...
@@ -892,6 +911,60 @@ void GraphItem::find_shortest_path()
qDebug
(
"* path highlighting end"
);
}
void
GraphItem
::
topk_with_pagerank
()
{
//k 입력
bool
isok
=
false
;
QInputDialog
*
inputDialog
=
new
QInputDialog
();
int
inputK
=
inputDialog
->
getInt
(
nullptr
,
"Enter K"
,
"K:"
,
3
,
1
,
whole_node_cnt
,
1
,
&
isok
);
if
(
!
isok
)
{
qDebug
(
"input cancelled"
);
return
;
}
//전체노드 색 변경
for
(
auto
&
n
:
nodeList
)
{
n
->
setColor
(
Qt
::
lightGray
);
}
auto
node_label_map
=
boost
::
get
(
vertex_name
,
*
graph
);
auto
node_pagerank_map
=
boost
::
get
(
vertex_pagerank
,
*
graph
);
vertex_iterator
vi
,
vi_end
;
//페이지랭크 계산
qDebug
(
"* pagerank start"
);
boost
::
graph
::
page_rank
(
*
graph
,
node_pagerank_map
);
for
(
boost
::
tie
(
vi
,
vi_end
)
=
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
printf
(
"%s
\t\t
%f
\n
"
,
node_label_map
[
*
vi
].
c_str
(),
node_pagerank_map
[
*
vi
]);
}
qDebug
(
"* pagerank end"
);
//페이지랭크 topK 계산
TopKHeap
<
pair
<
double
,
string
>>
heap
(
inputK
);
for
(
boost
::
tie
(
vi
,
vi_end
)
=
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
heap
.
push
(
make_pair
(
node_pagerank_map
[
*
vi
],
node_label_map
[
*
vi
]));
}
pair
<
double
,
string
>
*
topk_arr
=
new
pair
<
double
,
string
>
[
inputK
];
for
(
int
i
=
0
;
i
<
inputK
;
++
i
)
{
topk_arr
[
i
]
=
heap
.
pop
();
qDebug
()
<<
"topk["
<<
i
<<
"] = "
<<
topk_arr
[
i
].
first
<<
", "
<<
QString
::
fromStdString
(
topk_arr
[
i
].
second
);
}
for
(
auto
&
n
:
nodeList
)
{
auto
label
=
n
->
getLabel
();
n
->
setColor
(
QColor
(
Qt
::
lightGray
));
for
(
int
i
=
0
;
i
<
inputK
;
++
i
)
{
auto
&
p
=
topk_arr
[
i
];
if
(
label
.
toStdString
()
==
p
.
second
)
{
n
->
setColor
(
QColor
(
Qt
::
red
));
break
;
}
}
}
delete
[]
topk_arr
;
}
void
GraphItem
::
reset_color
()
{
for
(
auto
&
n
:
nodeList
)
{
...
...
PaperGraph/GraphItem.h
View file @
02cb0a3
...
...
@@ -8,6 +8,7 @@
using
namespace
std
;
using
namespace
boost
;
//#define CITATION_COUNT
class
GraphItem
:
public
QGraphicsItem
...
...
@@ -29,8 +30,9 @@ public:
void
might_know
();
void
topK_highlight_with_total
();
void
topK_highlight_with_target
();
void
topK_using_custom_score
();
//
void topK_using_custom_score();
void
find_shortest_path
();
void
topk_with_pagerank
();
void
reset_color
();
//test
...
...
PaperGraph/MainWindow.cpp
View file @
02cb0a3
...
...
@@ -52,6 +52,9 @@ void MainWindow::createActions()
findShortestPathAct
=
new
QAction
(
tr
(
"Find Shortest Path"
),
this
);
findShortestPathAct
->
setStatusTip
(
"Find shortest path between two node"
);
connect
(
findShortestPathAct
,
&
QAction
::
triggered
,
this
,
&
MainWindow
::
find_shortest_path
);
topkWithPagerankAct
=
new
QAction
(
tr
(
"topK with pagerank"
),
this
);
topkWithPagerankAct
->
setStatusTip
(
tr
(
"highlight which is in top k pagerank in whole graph"
));
connect
(
topkWithPagerankAct
,
&
QAction
::
triggered
,
this
,
&
MainWindow
::
topk_with_pagerank
);
resetColorAct
=
new
QAction
(
tr
(
"Reset colors"
),
this
);
resetColorAct
->
setStatusTip
(
tr
(
"Reset all node's color"
));
...
...
@@ -73,6 +76,7 @@ void MainWindow::createMenus()
actionMenu
->
addAction
(
topkWithTotalAct
);
actionMenu
->
addAction
(
topKWithTargetAct
);
actionMenu
->
addAction
(
findShortestPathAct
);
actionMenu
->
addAction
(
topkWithPagerankAct
);
actionMenu
->
addAction
(
resetColorAct
);
...
...
@@ -109,6 +113,10 @@ void MainWindow::find_shortest_path()
graphWidget
->
find_shortest_path
();
}
void
MainWindow
::
topk_with_pagerank
()
{
graphWidget
->
topk_with_pagerank
();
}
void
MainWindow
::
reset_color
()
{
graphWidget
->
reset_color
();
...
...
PaperGraph/MainWindow.h
View file @
02cb0a3
...
...
@@ -25,6 +25,7 @@ private:
QAction
*
topkWithTotalAct
;
QAction
*
topKWithTargetAct
;
QAction
*
resetColorAct
;
QAction
*
topkWithPagerankAct
;
QAction
*
findShortestPathAct
;
//test
...
...
@@ -41,6 +42,7 @@ private slots:
void
topK_with_total
();
void
topK_with_target
();
void
find_shortest_path
();
void
topk_with_pagerank
();
void
reset_color
();
//test
void
test
();
...
...
PaperGraph/PaperGraph.vcxproj.filters
View file @
02cb0a3
...
...
@@ -92,6 +92,9 @@
<ClCompile Include="json_processor.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ChartDialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="PaperGraphWidget.h">
...
...
@@ -129,5 +132,8 @@
<ClInclude Include="json_processor.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ChartDialog.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
...
...
PaperGraph/PaperGraphWidget.cpp
View file @
02cb0a3
...
...
@@ -75,6 +75,11 @@ void PaperGraphWidget::find_shortest_path()
scene
->
update
();
}
void
PaperGraphWidget
::
topk_with_pagerank
()
{
graphItem
->
topk_with_pagerank
();
scene
->
update
();
}
void
PaperGraphWidget
::
reset_color
()
{
graphItem
->
reset_color
();
...
...
PaperGraph/PaperGraphWidget.h
View file @
02cb0a3
...
...
@@ -19,6 +19,7 @@ public:
void
topk_with_total
();
void
topk_with_target
();
void
find_shortest_path
();
void
topk_with_pagerank
();
void
reset_color
();
//test
...
...
PaperGraph/main.cpp
View file @
02cb0a3
...
...
@@ -3,47 +3,6 @@
#include "MainWindow.h"
int
main
(
int
argc
,
char
*
argv
[])
{
//if (1) {
// _curl_processor.set_url("http://dblp.uni-trier.de/rec/bib1/conf/sbrn/WedemannCD06");
// _curl_processor.perform();
// printf("%s", _curl_processor.get_buffer().c_str());
//
// _bibtex_processor.read(_curl_processor.get_buffer());
// std::string doi;
// _bibtex_processor.get_value("doi", doi);
// std::string address = std::string("http://api.crossref.org/works/")+doi;
// _curl_processor.set_url(address.c_str());
// _curl_processor.perform();
// printf("json: %s\n", _curl_processor.get_buffer().c_str());
// //rapidjson test
// rapidjson::Document d;
// d.Parse(_curl_processor.get_buffer().c_str());
// rapidjson::Value& value_status = d["status"];
// std::string status_str = value_status.GetString();
// printf("status: %s\n", status_str.c_str());
// if (status_str != "ok") {
// printf("status: %s\n", status_str.c_str());
// printf("not ok\n");
// return 1;
// }
// rapidjson::Value& value_message = d["message"];
// rapidjson::Value& citation_count = value_message["is-referenced-by-count"];
// int cit_cnt = citation_count.GetInt();
// printf("citation: %d\n", cit_cnt);
// //
// rapidjson::Value& citation_count2 = d["message"]["is-referenced-by-count"];
// printf("%d\n", citation_count2.GetInt());
// return 0;
//}
QApplication
app
(
argc
,
argv
);
MainWindow
m
;
...
...
PaperGraph/stdafx.h
View file @
02cb0a3
...
...
@@ -16,9 +16,12 @@
#include <qmath.h>
#include <QMessageBox>
#include <QtGui>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include <QtWidgets>
#include <QtCharts/QChartView>
#include <QtCharts/QBarSeries>
#include <QtCharts/QBarSet>
#include <QtCharts/QLegend>
#include <QtCharts/QBarCategoryAxis>
#include <boost/algorithm/string.hpp> //boost::split
#include <boost/bimap.hpp>
...
...
@@ -62,6 +65,8 @@ using bibtex::BibTeXEntry;
using
namespace
boost
;
using
namespace
std
;
/* Qt namespaces */
/* function declaration */
size_t
write_callback
(
void
*
contents
,
size_t
size
,
size_t
nmemb
,
void
*
userp
);
...
...
@@ -69,15 +74,65 @@ size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp);
enum
vertex_position_t
{
vertex_position
};
enum
vertex_type_t
{
vertex_type
};
enum
vertex_record_t
{
vertex_record
};
enum
vertex_citation_t
{
vertex_citation
};
enum
vertex_citation_t
{
vertex_citation
};
//for paper
enum
vertex_pagerank_t
{
vertex_pagerank
};
enum
vertex_category_t
{
vertex_category
};
//for paper
enum
vertex_title_t
{
vertex_title
};
//for paper
enum
vertex_year_t
{
vertex_year
};
//for paper
enum
vertex_category_accuracy_t
{
vertex_category_accuracy
};
//for paper
namespace
boost
{
BOOST_INSTALL_PROPERTY
(
vertex
,
position
);
BOOST_INSTALL_PROPERTY
(
vertex
,
type
);
BOOST_INSTALL_PROPERTY
(
vertex
,
record
);
BOOST_INSTALL_PROPERTY
(
vertex
,
citation
);
BOOST_INSTALL_PROPERTY
(
vertex
,
pagerank
);
BOOST_INSTALL_PROPERTY
(
vertex
,
category
);
BOOST_INSTALL_PROPERTY
(
vertex
,
title
);
BOOST_INSTALL_PROPERTY
(
vertex
,
year
);
BOOST_INSTALL_PROPERTY
(
vertex
,
category_accuracy
);
}
enum
PAPER_CATEGORY
{
CS_AI
,
CS_CL
,
CS_CC
,
CS_CE
,
CS_CG
,
CS_GT
,
CS_CV
,
CS_CY
,
CS_CR
,
CS_DS
,
CS_DB
,
CS_DL
,
CS_DM
,
CS_DC
,
CS_ET
,
CS_FL
,
CS_GL
,
CS_GR
,
CS_AR
,
CS_HC
,
CS_IR
,
CS_IT
,
CS_LG
,
CS_LO
,
CS_MS
,
CS_MA
,
CS_MM
,
CS_NI
,
CS_NE
,
CS_NA
,
CS_OS
,
CS_OH
,
CS_PF
,
CS_PL
,
CS_RO
,
CS_SI
,
CS_SE
,
CS_SD
,
CS_SC
,
CS_SY
};
enum
NODE_TYPE
{
NODE_PAPER
,
NODE_AUTHOR
...
...
@@ -98,8 +153,12 @@ typedef boost::property<vertex_index_t, int,
boost
::
property
<
vertex_type_t
,
int
,
//타입. enum NODE_TYPE에 정의됨
boost
::
property
<
vertex_record_t
,
int
,
//이웃 노드 개수
boost
::
property
<
vertex_citation_t
,
int
,
//피인용수
boost
::
property
<
vertex_pagerank_t
,
double
>
//페이지랭크 값
>>>>>
boost
::
property
<
vertex_pagerank_t
,
double
,
//페이지랭크값 계산해서 저장할 property
boost
::
property
<
vertex_category_t
,
int
,
//논문 주제
boost
::
property
<
vertex_title_t
,
std
::
string
,
//논문 제목
boost
::
property
<
vertex_year_t
,
int
,
boost
::
property
<
vertex_category_accuracy_t
,
double
>
>>>>>>>>>
>
VertexProperties
;
typedef
boost
::
adjacency_list
<
listS
,
//outEdgeList
...
...
@@ -126,8 +185,8 @@ namespace {
const
int
NODE_SIZE
=
4
;
const
int
LAYOUT_MODE
=
GRAPH_LAYOUT
::
RANDOM_LAYOUT
;
//const int SCREEN_SIZE = 3000;
const
int
SCREEN_SIZE
=
30
00
;
const
int
READ_LINE_UNIT
=
10
;
//한 번에 몇 라인을 읽을지
const
int
SCREEN_SIZE
=
5
00
;
const
int
READ_LINE_UNIT
=
10
0
;
//한 번에 몇 라인을 읽을지
/* curl processor */
curl_processor
_curl_processor
;
...
...
Please
register
or
login
to post a comment