diff --git a/vipra-ui/app/html/explorer.html b/vipra-ui/app/html/explorer.html index 9cd0b7ee52a311d9a8aed0b78adf4634ff9f8a62..9c87e856d258e02e707d973bc7864a74bc798725 100644 --- a/vipra-ui/app/html/explorer.html +++ b/vipra-ui/app/html/explorer.html @@ -1,6 +1,6 @@ <div class="fullsize navpadding container-fluid explorer" ng-cloak ng-hide="!rootModels.topicModel || state.name !== 'explorer'"> <div class="row row-50"> - <div class="col-xs-2 sidebar"> + <div class="col-xs-3 col-md-2 sidebar"> <div class="btn-group btn-group-justified" role="group" aria-label="..."> <a tabindex="0" class="btn btn-sm btn-default" ng-click="checkTopics(true)" title="Select all topics">All</a> <a tabindex="0" class="btn btn-sm btn-default" ng-click="checkTopics(false)" title="Deselect all topics">None</a> @@ -22,11 +22,11 @@ <span class="glyphicon glyphicon-remove-circle searchclear" ng-click="search=''"></span> </div> <ul class="list-unstyled topic-choice"> - <li ng-repeat="topic in topics | orderBy:explorerModels.sorttopics:explorerModels.sortdir | filter:search" ng-mouseenter="highlightSeries(topic.id, true)" ng-mouseleave="highlightSeries(topic.id, false)"> - <div class="checkbox checkbox-condensed" ng-class="{selected:topic.selected}"> + <li ng-repeat="topic in topics | orderBy:explorerModels.sorttopics:explorerModels.sortdir | filter:search" ng-mouseenter="highlightSeries(topic.id, true)" ng-mouseleave="highlightSeries(topic.id, false)" ng-class="{selected:topic.selected}" class="text-muted"> + <div class="checkbox checkbox-condensed"> <span class="valuebar" ng-style="{width:topic.topicCurrValue}"></span> - <input tabindex="0" type="checkbox" ng-model="topic.selected" ng-attr-id="{{::topic.id}}" ng-change="redrawGraph()"> - <label class="check" ng-attr-for="{{::topic.id}}"> + <input tabindex="0" type="checkbox" ng-model="topic.selected" ng-attr-id="relevance-{{::topic.id}}" ng-change="redrawGraph()"> + <label class="check" ng-attr-for="relevance-{{::topic.id}}"> <topic-menu topic="topic" class="menu-button" /> <span class="ellipsis" ng-attr-title="{{::topic.name}}"> <span ng-bind="topic.name"></span> @@ -40,7 +40,7 @@ </li> </ul> </div> - <div class="col-xs-10 center"> + <div class="col-xs-9 col-md-10 center"> <div class="wrapper"> <div class="topbar"> <small>Values:</small> @@ -70,10 +70,27 @@ </div> </div> <div class="row row-50"> - <div class="col-xs-2 sidebar"> - + <div class="col-xs-3 col-md-2 sidebar"> + <ul class="list-unstyled topic-choice no-offset"> + <li ng-repeat="topic in selectedTopics = (topics | filter: {selected: true} | orderBy:explorerModels.sorttopics:explorerModels.sortdir)" ng-mouseenter="highlightSeries(topic.id, true)" ng-mouseleave="highlightSeries(topic.id, false)" ng-class="{active:explorerModels.activeTopic.id===topic.id}" class="pointer text-muted"> + <div class="radio radio-condensed"> + <span class="valuebar" ng-style="{width:topic.topicCurrValue}"></span> + <input tabindex="0" type="radio" ng-model="explorerModels.activeTopic" ng-attr-id="detail-{{::topic.id}}" name="topic-active" ng-value="topic"> + <label class="radio" ng-attr-for="detail-{{::topic.id}}"> + <topic-menu topic="topic" class="menu-button" /> + <span class="ellipsis" ng-attr-title="{{::topic.name}}"> + <span ng-bind="topic.name"></span> + </span> + </label> + <span class="colorbox shown" style="background:{{::topic.color}}" bs-popover popover-title="{{topic.name}}" popover-template="partials/topic-popover.html" popover-delay="500"></span> + </div> + </li> + <li ng-hide="selectedTopics.length > 0"> + <p class="text-muted text-center">No topics selected</p> + </li> + </ul> </div> - <div class="col-xs-10 center"> + <div class="col-xs-9 col-md-10 center"> </div> </div> diff --git a/vipra-ui/app/js/controllers.js b/vipra-ui/app/js/controllers.js index c2e873536caf47cc32240e4959527a5784ab63f3..4da4b088679c4fd5b4309a58a3db703485fbb037 100644 --- a/vipra-ui/app/js/controllers.js +++ b/vipra-ui/app/js/controllers.js @@ -585,7 +585,8 @@ relevances.push({ x: new Date(sequence.window.startDate).getTime(), y: relevance, - seq: sequence + sequence: sequence, + topic: topic }); } @@ -602,7 +603,7 @@ // highcharts configuration $scope.topicSeq = areaRelevanceChart(series, $scope.explorerModels.chartstyle, - $scope.explorerModels.chartstack); + $scope.explorerModels.chartstack, $scope.pointSelected); $scope.topicsSelected = series.length; }; @@ -656,6 +657,20 @@ highcharts.xAxis[0].setExtremes(null, null); }; + $scope.pointSelected = function(e) { + $scope.$apply(function() { + $scope.activateTopic(e.point.topic); + }); + }; + + $scope.activateTopic = function(topic) { + var active = topic.active; + for(var i = 0; i < $scope.topics.length; i++) { + $scope.topics[i].active = false; + } + topic.active = !active; + }; + $scope.$watchGroup(['explorerModels.seqstyle', 'explorerModels.chartstyle', 'explorerModels.chartstack'], $scope.redrawGraph); $scope.$watch('explorerModels.sorttopics', function() { @@ -672,6 +687,12 @@ $scope.topics[i].topicCurrValue = $scope.topicCurrValue($scope.topics[i]); }, 0); }); + + $scope.$watch('explorerModels.activeTopic', function() { + if(!$scope.activeTopic) return; + + // TODO implement + }); } ]); @@ -1430,7 +1451,7 @@ * Shared Highcharts configurations ****************************************************************************/ - function areaRelevanceChart(series, chartType, chartStack) { + function areaRelevanceChart(series, chartType, chartStack, clickCallback) { return { chart: { type: (chartType || 'areaspline'), @@ -1487,6 +1508,11 @@ } } } + }, + point: { + events: { + click: clickCallback + } } } }, diff --git a/vipra-ui/app/less/app.less b/vipra-ui/app/less/app.less index c0e33a023cdf483a8fa197614f6b508c91a9ab88..3df7c0730c3bc38d65a52372b954859b8c7459c4 100644 --- a/vipra-ui/app/less/app.less +++ b/vipra-ui/app/less/app.less @@ -199,6 +199,7 @@ a:hover { outline: none; } +.radio-condensed, .checkbox-condensed { margin-top: 0; margin-bottom: 0; @@ -252,7 +253,6 @@ a:hover { background: #f9f9f9; padding: @sidebar-padding; height: 100%; - min-width: 250px; > * + * { margin-top: 5px; } @@ -281,14 +281,26 @@ a:hover { right: @sidebar-padding; overflow-y: auto; margin-bottom: 0; - label { + .ellipsis { padding-right: 15px; + } + li { + position: relative; + height: 21px; + margin-top: 1px; + } + label { + margin: 0; + font-weight: normal; &:before, &:after { margin-top: 2px; margin-left: -18px; } } + &.no-offset { + top: 5px; + } .popover-area { position: absolute; right: 0; @@ -299,6 +311,10 @@ a:hover { topic-menu { position: absolute; } + .selected, + .active { + color: #000; + } } .colorbox { position: absolute;