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-05-21 16:03:03 +0900
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
58969a24deff06f1d091ff3f73e9d42108a950fe
58969a24
1 parent
98311824
add shortest path menu
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
160 additions
and
54 deletions
PaperGraph/EdgeItem.cpp
PaperGraph/EdgeItem.h
PaperGraph/GraphItem.cpp
PaperGraph/GraphItem.h
PaperGraph/MainWindow.cpp
PaperGraph/MainWindow.h
PaperGraph/PaperGraphWidget.cpp
PaperGraph/PaperGraphWidget.h
PaperGraph/stdafx.h
PaperGraph/EdgeItem.cpp
View file @
58969a2
...
...
@@ -13,7 +13,8 @@ void EdgeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
}
EdgeItem
::
EdgeItem
(
double
x1
,
double
y1
,
double
x2
,
double
y2
,
QColor
color
,
int
width
)
EdgeItem
::
EdgeItem
(
double
x1
,
double
y1
,
double
x2
,
double
y2
,
QColor
color
,
int
width
,
QString
from
,
QString
to
)
{
this
->
x1
=
x1
;
this
->
y1
=
y1
;
...
...
@@ -22,6 +23,9 @@ EdgeItem::EdgeItem(double x1, double y1, double x2, double y2, QColor color, int
this
->
color
=
color
;
this
->
width
=
width
;
this
->
from
=
from
;
this
->
to
=
to
;
setZValue
(
0
);
//노드 앞 가리지 않도록 ZValue 설정
/*setFlags(ItemIsSelectable | ItemIsMovable);
...
...
PaperGraph/EdgeItem.h
View file @
58969a2
...
...
@@ -9,6 +9,7 @@ class EdgeItem
{
private
:
double
x1
,
y1
,
x2
,
y2
;
QString
from
,
to
;
int
width
;
QColor
color
;
...
...
@@ -18,7 +19,16 @@ protected:
void
mouseReleaseEvent
(
QGraphicsSceneMouseEvent
*
event
)
override
;
public
:
EdgeItem
(
double
x1
,
double
y1
,
double
x2
,
double
y2
,
QColor
color
,
int
width
);
EdgeItem
(
double
x1
,
double
y1
,
double
x2
,
double
y2
,
QColor
color
,
int
width
,
QString
from
,
QString
to
);
//getter
QString
getFrom
()
{
return
from
;
}
QString
getTo
()
{
return
to
;
}
//setter
void
setWidth
(
int
w
)
{
width
=
w
;
}
void
setColor
(
QColor
color
)
{
this
->
color
=
color
;
}
QRectF
boundingRect
()
const
override
;
QPainterPath
shape
()
const
override
;
...
...
PaperGraph/GraphItem.cpp
View file @
58969a2
...
...
@@ -31,6 +31,11 @@ void GraphItem::read_more()
vector
<
pair
<
string
,
string
>>
edges
;
vector
<
pair
<
int
,
int
>>
edges_indexes
;
//property maps
auto
node_position_map
=
boost
::
get
(
vertex_position
,
*
graph
);
auto
node_label_map
=
boost
::
get
(
vertex_name
,
*
graph
);
auto
node_type_map
=
boost
::
get
(
vertex_type
,
*
graph
);
int
line_cnt
=
0
;
qDebug
()
<<
"* graph reading start"
;
...
...
@@ -145,16 +150,16 @@ void GraphItem::read_more()
switch
(
LAYOUT_MODE
)
{
case
GRAPH_LAYOUT
:
:
RANDOM_LAYOUT
:
random_graph_layout
(
*
graph
,
get
(
vertex_position
,
*
graph
)
,
rect_top
);
random_graph_layout
(
*
graph
,
node_position_map
,
rect_top
);
break
;
case
GRAPH_LAYOUT
:
:
CIRCLE_LAYOUT
:
circle_graph_layout
(
*
graph
,
get
(
vertex_position
,
*
graph
)
,
SCREEN_SIZE
/
2
);
circle_graph_layout
(
*
graph
,
node_position_map
,
SCREEN_SIZE
/
2
);
break
;
case
GRAPH_LAYOUT
:
:
FRUCHTERMAN_REINGOLD_LAYOUT
:
fruchterman_reingold_force_directed_layout
(
*
graph
,
get
(
vertex_position
,
*
graph
)
,
node_position_map
,
topology
,
attractive_force
(
square_distance_attractive_force
())
.
cooling
(
linear_cooling
<
double
>
(
50
))
...
...
@@ -168,32 +173,30 @@ void GraphItem::read_more()
nodeList
.
clear
();
edgeList
.
clear
();
//add edges
auto
position
=
boost
::
get
(
vertex_position
,
*
graph
);
auto
label
=
boost
::
get
(
vertex_name
,
*
graph
);
auto
nodeType
=
boost
::
get
(
vertex_type
,
*
graph
);
//edge_iterator ei, ei_end;
vertex_descriptor
u
,
v
;
for
(
boost
::
tie
(
ei
,
ei_end
)
=
boost
::
edges
(
*
graph
);
ei
!=
ei_end
;
++
ei
)
{
u
=
source
(
*
ei
,
*
graph
);
v
=
target
(
*
ei
,
*
graph
);
Point
p1
=
position
[
u
];
Point
p2
=
position
[
v
];
Point
p1
=
node_position_map
[
u
];
Point
p2
=
node_position_map
[
v
];
//make edge item and push it to list
EdgeItem
*
edge
;
edge
=
new
EdgeItem
(
p1
[
0
],
p1
[
1
],
p2
[
0
],
p2
[
1
],
QColor
(
Qt
::
black
),
0
);
edge
=
new
EdgeItem
(
p1
[
0
],
p1
[
1
],
p2
[
0
],
p2
[
1
],
QColor
(
Qt
::
black
),
0
,
QString
(
node_label_map
[
u
].
c_str
()),
QString
(
node_label_map
[
v
].
c_str
()));
edge
->
setPos
(
p1
[
0
],
p1
[
1
]);
edgeList
<<
edge
;
}
//add nodes
for
(
boost
::
tie
(
vi
,
vi_end
)
=
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
Point
p
=
position
[
*
vi
];
auto
nt
=
node
Type
[
*
vi
];
std
::
string
name
=
label
[
*
vi
];
Point
p
=
node_position_map
[
*
vi
];
auto
nt
=
node
_type_map
[
*
vi
];
std
::
string
name
=
node_label_map
[
*
vi
];
//make node item and push it to list
NodeItem
*
node
;
...
...
@@ -244,8 +247,8 @@ void GraphItem::might_know()
Graph
::
adjacency_iterator
ai
,
ai_end
;
vector
<
string
>
might_know_vec
;
auto
label
=
get
(
vertex_name
,
*
graph
);
auto
node
Type
=
get
(
vertex_type
,
*
graph
);
auto
node_label_map
=
get
(
vertex_name
,
*
graph
);
auto
node
_type_map
=
get
(
vertex_type
,
*
graph
);
// 회색 색칠
for
(
auto
&
n
:
nodeList
)
{
...
...
@@ -258,7 +261,7 @@ void GraphItem::might_know()
// find target node
for
(
boost
::
tie
(
vi
,
vi_end
)
=
boost
::
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
if
(
label
[
*
vi
]
==
std
::
string
(
TARGET_AUTHOR_NAME
))
{
if
(
node_label_map
[
*
vi
]
==
std
::
string
(
TARGET_AUTHOR_NAME
))
{
vtarget
=
vi
;
break
;
}
...
...
@@ -286,7 +289,7 @@ void GraphItem::might_know()
for
(
boost
::
tie
(
ai
,
ai_end
)
=
boost
::
adjacent_vertices
(
*
vtarget
,
*
graph
);
ai
!=
ai_end
;
++
ai
)
{
might_know_vec
.
push_back
(
label
[
*
ai
]);
might_know_vec
.
push_back
(
node_label_map
[
*
ai
]);
}
// highlight
...
...
@@ -318,9 +321,9 @@ void GraphItem::topK_highlight_with_total()
vertex_iterator
vi
,
vi_end
;
Graph
::
adjacency_iterator
ai
,
ai_end
;
auto
node
Label
=
boost
::
get
(
vertex_name
,
*
graph
);
auto
node
Type
=
boost
::
get
(
vertex_type
,
*
graph
);
auto
n
umOfRecords
=
boost
::
get
(
vertex_record
,
*
graph
);
auto
node
_label_map
=
boost
::
get
(
vertex_name
,
*
graph
);
auto
node
_type_map
=
boost
::
get
(
vertex_type
,
*
graph
);
auto
n
ode_records_map
=
boost
::
get
(
vertex_record
,
*
graph
);
//실적 count 초기화
//for (boost::tie(vi, vi_end) = boost::vertices(*graph); vi != vi_end; ++vi) {
...
...
@@ -333,20 +336,20 @@ void GraphItem::topK_highlight_with_total()
// <record, label>
TopKHeap
<
pair
<
int
,
string
>>
heap
(
TOP_K
);
for
(
boost
::
tie
(
vi
,
vi_end
)
=
boost
::
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
if
(
node
Type
[
*
vi
]
!=
NODE_TYPE
::
NODE_AUTHOR
)
{
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
[
*
ai
]
==
NODE_TYPE
::
NODE_PAPER
)
{
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
[
*
vi
]));
heap
.
push
(
make_pair
(
record_cnt
,
node
_label_map
[
*
vi
]));
//qDebug() << record_cnt;
}
...
...
@@ -371,28 +374,53 @@ void GraphItem::topK_highlight_with_total()
}
}
void
GraphItem
::
test
()
void
GraphItem
::
find_shortest_path
()
{
qDebug
(
"* path highlighting start"
);
vertex_iterator
vi
,
vi_end
;
//find start, end node's id
auto
vertex_idx
=
boost
::
get
(
vertex_index
,
*
graph
);
auto
nodeLabel
=
boost
::
get
(
vertex_name
,
*
graph
);
int
start_idx
=-
1
,
end_idx
=-
1
;
for
(
boost
::
tie
(
vi
,
vi_end
)
=
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
//string node_name = boost::get(vertex_name, *graph, *vi);
const
string
&
node_name
=
nodeLabel
[
*
vi
];
if
(
node_name
==
"Jung Gon Kim"
)
{
start_idx
=
vertex_idx
[
*
vi
];
}
else
if
(
node_name
==
"Yong-Jin Kim"
)
{
end_idx
=
vertex_idx
[
*
vi
];
auto
node_idx_map
=
boost
::
get
(
vertex_index
,
*
graph
);
auto
node_label_map
=
boost
::
get
(
vertex_name
,
*
graph
);
string
target_start
,
target_end
;
bool
isok
=
false
;
QInputDialog
*
inputDialog
=
new
QInputDialog
();
target_start
=
inputDialog
->
getText
(
nullptr
,
"Enter target's name"
,
"Start node's name:"
,
QLineEdit
::
Normal
,
"Akira Idoue"
,
&
isok
).
toStdString
();
if
(
!
isok
)
{
qDebug
(
"input cancelled"
);
return
;
}
qDebug
()
<<
target_start
.
c_str
();
target_end
=
inputDialog
->
getText
(
nullptr
,
"Enter target's name"
,
"End node's name:"
,
QLineEdit
::
Normal
,
"Kayo Kurosaki"
,
&
isok
).
toStdString
();
if
(
!
isok
)
{
qDebug
(
"input cancelled"
);
return
;
}
qDebug
()
<<
target_end
.
c_str
();
int
start_idx
=
-
1
,
end_idx
=
-
1
;
for
(
boost
::
tie
(
vi
,
vi_end
)
=
vertices
(
*
graph
);
vi
!=
vi_end
;
++
vi
)
{
const
string
&
node_name
=
node_label_map
[
*
vi
];
if
(
node_name
==
target_start
)
{
start_idx
=
node_idx_map
[
*
vi
];
}
else
if
(
node_name
==
target_end
)
{
end_idx
=
node_idx_map
[
*
vi
];
}
}
if
(
start_idx
==-
1
||
end_idx
==
-
1
)
{
if
(
start_idx
==
-
1
||
end_idx
==
-
1
)
{
qDebug
()
<<
start_idx
<<
" "
<<
end_idx
;
qDebug
(
"no target node"
);
return
;
...
...
@@ -402,14 +430,25 @@ void GraphItem::test()
return
;
}
/*QMessageBox msgBox;
msgBox.setText("The document has been modified.");
msgBox.setInformativeText("Do you want to save your changes?");
msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
qDebug() << "ret: " << ret;
if (ret == QMessageBox::Save) {
qDebug() << "save";
}*/
vector
<
vertex_descriptor
>
parents
(
num_vertices
(
*
graph
));
vector
<
double
>
distances
(
num_vertices
(
*
graph
));
vertex_descriptor
start_vertex
=
boost
::
vertex
(
start_idx
,
*
graph
);
//shortest path using dijkstra
boost
::
dijkstra_shortest_paths
(
*
graph
,
start_vertex
,
predecessor_map
(
boost
::
make_iterator_property_map
(
parents
.
begin
(),
boost
::
get
(
boost
::
vertex_index
,
*
graph
)
)).
distance_map
(
boost
::
make_iterator_property_map
(
distances
.
begin
(),
get
(
boost
::
vertex_index
,
*
graph
)
)));
predecessor_map
(
boost
::
make_iterator_property_map
(
parents
.
begin
(),
node_idx_map
)).
distance_map
(
boost
::
make_iterator_property_map
(
distances
.
begin
(),
node_idx_map
)));
//check distances
//qDebug() << "dist: " << distances[end_idx];
...
...
@@ -426,20 +465,49 @@ void GraphItem::test()
//path finding
qDebug
(
"* path finding start"
);
vector
<
string
>
paths
;
vertex_descriptor
current
=
boost
::
vertex
(
end_idx
,
*
graph
);
qDebug
()
<<
"end: "
<<
nodeLabel
[
current
].
c_str
();
paths
.
push_back
(
node_label_map
[
current
]);
qDebug
()
<<
"end: "
<<
node_label_map
[
current
].
c_str
();
while
(
1
)
{
current
=
parents
[
vertex_idx
[
current
]];
qDebug
()
<<
nodeLabel
[
current
].
c_str
();
current
=
parents
[
node_idx_map
[
current
]];
paths
.
push_back
(
node_label_map
[
current
]);
qDebug
()
<<
node_label_map
[
current
].
c_str
();
if
(
current
==
start_vertex
)
break
;
}
qDebug
(
"* path finding end"
);
qDebug
(
"* path highlighting start"
);
for
(
auto
&
n
:
nodeList
)
{
if
(
find
(
paths
.
begin
(),
paths
.
end
(),
n
->
getLabel
().
toStdString
())
!=
paths
.
end
())
{
n
->
setColor
(
QColor
(
Qt
::
blue
));
}
}
size_t
paths_sz
=
paths
.
size
();
for
(
int
i
=
0
;
i
<
paths_sz
-
1
;
++
i
)
{
for
(
auto
&
e
:
edgeList
)
{
if
((
e
->
getFrom
().
toStdString
()
==
paths
[
i
]
&&
e
->
getTo
().
toStdString
()
==
paths
[
i
+
1
])
||
(
e
->
getFrom
().
toStdString
()
==
paths
[
i
+
1
]
&&
e
->
getTo
().
toStdString
()
==
paths
[
i
]))
{
e
->
setColor
(
QColor
(
Qt
::
blue
));
e
->
setWidth
(
3
);
}
}
}
qDebug
(
"* path highlighting end"
);
}
void
GraphItem
::
test
()
{
qDebug
(
"* test action start"
);
qDebug
(
"* test action end"
);
}
//event handler
void
GraphItem
::
mousePressEvent
(
QGraphicsSceneMouseEvent
*
event
)
{
...
...
PaperGraph/GraphItem.h
View file @
58969a2
...
...
@@ -29,6 +29,7 @@ public:
void
might_know
();
void
reset_color
();
void
topK_highlight_with_total
();
void
find_shortest_path
();
//test
void
test
();
...
...
PaperGraph/MainWindow.cpp
View file @
58969a2
...
...
@@ -48,6 +48,9 @@ void MainWindow::createActions()
resetColorAct
=
new
QAction
(
tr
(
"Reset colors"
),
this
);
resetColorAct
->
setStatusTip
(
tr
(
"Reset all node's color"
));
connect
(
resetColorAct
,
&
QAction
::
triggered
,
this
,
&
MainWindow
::
reset_color
);
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
);
testAct
=
new
QAction
(
tr
(
"test action"
),
this
);
testAct
->
setStatusTip
(
tr
(
"test test"
));
...
...
@@ -63,6 +66,7 @@ void MainWindow::createMenus()
actionMenu
->
addAction
(
mightKnowAct
);
actionMenu
->
addAction
(
topkAct
);
actionMenu
->
addAction
(
resetColorAct
);
actionMenu
->
addAction
(
findShortestPathAct
);
testMenu
=
menuBar
()
->
addMenu
(
tr
(
"&Test"
));
testMenu
->
addAction
(
testAct
);
...
...
@@ -84,7 +88,7 @@ void MainWindow::might_know()
void
MainWindow
::
topk
()
{
graphWidget
->
topk
();
graphWidget
->
topk
_with_total
();
}
void
MainWindow
::
reset_color
()
...
...
@@ -92,6 +96,11 @@ void MainWindow::reset_color()
graphWidget
->
reset_color
();
}
void
MainWindow
::
find_shortest_path
()
{
graphWidget
->
find_shortest_path
();
}
void
MainWindow
::
test
()
{
graphWidget
->
test
();
...
...
PaperGraph/MainWindow.h
View file @
58969a2
...
...
@@ -24,6 +24,7 @@ private:
QAction
*
mightKnowAct
;
QAction
*
topkAct
;
QAction
*
resetColorAct
;
QAction
*
findShortestPathAct
;
//test
QMenu
*
testMenu
;
...
...
@@ -38,6 +39,7 @@ private slots:
void
might_know
();
void
topk
();
void
reset_color
();
void
find_shortest_path
();
//test
void
test
();
};
...
...
PaperGraph/PaperGraphWidget.cpp
View file @
58969a2
...
...
@@ -56,12 +56,19 @@ void PaperGraphWidget::might_know()
scene
->
update
();
}
void
PaperGraphWidget
::
topk
()
void
PaperGraphWidget
::
topk
_with_total
()
{
//ü TopK highlight
graphItem
->
topK_highlight_with_total
();
scene
->
update
();
}
void
PaperGraphWidget
::
find_shortest_path
()
{
graphItem
->
find_shortest_path
();
scene
->
update
();
}
void
PaperGraphWidget
::
reset_color
()
{
graphItem
->
reset_color
();
...
...
@@ -71,11 +78,12 @@ void PaperGraphWidget::reset_color()
void
PaperGraphWidget
::
test
()
{
//test
testCombo
->
addItem
(
to_string
(
rand
()
%
300
).
c_str
());
testCombo
->
addItem
(
to_string
(
rand
()
%
300
).
c_str
());
testCombo
->
addItem
(
to_string
(
rand
()
%
300
).
c_str
());
//
testCombo->addItem(to_string(rand() % 300).c_str());
//
testCombo->addItem(to_string(rand() % 300).c_str());
//
testCombo->addItem(to_string(rand() % 300).c_str());
graphItem
->
test
();
scene
->
update
();
}
void
PaperGraphWidget
::
handleSelectionChanged
(
int
idx
)
...
...
PaperGraph/PaperGraphWidget.h
View file @
58969a2
...
...
@@ -16,7 +16,8 @@ public:
//main window slots
void
read_more
();
void
might_know
();
void
topk
();
void
topk_with_total
();
void
find_shortest_path
();
void
reset_color
();
//test
...
...
PaperGraph/stdafx.h
View file @
58969a2
...
...
@@ -7,6 +7,7 @@
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGridLayout>
#include <QInputDialog>
#include <QKeyEvent>
#include <QList>
#include <QMainWindow>
...
...
@@ -100,8 +101,10 @@ namespace {
/* visualization */
const
int
NODE_SIZE
=
4
;
const
int
LAYOUT_MODE
=
GRAPH_LAYOUT
::
RANDOM_LAYOUT
;
//const int SCREEN_SIZE = 3000;
const
int
SCREEN_SIZE
=
500
;
const
int
READ_LINE_UNIT
=
20
;
//한 번에 몇 라인을 읽을지
//const int READ_LINE_UNIT = 20; //한 번에 몇 라인을 읽을지
const
int
READ_LINE_UNIT
=
40
;
/* topK */
const
int
TOP_K
=
5
;
//상위 몇 개 아이템에 대해 highlight 할 지
...
...
Please
register
or
login
to post a comment