Skip to content

Commit

Permalink
Introduce the vertex attribute 'kind'
Browse files Browse the repository at this point in the history
Now, the different kindes of artifacts (mail, issue, file, function,
feature) can be plotted with different colors. For this functionality a
new vertex attribute 'kind' is necessary, which include the informations
of the attribute 'artifact.type' or the vertex type 'author'.

Signed-off-by: Barbara Eckl <[email protected]>
Signed-off-by: Claus Hunsen <[email protected]>
  • Loading branch information
ecklbarb committed Apr 17, 2018
1 parent 1d19970 commit 43ea94f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 10 deletions.
32 changes: 25 additions & 7 deletions util-networks.R
Original file line number Diff line number Diff line change
Expand Up @@ -403,11 +403,11 @@ NetworkBuilder = R6::R6Class("NetworkBuilder",
relation,
cochange = {
bip.relation = private$proj.data$get.author2artifact()
artifact.type =private$proj.data$get.project.conf.entry("artifact")
artifact.type = private$proj.data$get.project.conf.entry("artifact")
},
callgraph = {
bip.relation = private$proj.data$get.author2artifact()
artifact.type =private$proj.data$get.project.conf.entry("artifact")
artifact.type = private$proj.data$get.project.conf.entry("artifact")
},
mail = {
bip.relation = private$proj.data$get.author2thread()
Expand Down Expand Up @@ -547,6 +547,9 @@ NetworkBuilder = R6::R6Class("NetworkBuilder",
## TODO get edge and vertex data
)
igraph::E(network)$relation = relation

# the kind is in this case the same as the type attribute
igraph::V(network)$kind = TYPE.AUTHOR
return(network)
})
net = merge.networks(networks)
Expand Down Expand Up @@ -591,7 +594,7 @@ NetworkBuilder = R6::R6Class("NetworkBuilder",

## construct network
relations = private$network.conf$get.value("artifact.relation")
networks = lapply(relations, function(relation){
networks = lapply(relations, function(relation) {
network = switch(
relation,
cochange = private$get.artifact.network.cochange(),
Expand All @@ -601,6 +604,13 @@ NetworkBuilder = R6::R6Class("NetworkBuilder",
stop(sprintf("The artifact relation '%s' does not exist.", relation))
)
igraph::E(network)$relation = relation

## for cochange, we use the exact artifact type as vertex attribute 'kind'
if (relation == "cochange") {
igraph::V(network)$kind = private$proj.data$get.project.conf.entry("artifact")
} else {
igraph::V(network)$kind = relation
}
return(network)
})
net = merge.networks(networks)
Expand Down Expand Up @@ -642,7 +652,8 @@ NetworkBuilder = R6::R6Class("NetworkBuilder",
vertices = data.frame(
name = c(author.vertices, artifact.vertices),
type = c(rep(TYPE.AUTHOR, length(author.vertices)), rep(TYPE.ARTIFACT, length(artifact.vertices))),
artifact.type = c(rep(NA, length(author.vertices)), rep(artifact.type, length(artifact.vertices)))
artifact.type = c(rep(NA, length(author.vertices)), rep(artifact.type, length(artifact.vertices))),
kind = c(rep(TYPE.AUTHOR, length(author.vertices)), rep(artifact.type , length(artifact.vertices)))
)
return(vertices)
})
Expand Down Expand Up @@ -714,6 +725,7 @@ NetworkBuilder = R6::R6Class("NetworkBuilder",
networks = self$get.networks()
authors.to.artifacts = networks[["authors.to.artifacts"]]
authors.net = networks[["authors.net"]]
igraph::V(authors.net)$kind = TYPE.AUTHOR
artifacts.net = networks[["artifacts.net"]]

## remove authors from author-artifact relation, if needed:
Expand All @@ -736,13 +748,19 @@ NetworkBuilder = R6::R6Class("NetworkBuilder",
## "cochange" and "callgraph"), then the vertex names need to be unified so that all vertices are
## represented properly and, more important here, all bipartite relations can be added
artifacts = lapply(authors.to.artifacts, function(a2a.rel) {
return(unique(plyr::rbind.fill(a2a.rel)[[ "data.vertices" ]]))
artifact.list = plyr::rbind.fill(a2a.rel)[ c("data.vertices", "artifact.type") ]
artifact.list = unique(artifact.list)
return(artifact.list)
})
artifacts.all <- unlist(artifacts)
artifacts.all = plyr::rbind.fill(artifacts)

artifacts.from.net = igraph::get.vertex.attribute(artifacts.net, "name")
# browser(expr = length(setdiff(artifacts.all, artifacts.from.net)) > 0)
artifacts.net = artifacts.net + igraph::vertices(setdiff(artifacts.all, artifacts.from.net), type = TYPE.ARTIFACT)
artifacts.to.add = setdiff(artifacts.all[["data.vertices"]], artifacts.from.net)
artifacts.to.add.kind = artifacts.all[ artifacts.all[["data.vertices"]] %in% artifacts.to.add, "artifact.type" ]
artifacts.net = artifacts.net + igraph::vertices(artifacts.to.add, type = TYPE.ARTIFACT,
artifact.type = artifacts.to.add.kind,
kind = artifacts.to.add.kind)

## check directedness and adapt artifact network if needed
if (igraph::is.directed(authors.net) && !igraph::is.directed(artifacts.net)) {
Expand Down
6 changes: 3 additions & 3 deletions util-plot.R
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ PLOT.VERTEX.SIZE = 10
PLOT.VERTEX.SIZE.LEGEND = PLOT.VERTEX.SIZE / 2

## vertex-label color
PLOT.VERTEX.LABEL.COLOR = "gray55"
PLOT.VERTEX.LABEL.COLOR = "gray60"


## / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /
Expand Down Expand Up @@ -144,14 +144,14 @@ plot.get.plot.for.network = function(network, labels = TRUE) {
p = p +

## plot vertices
ggraph::geom_node_point(ggplot2::aes(color = vertex.type, shape = vertex.type), size = PLOT.VERTEX.SIZE) +
ggraph::geom_node_point(ggplot2::aes(color = kind, shape = vertex.type), size = PLOT.VERTEX.SIZE) +
ggraph::geom_node_text(ggplot2::aes(label = if (labels) name else c("")), size = 3.5, color = PLOT.VERTEX.LABEL.COLOR) +


## scale vertices (colors and styles)
ggplot2::scale_shape_discrete(name = "Vertices", solid = TRUE) +
viridis::scale_color_viridis(name = "Vertices", option = "plasma", discrete = TRUE,
end = 0.8, begin = 0.40) +
end = 0.8, begin = 0.05) +

## scale edges (colors and styles)
ggraph::scale_edge_linetype(name = "Relations") +
Expand Down
6 changes: 6 additions & 0 deletions util-read.R
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ read.mails = function(data.path) {
## set pattern for thread ID for better recognition
mail.data[["thread"]] = sprintf("<thread-%s>", mail.data[["thread"]])

## set proper artifact type for proper vertex attribute 'artifact.type'
mail.data["artifact.type"] = "Mail"

## remove mails without a proper date as they mess up directed mail-based networks
## this basically only applies for project-level analysis
empty.dates = which(mail.data[["date"]] == "" | is.na(mail.data[["date"]]))
Expand Down Expand Up @@ -381,6 +384,9 @@ read.issues = function(data.path) {
## set pattern for issue ID for better recognition
issue.data[["issue.id"]] = sprintf("<issue-%s>", issue.data[["issue.id"]])

## set proper artifact type for proper vertex attribute 'artifact.type'
issue.data["artifact.type"] = "Issue"

## convert 'is.pull.request' column to logicals
issue.data[["is.pull.request"]] = as.logical(issue.data[["is.pull.request"]])

Expand Down

0 comments on commit 43ea94f

Please sign in to comment.