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

updated ui

parent c802eb09
No related branches found
No related tags found
No related merge requests found
Showing
with 556 additions and 610 deletions
<div class="container" ng-cloak ng-hide="$state.current.name !== 'about'">
<div class="row">
<div class="col-md-12">
<div class="page-header">
<h1>About</h1>
</div>
......@@ -274,4 +276,6 @@
</tbody>
</table>
</div>
</div>
</div>
<div ng-cloak ui-view></div>
<div class="container" ng-cloak ng-hide="$state.current.name !== 'articles'">
<div class="row">
<div class="col-md-12">
<div class="text-muted">
Found
<ng-pluralize count="articlesTotal||0" when="{0:'no articles',1:'1 article',other:'{} articles'}"></ng-pluralize> in the database.
......@@ -17,12 +19,32 @@
</span>
<br> Page <span ng-bind="page||1"></span> of <span ng-bind="maxPage||1"></span>.
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<pagination total="articlesTotal" page="page" limit="limit" change="changePage" />
<ol ng-attr-start="{{(page-1)*limit+1}}">
<li ng-repeat="article in articles">
</div>
</div>
<div class="row">
<div class="col-md-12">
<table class="table table-hover table-condensed">
<tbody>
<tr ng-repeat="article in articles">
<td>
<a ui-sref="articles.show({id: article.id})" ng-bind="::article.title"></a>
</li>
</ol>
&nbsp;
<small class="text-muted" ng-bind-template="[{{::Vipra.formatDate(article.date)}}]"></small>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-md-12">
<pagination total="articlesTotal" page="page" limit="limit" />
</div>
</div>
</div>
<div ng-cloak ui-view></div>
<div class="container" ng-cloak ng-hide="$state.current.name !== 'articles.show'">
<div class="row">
<div class="col-md-12">
<div class="page-header">
<h1 ng-bind="::article.title"></h1>
<table class="item-actions">
......@@ -8,18 +10,17 @@
Network graph
</a>
</td>
<td>
<a class="btn btn-default" ui-sref="articles.show.similar({id:article.id})">
Similar
</a>
</td>
</tr>
</table>
</div>
<h3>Info</h3>
</div>
</div>
<div class="row">
<div class="col-md-8">
<div class="row">
<div class="col-md-12">
<table class="table table-bordered table-condensed table-fixed table-infos">
<h3>Info</h3>
<table class="table table-bordered table-condensed table-infos">
<tbody>
<tr>
<th>ID</th>
......@@ -38,14 +39,6 @@
</a>
</td>
</tr>
<tr>
<th>Created</th>
<td ng-bind="::articleCreated"></td>
</tr>
<tr>
<th>Last modified</th>
<td ng-bind="::articleModified"></td>
</tr>
<tr>
<th>Word count</th>
<td ng-bind="::article.stats.wordCount"></td>
......@@ -54,32 +47,46 @@
</table>
</div>
</div>
<h3>Topics</h3>
<div class="row">
<div class="col-md-5">
<table class="table table-morecondensed" ng-show="article.topics.length > 0">
<div class="col-md-12">
<h3>Similar articles</h3>
<ul class="list-unstyled" ng-attr-start="{{(page-1)*limit+1}}">
<li ng-repeat="simArticle in article.similarArticles" class="ellipsize">
<small class="text-muted percent-align" ng-bind-template="({{((1-simArticle.divergence)*100).toFixed(0)}}%)"></small>
<a ui-sref="articles.show({id: simArticle.article.id})" ng-attr-title="{{::simArticle.article.title}}" ng-bind="::simArticle.article.title"></a>
</li>
</ul>
</div>
</div>
</div>
<div class="col-md-4">
<h3>Topics</h3>
<table class="table table-bordered table-condensed table-nomargin" ng-show="article.topics.length > 0">
<tbody>
<tr>
<th>
Name
</th>
<th class="topic-share">
<th class="topic-share text-right">
Share
</th>
</tr>
<tr ng-repeat="topic in article.topics | orderBy:topicSort:topicSortRev">
<td>
<topic-link topic="topic.topic" />
<span class="colorbox" style="background:{{::topic.color}}"></span>
</td>
<td class="text-right" ng-bind-template="{{(topic.share*100).toFixed(1)}}%"></td>
</tr>
</tbody>
</table>
<span class="text-muted" ng-hide="article.topics.length > 0">No topics</span>
</div>
<div class="col-md-7">
<div class="pie-chart" id="topic-share" highcharts="topicShare"></div>
</div>
</div>
<hr>
<p ng-bind-html="::article.text" class="text-justify"></p>
<div class="row">
<div class="col-md-12 text-justify" ng-bind-html="::article.text"></div>
</div>
</div>
<div ng-cloak ui-view></div>
<div class="container" ng-cloak ng-hide="$state.current.name !== 'articles.show.similar'">
<div class="page-header">
<h1 ng-bind="::article.title"></h1>
<table class="item-actions">
<tr>
<td>
<a class="btn btn-default" ui-sref="^">Back</a>
</td>
</tr>
</table>
</div>
<h3>Similar articles</h3>
<div class="row">
</div>
</div>
\ No newline at end of file
......@@ -24,7 +24,7 @@
<label class="check" ng-attr-for="{{::topic.id}}">
<span class="ellipsis" ng-bind="::topic.name"></span>
</label>
<span class="colorbox" style="background:rgb({{::topic.color.join()}})"></span>
<span class="colorbox" style="background:{{::topic.color}}"></span>
</div>
</li>
</ul>
......
......@@ -47,7 +47,7 @@
<p>
<span class="text" ng-bind="article.text"></span>
<br>
<small class="text-muted" ng-bind-template="{{article.meta.score | toPercent}}% &ndash; {{article.date | formatDate}}"></small>
<small class="text-muted" ng-bind-template="{{::Vipra.toPercent(article.meta.score)}}% &ndash; {{::Vipra.formatDate(article.date)}}"></small>
</p>
</li>
</ul>
......
<div class="container" ng-cloak ng-hide="$state.current.name !== 'topics'">
<div class="row">
<div class="col-md-12">
<div class="text-muted">
Found
<ng-pluralize count="topicsTotal||0" when="{0:'no topics',1:'1 topic',other:'{} topics'}"></ng-pluralize> in the database.
......@@ -16,12 +18,30 @@
</span>
<br> Page <span ng-bind="page||1"></span> of <span ng-bind="maxPage||1"></span>.
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<pagination total="topicsTotal" page="page" limit="limit" change="changePage" />
<ol ng-attr-start="{{(page-1)*limit+1}}">
<li ng-repeat="topic in topics">
<a ui-sref="topics.show({id: topic.id})">{{topic.name}}</a>
</li>
</ol>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table class="table table-hover table-condensed">
<tbody>
<tr ng-repeat="topic in topics">
<td>
<a ui-sref="topics.show({id: topic.id})" ng-bind="::topic.name"></a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-md-12">
<pagination total="topicsTotal" page="page" limit="limit" />
</div>
</div>
</div>
<div ng-cloak ui-view></div>
<div class="container" ng-cloak ng-hide="$state.current.name !== 'topics.show'">
<div class="row">
<div class="col-md-12">
<div class="page-header">
<h1>
<div ng-bind="topic.name" ng-hide="isRename"></div>
......@@ -36,9 +38,11 @@
</tr>
</table>
</div>
<h3>Info</h3>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h3>Info</h3>
<table class="table table-bordered table-condensed table-fixed table-infos">
<tbody>
<tr>
......@@ -57,9 +61,9 @@
</table>
</div>
</div>
<h3>Relevance over time</h3>
<div class="row">
<div class="col-md-12">
<h3>Relevance over time</h3>
<div class="well well-sm">
<div class="radio radio-inline">
<input type="radio" id="seqAbsolute" ng-model="opts.seqstyle" value="absolute">
......@@ -72,8 +76,7 @@
</div>
</div>
</div>
<br>
<div class="row">
<div class="row row-spaced">
<div class="col-md-12">
<div class="area-chart" id="topic-seq" highcharts="topicSeq"></div>
</div>
......
......@@ -16,7 +16,6 @@
'vipra.controllers',
'vipra.directives',
'vipra.factories',
'vipra.filters',
'vipra.templates'
]);
......@@ -64,12 +63,6 @@
controller: 'ArticlesShowController'
});
$stateProvider.state('articles.show.similar', {
url: '/similar',
templateUrl: 'html/articles/similar.html',
controller: 'ArticlesSimilarController'
});
// states: topics
$stateProvider.state('topics', {
......@@ -136,6 +129,8 @@
$rootScope.loading = {};
$rootScope.Vipra = window.Vipra;
}]);
})();
......@@ -2,7 +2,7 @@
* Vipra Application
* Controllers
******************************************************************************/
/* globals angular, Vipra, moment, vis, console, $, prompt */
/* globals angular, Vipra, moment, vis, console, $, prompt, randomColor */
(function() {
"use strict";
......@@ -309,7 +309,7 @@
fields: 'name,sequences,avgRelevance,varRelevance,risingRelevance,fallingRelevance,risingDecayRelevance'
}, function(data) {
$scope.topics = data;
var colors = Vipra.generateColors($scope.topics.length);
var colors = randomColor({ count: $scope.topics.length, seed: 1 });
for (var i = 0; i < $scope.topics.length; i++)
$scope.topics[i].color = colors[i];
}, function(err) {
......@@ -353,7 +353,7 @@
series.push({
name: topic.name,
data: relevances,
color: 'rgb(' + topic.color.join() + ')'
color: topic.color
});
}
}
......@@ -430,11 +430,26 @@
// calculate percentage share
if ($scope.article.topics) {
var topicShareSeries = [],
topics = $scope.article.topics;
for (var i = 0; i < topics.length; i++) {
topicShareSeries.push({ name: topics[i].topic.name.ellipsize(20), y: topics[i].share });
topics = $scope.article.topics,
maximum = { y: 0 },
colors = randomColor({ count: $scope.article.topics.length });
for (var i = 0, d; i < topics.length; i++) {
d = {
name: topics[i].topic.name,
y: topics[i].share,
color: colors[i]
};
topicShareSeries.push(d);
if(d.y > maximum.y)
maximum = d;
$scope.article.topics[i].color = colors[i];
}
// preselect biggest value
maximum.selected = maximum.sliced = true;
// highcharts data
$scope.topicShare = topicShareChart([{
name: 'Topic Share',
......@@ -452,16 +467,8 @@
/**
* Article Similar route
*/
app.controller('ArticlesSimilarController', ['$scope', '$stateParams', 'ArticleFactory',
function($scope, $stateParams, ArticleFactory) {
ArticleFactory.get({
id: $stateParams.id
}, function(data) {
$scope.articles = data;
}, function(err) {
$scope.errors = err;
});
app.controller('ArticlesSimilarController', [
function() {
}
]);
......@@ -696,10 +703,20 @@
function topicShareChart(series) {
return {
chart: { type: 'pie' },
chart: {
type: 'pie',
spacingBottom: 0,
spacingTop: 0,
spacingLeft: 20,
spacingRight: 20,
},
credits: { enabled: false },
plotOptions: {
pie: { allowPointSelect: true }
pie: {
size: '100%',
dataLabels: { enabled: false },
allowPointSelect: true
}
},
title: { text: '' },
tooltip: { pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>' },
......
/******************************************************************************
* Vipra Application
* Filters
******************************************************************************/
/* globals angular, Vipra */
(function() {
"use strict";
var app = angular.module('vipra.filters', []);
app.filter('toPercent', function() {
return Vipra.toPercent;
});
app.filter('formatDate', function() {
return Vipra.formatDate;
});
app.filter('formatDateTime', function() {
return Vipra.formatDateTime;
});
})();
......@@ -9,6 +9,8 @@
window.Vipra = window.Vipra || {};
Vipra.momo = 'hi';
/**
* Helpers
*/
......@@ -36,98 +38,6 @@
return 'id' + Math.random().toString(36).substring(7);
};
/**
* taken from
* https://jsfiddle.net/aldass/9f0yadfy/
*/
Vipra.generateColors = function(t) {
t = parseInt(t);
if (t < 2)
throw new Error("'t' must be greater than 1.");
// distribute the colors evenly on
// the hue range (the 'H' in HSV)
var i = 360 / (t - 1);
// hold the generated colors
var r = [];
var sv = 70;
for (var x = 0; x < t; x++) {
// alternate the s, v for more
// contrast between the colors.
sv = sv > 90 ? 70 : sv + 10;
r.push(Vipra.hsvToRgb(i * x, sv, sv));
}
return r;
};
/**
* HSV to RGB color conversion
*
* H runs from 0 to 360 degrees
* S and V run from 0 to 100
*
* Ported from the excellent java algorithm by Eugene Vishnevsky at:
* http://www.cs.rit.edu/~ncs/color/t_convert.html
*/
Vipra.hsvToRgb = function(h, s, v) {
var r, g, b;
var i;
var f, p, q, t;
h = Math.max(0, Math.min(360, h));
s = Math.max(0, Math.min(100, s));
v = Math.max(0, Math.min(100, v));
s /= 100;
v /= 100;
if (s === 0) {
r = g = b = v;
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
h /= 60;
i = Math.floor(h);
f = h - i;
p = v * (1 - s);
q = v * (1 - s * f);
t = v * (1 - s * (1 - f));
switch (i) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default:
r = v;
g = p;
b = q;
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
};
/**
* Polyfills
*/
......
......@@ -181,13 +181,6 @@ ul.dashed {
}
}
.row {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
.caret.caret-up {
content: "";
border-top: 0;
......@@ -198,18 +191,16 @@ ul.dashed {
padding: 0;
}
.page-header h1 {
min-height: 48px;
}
.table-fixed {
table-layout: fixed;
}
.table-infos {
tr > *:first-child {
width: 200px;
.table-nomargin {
margin: 0;
}
.page-header h1 {
min-height: 48px;
}
.nya-bs-condensed {
......@@ -288,6 +279,14 @@ revolve-select, [revolve-select] {
vertical-align: middle;
}
.colorbox {
display: inline-block;
width: 10px;
height: 20px;
vertical-align: middle;
float: right;
}
.explorer {
@sidebar-width: 300px;
......@@ -338,14 +337,10 @@ revolve-select, [revolve-select] {
}
.colorbox {
display: inline-block;
visibility: hidden;
width: 10px;
height: 20px;
vertical-align: middle;
position: absolute;
right: 0;
top: 0;
visibility: hidden;
}
.checkbox:hover .colorbox,
......@@ -415,6 +410,19 @@ input[type=checkbox],
}
}
.table-infos {
th {
white-space: nowrap;
}
}
.percent-align {
width: 45px;
text-align: right;
display: inline-block;
vertical-align: text-top;
}
@-moz-keyframes spin { 100% { -moz-transform: rotateY(360deg); } }
@-webkit-keyframes spin { 100% { -webkit-transform: rotateY(360deg); } }
@keyframes spin { 100% { -webkit-transform: rotateY(360deg); transform:rotateY(360deg); } }
......
......@@ -21,15 +21,15 @@
"jquery": "^2.x",
"angular": "^1.x",
"angular-resource": "^1.x",
"angular-ui-router": "^0.2.17",
"angular-ui-router": "^0.x",
"angular-sanitize": "^1.x",
"highcharts": "^4.x",
"vis": "^4.x",
"moment": "^2.x",
"nya-bootstrap-select": "^2.x",
"font-awesome": "^4.x",
"awesome-bootstrap-checkbox": "^0.3.7",
"angular-bootstrap": "^1.x",
"angular-animate": "^1.5.0"
"awesome-bootstrap-checkbox": "^0.x",
"angular-animate": "^1.x",
"randomcolor": "randomColor#^0.x"
}
}
......@@ -19,11 +19,11 @@ var assets = {
'bower_components/angular-sanitize/angular-sanitize.min.js',
'bower_components/angular-ui-router/release/angular-ui-router.min.js',
'bower_components/bootstrap/dist/js/bootstrap.min.js',
//'bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js',
'bower_components/highcharts/highcharts.js',
'bower_components/vis/dist/vis.min.js',
'bower_components/moment/min/moment.min.js',
'bower_components/nya-bootstrap-select/dist/js/nya-bs-select.min.js'
'bower_components/nya-bootstrap-select/dist/js/nya-bs-select.min.js',
'bower_components/randomcolor/randomColor.js'
],
css: [
'bower_components/bootstrap/dist/css/bootstrap.min.css',
......
......@@ -106,7 +106,7 @@ public class Constants {
* Maximum divergence between a document and similar documents. Lower values
* mean more similar documents (less divergence). Default 1.0.
*/
public static final double MAX_DIVERGENCE = 1.0;
public static final double MAX_DIVERGENCE = 0.25;
/**
* Dynamic minimum iterations. Used for dynamic topic modeling. Default 100.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment