Commit 1b995bc0 by Rashid Khan

Merge pull request #47 from rashidkpc/master

Fix for #43, partial fix for #41. Removed query mode from pie and moved to hits panel
parents 296d58cf c407da00
...@@ -6,13 +6,34 @@ ...@@ -6,13 +6,34 @@
<div class="span2"> <div class="span2">
<label class="small">Aggregate</label><input type="checkbox" ng-model="panel.aggregate" ng-checked="panel.aggregate"> <label class="small">Aggregate</label><input type="checkbox" ng-model="panel.aggregate" ng-checked="panel.aggregate">
</div> </div>
<div class="span3" ng-show="!panel.aggregate"><label class="small">Counter Style</label> <div class="span3" ng-show="!panel.aggregate">
<label class="small">Counter Style</label>
<select class="input-small" ng-model="panel.arrangement" ng-options="f for f in ['none','horizontal','vertical']"></select></span> <select class="input-small" ng-model="panel.arrangement" ng-options="f for f in ['none','horizontal','vertical']"></select></span>
</div> </div>
<div class="span2" ng-show="!panel.aggregate">
<label class="small">Chart</label><input type="checkbox" ng-model="panel.chart" ng-checked="panel.chart"> </div>
<h5 ng-show="!panel.aggregate">Chart Options</h5>
<div class="row-fluid" ng-show="!panel.aggregate">
<div class="span3">
<label class="small">Style</label>
<select class="input-small" ng-model="panel.chart" ng-options="f for f in ['none','bar','pie']"></select></span>
</div>
<div class="row-fluid" >
<div class="span3" ng-show="!panel.aggregate">
<label class="small">Legend</label>
<select class="input-small" ng-model="panel.counter_pos" ng-options="f for f in ['above','below']"></select></span>
</div>
<div class="span1" ng-show='panel.chart == "pie"'>
<label class="small"> Donut </label><input type="checkbox" ng-model="panel.donut" ng-checked="panel.donut">
</div>
<div class="span1" ng-show='panel.chart == "pie"'>
<label class="small"> Tilt </label><input type="checkbox" ng-model="panel.tilt" ng-checked="panel.tilt">
</div>
<div class="span1" ng-show='panel.chart == "pie"'>
<label class="small"> Labels </label><input type="checkbox" ng-model="panel.labels" ng-checked="panel.labels">
</div> </div>
</div> </div>
<h5>Queries</h5>
<div class="row-fluid"> <div class="row-fluid">
<div class="span3"> <div class="span3">
<form style="margin-bottom: 0px"> <form style="margin-bottom: 0px">
......
<kibana-panel ng-controller='hits' ng-init="init()"> <kibana-panel ng-controller='hits' ng-init="init()">
<div ng-show="panel.counters">
<div ng-show="panel.counters && panel.counter_pos == 'above'">
<!-- no chart, aggregated numbers -->
<p ng-style="panel.style" ng-show="panel.aggregate">{{hits}}</p> <p ng-style="panel.style" ng-show="panel.aggregate">{{hits}}</p>
<!-- vertical legend -->
<table ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'vertical'"> <table ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'vertical'">
<tr style="line-height:{{panel.style['font-size']}}" ng-repeat="query in plot.getData()"> <tr style="line-height:{{panel.style['font-size']}}" ng-repeat="query in plot.getData()">
<td ng-show="panel.chart" style="background:{{query.color}};width:{{panel.style['font-size']}}"></td> <td style="padding-right:10px;padding-left:10px;">{{query.label}}</td><td>{{query.hits}}</td> <td style="background:{{query.color}};width:{{panel.style['font-size']}}"></td> <td style="padding-right:10px;padding-left:10px;">{{query.label}}</td><td>{{query.data[0][1]}}</td>
</tr> </tr>
</table> </table>
<!-- horizontal legend -->
<div ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'horizontal'" ng-repeat="query in plot.getData()" style="float:left;padding-left: 10px;"> <div ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'horizontal'" ng-repeat="query in plot.getData()" style="float:left;padding-left: 10px;">
<span ng-show='panel.chart'><div style="display:inline-block;border-radius:{{panel.style['font-size']}};background:{{query.color}};height:{{panel.style['font-size']}};width:{{panel.style['font-size']}}"></div></span> {{query.label}} ({{query.hits}}) <span ng-show="!$last">|</span> <span><div style="display:inline-block;border-radius:{{panel.style['font-size']}};background:{{query.color}};height:{{panel.style['font-size']}};width:{{panel.style['font-size']}}"></div></span> {{query.label}} ({{query.data[0][1]}}) </span>
</div><br> </div><br>
</div><div style="clear:both"></div>
<div ng-show='panel.chart && !panel.aggregate ' hits-chart params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div> </div>
<div style="clear:both"></div>
<div ng-show='panel.chart != "none" && !panel.aggregate ' hits-chart params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div>
<div ng-show="panel.counters && panel.counter_pos == 'below'">
<!-- no chart, aggregated numbers -->
<p ng-style="panel.style" ng-show="panel.aggregate">{{hits}}</p>
<!-- vertical legend -->
<table ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'vertical'">
<tr style="line-height:{{panel.style['font-size']}}" ng-repeat="query in plot.getData()">
<tdstyle="background:{{query.color}};width:{{panel.style['font-size']}}"></td> <td style="padding-right:10px;padding-left:10px;">{{query.label}}</td><td>{{query.data[0][1]}}</td>
</tr>
</table>
<!-- horizontal legend -->
<div ng-style="panel.style" ng-show="!panel.aggregate && panel.arrangement == 'horizontal'" ng-repeat="query in plot.getData()" style="float:left;padding-left: 10px;">
<span><div style="display:inline-block;border-radius:{{panel.style['font-size']}};background:{{query.color}};height:{{panel.style['font-size']}};width:{{panel.style['font-size']}}"></div></span> {{query.label}} ({{query.data[0][1]}}) </span>
</div><br>
</div>
</kibana-panel> </kibana-panel>
\ No newline at end of file
...@@ -8,9 +8,11 @@ angular.module('kibana.hits', []) ...@@ -8,9 +8,11 @@ angular.module('kibana.hits', [])
style : { "font-size": '10pt'}, style : { "font-size": '10pt'},
aggregate : true, aggregate : true,
arrangement : 'vertical', arrangement : 'vertical',
chart : true, chart : 'none',
counters: true, counter_pos : 'above',
count_pos: 'above' donut : false,
tilt : false,
labels : true
} }
_.defaults($scope.panel,_d) _.defaults($scope.panel,_d)
...@@ -143,31 +145,61 @@ angular.module('kibana.hits', []) ...@@ -143,31 +145,61 @@ angular.module('kibana.hits', [])
function render_panel() { function render_panel() {
var scripts = $LAB.script("common/lib/panels/jquery.flot.js") var scripts = $LAB.script("common/lib/panels/jquery.flot.js")
.script("common/lib/panels/jquery.flot.pie.js")
// Populate element. Note that jvectormap appends, does not replace.
// Populate element.
scripts.wait(function(){ scripts.wait(function(){
// Populate element // Populate element
try { try {
// Add plot to scope so we can build out own legend // Add plot to scope so we can build out own legend
scope.plot = $.plot(elem, scope.data, { if(scope.panel.chart === 'bar')
legend: { show: false }, scope.plot = $.plot(elem, scope.data, {
series: { legend: { show: false },
lines: { show: false, }, series: {
bars: { show: true, fill: 1, barWidth: 0.8, horizontal: false }, lines: { show: false, },
shadowSize: 1 bars: { show: true, fill: 1, barWidth: 0.8, horizontal: false },
}, shadowSize: 1
yaxis: { show: true, min: 0, color: "#000" }, },
xaxis: { show: false }, yaxis: { show: true, min: 0, color: "#000" },
grid: { xaxis: { show: false },
backgroundColor: '#fff', grid: {
borderWidth: 0, backgroundColor: '#fff',
borderColor: '#eee', borderWidth: 0,
color: "#eee", borderColor: '#eee',
hoverable: true, color: "#eee",
}, hoverable: true,
colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D'] },
}) colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D']
})
if(scope.panel.chart === 'pie')
scope.plot = $.plot(elem, scope.data, {
legend: { show: false },
series: {
pie: {
innerRadius: scope.panel.donut ? 0.4 : 0,
tilt: scope.panel.tilt ? 0.45 : 1,
radius: 1,
show: true,
combine: {
color: '#999',
label: 'The Rest'
},
label: {
show: scope.panel.labels,
radius: 2/3,
formatter: function(label, series){
return '<div ng-click="build_search(panel.query.field,\''+label+'\') "style="font-size:8pt;text-align:center;padding:2px;color:white;">'+
label+'<br/>'+Math.round(series.percent)+'%</div>';
},
threshold: 0.1
}
}
},
//grid: { hoverable: true, clickable: true },
grid: { hoverable: true, clickable: true },
colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D']
});
// Work around for missing legend at initialization // Work around for missing legend at initialization
if(!scope.$$phase) if(!scope.$$phase)
scope.$apply() scope.$apply()
...@@ -198,9 +230,11 @@ angular.module('kibana.hits', []) ...@@ -198,9 +230,11 @@ angular.module('kibana.hits', [])
elem.bind("plothover", function (event, pos, item) { elem.bind("plothover", function (event, pos, item) {
if (item) { if (item) {
var value = scope.panel.chart === 'bar' ?
item.datapoint[1] : item.datapoint[1][0][1];
tt(pos.pageX, pos.pageY, tt(pos.pageX, pos.pageY,
"<div style='vertical-align:middle;border-radius:10px;display:inline-block;background:"+item.series.color+";height:20px;width:20px'></div> "+ "<div style='vertical-align:middle;border-radius:10px;display:inline-block;background:"+
item.datapoint[1].toFixed(0)) item.series.color+";height:20px;width:20px'></div> "+value.toFixed(0))
} else { } else {
$("#pie-tooltip").remove(); $("#pie-tooltip").remove();
} }
......
...@@ -82,7 +82,7 @@ angular.module('kibana.map', []) ...@@ -82,7 +82,7 @@ angular.module('kibana.map', [])
$scope.build_search = function(field,value) { $scope.build_search = function(field,value) {
$scope.panel.query = add_to_query($scope.panel.query,field,value,false) $scope.panel.query = add_to_query($scope.panel.query,field,value,false)
$scope.get_data(); $scope.get_data();
eventBus.broadcast($scope.$id,$scope.panel.group,'query',$scope.panel.query); eventBus.broadcast($scope.$id,$scope.panel.group,'query',[$scope.panel.query]);
} }
}) })
......
...@@ -46,41 +46,6 @@ ...@@ -46,41 +46,6 @@
</div> </div>
</div> </div>
</div> </div>
<div ng-switch-when="query">
<div class="row-fluid">
<div class="span3">
<form style="margin-bottom: 0px">
<h6>Label</h6>
<input type="text" placeholder="New Label" style="width:70%" ng-model="newlabel">
</form>
</div>
<div class="span8">
<form class="input-append" style="margin-bottom: 0px">
<h6>Query</h6>
<input type="text" placeholder="New Query" style="width:80%" ng-model="newquery">
<button class="btn" ng-click="add_query(newlabel,newquery);newlabel='';newquery=''"><i class="icon-plus"></i></button>
</form>
</div>
<div class="span1">
</div>
</div>
<div class="row-fluid" ng-repeat="q in panel.query">
<div class="span3">
<form style="margin-bottom: 0px">
<input type="text" style="width:70%" ng-model="q.label">
</form>
</div>
<div class="span8">
<form class="input-append" style="margin-bottom: 0px">
<input type="text" style="width:80%" ng-model="q.query">
<button class="btn" ng-click="get_data()"><i class="icon-search"></i></button>
</form>
</div>
<div class="span1">
<i class="icon-remove pointer" ng-click="remove_query(q)"></i>
</div>
</div>
</div>
</div> </div>
<div class="row-fluid"> <div class="row-fluid">
<div class="span1"> <div class="span1">
...@@ -97,7 +62,7 @@ ...@@ -97,7 +62,7 @@
</div> </div>
<div class="span2"> <div class="span2">
<label class="small">Mode</label> <label class="small">Mode</label>
<select class="input-small" ng-change="set_mode(panel.mode)" ng-model="panel.mode" ng-options="f for f in ['query','terms','goal']"></select> <select class="input-small" ng-change="set_mode(panel.mode)" ng-model="panel.mode" ng-options="f for f in ['terms','goal']"></select>
</div> </div>
</div> </div>
<h5>Panel Spy</h5> <h5>Panel Spy</h5>
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
<span ng-show='panel.spyable' style="position:absolute;right:0px;top:0px" class='panelextra pointer'> <span ng-show='panel.spyable' style="position:absolute;right:0px;top:0px" class='panelextra pointer'>
<i bs-modal="'partials/modal.html'" class="icon-eye-open"></i> <i bs-modal="'partials/modal.html'" class="icon-eye-open"></i>
</span> </span>
<span ng-show="panel.legend" ng-repeat='series in legend' style='padding-right:5px'>
<div style='white-space:nowrap;display:table-cell'> <div ng-repeat="query in plot.getData()" style="float:left;padding-left: 10px;">
<div style="display:inline-block;background:{{series.color}};height:10px;width:10px;border-radius:5px;"></div> <span ng-show='panel.chart != "none"'><div style="display:inline-block;border-radius:5px;background:{{query.color}};height:10px;width:10px"></div></span><span class="small"> {{query.label}} ({{query.data[0][1]}}) </span></span>
<div class='small' style='display:inline-block'>{{series.label}} ({{series.percent}}%)</div> </div><br>
</div> <div style="clear:both"></div>
</span>
<div pie params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div> <div pie params="{{panel}}" style="height:{{panel.height || row.height}};position:relative"></div>
</kibana-panel> </kibana-panel>
\ No newline at end of file
...@@ -20,16 +20,7 @@ angular.module('kibana.pie', []) ...@@ -20,16 +20,7 @@ angular.module('kibana.pie', [])
$scope.init = function() { $scope.init = function() {
eventBus.register($scope,'time', function(event,time){set_time(time)}); eventBus.register($scope,'time', function(event,time){set_time(time)});
eventBus.register($scope,'query', function(event, query) { eventBus.register($scope,'query', function(event, query) {
if($scope.panel.mode !== 'query') { $scope.panel.query.query = _.isArray(query) ? query[0] : query;
$scope.panel.query.query = query;
$scope.panel.query.query = _.isArray(query) ? query[0] : query;
} else {
if(_.isArray(query))
$scope.panel.query = _.map(query,function(q) {
return {query: q, label: q}})
else
$scope.panel.query[0] = {query: query, label: query}
}
$scope.get_data(); $scope.get_data();
}); });
// Now that we're all setup, request the time from our group // Now that we're all setup, request the time from our group
...@@ -60,9 +51,6 @@ angular.module('kibana.pie', []) ...@@ -60,9 +51,6 @@ angular.module('kibana.pie', [])
case 'terms': case 'terms':
$scope.panel.query = {query:"*",field:"_all"}; $scope.panel.query = {query:"*",field:"_all"};
break; break;
case 'query':
$scope.panel.query = [{query:"*",label:"*"}];
break;
case 'goal': case 'goal':
$scope.panel.query = {query:"*",goal:100}; $scope.panel.query = {query:"*",goal:100};
break; break;
...@@ -77,49 +65,8 @@ angular.module('kibana.pie', []) ...@@ -77,49 +65,8 @@ angular.module('kibana.pie', [])
$scope.panel.loading = true; $scope.panel.loading = true;
var request = $scope.ejs.Request().indices($scope.panel.index); var request = $scope.ejs.Request().indices($scope.panel.index);
// If we have an array, use query facet // Terms mode
if($scope.panel.mode == "query") { if ($scope.panel.mode == "terms") {
if(!(_.isArray($scope.panel.query)))
$scope.panel.query = [$scope.panel.query];
var queries = [];
// Build the question part of the query
_.each($scope.panel.query, function(v) {
queries.push(ejs.FilteredQuery(
ejs.QueryStringQuery(v.query || '*'),
ejs.RangeFilter($scope.time.field)
.from($scope.time.from)
.to($scope.time.to))
)
});
// Then the insert into facet and make the request
_.each(queries, function(v) {
request = request.facet(ejs.QueryFacet(_.indexOf(queries,v))
.query(v)
.facetFilter(ejs.QueryFilter(v))
)
})
$scope.populate_modal(request);
var results = request.doSearch();
// Populate scope when we have results
results.then(function(results) {
$scope.panel.loading = false;
$scope.hits = results.hits.total;
$scope.data = [];
_.each(results.facets, function(v, k) {
var series = {};
var label = _.isUndefined($scope.panel.query[k].label) ?
$scope.panel.query[k].query : $scope.panel.query[k].label
var slice = { label : label, data : v.count };
if (!(_.isUndefined($scope.panel.query[k].color)))
slice.color = $scope.panel.query[k].color;
$scope.data.push(slice)
});
$scope.$emit('render');
});
// If we don't have an array, assume its a term facet.
} else if ($scope.panel.mode == "terms") {
request = request request = request
.facet(ejs.TermsFacet('pie') .facet(ejs.TermsFacet('pie')
.field($scope.panel.query.field || $scope.panel.default_field) .field($scope.panel.query.field || $scope.panel.default_field)
...@@ -131,7 +78,6 @@ angular.module('kibana.pie', []) ...@@ -131,7 +78,6 @@ angular.module('kibana.pie', [])
ejs.RangeFilter($scope.time.field) ejs.RangeFilter($scope.time.field)
.from($scope.time.from) .from($scope.time.from)
.to($scope.time.to) .to($scope.time.to)
.cache(false)
)))).size(0) )))).size(0)
$scope.populate_modal(request); $scope.populate_modal(request);
...@@ -157,6 +103,7 @@ angular.module('kibana.pie', []) ...@@ -157,6 +103,7 @@ angular.module('kibana.pie', [])
}); });
$scope.$emit('render'); $scope.$emit('render');
}); });
// Goal mode
} else { } else {
request = request request = request
.query(ejs.QueryStringQuery($scope.panel.query.query || '*')) .query(ejs.QueryStringQuery($scope.panel.query.query || '*'))
...@@ -196,7 +143,7 @@ angular.module('kibana.pie', []) ...@@ -196,7 +143,7 @@ angular.module('kibana.pie', [])
$scope.build_search = function(field,value) { $scope.build_search = function(field,value) {
$scope.panel.query.query = add_to_query($scope.panel.query.query,field,value,false) $scope.panel.query.query = add_to_query($scope.panel.query.query,field,value,false)
$scope.get_data(); $scope.get_data();
eventBus.broadcast($scope.$id,$scope.panel.group,'query',$scope.panel.query.query); eventBus.broadcast($scope.$id,$scope.panel.group,'query',[$scope.panel.query.query]);
} }
function set_time(time) { function set_time(time) {
...@@ -275,14 +222,7 @@ angular.module('kibana.pie', []) ...@@ -275,14 +222,7 @@ angular.module('kibana.pie', [])
// Populate element // Populate element
if(elem.is(":visible")){ if(elem.is(":visible")){
scripts.wait(function(){ scripts.wait(function(){
var plot = $.plot(elem, scope.data, pie); scope.plot = $.plot(elem, scope.data, pie);
scope.legend = [];
_.each(plot.getData(),function(series) {
var item = _.pick(series,'label','color','percent')
item.percent = parseFloat(item.percent).toFixed(1)
scope.legend.push(item)
})
console.log(scope.legend)
}); });
} }
} }
......
...@@ -13,24 +13,18 @@ angular.module('kibana.stringquery', []) ...@@ -13,24 +13,18 @@ angular.module('kibana.stringquery', [])
} }
_.defaults($scope.panel,_d); _.defaults($scope.panel,_d);
var _groups = _.isArray($scope.panel.group) ?
$scope.panel.group : [$scope.panel.group];
$scope.init = function() { $scope.init = function() {
// I don't like this compromise. I'm not totally sure what this panel // If we're in multi query mode, they all get wiped out if we receive a
// Should do if its in multi query mode and receives a query. For now, just // query. Query events must be exchanged as arrays.
// replace the first one, though I feel like that isn't right.
eventBus.register($scope,'query',function(event,query) { eventBus.register($scope,'query',function(event,query) {
if (_.isArray($scope.panel.query))
$scope.panel.query[0] = query
else
$scope.panel.query = query; $scope.panel.query = query;
}); });
} }
$scope.send_query = function(query) { $scope.send_query = function(query) {
eventBus.broadcast($scope.$id,$scope.panel.group,'query',query) var _query = _.isArray(query) ? query : [query]
eventBus.broadcast($scope.$id,$scope.panel.group,'query',_query)
} }
$scope.add_query = function() { $scope.add_query = function() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment