diff --git a/vipra-ui/app/html/articles/index.html b/vipra-ui/app/html/articles/index.html index 49ab0bc935473eecd1d9cef885b21b3e164b6d46..2aae37d40bba5977d759450a9972ea9c78bb0181 100644 --- a/vipra-ui/app/html/articles/index.html +++ b/vipra-ui/app/html/articles/index.html @@ -23,7 +23,7 @@ </div> <div class="row"> <div class="col-md-12"> - <pagination total="articlesTotal" page="page" limit="limit" change="changePage" /> + <pagination total="articlesTotal" page="page" limit="limit" /> </div> </div> <div class="row"> diff --git a/vipra-ui/app/html/articles/show.html b/vipra-ui/app/html/articles/show.html index 3f335dee4593485392aded28bf80ab4ebabb4bff..8666ede849312103b2f1283386cf32d7af3e7712 100644 --- a/vipra-ui/app/html/articles/show.html +++ b/vipra-ui/app/html/articles/show.html @@ -51,7 +51,7 @@ <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"> + <li ng-repeat="simArticle in article.similarArticles" class="ellipsis"> <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> diff --git a/vipra-ui/app/html/explorer.html b/vipra-ui/app/html/explorer.html index 8734f3db1e4bc341738930b8adaf6ab75b7af631..d41fb5268facc705106dd1d7b83c6cf0eb024218 100644 --- a/vipra-ui/app/html/explorer.html +++ b/vipra-ui/app/html/explorer.html @@ -19,7 +19,7 @@ </div> <ul class="list-unstyled topic-choice"> <li ng-repeat="topic in topics | orderBy:opts.sorttopics | filter:search"> - <div class="checkbox checkbox-condensed" ng-attr-title="{{::topic.name}}" ng-class="{selected:opts.selectedTopics[topic.id]}"> + <div class="checkbox checkbox-condensed" ng-class="{selected:opts.selectedTopics[topic.id]}" bs-popover popover-title="{{::topic.name}}" popover-html="{{::topicPopover(topic)}}"> <input type="checkbox" ng-model="opts.selectedTopics[topic.id]" ng-attr-id="{{::topic.id}}"> <label class="check" ng-attr-for="{{::topic.id}}"> <span class="ellipsis" ng-bind="::topic.name"></span> @@ -30,27 +30,29 @@ </ul> </div> <div class="center message-container"> - <div class="topbar"> - <small>Values:</small> - <div class="btn-group"> - <a class="btn btn-sm btn-default" ng-model="opts.seqstyle" bs-radio="'absolute'">Absolute</a> - <a class="btn btn-sm btn-default" ng-model="opts.seqstyle" bs-radio="'relative'">Relative</a> - </div> - - <small>Chart:</small> - <div class="btn-group"> - <a class="btn btn-sm btn-default" ng-model="opts.chartstyle" bs-radio="'areaspline'">Area</a> - <a class="btn btn-sm btn-default" ng-model="opts.chartstyle" bs-radio="'spline'">Line</a> - </div> - - <small>Stacking:</small> - <div class="btn-group"> - <a class="btn btn-sm btn-default" ng-model="opts.chartstack" bs-radio="'none'">None</a> - <a class="btn btn-sm btn-default" ng-model="opts.chartstack" bs-radio="'normal'">Value</a> - <a class="btn btn-sm btn-default" ng-model="opts.chartstack" bs-radio="'percent'">Percent</a> + <div class="wrapper"> + <div class="topbar"> + <small>Values:</small> + <div class="btn-group"> + <a class="btn btn-sm btn-default" ng-model="opts.seqstyle" bs-radio="'absolute'">Absolute</a> + <a class="btn btn-sm btn-default" ng-model="opts.seqstyle" bs-radio="'relative'">Relative</a> + </div> + + <small>Chart:</small> + <div class="btn-group"> + <a class="btn btn-sm btn-default" ng-model="opts.chartstyle" bs-radio="'areaspline'">Area</a> + <a class="btn btn-sm btn-default" ng-model="opts.chartstyle" bs-radio="'spline'">Line</a> + </div> + + <small>Stacking:</small> + <div class="btn-group"> + <a class="btn btn-sm btn-default" ng-model="opts.chartstack" bs-radio="'none'">None</a> + <a class="btn btn-sm btn-default" ng-model="opts.chartstack" bs-radio="'normal'">Value</a> + <a class="btn btn-sm btn-default" ng-model="opts.chartstack" bs-radio="'percent'">Percent</a> + </div> </div> + <div class="chart" id="topic-seq" highcharts="topicSeq"></div> + <div class="message text-muted" ng-show="!topicsSelected">No topic selected</div> </div> - <div class="chart" id="topic-seq" highcharts="topicSeq"></div> - <div class="message text-muted" ng-show="!topicsSelected">No topic selected</div> </div> </div> \ No newline at end of file diff --git a/vipra-ui/app/html/index.html b/vipra-ui/app/html/index.html index 060ae53dcf0550b946a9206e627187ee4379a0cb..778502353cc8ab0b1236de6dc110dc6ee504c067 100644 --- a/vipra-ui/app/html/index.html +++ b/vipra-ui/app/html/index.html @@ -13,7 +13,7 @@ <div class="col-md-8 text-center"> <h4>Latest articles</h4> <ul class="list-unstyled"> - <li class="ellipsize" ng-repeat="article in latestArticles"> + <li class="ellipsis" ng-repeat="article in latestArticles"> <a ui-sref="articles.show({id:article.id})" ng-bind="article.title"></a> </li> </ul> @@ -21,7 +21,7 @@ <div class="col-md-4 text-center"> <h4>Latest topics</h4> <ul class="list-unstyled"> - <li class="ellipsize" ng-repeat="topic in latestTopics"> + <li class="ellipsis" ng-repeat="topic in latestTopics"> <a ui-sref="topics.show({id:topic.id})" ng-bind="topic.name"></a> </li> </ul> diff --git a/vipra-ui/app/html/topics/articles.html b/vipra-ui/app/html/topics/articles.html index 8f52eb096c2567ffaee99773e98b7dc4d7db0dfb..363190a7405a5ff41bf5ec286ed28ae5f30f707b 100644 --- a/vipra-ui/app/html/topics/articles.html +++ b/vipra-ui/app/html/topics/articles.html @@ -1,38 +1,62 @@ <div class="container" ng-cloak ng-hide="$state.current.name !== 'topics.show.articles'"> - <div class="page-header"> - <h1 ng-bind-template="Articles for topic '{{::topic.name}}'"></h1> - <table class="item-actions"> - <tr> - <td> - <a class="btn btn-default" ui-sref="^">Back</a> - </td> - </tr> - </table> + <div class="row"> + <div class="col-md-12"> + <div class="page-header"> + <h1 ng-bind-template="Articles for topic '{{::topic.name}}'"></h1> + <table class="item-actions"> + <tr> + <td> + <a class="btn btn-default" ui-sref="^">Back</a> + </td> + </tr> + </table> + </div> + </div> </div> - <div class="text-muted"> - Found - <ng-pluralize count="articlesTotal||0" when="{0:'no articles',1:'1 article',other:'{} articles'}"></ng-pluralize> in the database. - <span ng-show="articlesTotal"> - Sort by - <ol class="nya-bs-select nya-bs-condensed" ng-model="opts.sort"> - <li value="title" class="nya-bs-option"><a>Title</a></li> - <li value="date" class="nya-bs-option"><a>Date</a></li> - <li value="created" class="nya-bs-option"><a>Added</a></li> - </ol> - Direction - <ol class="nya-bs-select nya-bs-condensed" ng-model="opts.order"> - <li value="+" class="nya-bs-option"><a>Ascending</a></li> - <li value="-" class="nya-bs-option"><a>Descending</a></li> - </ol> - </span> - <br> Page <span ng-bind="page||1"></span> of <span ng-bind="maxPage||1"></span>. + <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. + <span ng-show="articlesTotal"> + Sort by + <ol class="nya-bs-select nya-bs-condensed" ng-model="opts.sort"> + <li value="title" class="nya-bs-option"><a>Title</a></li> + <li value="date" class="nya-bs-option"><a>Date</a></li> + <li value="created" class="nya-bs-option"><a>Added</a></li> + </ol> + Direction + <ol class="nya-bs-select nya-bs-condensed" ng-model="opts.order"> + <li value="+" class="nya-bs-option"><a>Ascending</a></li> + <li value="-" class="nya-bs-option"><a>Descending</a></li> + </ol> + </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" /> + </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> + </td> + </tr> + </tbody> + </table> + </div> + </div> + <div class="row"> + <div class="col-md-12"> + <pagination total="articlesTotal" page="page" limit="limit" change="changePage" /> + </div> </div> - <pagination total="articlesTotal" page="page" limit="limit" change="changePage" /> - <ol ng-attr-start="{{(page-1)*limit+1}}"> - <li ng-repeat="article in articles"> - <a ui-sref="articles.show({id: article.id})" ng-bind="::article.title"></a> - </li> - </ol> - <pagination total="articlesTotal" page="page" limit="limit" /> </div> <div ng-cloak ui-view></div> diff --git a/vipra-ui/app/html/topics/index.html b/vipra-ui/app/html/topics/index.html index 9cb3bc813f67dc49fc226b61e7e5f150bb99e266..95ce765a5ccec091780deb037192d9e022c817db 100644 --- a/vipra-ui/app/html/topics/index.html +++ b/vipra-ui/app/html/topics/index.html @@ -22,7 +22,7 @@ </div> <div class="row"> <div class="col-md-12"> - <pagination total="topicsTotal" page="page" limit="limit" change="changePage" /> + <pagination total="topicsTotal" page="page" limit="limit" /> </div> </div> <div class="row"> diff --git a/vipra-ui/app/html/topics/show.html b/vipra-ui/app/html/topics/show.html index 0f3b21d51df118480f9930154224d255e0ef4e63..fbbc8d31049640dee8cfd11dd73b1b170c6341f5 100644 --- a/vipra-ui/app/html/topics/show.html +++ b/vipra-ui/app/html/topics/show.html @@ -49,14 +49,6 @@ <th>ID</th> <td ng-bind="::topic.id"></td> </tr> - <tr> - <th>Created</th> - <td ng-bind="::topicCreated"></td> - </tr> - <tr> - <th>Last modified</th> - <td ng-bind="::topicModified"></td> - </tr> </tbody> </table> </div> diff --git a/vipra-ui/app/js/controllers.js b/vipra-ui/app/js/controllers.js index e5067fb8826a20df6f44c87b24cc2e44eb7c4cd7..a7825d391213d1cf126f9d4447d9d95d3cb62b64 100644 --- a/vipra-ui/app/js/controllers.js +++ b/vipra-ui/app/js/controllers.js @@ -2,7 +2,7 @@ * Vipra Application * Controllers ******************************************************************************/ -/* globals angular, Vipra, moment, vis, console, $, prompt, randomColor */ +/* globals angular, Vipra, moment, vis, console, $, prompt, randomColor, Highcharts */ (function() { "use strict"; @@ -353,22 +353,33 @@ series.push({ name: topic.name, data: relevances, - color: topic.color + color: topic.color, + topic: topic }); } } // highcharts configuration - $scope.topicSeq = areaRelevanceChart(series, $scope.selectSequence, $scope.opts.chartstyle, $scope.opts.chartstack); + $scope.topicSeq = areaRelevanceChart(series, $scope.selectNode, $scope.opts.chartstyle, + $scope.opts.chartstack); $scope.topicsSelected = series.length; }; - $scope.selectSequence = function(node) { + $scope.selectNode = function(node) { $scope.$apply(function() { - + }); }; + $scope.topicPopover = function(topic) { + return "<table class=\"table table-bordered table-condensed table-nomargin\"><tbody><tr><td>μ</td><td>σ</td><td>↘</td><td>↗</td><td>↝</td></tr><tr><td>" + + topic.avgRelevance.toFixed(2) + "</td><td>" + + topic.varRelevance.toFixed(2) + "</td><td>" + + topic.fallingRelevance.toFixed(2) + "</td><td>" + + topic.risingRelevance.toFixed(2) + "</td><td>" + + topic.risingDecayRelevance.toFixed(2) + "</td></tr></tbody></table>"; + }; + $scope.$watchCollection('opts.selectedTopics', $scope.redrawGraph); $scope.$watchGroup(['opts.seqstyle', 'opts.chartstyle', 'opts.chartstack'], $scope.redrawGraph); } @@ -441,7 +452,7 @@ }; topicShareSeries.push(d); - if(d.y > maximum.y) + if (d.y > maximum.y) maximum = d; $scope.article.topics[i].color = colors[i]; @@ -583,7 +594,7 @@ function($scope, $stateParams, $location, TopicFactory) { $scope.opts = { - sort: 'name', + sort: 'title', order: '+' }; @@ -667,18 +678,30 @@ spacingLeft: 0, spacingRight: 0 }, - title: { text: '' }, + title: { + text: '' + }, xAxis: { type: 'datetime', - title: { text: '' } + title: { + text: '' + } + }, + yAxis: { + title: { + text: 'Relevance' + } }, - yAxis: { title: { text: 'Relevance' } }, tooltip: { headerFormat: '', pointFormat: '{point.x:%Y}: {point.y:.4f}' }, - legend: { enabled: false }, - credits: { enabled: false }, + legend: { + enabled: false + }, + credits: { + enabled: false + }, plotOptions: { areaspline: { fillOpacity: 0.5, @@ -694,6 +717,18 @@ clickCallback(e.point); } } + }, + states: { + hover: { + halo: { + size: 9, + attributes: { + fill: Highcharts.getOptions().colors[2], + 'stroke-width': 2, + stroke: Highcharts.getOptions().colors[1] + } + } + } } } }, @@ -710,16 +745,24 @@ spacingLeft: 20, spacingRight: 20, }, - credits: { enabled: false }, + credits: { + enabled: false + }, plotOptions: { pie: { size: '100%', - dataLabels: { enabled: false }, + dataLabels: { + enabled: false + }, allowPointSelect: true } }, - title: { text: '' }, - tooltip: { pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>' }, + title: { + text: '' + }, + tooltip: { + pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>' + }, series: series }; } diff --git a/vipra-ui/app/js/directives.js b/vipra-ui/app/js/directives.js index bd32cca328ae412a565d5dfef31aca6dcb8af53d..c7663debe92f0b03303f8c9b2955717e6e071c6a 100644 --- a/vipra-ui/app/js/directives.js +++ b/vipra-ui/app/js/directives.js @@ -2,7 +2,7 @@ * Vipra Application * Directives ******************************************************************************/ -/* globals angular, console */ +/* globals angular, console, $ */ (function() { "use strict"; @@ -120,4 +120,23 @@ }; }); + app.directive('bsPopover', function () { + return { + restrict: 'A', + link: function ($scope, $elem, $attrs) { + $scope.label = $attrs.popoverLabel; + $($elem).popover({ + animation: ($attrs.popoverAnimation === 'true') || true, + container: $attrs.popoverContainer || 'body', + content: $attrs.popoverHtml, + delay: parseInt($attrs.popoverDelay || 1000, 10), + html: $attrs.popoverHtml || true, + placement: $attrs.popoverPlacement || 'right', + title: $attrs.popoverTitle, + trigger: $attrs.popoverTrigger || 'hover' + }); + } + }; + }); + })(); diff --git a/vipra-ui/app/js/helpers.js b/vipra-ui/app/js/helpers.js index 27d36b43d6b95676b7e74ad3a5fb7af1236086d6..b0e780f9b03cf87783047edf359cf7a1db246eb8 100644 --- a/vipra-ui/app/js/helpers.js +++ b/vipra-ui/app/js/helpers.js @@ -42,15 +42,6 @@ * Polyfills */ - if (typeof String.prototype.ellipsize === 'undefined') - String.prototype.ellipsize = function(max) { - max = max || 20; - if (this.length > max) { - return this.substring(0, max) + '...'; - } - return this; - }; - if (typeof String.prototype.multiline === 'undefined') String.prototype.multiline = function(max) { return this.split(new RegExp("((?:\\w+ ){" + max + "})", "g")).filter(Boolean).join("\n"); diff --git a/vipra-ui/app/less/app.less b/vipra-ui/app/less/app.less index 59964cbc5db78c0ce4e4fb74636b876a047be350..a87797aa86ad2c6a2219d0985ccdd622e56fe0cd 100644 --- a/vipra-ui/app/less/app.less +++ b/vipra-ui/app/less/app.less @@ -13,16 +13,6 @@ a:hover { cursor:pointer; } -ul.dashed { - list-style: none; - padding: 0; - - li:before { - content: "–"; - padding-right: 5px; - } -} - .heading { height: 125px; margin: 25px 0; @@ -42,12 +32,6 @@ ul.dashed { } } -.ellipsize { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - .navbar-default { .collapse:not(.in) { .navbar-nav > .active { @@ -75,27 +59,6 @@ ul.dashed { margin-bottom: 15px; } -.footer { - position: absolute; - bottom: 0; - width: 100%; - /* Set the fixed height of the footer here */ - height: 50px; - border-top-width: 1px; - border-top-style: solid; -} - -.loading:before { - .overlay; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - background: rgba(0,0,0,0.1); - content: " "; -} - .graph { position: absolute; top: 50px; @@ -181,16 +144,6 @@ ul.dashed { } } -.caret.caret-up { - content: ""; - border-top: 0; - border-bottom: 4px dashed; -} - -.table.table-morecondensed > tbody > tr > td { - padding: 0; -} - .table-fixed { table-layout: fixed; } @@ -216,24 +169,10 @@ ul.dashed { } } -.btn-condensed { - padding: 0px 12px; - margin-top: -2px; -} - .topic-share { width: 75px; } -revolve-select, [revolve-select] { - .noselect; - cursor: pointer; -} - -#nprogress .spinner { - display: none; -} - .logo { &.hover { .logo-shape { @@ -257,14 +196,6 @@ revolve-select, [revolve-select] { outline: none; } -.fullheight { - height: 100%; - - .row > * { - height: 100%; - } -} - .checkbox-condensed { margin-top: 0; margin-bottom: 0; @@ -330,6 +261,9 @@ revolve-select, [revolve-select] { .topic-choice { position: absolute; + top: 110px; + bottom: 0; + overflow-y: auto; label { padding-right: 15px; @@ -358,22 +292,6 @@ input[type=checkbox], vertical-align: bottom; } -.btn-groups { - .btn-group:not(:first-child) { - .btn { - border-top-left-radius: 0; - border-top-right-radius: 0; - } - } - - .btn-group:not(:last-child) { - .btn { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - } - } -} - .message-container { position: relative; } @@ -401,15 +319,6 @@ input[type=checkbox], width: 100% !important; } -.btn-default-none { - &, &:focus, &:hover, &:active { - .noselect; - background: transparent; - cursor: default; - box-shadow: none; - } -} - .table-infos { th { white-space: nowrap; @@ -423,6 +332,12 @@ input[type=checkbox], vertical-align: text-top; } +.wrapper { + position: relative; + width: 100%; + height: 100%; +} + @-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); } }