Skip to content

Commit

Permalink
Merge pull request #2731 from spalger/fieldFormatting
Browse files Browse the repository at this point in the history
Field formatting
  • Loading branch information
spalger committed May 4, 2015
2 parents f3d57dd + e05c7bd commit 5924d84
Show file tree
Hide file tree
Showing 130 changed files with 3,276 additions and 1,256 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
define(function (require) {
var _ = require('lodash');
define(function () {
return function (leaf) {
// walk up the branch for each parent
function walk(item, memo) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
define(function (require) {
define(function () {
return function PointSeriesInitX() {
return function initXAxis(chart) {
var x = chart.aspects.x;
Expand All @@ -14,4 +14,4 @@ define(function (require) {
}
};
};
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ define(function (require) {
chart.yScale = xAggOutput.metricScale || null;
};
};
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
define(function (require) {
return function PointSeriesTooltipFormatter($compile, $rootScope) {
var _ = require('lodash');
var $ = require('jquery');

var $tooltipScope = $rootScope.$new();
Expand Down
22 changes: 5 additions & 17 deletions src/kibana/components/agg_table/agg_table.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ define(function (require) {
.directive('kbnAggTable', function ($filter, config, Private, compileRecursiveDirective) {
var _ = require('lodash');

var orderBy = $filter('orderBy');

return {
restrict: 'E',
template: require('text!components/agg_table/agg_table.html'),
Expand Down Expand Up @@ -54,7 +52,7 @@ define(function (require) {
}

// escape each cell in each row
var csvRows = rows.map(function (row, i) {
var csvRows = rows.map(function (row) {
return row.map(escape);
});

Expand All @@ -72,16 +70,13 @@ define(function (require) {
var table = $scope.table;

if (!table) {
$scope.formattedRows = null;
$scope.rows = null;
$scope.formattedColumns = null;
return;
}

setFormattedRows(table);
setFormattedColumns(table);
});

function setFormattedColumns(table) {
self.csv.filename = (table.title() || 'table') + '.csv';
$scope.rows = table.rows;
$scope.formattedColumns = table.columns.map(function (col, i) {
var agg = $scope.table.aggConfig(col);
var field = agg.field();
Expand All @@ -98,14 +93,7 @@ define(function (require) {

return formattedColumn;
});
}

function setFormattedRows(table) {
$scope.rows = table.rows;

// update the csv file's title
self.csv.filename = (table.title() || 'table') + '.csv';
}
});
}
};
});
Expand Down
28 changes: 18 additions & 10 deletions src/kibana/components/agg_types/metrics/_metric_agg_type.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
define(function (require) {
return function MetricAggTypeProvider(Private, indexPatterns) {
return function MetricAggTypeProvider(Private) {
var _ = require('lodash');
var AggType = Private(require('components/agg_types/_agg_type'));
var fieldFormats = Private(require('registry/field_formats'));

_(MetricAggType).inherits(AggType);
function MetricAggType(config) {
MetricAggType.Super.call(this, config);

if (_.isFunction(config.getValue)) {
this.getValue = config.getValue;
}
// allow overriding any value on the prototype
_.forOwn(config, function (val, key) {
if (_.has(MetricAggType.prototype, key)) {
this[key] = val;
}
}, this);
}

/**
Expand All @@ -21,15 +25,19 @@ define(function (require) {
return bucket[agg.id].value;
};

/**
* Pick a format for the values produced by this agg type,
* overriden by several metrics that always output a simple
* number
*
* @param {agg} agg - the agg to pick a format for
* @return {FieldFromat}
*/
MetricAggType.prototype.getFormat = function (agg) {
var field = agg.field();
if (field && field.type === 'date' && field.format) {
return field.format;
} else {
return indexPatterns.fieldFormats.byName.number;
}
return field ? field.format : fieldFormats.getDefaultInstance('number');
};

return MetricAggType;
};
});
});
2 changes: 1 addition & 1 deletion src/kibana/components/agg_types/metrics/avg.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ define(function (require) {
]
});
};
});
});
6 changes: 5 additions & 1 deletion src/kibana/components/agg_types/metrics/cardinality.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
define(function (require) {
return function AggTypeMetricCardinalityProvider(Private) {
var MetricAggType = Private(require('components/agg_types/metrics/_metric_agg_type'));
var fieldFormats = Private(require('registry/field_formats'));

return new MetricAggType({
name: 'cardinality',
title: 'Unique Count',
makeLabel: function (aggConfig) {
return 'Unique count of ' + aggConfig.params.field.displayName;
},
getFormat: function () {
return fieldFormats.getDefaultInstance('number');
},
params: [
{
name: 'field'
}
]
});
};
});
});
8 changes: 6 additions & 2 deletions src/kibana/components/agg_types/metrics/count.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
define(function (require) {
return function AggTypeMetricCountProvider(Private) {
var MetricAggType = Private(require('components/agg_types/metrics/_metric_agg_type'));
var fieldFormats = Private(require('registry/field_formats'));

return new MetricAggType({
name: 'count',
title: 'Count',
hasNoDsl: true,
makeLabel: function (aggConfig) {
makeLabel: function () {
return 'Count';
},
getFormat: function () {
return fieldFormats.getDefaultInstance('number');
},
getValue: function (agg, bucket) {
return bucket.doc_count;
}
});
};
});
});
4 changes: 4 additions & 0 deletions src/kibana/components/agg_types/metrics/percentile_ranks.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ define(function (require) {

var MetricAggType = Private(require('components/agg_types/metrics/_metric_agg_type'));
var getResponseAggConfig = Private(require('components/agg_types/metrics/_get_response_agg_config'));
var fieldFormats = Private(require('registry/field_formats'));

var valuesEditor = require('text!components/agg_types/controls/percentile_ranks.html');
// required by the values editor
Expand Down Expand Up @@ -39,6 +40,9 @@ define(function (require) {
return new ValueAggConfig(value);
});
},
getFormat: function () {
return fieldFormats.getInstance('percent') || fieldFormats.getDefaultInstance('number');
},
getValue: function (agg, bucket) {
// values for 1, 5, and 10 will come back as 1.0, 5.0, and 10.0 so we
// parse the keys and respond with the value that matches
Expand Down
4 changes: 4 additions & 0 deletions src/kibana/components/agg_types/metrics/percentiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ define(function (require) {
var MetricAggType = Private(require('components/agg_types/metrics/_metric_agg_type'));
var getResponseAggConfig = Private(require('components/agg_types/metrics/_get_response_agg_config'));
var ordinalSuffix = require('utils/ordinal_suffix');
var fieldFormats = Private(require('registry/field_formats'));

var percentsEditor = require('text!components/agg_types/controls/percentiles.html');
// required by the percentiles editor
Expand Down Expand Up @@ -40,6 +41,9 @@ define(function (require) {
return new ValueAggConfig(percent);
});
},
getFormat: function () {
return fieldFormats.getInstance('percent') || fieldFormats.getDefaultInstance('number');
},
getValue: function (agg, bucket) {
// percentiles for 1, 5, and 10 will come back as 1.0, 5.0, and 10.0 so we
// parse the keys and respond with the value that matches
Expand Down
66 changes: 56 additions & 10 deletions src/kibana/components/bind.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
define(function (require) {
var _ = require('lodash');
var angular = require('angular');

require('modules').get('kibana')
.config(function ($provide) {

function strictEquality(a, b) {
// are the values equal? or, are they both NaN?
return a === b || (a !== a && b !== b);
}

function errorNotAssignable(source, target) {
throw Error('Unable to accept change to bound $scope property "' + source + '"' +
' because source expression "' + target + '" is not assignable!');
}

$provide.decorator('$rootScope', function ($delegate, $parse) {
/**
* Two-way bind a value from scope to another property on scope. This
Expand All @@ -12,23 +23,58 @@ define(function (require) {
*
* @param {expression} to - the location on scope to bind to
* @param {expression} from - the location on scope to bind from
* @param {Scope} $sourceScope - the scope to read "from" expression from
* @return {undefined}
*/
$delegate.constructor.prototype.$bind = function (to, from) {
var $source = this.$parent;
$delegate.constructor.prototype.$bind = function (to, from, $sourceScope) {
var $source = $sourceScope || this.$parent;
var $target = this;

var getter = $parse(from);
var setter = $parse(to).assign;
// parse expressions
var $to = $parse(to);
if (!$to.assign) errorNotAssignable(to, from);
var $from = $parse(from);
$from.assignOrFail = $from.assign || function () {
// revert the change and throw an error, child writes aren't supported
$to($target, lastSourceVal = $from($source));
errorNotAssignable(from, to);
};

// bind scopes to expressions
var getTarget = function () { return $to($target); };
var setTarget = function (v) { return $to.assign($target, v); };
var getSource = function () { return $from($source); };
var setSource = function (v) { return $from.assignOrFail($source, v); };

// if we are syncing down a literal, then we use loose equality check
var strict = !$from.literal;
var compare = strict ? strictEquality : angular.equals;

// to support writing from the child to the parent we need to know
// which source has changed. Track the source value and anytime it
// changes (even if the target value changed too) push from source
// to target. If the source hasn't changed then the change is from
// the target and push accordingly
var lastSourceVal = getSource();

// push the initial value down, start off in sync
setTarget(lastSourceVal);

$target.$watch(function () {
var sourceVal = getSource();
var targetVal = getTarget();

var outOfSync = !compare(sourceVal, targetVal);
var sourceChanged = outOfSync && !compare(sourceVal, lastSourceVal);

if (sourceChanged) setTarget(sourceVal);
else if (outOfSync) setSource(targetVal);

setter($target, getter($source));
this.$watch(
function () { return getter($source); },
function (val) { setter($target, val); }
);
return lastSourceVal = sourceVal;
}, null, !strict);
};

return $delegate;
});
});
});
});
43 changes: 43 additions & 0 deletions src/kibana/components/bound_to_config_obj.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
define(function (require) {
return function BoundToConfigObjProvider($rootScope, config) {
var _ = require('lodash');

/**
* Create an object with properties that may be bound to config values.
* The input object is basically cloned unless one of it's own properties
* resolved to a string value that starts with an equal sign. When that is
* found, that property is forever bound to the corresponding config key.
*
* example:
*
* // name is cloned, height is bound to the defaultHeight config key
* { name: 'john', height: '=defaultHeight' };
*
* @param {Object} input
* @return {Object}
*/
function BoundToConfigObj(input) {
var self = this;

_.forOwn(input, function (val, prop) {
if (!_.isString(val) || val.charAt(0) !== '=') {
self[prop] = val;
return;
}

var configKey = val.substr(1);

update();
$rootScope.$on('init:config', update);
$rootScope.$on('change:config.' + configKey, update);
function update() {
self[prop] = config.get(configKey);
}

});
}

return BoundToConfigObj;

};
});
Loading

0 comments on commit 5924d84

Please sign in to comment.