1 (function( app, i18n, raphael ) {
5 ui.DateHistogram = ui.AbstractWidget.extend({
7 printEl: null, // (optional) if supplied, clicking on elements in the histogram changes the query
8 cluster: null, // (required)
9 query: null, // (required) the current query
10 spec: null // (required) // date field spec
14 this.el = $(this._main_template());
15 this.query = this.config.query.clone();
16 // check if the index/types have changed and rebuild the histogram
17 this.config.query.on("results", function(query) {
18 if(this.queryChanged) {
19 this.buildHistogram(query);
20 this.queryChanged = false;
23 this.config.query.on("setIndex", function(query, params) {
24 this.query.setIndex(params.index, params.add);
25 this.queryChanged = true;
27 this.config.query.on("setType", function(query, params) {
28 this.query.setType(params.type, params.add);
29 this.queryChanged = true;
31 this.query.search.size = 0;
32 this.query.on("results", this._stat_handler);
33 this.query.on("results", this._aggs_handler);
34 this.buildHistogram();
36 buildHistogram: function(query) {
37 this.statAggs = this.query.addAggs({
38 stats: { field: this.config.spec.field_name }
41 this.query.removeAggs(this.statAggs);
43 _stat_handler: function(query, results) {
44 if(! results.aggregations[this.statAggs]) { return; }
45 this.stats = results.aggregations[this.statAggs];
46 // here we are calculating the approximate range that will give us less than 121 columns
47 var rangeNames = [ "year", "year", "month", "day", "hour", "minute" ];
48 var rangeFactors = [100000, 12, 30, 24, 60, 60000 ];
49 this.intervalRange = 1;
50 var range = this.stats.max - this.stats.min;
52 this.intervalName = rangeNames.pop();
53 var factor = rangeFactors.pop();
54 this.intervalRange *= factor;
55 range = range / factor;
57 this.dateAggs = this.query.addAggs({
59 field: this.config.spec.field_name,
60 interval: this.intervalName
64 this.query.removeAggs(this.dateAggs);
66 _aggs_handler: function(query, results) {
67 if(! results.aggregations[this.dateAggs]) { return; }
68 var buckets = [], range = this.intervalRange;
69 var min = Math.floor(this.stats.min / range) * range;
70 var prec = [ "year", "month", "day", "hour", "minute", "second" ].indexOf(this.intervalName);
71 results.aggregations[this.dateAggs].buckets.forEach(function(entry) {
72 buckets[parseInt((entry.key - min) / range , 10)] = entry.doc_count;
74 for(var i = 0; i < buckets.length; i++) {
75 buckets[i] = buckets[i] || 0;
77 this.el.removeClass("loading");
78 var el = this.el.empty();
79 var w = el.width(), h = el.height();
80 var r = raphael(el[0], w, h );
81 var printEl = this.config.printEl;
82 query = this.config.query;
83 r.g.barchart(0, 0, w, h, [buckets], { gutter: "0", vgutter: 0 }).hover(
85 this.flag = r.g.popup(this.bar.x, h - 5, this.value || "0").insertBefore(this);
87 this.flag.animate({opacity: 0}, 200, ">", function () {this.remove();});
91 printEl.val(window.dateRangeParser.print(min + this.bar.index * range, prec));
92 printEl.trigger("keyup");
97 _main_template: function() { return (
98 { tag: "DIV", cls: "uiDateHistogram loading", css: { height: "50px" }, children: [
99 i18n.text("General.LoadingAggs")
104 })( this.app, this.i18n, this.Raphael );