2  * Copyright 2010-2013 Ben Birch
 
   4  * Licensed under the Apache License, Version 2.0 (the "License");
 
   5  * you may not use this software except in compliance with the License.
 
   6  * You may obtain a copy of the License at
 
   8  *   http://www.apache.org/licenses/LICENSE-2.0
 
  10  * Unless required by applicable law or agreed to in writing, software
 
  11  * distributed under the License is distributed on an "AS IS" BASIS,
 
  12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  13  * See the License for the specific language governing permissions and
 
  14  * limitations under the License.
 
  16 (function( app, i18n, raphael ) {
 
  18         var ui = app.ns("ui");
 
  20         ui.DateHistogram = ui.AbstractWidget.extend({
 
  22                         printEl: null, // (optional) if supplied, clicking on elements in the histogram changes the query
 
  23                         cluster: null, // (required)
 
  24                         query: null,   // (required) the current query
 
  25                         spec: null     // (required) // date field spec
 
  29                         this.el = $(this._main_template());
 
  30                         this.query = this.config.query.clone();
 
  31                         // check if the index/types have changed and rebuild the histogram
 
  32                         this.config.query.on("results", function(query) {
 
  33                                 if(this.queryChanged) {
 
  34                                         this.buildHistogram(query);
 
  35                                         this.queryChanged = false;
 
  38                         this.config.query.on("setIndex", function(query, params) {
 
  39                                 this.query.setIndex(params.index, params.add);
 
  40                                 this.queryChanged = true;
 
  42                         this.config.query.on("setType", function(query, params) {
 
  43                                 this.query.setType(params.type, params.add);
 
  44                                 this.queryChanged = true;
 
  46                         this.query.search.size = 0;
 
  47                         this.query.on("results", this._stat_handler);
 
  48                         this.query.on("results", this._aggs_handler);
 
  49                         this.buildHistogram();
 
  51                 buildHistogram: function(query) {
 
  52                         this.statAggs = this.query.addAggs({
 
  53                                 stats: { field: this.config.spec.field_name }
 
  56                         this.query.removeAggs(this.statAggs);
 
  58                 _stat_handler: function(query, results) {
 
  59                         if(! results.aggregations[this.statAggs]) { return; }
 
  60                         this.stats = results.aggregations[this.statAggs];
 
  61                         // here we are calculating the approximate range  that will give us less than 121 columns
 
  62                         var rangeNames = [ "year", "year", "month", "day", "hour", "minute" ];
 
  63                         var rangeFactors = [100000, 12, 30, 24, 60, 60000 ];
 
  64                         this.intervalRange = 1;
 
  65                         var range = this.stats.max - this.stats.min;
 
  67                                 this.intervalName = rangeNames.pop();
 
  68                                 var factor = rangeFactors.pop();
 
  69                                 this.intervalRange *= factor;
 
  70                                 range = range / factor;
 
  72                         this.dateAggs = this.query.addAggs({
 
  74                                         field: this.config.spec.field_name,
 
  75                                         interval: this.intervalName
 
  79                         this.query.removeAggs(this.dateAggs);
 
  81                 _aggs_handler: function(query, results) {
 
  82                         if(! results.aggregations[this.dateAggs]) { return; }
 
  83                         var buckets = [], range = this.intervalRange;
 
  84                         var min = Math.floor(this.stats.min / range) * range;
 
  85                         var prec = [ "year", "month", "day", "hour", "minute", "second" ].indexOf(this.intervalName);
 
  86                         results.aggregations[this.dateAggs].buckets.forEach(function(entry) {
 
  87                                 buckets[parseInt((entry.key - min) / range , 10)] = entry.doc_count;
 
  89                         for(var i = 0; i < buckets.length; i++) {
 
  90                                 buckets[i] = buckets[i] || 0;
 
  92                         this.el.removeClass("loading");
 
  93                         var el = this.el.empty();
 
  94                         var w = el.width(), h = el.height();
 
  95                         var r = raphael(el[0], w, h );
 
  96                         var printEl = this.config.printEl;
 
  97                         query = this.config.query;
 
  98                         r.g.barchart(0, 0, w, h, [buckets], { gutter: "0", vgutter: 0 }).hover(
 
 100                                         this.flag = r.g.popup(this.bar.x, h - 5, this.value || "0").insertBefore(this);
 
 102                                         this.flag.animate({opacity: 0}, 200, ">", function () {this.remove();});
 
 106                                         printEl.val(window.dateRangeParser.print(min + this.bar.index * range, prec));
 
 107                                         printEl.trigger("keyup");
 
 112                 _main_template: function() { return (
 
 113                         { tag: "DIV", cls: "uiDateHistogram loading", css: { height: "50px" }, children: [
 
 114                                 i18n.text("General.LoadingAggs")
 
 119 })( this.app, this.i18n, this.Raphael );