diff --git a/vipra-ui/app/html/articles/show.html b/vipra-ui/app/html/articles/show.html index 2eb45fbbe1b93b12374da912f15a6e11968e3b17..f6b8e720976d16ea9a3acbe44f306ec629cfd3e5 100644 --- a/vipra-ui/app/html/articles/show.html +++ b/vipra-ui/app/html/articles/show.html @@ -14,14 +14,6 @@ <th>URL</th> <td><a ng-href="{{::article.url}}" ng-bind="::article.url"></a></td> </tr> - <tr> - <th>Topics</th> - <td class="topic-links"> - <topic-link topic="topic.topic" ng-repeat="topic in article.topics"> - <span ng-bind-template="({{topic.count / article.stats.wordCount | toPercent}}%)"></span> - </topic-link> - </td> - </tr> <tr> <th>Created</th> <td ng-bind="::article.created"></td> @@ -43,4 +35,18 @@ </tbody> </table> +<h3>Topics <hide-link target="#topics"/></h3> + +<div class="row" id="topics"> + <div class="col-md-4 topic-links"> + <topic-link topic="topic.topic" ng-repeat="topic in article.topics"> + <span ng-bind-template="({{topic.share}}%)"></span> + </topic-link> + </div> + <div class="col-md-8"> + <div class="pie-chart" id="topic-share" highcharts="topicShare"></div> + </div> +</div> + +<hr> <p ng-bind-html="::article.text"></p> \ No newline at end of file diff --git a/vipra-ui/app/js/controllers.js b/vipra-ui/app/js/controllers.js index 9f7c3db157569e7a6846bc5c0fc7851b9c46a514..840127677bc4d67e331da6a5ce482cc7d6790ac4 100644 --- a/vipra-ui/app/js/controllers.js +++ b/vipra-ui/app/js/controllers.js @@ -100,6 +100,33 @@ $scope.article.modified = formatDateTime($scope.article.modified); $scope.articleMeta = response.meta; $scope.queryTime = response.$queryTime; + + // calculate percentage share + var topicShareSeries = [], + topics = $scope.article.topics; + for(var i = 0; i < topics.length; i++) { + var share = toPercent(topics[i].count / $scope.article.stats.wordCount); + topics[i].share = share; + topicShareSeries.push({name: topics[i].topic.name.ellipsize(20), y: share}); + } + + // highcharts data + var topicShare = { + chart: { type: 'pie' }, + credits: { enabled: false }, + plotOptions: { + pie: { allowPointSelect: true } + }, + title: { text: 'Topic share' }, + tooltip: { pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>' }, + series: [{ + name: 'Topic Share', + colorByPoint: true, + data: topicShareSeries + }] + }; + + $scope.topicShare = topicShare; }); }]); diff --git a/vipra-ui/app/js/directives.js b/vipra-ui/app/js/directives.js index 867fd6e4d5edd2211b3897e217065b71c5a0125f..a7992274406b22245bf113e595d59b6b6241ee0d 100644 --- a/vipra-ui/app/js/directives.js +++ b/vipra-ui/app/js/directives.js @@ -221,4 +221,45 @@ }; }]); + app.directive('highcharts', function() { + return { + scope: { + highcharts: '=' + }, + link: function($scope, $element) { + $scope.$watch('highcharts', function(newVal) { + if(!newVal) return; + + $element.highcharts($scope.highcharts); + }); + } + }; + }); + + app.directive('hideLink', function() { + return { + scope: { + target: '@' + }, + replace: true, + template: '<a class="hide-link" href="#" ng-bind="text" ng-click="change($event)"></a>', + link: function($scope) { + var target = $($scope.target); + if(!target.length) return; + + var setText = function(b) { + $scope.text = b ? 'hide' : 'show'; + }; + + $scope.change = function(e) { + e.preventDefault(); + setText(!target.is(':visible')); + target.slideToggle(); + }; + + setText(target.is(':visible')); + } + }; + }); + })(); \ No newline at end of file diff --git a/vipra-ui/app/js/helpers.js b/vipra-ui/app/js/helpers.js index cf43be3f05b0a0a0358d1f86f828f1f207938160..0b390950fd44601a869a750841cb6800d0c967c4 100644 --- a/vipra-ui/app/js/helpers.js +++ b/vipra-ui/app/js/helpers.js @@ -20,6 +20,7 @@ }; String.prototype.ellipsize = function(max) { + max = max || 20; if(this.length > max) { return this.substring(0, max) + '...'; } diff --git a/vipra-ui/app/less/app.less b/vipra-ui/app/less/app.less index 313bcd09d99686450621c94930766a75f1e2226f..5b4e052f352493fdc103a1a2374a050a824e27b7 100644 --- a/vipra-ui/app/less/app.less +++ b/vipra-ui/app/less/app.less @@ -117,6 +117,14 @@ body { border-radius: 3px; } +.topic-links .topic-link { + display: block; +} + +.hide-link { + font-size: 12px; +} + .noselect { -webkit-touch-callout: none; -webkit-user-select: none;