Skip to content

Commit

Permalink
Merge pull request #10 from w33ble/negatives
Browse files Browse the repository at this point in the history
Working negative y-axes values
  • Loading branch information
stormpython committed Feb 5, 2015
2 parents 215e8c4 + ad9c972 commit 0923e73
Show file tree
Hide file tree
Showing 45 changed files with 1,392 additions and 724 deletions.
2 changes: 1 addition & 1 deletion bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"leaflet": "0.7.3",
"lesshat": "~3.0.2",
"lodash": "~2.4.1",
"moment": "~2.5.1",
"moment": "~2.9.0",
"moment-timezone": "~0.0.3",
"ng-clip": "~0.2.4",
"require-css": "~0.1.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
define(function (require) {
return function PointSeriesOrderedDateAxis(timefilter) {
var moment = require('moment');
var interval = require('utils/interval');

return function orderedDateAxis(vis, table, chart) {
return function orderedDateAxis(vis, chart) {
var aspects = chart.aspects;
var bounds = timefilter.getBounds();
var format = interval.calculate(
moment(bounds.min.valueOf()),
moment(bounds.max.valueOf()),
table.rows.length
).format;
var buckets = aspects.x.agg.buckets;
var format = buckets.getScaledDateFormat();

chart.xAxisFormatter = function (val) {
return moment(val).format(format);
};

var xAggOutput = aspects.x.agg.write();
chart.ordered = {
date: true,
interval: interval.toMs(xAggOutput.params.interval)
interval: buckets.getInterval(),
};

if (vis.indexPattern.timeFieldName) {
var timeBounds = timefilter.getBounds();
chart.ordered.min = timeBounds.min.valueOf();
chart.ordered.max = timeBounds.max.valueOf();
var bounds = buckets.getBounds();
if (bounds) {
chart.ordered.min = bounds.min;
chart.ordered.max = bounds.max;
}
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ define(function (require) {

var datedX = aspects.x.agg.type.ordered && aspects.x.agg.type.ordered.date;
if (datedX) {
setupOrderedDateXAxis(vis, table, chart);
setupOrderedDateXAxis(vis, chart);
}

chart.series = getSeries(table.rows, chart);
Expand Down
6 changes: 6 additions & 0 deletions src/kibana/components/agg_types/_agg_type.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ define(function (require) {
* or undefined
*/
this.getResponseAggs = config.getResponseAggs || _.noop;

/**
* A function that will be called each time an aggConfig of this type
* is created, giving the agg type a chance to modify the agg config
*/
this.decorateAggConfig = config.decorateAggConfig || null;
}

return AggType;
Expand Down
22 changes: 8 additions & 14 deletions src/kibana/components/agg_types/buckets/_interval_options.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
define(function (require) {
return function IntervalOptionsService(Private) {
var moment = require('moment');
require('directives/input_whole_number');

// shorthand
var ms = function (type) { return moment.duration(1, type).asMilliseconds(); };
Expand All @@ -15,38 +16,31 @@ define(function (require) {
},
{
display: 'Second',
val: 'second',
ms: ms('second')
val: 'second'
},
{
display: 'Minute',
val: 'minute',
ms: ms('minute')
val: 'minute'
},
{
display: 'Hourly',
val: 'hour',
ms: ms('hour')
val: 'hour'
},
{
display: 'Daily',
val: 'day',
ms: ms('day')
val: 'day'
},
{
display: 'Weekly',
val: 'week',
ms: ms('week')
val: 'week'
},
{
display: 'Monthly',
val: 'month',
ms: ms('month')
val: 'month'
},
{
display: 'Yearly',
val: 'year',
ms: ms('year')
val: 'year'
}
];
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
define(function (require) {
var moment = require('moment');
var interval = require('utils/interval');
var buildRangeFilter = require('components/filter_manager/lib/range');

return function createDateHistogramFilterProvider(Private) {
var calculateInterval = Private(require('components/agg_types/param_types/_calculate_interval'));
return function (aggConfig, key) {
var result = calculateInterval(aggConfig);
var date = moment(key).add(result.interval, 'ms');
var moment = require('moment');
var buildRangeFilter = require('components/filter_manager/lib/range');

return function (agg, key) {
var start = moment(key);
var interval = agg.buckets.getInterval();

return buildRangeFilter(aggConfig.params.field, {
gte: parseInt(key, 10),
lte: date.valueOf()
}, aggConfig.vis.indexPattern);
return buildRangeFilter(agg.params.field, {
gte: start.valueOf(),
lte: start.add(interval).subtract(1, 'ms').valueOf()
}, agg.vis.indexPattern);
};

};
Expand Down
114 changes: 58 additions & 56 deletions src/kibana/components/agg_types/buckets/date_histogram.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,48 @@ define(function (require) {
return function DateHistogramAggType(timefilter, config, Private) {
var _ = require('lodash');
var moment = require('moment');
var interval = require('utils/interval');
var BucketAggType = Private(require('components/agg_types/buckets/_bucket_agg_type'));
var calculateInterval = Private(require('components/agg_types/param_types/_calculate_interval'));

var TimeBuckets = Private(require('components/time_buckets/time_buckets'));
var createFilter = Private(require('components/agg_types/buckets/create_filter/date_histogram'));

require('filters/field_type');
var tzOffset = moment().format('Z');

var pickInterval = function (bounds, targetBuckets) {
bounds || (bounds = timefilter.getBounds());
return interval.calculate(bounds.min, bounds.max, targetBuckets);
};
require('filters/field_type');

return new BucketAggType({
name: 'date_histogram',
title: 'Date Histogram',
ordered: {
date: true
},
makeLabel: function (aggConfig) {
var output = this.params.write(aggConfig);
makeLabel: function (agg) {
var output = this.params.write(agg);
var params = output.params;

if (output.metricScaleText) return params.field + ' per ' + output.metricScaleText;

var aggInterval = _.find(this.params.byName.interval.options, {
ms: interval.toMs(params.interval)
});

if (aggInterval) return aggInterval.display + ' ' + params.field;
else return params.field + ' per ' + interval.describe(params.interval);
return params.field + ' per ' + (output.metricScaleText || output.bucketInterval.description);
},
createFilter: createFilter,
decorateAggConfig: function () {
var buckets;
return {
buckets: {
configurable: true,
get: function () {
if (buckets) return buckets;

buckets = new TimeBuckets();
buckets.setInterval(_.get(this, ['params', 'interval']));
buckets.setBounds(timefilter.getActiveBounds());
return buckets;
}
}
};
},
params: [
{
name: 'field',
filterFieldTypes: 'date',
default: function (aggConfig) {
return aggConfig.vis.indexPattern.timeFieldName;
default: function (agg) {
return agg.vis.indexPattern.timeFieldName;
}
},

Expand All @@ -50,40 +53,35 @@ define(function (require) {
default: 'auto',
options: Private(require('components/agg_types/buckets/_interval_options')),
editor: require('text!components/agg_types/controls/interval.html'),
write: function (aggConfig, output, locals) {
// Get the selection
var selection = aggConfig.params.interval;

// If the selection isn't an object then it's going to be
// a string so we need to make it look like an object.
if (!_.isObject(selection)) {
// custom selection
selection = {
display: selection,
val: selection
};
onRequest: function (agg) {
// flag that prevents us from clobbering on subsequest calls to write()
agg.buckets._sentToEs = true;
agg.buckets.setBounds(timefilter.getActiveBounds());
},
write: function (agg, output) {
if (!agg.buckets._sentToEs) {
agg.buckets.setBounds(timefilter.getActiveBounds());
}

// If the selection is set to auto and the locals.renderBot
// exists we need to blow up (for some unknown reason)
if (selection.val === 'auto' && locals.renderBot) {
throw new Error('not implemented');
}
agg.buckets.setInterval(agg.params.interval);

// Calculate the actual interval
var result = calculateInterval(aggConfig);
var interval = agg.buckets.getInterval();
output.bucketInterval = interval;
output.params.interval = interval.expression;
output.params.pre_zone = tzOffset;
output.params.pre_zone_adjust_large_interval = true;

// Set the output params interval along with the metric scale and
// the metric scale test which is used in the label
output.params.interval = result.interval + 'ms';
if (result.metricScale) output.metricScale = result.metricScale;
output.metricScaleText = result.description;
var scaleMetrics = interval.scaled && interval.scale < 1;
if (scaleMetrics) {
scaleMetrics = _.every(agg.vis.aggs.bySchemaGroup.metrics, function (agg) {
return agg.type.name === 'count' || agg.type.name === 'sum';
});
}

// Since this is side effecting on output
// we will return right here.
// TODO: refactor so it's not side effecting so we can write tests
// around it.
return;
if (scaleMetrics) {
output.metricScale = interval.scale;
output.metricScaleText = interval.preScaled.description;
}
}
},

Expand All @@ -99,19 +97,23 @@ define(function (require) {
{
name: 'extended_bounds',
default: {},
write: function (aggConfig, output) {
var val = aggConfig.params.extended_bounds;
write: function (agg, output) {
var val = agg.params.extended_bounds;

if (val.min != null || val.max != null) {
output.params.extended_bounds = {
min: moment(val.min).valueOf(),
max: moment(val.max).valueOf()
};
} else if (aggConfig.vis.indexPattern.timeFieldName) {
var tfBounds = timefilter.getBounds();

return;
}

var bounds = timefilter.getActiveBounds();
if (bounds) {
output.params.extended_bounds = {
min: moment(tfBounds.min).valueOf(),
max: moment(tfBounds.max).valueOf()
min: moment(bounds.min).valueOf(),
max: moment(bounds.max).valueOf()
};
}
}
Expand Down
11 changes: 10 additions & 1 deletion src/kibana/components/agg_types/controls/interval.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
<div class="form-group">
<label>Interval</label>
<label>
Interval
<kbn-info
ng-show="agg.buckets.getInterval().scaled"
placement="right"
class="text-warning"
info="This interval creates {{ agg.buckets.getInterval().scale > 1 ? 'buckets that are too large' : 'too many buckets' }} to show in the selected time range, so it has been scaled to {{ agg.buckets.getInterval().description }}">
</kbn-info>
</label>
<select
ng-if="aggParam.options"
ng-model="agg.params.interval"
ng-change="agg.write()"
required
ng-options="opt as opt.display for opt in aggParam.options.raw | filter: optionEnabled"
class="form-control"
Expand Down
59 changes: 0 additions & 59 deletions src/kibana/components/agg_types/param_types/_calculate_interval.js

This file was deleted.

Loading

0 comments on commit 0923e73

Please sign in to comment.