Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add multifieldhistogram panel #1296

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions src/app/panels/multifieldhistogram/editor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<style>
.querySelect .query {
margin-right: 5px;
}
.querySelect .selected {
border: 3px solid;
}
.querySelect .unselected {
border: 0px solid;
}
</style>
<div class="editor-row row-fluid">
<div class="section span12">
<h5>Values</h5>
<table class="table table-condensed table-striped">
<thead>
<tr>
<th></th>
<th>Chart value</th>
<th>Transform Series</th>
<th>Queries</th>
<th ng-show="panel.values.length > 1">Delete</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="value in panel.values">
<td>
<label class="small">&nbsp</label>
<i class="icon-circle pointer" data-unique="1" bs-popover="'app/panels/multifieldhistogram/meta.html'" data-placement="right" ng-style="{color: value.color}"></i></td>
<td>
<div class="editor-option">
<label class="small">Mode</label>
<select ng-change="set_refresh(true)" class="input-small" ng-model="value.mode" ng-options="f for f in ['count','min','mean','max','total']"></select>
</div>
<div class="editor-option" ng-show="value.mode != 'count'">
<label class="small">Value Field <tip>This field must contain a numeric value</tip></label>
<input ng-change="set_refresh(true)" placeholder="Start typing" bs-typeahead="fields.list" type="text" class="input-medium" ng-model="value.value_field">
</div>
</td>
<td>
<div class="editor-option" ng-show="value.mode != 'count'">
<label class="small">Scale</label>
<input type="text" class="input-mini" ng-model="value.scale">
</div>
<div class="editor-option">
<label class="small">Seconds <tip>Normalize intervals to per-second</tip></label>
<input type="checkbox" ng-model="value.scaleSeconds" ng-checked="value.scaleSeconds">
</div>
<div class="editor-option">
<label class="small">Derivative <tip>Plot the change per interval in the series</tip></label>
<input type="checkbox" ng-model="value.derivative" ng-checked="value.derivative" ng-change="set_refresh(true)">
</div>
<div class="editor-option">
<label class="small">Zero fill <tip>Fills zeros in gaps.</tip></label>
<input type="checkbox" ng-model="value.zerofill" ng-checked="value.zerofill" ng-change="set_refresh(true)">
</div>
</td>
<td>
<div class="editor-option querySelect">
<label class="small">Selected Queries</label>
<span ng-style="{'border-color': querySrv.list()[id].color}" ng-class="{selected:_.contains(value.queries,id),unselected:!_.contains(value.queries,id)}" ng-repeat="id in querySrv.ids()" ng-click="value.queries = _.toggleInOut(value.queries,id);set_refresh(true);" class="query pointer badge">
<i class="icon-circle" ng-style="{color: querySrv.list()[id].color}"></i>
<span> {{querySrv.list()[id].alias || querySrv.list()[id].query}}</span>
</span>
</div>
</td>
<td ng-show="panel.values.length > 1">
<label class="small">&nbsp</label>
<i ng-click="panel.values = _.without(panel.values, value);set_refresh(true)" class="pointer icon-remove"></i>
</td>
</tr>
</tbody>
</table>
<button type="button" class="btn btn-success" ng-click="add_new_value(panel);set_refresh(true)"><i class="icon-plus-sign"></i> Add value</button>
</div>
</div>
<div class="editor-row">
<div class="section">
<h5>Time Options</h5>
<div class="editor-option">
<label class="small">Time Field</label>
<input ng-change="set_refresh(true)" placeholder="Start typing" bs-typeahead="fields.list" type="text" class="input-small" ng-model="panel.time_field">
</div>
<div class="editor-option">
<label class="small">Time correction</label>
<select ng-model="panel.timezone" class='input-small' ng-options="f for f in ['browser','utc']"></select>
</div>
<div class="editor-option">
<label class="small">Auto-interval</label><input type="checkbox" ng-model="panel.auto_int" ng-checked="panel.auto_int" />
</div>
<div class="editor-option" ng-show='panel.auto_int'>
<label class="small">Resolution <tip>Shoot for this many data points, rounding to sane intervals</tip></label>
<input type="number" class='input-mini' ng-model="panel.resolution" ng-change='set_refresh(true)'/>
</div>
<div class="editor-option" ng-hide='panel.auto_int'>
<label class="small">Interval <tip>Use Elasticsearch date math format (eg 1m, 5m, 1d, 2w, 1y)</tip></label>
<input type="text" class='input-mini' ng-model="panel.interval" ng-change='set_refresh(true)'/>
</div>
</div>
</div>
57 changes: 57 additions & 0 deletions src/app/panels/multifieldhistogram/interval.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
define([
'kbn'
],
function (kbn) {
'use strict';

/**
* manages the interval logic
* @param {[type]} interval_string An interval string in the format '1m', '1y', etc
*/
function Interval(interval_string) {
this.string = interval_string;

var info = kbn.describe_interval(interval_string);
this.type = info.type;
this.ms = Math.ceil(info.sec * 1000 * info.count);

// does the length of the interval change based on the current time?
if (this.type === 'y' || this.type === 'M') {
// we will just modify this time object rather that create a new one constantly
this.get = this.get_complex;
this.date = new Date(0);
} else {
this.get = this.get_simple;
}
}

Interval.prototype = {
toString: function () {
return this.string;
},
after: function(current_ms) {
return this.get(current_ms, 1);
},
before: function (current_ms) {
return this.get(current_ms, -1);
},
get_complex: function (current, delta) {
this.date.setTime(current);
switch(this.type) {
case 'M':
this.date.setUTCMonth(this.date.getUTCMonth() + delta);
break;
case 'y':
this.date.setUTCFullYear(this.date.getUTCFullYear() + delta);
break;
}
return this.date.getTime();
},
get_simple: function (current, delta) {
return current + (delta * this.ms);
}
};

return Interval;

});
39 changes: 39 additions & 0 deletions src/app/panels/multifieldhistogram/markersEditor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<div class="editor-row">
<h4>Markers</h4>
<div class="small">
Here you can specify a query to be plotted on your chart as a marker. Hovering over a marker will display the field you specify below. If more documents are found than the limit you set, they will be scored by Elasticsearch and events that best match your query will be displayed.
</div>
<style>
.querySelect .query {
margin-right: 5px;
}
.querySelect .selected {
border: 3px solid;
}
.querySelect .unselected {
border: 0px solid;
}
</style>
<p>
<div class="editor-option">
<label class="small">Enable</label>
<input type="checkbox" ng-change="set_refresh(true)" ng-model="panel.annotate.enable" ng-checked="panel.annotate.enable">
</div>
<div class="editor-option" ng-show="panel.annotate.enable">
<label class="small">Marker Query</label>
<input type="text" ng-change="set_refresh(true)" class="input-large" ng-model="panel.annotate.query"/>
</div>
<div class="editor-option" ng-show="panel.annotate.enable">
<label class="small">Tooltip field</label>
<input type="text" class="input-small" ng-model="panel.annotate.field" bs-typeahead="fields.list"/>
</div>
<div class="editor-option" ng-show="panel.annotate.enable">
<label class="small">Limit <tip>Max markers on the chart</tip></label>
<input type="number" class="input-mini" ng-model="panel.annotate.size" ng-change="set_refresh(true)"/>
</div>
<div class="editor-option" ng-show="panel.annotate.enable">
<label class="small">Sort <tip>Determine the most relevant markers using this field</tip></label>
<input type="text" class="input-small" bs-typeahead="fields.list" ng-model="panel.annotate.sort[0]" ng-change="set_refresh(true)" />
<i ng-click="panel.annotate.sort[1] = _.toggle(panel.annotate.sort[1],'desc','asc');set_refresh(true)" ng-class="{'icon-chevron-up': panel.annotate.sort[1] == 'asc','icon-chevron-down': panel.annotate.sort[1] == 'desc'}"></i>
</div>
</div>
22 changes: 22 additions & 0 deletions src/app/panels/multifieldhistogram/meta.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<div class="panel-query-meta row-fluid" style="width:260px">
<style>
.panel-query-meta fieldset label {
margin-top: 3px;
}
</style>

<fieldset>
<label class="small">Legend value</label>
<input class="input-medium input-value-alias" type="text" ng-model="value.alias" placeholder='Alias...' ng-change="set_refresh(true);" />
</fieldset>

<hr class="small" />
<div>
<i ng-repeat="color in querySrv.colors" class="pointer" ng-class="{'icon-circle-blank':value.color == color,'icon-circle':value.color != color}" ng-style="{color:color}" ng-click="value.color = color;set_refresh(true);"> </i>
</div>

<div class="pull-right">
<a class="btn btn-mini btn-value-remove-color" ng-click="value.color = null;set_refresh(true);" ng-show="value.color" class="pointer">Remove color</a>
<input class="btn btn-mini" ng-click="set_refresh(true);dismiss();" type="submit"/ value="Close">
</div>
</div>
108 changes: 108 additions & 0 deletions src/app/panels/multifieldhistogram/module.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<div ng-controller='multifieldhistogram' ng-init="init()" style="min-height:{{panel.height || row.height}}">
<style>
.histogram-legend {
display:inline-block;
padding-right:5px
}
.histogram-legend-dot {
display:inline-block;
height:10px;
width:10px;
border-radius:5px;
}
.histogram-legend-item {
display:inline-block;
}
.histogram-chart {
position:relative;
}
.histogram-options {
padding: 5px;
margin-right: 15px;
margin-bottom: 0px;
}
.histogram-options label {
margin: 0px 0px 0px 10px !important;
}
.histogram-options span {
white-space: nowrap;
}

/* this is actually should be in bootstrap */
.form-inline .checkbox {
display: inline-block;
}

.histogram-marker {
display: block;
width: 20px;
height: 21px;
background-image: url('img/annotation-icon.png');
background-repeat: no-repeat;
}

</style>
<div>
<span ng-show='panel.options'>
<a class="link small" ng-show='panel.options' ng-click="options=!options">
View <i ng-show="!options" class="icon-caret-right"></i><i ng-show="options" class="icon-caret-down"></i>
</a> |&nbsp
</span>
<span ng-show='panel.zoomlinks'>
<!--<a class='small' ng-click='zoom(0.5)'><i class='icon-zoom-in'></i> Zoom In</a>-->
<a class='small' ng-click='zoom(2)'><i class='icon-zoom-out'></i> Zoom Out</a> |&nbsp
</span>
<span ng-show="panel.legend" ng-repeat='series in _.values(legend)' class="histogram-legend">
<i class='icon-circle' ng-style="{color: series.query.color}"></i>
<span class='small histogram-legend-item'>
<span ng-if="panel.show_query">{{series.query.alias || series.query.query}}</span>
<span ng-if="!panel.show_query">{{series.query.alias}}</span>
<span ng-show="panel.legend_counts"> ({{series.hits}})</span>
</span>
</span>
<span ng-show="panel.legend" class="small"><span ng-show="panel.derivative"> change in </span><span class="strong" ng-show="panel.value_field && panel.mode != 'count'">{{panel.value_field}}</span> {{panel.mode}} per <strong ng-hide="panel.scaleSeconds">{{panel.interval}}</strong><strong ng-show="panel.scaleSeconds">1s</strong> | (<strong>{{hits}}</strong> hits)</span>
</div>
<form class="form-inline bordered histogram-options" ng-show="options">
<span>
<div class="checkbox">
<label class="small">
<input type="checkbox" ng-model="panel.lines" ng-checked="panel.lines" ng-change="render()">
Lines
</label>
</div>
<div class="checkbox">
<label class="small">
<input type="checkbox" ng-model="panel.points" ng-checked="panel.points" ng-change="render()">
Points
</label>
</div>
<div class="checkbox">
<label class="small">
<input type="checkbox" ng-model="panel.stack" ng-checked="panel.stack" ng-change="render()">
Stack
</label>
</div>
</span>
<span ng-show="panel.stack">
<div class="checkbox">
<label style="white-space:nowrap" class="small">
<input type="checkbox" ng-model="panel.percentage" ng-checked="panel.percentage" ng-change="render()">
Percent
</label>
</div>
</span>
<span>
<div class="checkbox">
<label class="small">
<input type="checkbox" ng-model="panel.legend" ng-checked="panel.legend" ng-change="render()">
Legend
</label>
</div>
</span>
<span>
<label class="small">Interval</label> <select ng-change="set_interval(panel.interval);get_data();" class="input-small" ng-model="panel.interval" ng-options="interval_label(time) for time in _.union([panel.interval],panel.intervals)"></select>
</span>
</form>
<center><img ng-show='panel.loading' src="img/load_big.gif"></center>
<div multifieldhistogram-chart class="pointer histogram-chart" params="{{panel}}"></div>
</div>
Loading