Skip to content
Snippets Groups Projects
Commit 0e410c2f authored by Eike Cochu's avatar Eike Cochu
Browse files

updated network graph

parent 3051919a
No related branches found
No related tags found
No related merge requests found
<div class="fullsize navpadding" vis-network vis-type="type" ng-model="model">
<div class="graph-legend">
<span style="color:#BBC9D2">Articles</span><br>
<span style="color:#DBB234">Topics</span><br>
<div class="fullsize navpadding" vis-network vis-type="type" vis-colors="colors" vis-shown="shown" ng-model="model">
<div class="graph-legend overlay">
<span style="color:{{colors.articles}}"><input type="checkbox" ng-model="shown.articles"> Articles</span><br>
<span style="color:{{colors.topics}}"><input type="checkbox" ng-model="shown.topics"> Topics</span><br>
<span style="color:{{colors.words}}"><input type="checkbox" ng-model="shown.words"> Words</span><br>
</div>
</div>
\ No newline at end of file
......@@ -52,6 +52,16 @@
function($scope, $state, $stateParams, ArticleFactory, TopicFactory) {
$scope.type = $stateParams.type;
$scope.colors = {
articles: '#BBC9D2',
topics: '#DBB234',
words: '#547C65'
};
$scope.shown = {
articles: true,
topics: true,
words: true
};
var factory;
if($stateParams.type === 'articles')
......
......@@ -57,30 +57,24 @@
};
});
app.directive('visNetwork', ['$state', '$timeout', 'ArticleFactory', 'TopicFactory',
function($state, $timeout, ArticleFactory, TopicFactory) {
app.directive('visNetwork', ['$state', '$timeout', 'ArticleFactory', 'TopicFactory', 'WordFactory',
function($state, $timeout, ArticleFactory, TopicFactory, WordFactory) {
return {
scope: {
ngModel: '=',
visType: '=',
visData: '=',
visOptions: '='
visColors: '=',
visShown: '='
},
transclude: true,
template: '<ng-transclude/><div class="fullsize navpadding" id="visgraph"></div>',
link: function($scope, $element) {
var id = 0,
ids = {},
nodes = [],
edges = [],
articleColor = '#BBC9D2',
topicColor = '#DBB234',
wordColor = '#B6C7BD',
container = $element.find("#visgraph")[0];
$scope.articleColor = articleColor;
$scope.topicColor = topicColor;
$scope.nodes = new vis.DataSet();
$scope.edges = new vis.DataSet();
$scope.data = {
......@@ -90,7 +84,7 @@
$scope.options = {
nodes: {
font: { size: 11 },
font: { size: 14 },
shape: 'dot',
borderWidth: 0
},
......@@ -102,57 +96,46 @@
layout: { randomSeed: 1 },
physics: {
barnesHut: {
springConstant: 0.005,
gravitationalConstant: -5000
springConstant: 0.008,
gravitationalConstant: -3500
}
}
};
var topicNode = function(topic) {
var newNode = function(title, type, show, dbid, color, shape) {
ids[dbid] = ++id;
return {
id: ++id,
title: topic.name,
label: topic.name.ellipsize(20),
type: 'topic',
topic: topic.id,
id: id,
title: title,
label: title,
type: type,
show: show,
dbid: dbid,
shape: shape || 'dot',
color: {
background: topicColor,
highlight: { background: topicColor }
background: color,
highlight: { background: color }
}
};
};
var topicNode = function(topic) {
topic = topic.topic || topic;
return newNode(topic.name, 'topic', 'topics.show', topic.id, $scope.visColors.topics, 'triangle');
};
var articleNode = function(article) {
return {
id: ++id,
title: article.title,
label: article.title.ellipsize(20),
type: 'article',
article: article.id,
color: {
background: articleColor,
highlight: { background: articleColor }
}
};
return newNode(article.title, 'article', 'articles.show', article.id, $scope.visColors.articles, 'square');
};
var wordNode = function(word) {
return {
id: ++id,
title: word.word,
label: word.word,
type: 'word',
word: word.word,
color: {
background: wordColor,
highlight: { background: wordColor }
}
};
return newNode(word.id, 'word', 'words.show', word.id, $scope.visColors.words);
};
var constructor = function(result, key, nodeFunction) {
if(result.data && result.data[key]) {
var data = result.data[key],
// construct new nodes
var constructor = function(result, node, key, nodeFunction) {
if(result.data && (!key || result.data[key])) {
var data = key ? result.data[key] : result.data,
newNodes = [],
newEdges = [];
for(var i = 0; i < data.length; i++) {
......@@ -163,7 +146,6 @@
} else {
newNodes.push(nodeFunction(current));
newEdges.push({from:id, to:node.id});
ids[current.id] = id;
}
}
if(newNodes.length) $scope.nodes.add(newNodes);
......@@ -178,24 +160,40 @@
selectTimeout = $timeout(function() {
var node = $scope.nodes.get(props.nodes[0]);
if(node && !node.loaded) {
if(node.type === 'article') {
var loaded = false;
if(node.type === 'article' && $scope.visShown.topics) {
// node is article, load article to get topics
ArticleFactory.get({id:node.article}, function(res) {
constructor(res, 'topics', topicNode);
ArticleFactory.get({id:node.dbid}, function(res) {
for(var i = 0; i < res.data.topics.length; i++)
res.data.topics[i] = res.data.topics[i].topic;
constructor(res, node, 'topics', topicNode);
});
loaded = true;
} else if(node.type === 'topic') {
// node is topic, load topic to get words
TopicFactory.get({id:node.topic}, function(res) {
constructor(res, 'words', wordNode);
});
} else if(node.type === 'word') {
// node is topic, load topic to get words and articles
if($scope.visShown.words) {
TopicFactory.get({id:node.dbid}, function(res) {
constructor(res, node, 'words', wordNode);
});
loaded = true;
}
if($scope.visShown.articles) {
TopicFactory.articles({id:node.dbid}, function(res) {
constructor(res, node, null, articleNode);
});
loaded = true;
}
} else if(node.type === 'word' && $scope.visShown.topics) {
// node is word, load word to get topics
WordFactory.get({id:node.word}, function(res) {
constructor(res, 'topics', topicNode);
WordFactory.get({id:node.dbid}, function(res) {
constructor(res, node, 'topics', topicNode);
});
loaded = true;
}
if(loaded) {
node.loaded = true;
$scope.nodes.update(node);
}
node.loaded = true;
$scope.nodes.update(node);
}
}, 500);
};
......@@ -204,31 +202,22 @@
$scope.open = function(props) {
$timeout.cancel(selectTimeout);
var node = $scope.nodes.get(props.nodes[0]);
if(node.type === 'article')
$state.transitionTo('articles.show', {id:node.article});
else if(node.type === 'topic')
$state.transitionTo('topics.show', {id:node.topic});
else if(node.type === 'word')
$state.transitionTo('words.show', {id:node.word});
$state.transitionTo(node.show, {id:node.dbid});
};
// watch for changes to model
$scope.$watch('ngModel', function(newVal, oldVal) {
if(!newVal) return;
// root node
// add root node
if($scope.visType === 'articles')
nodes.push(articleNode($scope.ngModel));
$scope.nodes.add([articleNode($scope.ngModel)]);
else if($scope.visType === 'topics')
nodes.push(topicNode($scope.ngModel));
$scope.nodes.add([topicNode($scope.ngModel)]);
else if($scope.visType === 'words')
nodes.push(wordNode($scope.ngModel));
$scope.nodes.add([wordNode($scope.ngModel)]);
ids[$scope.ngModel.id] = id;
// add nodes and edges
$scope.nodes.add(nodes);
$scope.edges.add(edges);
// create graph
$scope.visGraph = new vis.Network(container, $scope.data, $scope.options);
$scope.visGraph.on('selectNode', $scope.select);
......
......@@ -16,7 +16,8 @@
app.factory('TopicFactory', ['$resource', function($resource) {
return $resource(endpoint + '/topics/:id', {}, {
query: { isArray: false, cache: true }
query: { isArray: false, cache: true },
articles: { method: 'GET', isArray: false, url: endpoint + '/topics/:id/articles', cache: true }
});
}]);
......
......@@ -93,6 +93,7 @@ ul.dashed {
}
.loading:before {
.overlay;
position: absolute;
top: 0;
left: 0;
......@@ -100,7 +101,6 @@ ul.dashed {
bottom: 0;
background: rgba(0,0,0,0.1);
content: " ";
z-index: 9999;
}
.spinner {
......@@ -175,6 +175,10 @@ ul.dashed {
width: auto;
}
.overlay {
z-index: 9999;
}
#nprogress .spinner {
display: none;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment