Merge pull request #102 from rashidkpc/master

Moment.js + new color scheme. NOTE: INDEX STRING FORMAT HAS CHANGED
This commit is contained in:
Rashid Khan 2013-05-22 11:55:57 -07:00
commit 6efd85b42b
17 changed files with 7208 additions and 114 deletions

7069
common/css/bootstrap.dark.min.css vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -53,7 +53,7 @@
} }
.odd { .odd {
background-color: #f9f9f9; background-color: #3a3f44;
} }
.nomargin { .nomargin {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

6
common/lib/moment.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -110,9 +110,9 @@ function add_to_query(original,field,value,negate) {
*/ */
function calculate_interval(from,to,size,user_interval) { function calculate_interval(from,to,size,user_interval) {
if(_.isObject(from)) if(_.isObject(from))
from = from.getTime(); from = from.valueOf();
if(_.isObject(to)) if(_.isObject(to))
to = to.getTime(); to = to.valueOf();
return user_interval == 0 ? round_interval((to - from)/size) : user_interval; return user_interval == 0 ? round_interval((to - from)/size) : user_interval;
} }

View File

@ -1,6 +1,8 @@
/* /*
elasticsearch: URL to your elasticsearch server elasticsearch: URL to your elasticsearch server. You almost certainly don't
want 'http://localhost:9200' here. Even if Kibana and ES are on
the same host
kibana_index: The default ES index to use for storing Kibana specific object kibana_index: The default ES index to use for storing Kibana specific object
such as stored dashboards such as stored dashboards
modules: Panel modules to load. In the future these will be inferred modules: Panel modules to load. In the future these will be inferred

View File

@ -30,7 +30,7 @@
], ],
"timespan": "6h", "timespan": "6h",
"timefield": "@timestamp", "timefield": "@timestamp",
"index": "\"logstash-\"yyyy.mm.dd", "index": "[logstash-]YYYY.MM.DD",
"defaultindex": "NOINDEX", "defaultindex": "NOINDEX",
"index_interval": "day", "index_interval": "day",
"refresh": { "refresh": {

View File

@ -12,7 +12,7 @@
<title>Kibana 3</title> <title>Kibana 3</title>
<link rel="stylesheet" href="common/css/normalize.min.css"> <link rel="stylesheet" href="common/css/normalize.min.css">
<link rel="stylesheet" href="common/css/bootstrap.min.css"> <link rel="stylesheet" href="common/css/bootstrap.dark.min.css">
<link rel="stylesheet" href="common/css/animate.min.css"> <link rel="stylesheet" href="common/css/animate.min.css">
<link rel="stylesheet" href="common/css/bootstrap-responsive.min.css"> <link rel="stylesheet" href="common/css/bootstrap-responsive.min.css">
<link rel="stylesheet" href="common/css/font-awesome.min.css"> <link rel="stylesheet" href="common/css/font-awesome.min.css">
@ -37,7 +37,7 @@
<div class="navbar navbar-static-top"> <div class="navbar navbar-static-top">
<div class="navbar-inner"> <div class="navbar-inner">
<div class="container-fluid"> <div class="container-fluid">
<p class="navbar-text pull-right"><small><strong>Kibana 3</strong> <small>milestone pre-2</small></small></p> <p class="navbar-text pull-right"><small><strong>Kibana 3</strong> <small>milestone 2</small></small></p>
<span class="brand">{{dashboards.title}}</span> <span class="brand">{{dashboards.title}}</span>
<div class="brand"><i class='icon-edit pointer' ng-show='dashboards.editable' bs-modal="'partials/dasheditor.html'"></i></div> <div class="brand"><i class='icon-edit pointer' ng-show='dashboards.editable' bs-modal="'partials/dasheditor.html'"></i></div>
</div> </div>

View File

@ -28,9 +28,7 @@ var labjs = $LAB
.script("common/lib/angular-sanitize.min.js") .script("common/lib/angular-sanitize.min.js")
.script("common/lib/elastic.min.js") .script("common/lib/elastic.min.js")
.script("common/lib/elastic-angular-client.js") .script("common/lib/elastic-angular-client.js")
.script("common/lib/dateformat.js") .script("common/lib/moment.js")
.script("common/lib/date.js")
.script("common/lib/datepicker.js")
.script("common/lib/shared.js") .script("common/lib/shared.js")
.script("common/lib/filesaver.js") .script("common/lib/filesaver.js")
.script("js/services.js") .script("js/services.js")

View File

@ -249,11 +249,7 @@ angular.module('kibana.histogram', [])
$scope.set_time = function(time) { $scope.set_time = function(time) {
$scope.time = time; $scope.time = time;
// Should I be storing the index on the panel? It causes errors if the index $scope.index = time.index || $scope.index
// goes away. Hmmm.
$scope.index = time.index || $scope.index
// Only calculate interval if auto_int is set, otherwise don't touch it
$scope.get_data(); $scope.get_data();
} }
@ -305,21 +301,21 @@ angular.module('kibana.histogram', [])
points: { show: scope.panel.points, fill: 1, fillColor: false, radius: 5}, points: { show: scope.panel.points, fill: 1, fillColor: false, radius: 5},
shadowSize: 1 shadowSize: 1
}, },
yaxis: { show: scope.panel['y-axis'], min: 0, color: "#000" }, yaxis: { show: scope.panel['y-axis'], min: 0, color: "#c8c8c8" },
xaxis: { xaxis: {
timezone: scope.panel.timezone, timezone: scope.panel.timezone,
show: scope.panel['x-axis'], show: scope.panel['x-axis'],
mode: "time", mode: "time",
timeformat: time_format(scope.panel.interval), timeformat: time_format(scope.panel.interval),
label: "Datetime", label: "Datetime",
color: "#000", color: "#c8c8c8",
}, },
selection: { selection: {
mode: "x", mode: "x",
color: '#ccc' color: '#ccc'
}, },
grid: { grid: {
backgroundColor: '#fff', backgroundColor: '#272b30',
borderWidth: 0, borderWidth: 0,
borderColor: '#eee', borderColor: '#eee',
color: "#eee", color: "#eee",
@ -359,13 +355,12 @@ angular.module('kibana.histogram', [])
position: 'absolute', position: 'absolute',
top : y + 5, top : y + 5,
left : x + 5, left : x + 5,
color : "#000", color : "#c8c8c8",
border : '1px solid #000',
padding : '10px', padding : '10px',
'font-size': '11pt', 'font-size': '11pt',
'font-weight' : 200, 'font-weight' : 200,
'background-color': '#FFF', 'background-color': '#1f1f1f',
'border-radius': '10px', 'border-radius': '5px',
}).appendTo("body"); }).appendTo("body");
} }
@ -374,15 +369,15 @@ angular.module('kibana.histogram', [])
tt(pos.pageX, pos.pageY, tt(pos.pageX, pos.pageY,
"<div style='vertical-align:middle;display:inline-block;background:"+item.series.color+";height:15px;width:15px;border-radius:10px;'></div> "+ "<div style='vertical-align:middle;display:inline-block;background:"+item.series.color+";height:15px;width:15px;border-radius:10px;'></div> "+
item.datapoint[1].toFixed(0) + " @ " + item.datapoint[1].toFixed(0) + " @ " +
new Date(item.datapoint[0]).format('mm/dd HH:MM:ss')); moment(item.datapoint[0]).format('MM/DD HH:mm:ss'));
} else { } else {
$("#pie-tooltip").remove(); $("#pie-tooltip").remove();
} }
}); });
elem.bind("plotselected", function (event, ranges) { elem.bind("plotselected", function (event, ranges) {
scope.time.from = new Date(ranges.xaxis.from); scope.time.from = moment(ranges.xaxis.from);
scope.time.to = new Date(ranges.xaxis.to) scope.time.to = moment(ranges.xaxis.to)
eventBus.broadcast(scope.$id,scope.panel.group,'set_time',scope.time) eventBus.broadcast(scope.$id,scope.panel.group,'set_time',scope.time)
}); });
} }

View File

@ -181,10 +181,10 @@ angular.module('kibana.hits', [])
bars: { show: true, fill: 1, barWidth: 0.8, horizontal: false }, bars: { show: true, fill: 1, barWidth: 0.8, horizontal: false },
shadowSize: 1 shadowSize: 1
}, },
yaxis: { show: true, min: 0, color: "#000" }, yaxis: { show: true, min: 0, color: "#c8c8c8" },
xaxis: { show: false }, xaxis: { show: false },
grid: { grid: {
backgroundColor: '#fff', backgroundColor: '#272b30',
borderWidth: 0, borderWidth: 0,
borderColor: '#eee', borderColor: '#eee',
color: "#eee", color: "#eee",
@ -205,6 +205,10 @@ angular.module('kibana.hits', [])
color: '#999', color: '#999',
label: 'The Rest' label: 'The Rest'
}, },
stroke: {
color: '#272b30',
width: 0
},
label: { label: {
show: scope.panel.labels, show: scope.panel.labels,
radius: 2/3, radius: 2/3,
@ -243,13 +247,12 @@ angular.module('kibana.hits', [])
position: 'absolute', position: 'absolute',
top : y + 5, top : y + 5,
left : x + 5, left : x + 5,
color : "#000", color : "#c8c8c8",
border : '2px solid #000',
padding : '10px', padding : '10px',
'font-size': '11pt', 'font-size': '11pt',
'font-weight' : 200, 'font-weight' : 200,
'background-color': '#FFF', 'background-color': '#1f1f1f',
'border-radius': '10px', 'border-radius': '5px',
}).appendTo("body"); }).appendTo("body");
} }

View File

@ -34,7 +34,7 @@ angular.module('kibana.map', [])
var _d = { var _d = {
query : "*", query : "*",
map : "world", map : "world",
colors : ['#C8EEFF', '#0071A4'], colors : ['#A0E2E2', '#265656'],
size : 100, size : 100,
exclude : [], exclude : [],
spyable : true, spyable : true,
@ -143,9 +143,9 @@ angular.module('kibana.map', [])
$('.jvectormap-zoomin,.jvectormap-zoomout,.jvectormap-label').remove(); $('.jvectormap-zoomin,.jvectormap-zoomout,.jvectormap-label').remove();
var map = elem.vectorMap({ var map = elem.vectorMap({
map: scope.panel.map, map: scope.panel.map,
regionStyle: {initial: {fill: '#ddd'}}, regionStyle: {initial: {fill: '#8c8c8c'}},
zoomOnScroll: false, zoomOnScroll: false,
backgroundColor: '#fff', backgroundColor: '#272b30',
series: { series: {
regions: [{ regions: [{
values: scope.data, values: scope.data,
@ -157,12 +157,12 @@ angular.module('kibana.map', [])
$('.jvectormap-label').css({ $('.jvectormap-label').css({
"position" : "absolute", "position" : "absolute",
"display" : "none", "display" : "none",
"border" : "solid 2px #000", 'color' : "#c8c8c8",
"background" : "#FFF", 'padding' : '10px',
"font-weight" : 200, 'font-size': '11pt',
"border-radius": "5px", 'font-weight' : 200,
"color" : "#000", 'background-color': '#1f1f1f',
"padding" : "5px" 'border-radius': '5px'
}) })
var count = _.isUndefined(scope.data[code]) ? 0 : scope.data[code]; var count = _.isUndefined(scope.data[code]) ? 0 : scope.data[code];
$('.jvectormap-label').text(label.text() + ": " + count); $('.jvectormap-label').text(label.text() + ": " + count);

View File

@ -156,8 +156,8 @@ angular.module('kibana.pie', [])
var complete = results.hits.total; var complete = results.hits.total;
var remaining = $scope.panel.query.goal - complete; var remaining = $scope.panel.query.goal - complete;
$scope.data = [ $scope.data = [
{ label : 'Complete', data : complete, color: '#86B22D' }, { label : 'Complete', data : complete, color: '#BF6730' },
{ data : remaining, color: '#EEE'}] { data : remaining, color: '#e2d0c4'}]
$scope.$emit('render'); $scope.$emit('render');
}); });
} }
@ -214,9 +214,9 @@ angular.module('kibana.pie', [])
show: scope.panel.labels, show: scope.panel.labels,
radius: 0, radius: 0,
formatter: function(label, series){ formatter: function(label, series){
var font = parseInt(scope.row.height.replace('px',''))/10 + String('px') var font = parseInt(scope.row.height.replace('px',''))/8 + String('px')
if(!(_.isUndefined(label))) if(!(_.isUndefined(label)))
return '<div style="font-size:'+font+';font-weight:bold;text-align:center;padding:2px;color:black;">'+ return '<div style="font-size:'+font+';font-weight:bold;text-align:center;padding:2px;color:#fff;">'+
Math.round(series.percent)+'%</div>'; Math.round(series.percent)+'%</div>';
else else
return '' return ''
@ -236,7 +236,7 @@ angular.module('kibana.pie', [])
var pie = { var pie = {
series: { series: {
pie: { pie: {
innerRadius: scope.panel.donut ? 0.4 : 0, innerRadius: scope.panel.donut ? 0.45 : 0,
tilt: scope.panel.tilt ? 0.45 : 1, tilt: scope.panel.tilt ? 0.45 : 1,
radius: 1, radius: 1,
show: true, show: true,
@ -244,11 +244,19 @@ angular.module('kibana.pie', [])
color: '#999', color: '#999',
label: 'The Rest' label: 'The Rest'
}, },
label: label label: label,
stroke: {
color: '#272b30',
width: 0
}
} }
}, },
//grid: { hoverable: true, clickable: true }, //grid: { hoverable: true, clickable: true },
grid: { hoverable: true, clickable: true }, grid: {
backgroundColor: '#272b30',
hoverable: true,
clickable: true
},
legend: { show: false }, legend: { show: false },
colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D'] colors: ['#86B22D','#BF6730','#1D7373','#BFB930','#BF3030','#77207D']
}; };
@ -264,16 +272,17 @@ angular.module('kibana.pie', [])
function piett(x, y, contents) { function piett(x, y, contents) {
var tooltip = $('#pie-tooltip').length ? var tooltip = $('#pie-tooltip').length ?
$('#pie-tooltip') : $('<div id="pie-tooltip"></div>'); $('#pie-tooltip') : $('<div id="pie-tooltip"></div>');
tooltip.html(contents).css({ tooltip.html(contents).css({
position: 'absolute', position: 'absolute',
top : y + 10, top : y + 10,
left : x + 10, left : x + 10,
color : "#000", color : "#c8c8c8",
'font-weight': 200,
'border-radius': '5px',
border : '2px solid #000',
padding : '10px', padding : '10px',
'background-color': '#FFF', 'font-size': '11pt',
'font-weight' : 200,
'background-color': '#1f1f1f',
'border-radius': '5px',
}).appendTo("body"); }).appendTo("body");
} }

View File

@ -5,42 +5,42 @@
<tr><td><label><small>{{panel.label}}</small></label></td></tr> <tr><td><label><small>{{panel.label}}</small></label></td></tr>
<tr> <tr>
<td width="97%" style="padding-right:20px"> <td width="97%" style="padding-right:20px">
<input type="text" style="width:100%" ng-model="panel.query"> <span style="position:relative">
<i class="icon-remove-sign pointer" style="position:absolute;left:10px;top:3px" ng-show="panel.query.length > 0" ng-click="panel.query='';send_query(panel.query)"></i>
<input type="text" style="text-indent:20px;width:100%" ng-model="panel.query">
</span>
</td> </td>
<td style="margin-left:20px" width="1%"> <td style="margin-left:20px" width="1%">
<button style="margin-top:0px" type="submit" class="btn btn-info" ng-click="send_query(panel.query)"><i class="icon-search"></i></button> <button style="margin-top:0px" type="submit" class="btn btn-success btn-small" ng-click="send_query(panel.query)"><i class="icon-search"></i></button>
</td>
<td width="1%">
<button style="margin-top:0px" type="submit" class="btn btn-danger" ng-click="panel.query='';send_query(panel.query)"><i class="icon-ban-circle"></i></button>
</td>
<td width="1%">
<button style="margin-top:0px" ng-show="panel.multi" type="submit" class="btn" ng-click="add_query()"><i class="icon-plus"></i></button>
</td> </td>
<tr> <tr>
</table> </table>
</form> </form>
</div> </div>
<div class='row-fluid' ng-show="panel.multi && panel.multi_arrange == 'horizontal'"> <div class='row-fluid' ng-show="panel.multi && panel.multi_arrange == 'horizontal'">
<form class="form-inline" style="width:100%;margin:0px" >
<span ng-repeat="q in panel.query"> <span ng-repeat="q in panel.query">
<span class="input-append" style="margin-bottom:0px;margin-right:5px"> <span style="margin-bottom:0px;margin-right:5px;display:inline-block;position:relative">
<button class="btn btn-danger" type="submit" style="width:50px;margin-left:-50px;visibility:hidden"></button> <i class="icon-remove-sign pointer" style="position:absolute;left:10px;top:8px" ng-show="panel.query.length > 1" ng-click="remove_query($index);send_query(panel.query)"></i>
<input style="margin-bottom:5px;" type="text" ng-model="panel.query[$index]" ng-model-onblur style="width:90%"> <input style="margin-bottom:5px; text-indent: 20px;" type="text" ng-model="panel.query[$index]" ng-model-onblur style="width:90%">
<button class="btn btn-danger" ng-show="panel.query.length > 1" ng-click="remove_query($index);send_query(panel.query)"><i class="icon-minus"></i></button><br> <br>
</span> </span>
</span> </span>
</form> <br>
<button type="submit" class="btn btn-info" ng-click="send_query(panel.query)"><i class="icon-search"></i> Search</button> <button type="submit" class="btn btn-info" ng-click="send_query(panel.query)"><i class="icon-search"></i> Search</button>
<button type="submit" class="btn" ng-click="add_query();"><i class="icon-plus"></i> Add Query</button> <button type="submit" class="btn" ng-click="add_query();"><i class="icon-plus"></i></button>
</div> </div>
<div ng-show="panel.multi && panel.multi_arrange == 'vertical'"> <div ng-show="panel.multi && panel.multi_arrange == 'vertical'">
<form> <form>
<table class="form-horizontal"> <table class="form-horizontal" style="margin-bottom:5px;">
<tr><td class="small">Queries</td></tr> <tr><td class="small">Queries</td></tr>
<tr ng-repeat="q in panel.query" style="margin-bottom:10px"> <tr ng-repeat="q in panel.query" style="margin-bottom:10px">
<td width="99%"><input type="text" ng-model="panel.query[$index]" ng-model-onblur style="width:100%"></td> <td width="99%">
<span style="position:relative">
<i class="icon-remove-sign pointer" style="position:absolute;left:10px;top:3px" ng-show="panel.query.length > 1" ng-click="remove_query($index);send_query(panel.query)"></i>
<input type="text" ng-model="panel.query[$index]" ng-model-onblur style="text-indent: 20px;width:100%">
</span>
</td>
<td width="1%" style="visibility:hidden"><button class="btn btn-info" type="submit"></button></td> <td width="1%" style="visibility:hidden"><button class="btn btn-info" type="submit"></button></td>
<td width="1%"><button class="btn btn-danger" ng-show="panel.query.length > 1" ng-click="remove_query($index);send_query(panel.query)"><i class="icon-minus"></i></button></td>
</tr> </tr>
</table> </table>
<button type="submit" class="btn btn-info" ng-click="send_query(panel.query)"><i class="icon-search"></i> Search</button> <button type="submit" class="btn btn-info" ng-click="send_query(panel.query)"><i class="icon-search"></i> Search</button>

View File

@ -17,12 +17,12 @@
indices that match a specified timestamp pattern. This can be very indices that match a specified timestamp pattern. This can be very
efficient for some data sets (eg, logs) For example, to match the efficient for some data sets (eg, logs) For example, to match the
default logstash index pattern you might use default logstash index pattern you might use
<code>"logstash-"yyyy.mm.dd</code>. The quotes around "logstash-" are <code>[logstash-]YYYY.MM.DD</code>. The [] in "[logstash-]" are
important as they instruct Kibana not to treat those letters as a important as they instruct Kibana not to treat those letters as a
pattern. pattern.
</p> </p>
<p class="small"> <p class="small">
See <a href="http://blog.stevenlevithan.com/archives/date-time-format">http://blog.stevenlevithan.com/archives/date-time-format</a> See <a href="http://momentjs.com/docs/#/displaying/format/">http://momentjs.com/docs/#/displaying/format/</a>
for documentation on date formatting. for documentation on date formatting.
</p> </p>
@ -33,7 +33,7 @@
<h6>Timestamp</h6><select class="input-mini" ng-model="panel.index_interval" ng-options='f for f in ["none","hour","day","week","month","year"]'></select> <h6>Timestamp</h6><select class="input-mini" ng-model="panel.index_interval" ng-options='f for f in ["none","hour","day","week","month","year"]'></select>
</div> </div>
<div class="span5"> <div class="span5">
<h6>Index <span ng-show="panel.index_interval != 'none'">pattern <small>Absolutes in double quotes</small></span></h6> <h6>Index <span ng-show="panel.index_interval != 'none'">pattern <small>Absolutes in []</small></span></h6>
<input type="text" class="input-medium" ng-model="panel.index"> <input type="text" class="input-medium" ng-model="panel.index">
</div> </div>
<div class="span4"> <div class="span4">

View File

@ -39,6 +39,7 @@ angular.module('kibana.timepicker', [])
index : '_all', index : '_all',
defaultindex : "_all", defaultindex : "_all",
index_interval: "none", index_interval: "none",
timeformat : "",
group : "default", group : "default",
refresh : { refresh : {
enable : false, enable : false,
@ -60,20 +61,20 @@ angular.module('kibana.timepicker', [])
switch($scope.panel.mode) { switch($scope.panel.mode) {
case 'absolute': case 'absolute':
$scope.time = { $scope.time = {
from : new Date(Date.parse($scope.panel.time.from)) || time_ago($scope.panel.timespan), from : moment($scope.panel.time.from,'YYYY-MM-DD HH:mm:ss') || moment(time_ago($scope.panel.timespan)),
to : new Date(Date.parse($scope.panel.time.to)) || new Date() to : moment($scope.panel.time.to,'YYYY-MM-DD HH:mm:ss') || moment()
} }
break; break;
case 'since': case 'since':
$scope.time = { $scope.time = {
from : new Date(Date.parse($scope.panel.time.from)) || time_ago($scope.panel.timespan), from : moment($scope.panel.time.from,'YYYY-MM-DD HH:mm:ss') || moment(time_ago($scope.panel.timespan)),
to : new Date() || new Date() to : moment()
} }
break; break;
case 'relative': case 'relative':
$scope.time = { $scope.time = {
from : time_ago($scope.panel.timespan), from : moment(time_ago($scope.panel.timespan)),
to : new Date() to : moment()
} }
break; break;
} }
@ -88,26 +89,26 @@ angular.module('kibana.timepicker', [])
// request one be sent by broadcasting a 'get_time' with its _id to its group // request one be sent by broadcasting a 'get_time' with its _id to its group
// This panel can handle multiple groups // This panel can handle multiple groups
eventBus.register($scope,"get_time", function(event,id) { eventBus.register($scope,"get_time", function(event,id) {
eventBus.broadcast($scope.$id,id,'time',$scope.time) eventBus.broadcast($scope.$id,id,'time',unmoment($scope.time))
}); });
// In case some other panel broadcasts a time, set us to an absolute range // In case some other panel broadcasts a time, set us to an absolute range
eventBus.register($scope,"set_time", function(event,time) { eventBus.register($scope,"set_time", function(event,time) {
$scope.panel.mode = 'absolute'; $scope.panel.mode = 'absolute';
set_timepicker(time.from,time.to) set_timepicker(moment(time.from),moment(time.to))
$scope.time_apply() $scope.time_apply()
}); });
eventBus.register($scope,"zoom", function(event,factor) { eventBus.register($scope,"zoom", function(event,factor) {
var _timespan = ($scope.time.to.getTime() - $scope.time.from.getTime()); var _timespan = ($scope.time.to.valueOf() - $scope.time.from.valueOf());
try { try {
if($scope.panel.mode != 'absolute') { if($scope.panel.mode != 'absolute') {
$scope.panel.mode = 'since' $scope.panel.mode = 'since'
set_timepicker(new Date($scope.time.to.getTime() - _timespan*factor),$scope.time.to) set_timepicker(moment($scope.time.to.valueOf() - _timespan*factor),$scope.time.to)
} else { } else {
var _center = $scope.time.to - _timespan/2 var _center = $scope.time.to.valueOf() - _timespan/2
set_timepicker(new Date(_center - (_timespan*factor)/2), set_timepicker(moment(_center - (_timespan*factor)/2),
new Date(_center + (_timespan*factor)/2)) moment(_center + (_timespan*factor)/2))
} }
} catch (e) { } catch (e) {
console.log(e) console.log(e)
@ -152,16 +153,16 @@ angular.module('kibana.timepicker', [])
$scope.to_now = function() { $scope.to_now = function() {
$scope.timepicker.to = { $scope.timepicker.to = {
time : new Date().format("HH:MM:ss"), time : moment().format("HH:mm:ss"),
date : new Date().format("mm/dd/yyyy") date : moment().format("MM/DD/YYYY")
} }
} }
$scope.set_timespan = function(timespan) { $scope.set_timespan = function(timespan) {
$scope.panel.timespan = timespan; $scope.panel.timespan = timespan;
$scope.timepicker.from = { $scope.timepicker.from = {
time : time_ago(timespan).format("HH:MM:ss"), time : moment(time_ago(timespan)).format("HH:mm:ss"),
date : time_ago(timespan).format("mm/dd/yyyy") date : moment(time_ago(timespan)).format("MM/DD/YYYY")
} }
$scope.time_apply(); $scope.time_apply();
} }
@ -172,22 +173,22 @@ angular.module('kibana.timepicker', [])
// //
$scope.time_calc = function(){ $scope.time_calc = function(){
// If time picker is defined (on initialization) // If time picker is defined (usually is)
if(!(_.isUndefined($scope.timepicker))) { if(!(_.isUndefined($scope.timepicker))) {
var from = $scope.panel.mode === 'relative' ? time_ago($scope.panel.timespan) : var from = $scope.panel.mode === 'relative' ? moment(time_ago($scope.panel.timespan)) :
new Date(Date.parse($scope.timepicker.from.date + " " + $scope.timepicker.from.time)) moment($scope.timepicker.from.date + " " + $scope.timepicker.from.time,'MM/DD/YYYY HH:mm:ss')
var to = $scope.panel.mode !== 'absolute' ? new Date() : var to = $scope.panel.mode !== 'absolute' ? moment() :
new Date(Date.parse($scope.timepicker.to.date + " " + $scope.timepicker.to.time)) moment($scope.timepicker.to.date + " " + $scope.timepicker.to.time,'MM/DD/YYYY HH:mm:ss')
// Otherwise // Otherwise (probably initialization)
} else { } else {
var from = $scope.panel.mode === 'relative' ? time_ago($scope.panel.timespan) : var from = $scope.panel.mode === 'relative' ? moment(time_ago($scope.panel.timespan)) :
$scope.time.from; $scope.time.from;
var to = $scope.panel.mode !== 'absolute' ? new Date() : var to = $scope.panel.mode !== 'absolute' ? moment() :
$scope.time.to; $scope.time.to;
} }
if (from.getTime() >= to.getTime()) if (from.valueOf() >= to.valueOf())
from = new Date(to.getTime() - 1000) from = moment(to.valueOf() - 1000)
$timeout(function(){ $timeout(function(){
set_timepicker(from,to) set_timepicker(from,to)
@ -209,11 +210,11 @@ angular.module('kibana.timepicker', [])
if($scope.panel.index_interval !== 'none') { if($scope.panel.index_interval !== 'none') {
indices($scope.time.from,$scope.time.to).then(function (p) { indices($scope.time.from,$scope.time.to).then(function (p) {
$scope.time.index = p; $scope.time.index = p;
eventBus.broadcast($scope.$id,$scope.panel.group,'time',$scope.time) eventBus.broadcast($scope.$id,$scope.panel.group,'time',unmoment($scope.time))
}); });
} else { } else {
$scope.time.index = [$scope.panel.index]; $scope.time.index = [$scope.panel.index];
eventBus.broadcast($scope.$id,$scope.panel.group,'time',$scope.time) eventBus.broadcast($scope.$id,$scope.panel.group,'time',unmoment($scope.time))
} }
// Update panel's string representation of the time object.Don't update if // Update panel's string representation of the time object.Don't update if
@ -221,8 +222,8 @@ angular.module('kibana.timepicker', [])
// json for relative periods // json for relative periods
if($scope.panel.mode !== 'relative') { if($scope.panel.mode !== 'relative') {
$scope.panel.time = { $scope.panel.time = {
from : $scope.time.from.format("mm/dd/yyyy HH:MM:ss"), from : $scope.time.from.format("MM/DD/YYYY HH:mm:ss"),
to : $scope.time.to.format("mm/dd/yyyy HH:MM:ss"), to : $scope.time.to.format("MM/DD/YYYY HH:mm:ss"),
index : $scope.time.index, index : $scope.time.index,
}; };
} else { } else {
@ -230,16 +231,25 @@ angular.module('kibana.timepicker', [])
} }
}; };
// Prefer to pass around Date() objects in the EventBus since interacting with
// moment objects in libraries that are expecting Date()s can be tricky
function unmoment(time) {
time = _.clone(time)
time.from = time.from.toDate()
time.to = time.to.toDate()
return time;
}
function set_timepicker(from,to) { function set_timepicker(from,to) {
// Janky 0s timeout to get around $scope queue processing view issue // Janky 0s timeout to get around $scope queue processing view issue
$scope.timepicker = { $scope.timepicker = {
from : { from : {
time : from.format("HH:MM:ss"), time : from.format("HH:mm:ss"),
date : from.format("mm/dd/yyyy") date : from.format("MM/DD/YYYY")
}, },
to : { to : {
time : to.format("HH:MM:ss"), time : to.format("HH:mm:ss"),
date : to.format("mm/dd/yyyy") date : to.format("MM/DD/YYYY")
} }
} }
} }
@ -282,8 +292,10 @@ angular.module('kibana.timepicker', [])
// I extract the date from an object that I'm get the UTC date. Stupid js. // I extract the date from an object that I'm get the UTC date. Stupid js.
// I die a little inside every time I call this function. // I die a little inside every time I call this function.
// Update: I just read this again. I died a little more inside. // Update: I just read this again. I died a little more inside.
// Update2: More death.
function fake_utc(date) { function fake_utc(date) {
return new Date(date.getTime() + date.getTimezoneOffset() * 60000); date = date.clone().toDate()
return moment(new Date(date.getTime() + date.getTimezoneOffset() * 60000));
} }
// Create an array of date objects by a given interval // Create an array of date objects by a given interval
@ -296,19 +308,19 @@ angular.module('kibana.timepicker', [])
range.push(start.clone()); range.push(start.clone());
switch (interval) { switch (interval) {
case 'hour': case 'hour':
start.addHours(1) start.add('hours',1)
break break
case 'day': case 'day':
start.addDays(1) start.add('days',1)
break break
case 'week': case 'week':
start.addWeeks(1) start.add('weeks',1)
break break
case 'month': case 'month':
start.addMonths(1) start.add('months',1)
break break
case 'year': case 'year':
start.addYears(1) start.add('years',1)
break break
} }
} }