Skip to content

Commit

Permalink
Merge branch 'master' into embedded-vis
Browse files Browse the repository at this point in the history
Conflicts:
	src/kibana/plugins/visualize/editor/editor.html
  • Loading branch information
Spencer Alger committed Nov 21, 2014
2 parents 79bdfe7 + 46e3977 commit fb1484a
Show file tree
Hide file tree
Showing 49 changed files with 1,040 additions and 428 deletions.
2 changes: 2 additions & 0 deletions src/kibana/components/courier/data_source/_abstract.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ define(function (require) {
'match_all': {}
};
}
flatState.body.fields = ['*', '_source'];


/**
* Create a filter that can be reversed for filters with negate set
Expand Down
34 changes: 34 additions & 0 deletions src/kibana/components/highlight/highlight.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
define(function (require) {
require('components/highlight/highlight_tags');

var _ = require('lodash');
var angular = require('angular');
var module = require('modules').get('kibana');

module.filter('highlight', function (highlightTags) {
return function (formatted, highlight) {
if (typeof formatted === 'object') formatted = angular.toJson(formatted);

formatted = _.escape(formatted);

_.each(highlight, function (section) {
section = _.escape(section);

// Strip out the highlight tags to compare against the formatted string
var untagged = section
.split(highlightTags.pre).join('')
.split(highlightTags.post).join('');

// Replace all highlight tags with proper html tags
var tagged = section
.split(highlightTags.pre).join('<mark>')
.split(highlightTags.post).join('</mark>');

// Replace all instances of the untagged string with the properly tagged string
formatted = formatted.split(untagged).join(tagged);
});

return formatted;
};
});
});
11 changes: 11 additions & 0 deletions src/kibana/components/highlight/highlight_tags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
define(function (require) {
var module = require('modules').get('kibana');

// By default, ElasticSearch surrounds matched values in <em></em>. This is not ideal because it is possible that
// the value could contain <em></em> in the value. We define these custom tags that we would never expect to see
// inside a field value.
module.constant('highlightTags', {
pre: '@kibana-highlighted-field@',
post: '@/kibana-highlighted-field@'
});
});
46 changes: 46 additions & 0 deletions src/kibana/components/index_patterns/_map_field.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
define(function (require) {
return function MapFieldFn(Private, config) {
var _ = require('lodash');
var castMappingType = Private(require('components/index_patterns/_cast_mapping_type'));

/**
* Accepts a field object and its name, and tries to give it a mapping
* @param {Object} field - the field mapping returned by elasticsearch
* @param {String} type - name of the field
* @return {Object} - the resulting field after overrides and tweaking
*/
return function mapField(field, name) {
var keys = Object.keys(field.mapping);
if (keys.length === 0 || (name[0] === '_') && !_.contains(config.get('metaFields'), name)) return;

var mapping = _.cloneDeep(field.mapping[keys.shift()]);
mapping.type = castMappingType(mapping.type);

// Override the mapping, even if elasticsearch says otherwise
var mappingOverrides = {
_id: {
indexed: true
},
_timestamp: {
indexed: true,
type: 'date'
}
};

if (!mapping.index || mapping.index === 'no') {
// elasticsearch responds with false sometimes and 'no' others
mapping.indexed = false;
} else {
mapping.indexed = true;
}

mapping.analyzed = mapping.index === 'analyzed' ? true : false;

if (mappingOverrides[name]) {
_.merge(mapping, mappingOverrides[name]);
}

return mapping;
};
};
});
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ define(function (require) {
var _ = require('lodash');
var MappingConflict = require('errors').MappingConflict;
var castMappingType = Private(require('components/index_patterns/_cast_mapping_type'));
var mapField = Private(require('components/index_patterns/_map_field'));


/**
* Convert the ES response into the simple map for fields to
Expand All @@ -22,20 +24,7 @@ define(function (require) {
var keys = Object.keys(field.mapping);
if (keys.length === 0 || (name[0] === '_') && !_.contains(config.get('metaFields'), name)) return;

var mapping = _.cloneDeep(field.mapping[keys.shift()]);
mapping.type = castMappingType(mapping.type);

if (name === '_id') {
// _id is allways indexed
mapping.indexed = true;
} else if (!mapping.index || mapping.index === 'no') {
// elasticsearch responds with false sometimes and 'no' others
mapping.indexed = false;
} else {
mapping.indexed = true;
}

mapping.analyzed = mapping.index === 'analyzed' ? true : false;
var mapping = mapField(field, name);

if (fields[name]) {
if (fields[name].type !== mapping.type
Expand Down
24 changes: 24 additions & 0 deletions src/kibana/components/listen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
define(function (require) {
var _ = require('lodash');

require('modules').get('kibana')
.run(function ($rootScope) {

/**
* Helper that registers an event listener, and removes that listener when
* the $scope is destroyed.
*
* @param {EventEmitter} emitter - the event emitter to listen to
* @param {string} eventName - the event name
* @param {Function} handler - the event handler
* @return {undefined}
*/
$rootScope.constructor.prototype.$listen = function (emitter, eventName, handler) {
emitter.on(eventName, handler);
this.$on('$destroy', function () {
emitter.off(eventName, handler);
});
};

});
});
5 changes: 5 additions & 0 deletions src/kibana/components/notify/notify.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ define(function (require) {
return Notifier;
});

module.run(function ($timeout) {
// provide alternate methods for setting timeouts, which will properly trigger digest cycles
rootNotifier._setTimerFns($timeout, $timeout.cancel);
});

/**
* Global Angular exception handler (NOT JUST UNCAUGHT EXCEPTIONS)
*/
Expand Down
6 changes: 6 additions & 0 deletions src/kibana/components/style_compile/style_compile.css.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.truncate-by-height {
max-height: <%= truncateMaxHeight %>;
}
.truncate-by-height::before {
top: <%= truncateGradientTop %>;
}
32 changes: 32 additions & 0 deletions src/kibana/components/style_compile/style_compile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
define(function (require) {
var _ = require('lodash');
var $ = require('jquery');
var $style = $('<style>').appendTo('head').attr('id', 'style-compile');

require('modules')
.get('kibana')
.run(function ($rootScope, $compile, config) {
var truncateGradientHeight = 15;
var template = _.template(require('text!components/style_compile/style_compile.css.tmpl'));
var locals = {};

$rootScope.$on('$destroy', function () {
$style.remove();
});

// watch the value of the truncate:maxHeight config param
$rootScope.$watch(function () {
return config.get('truncate:maxHeight');
}, function (maxHeight) {
if (maxHeight > 0) {
locals.truncateMaxHeight = maxHeight + 'px !important';
locals.truncateGradientTop = maxHeight - truncateGradientHeight + 'px';
} else {
locals.truncateMaxHeight = 'none';
locals.truncateGradientTop = '-' + truncateGradientHeight + 'px';
}

$style.html(template(locals));
});
});
});
2 changes: 1 addition & 1 deletion src/kibana/components/timepicker/timepicker.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@
</div>

<div class="kbn-timepicker-section">
<label>&nbsp</label><br>
<label>&nbsp;</label><br>
<div class="form-group">
<button
type="submit"
Expand Down
File renamed without changes.
28 changes: 28 additions & 0 deletions src/kibana/components/tooltip/tooltip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
define(function (require) {
var html = require('text!components/tooltip/tooltip.html');

require('modules').get('kibana')
.config(function ($tooltipProvider) {
$tooltipProvider.options({
placement: 'bottom',
animation: true,
popupDelay: 150,
appendToBody: false
});
})
.directive('kbnTooltip', function () {
return {
restrict: 'E',
template: html,
transclude: true,
replace: true,
scope: true,
link: function ($scope, $el, attr) {
$scope.text = attr.text;
$scope.placement = attr.placement || 'top';
$scope.delay = attr.delay || 400;
$scope.appendToBody = attr.appendToBody || 0;
}
};
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,26 @@ define(function (require) {
var OFFSET = 10;
var $clone;

function positionTooltip($window, $chart, $tooltip, $sizer, event) {
$chart = $($chart);
$tooltip = $($tooltip);

if (!$chart.size() || !$tooltip.size()) return;

var size = getTtSize($tooltip, $sizer);
function positionTooltip(opts) {
if (!opts) return;
var $chart = $(opts.$chart);
var $el = $(opts.$el);
var $window = $(opts.$window || window);
var $sizer = $(opts.$sizer);
var prev = opts.prev || {};
var event = opts.event;

if (!$chart.size() || !$el.size()) return;

var size = getTtSize($el, $sizer);
var pos = getBasePosition(size, event);

var overflow = getOverflow(size, pos, [$chart, $window]);

return placeToAvoidOverflow(pos, overflow);
return placeToAvoidOverflow(pos, prev, overflow);
}

function getTtSize($tooltip, $sizer) {
var ttHtml = $tooltip.html();
function getTtSize($el, $sizer) {
var ttHtml = $el.html();
if ($sizer.html() !== ttHtml) {
$sizer.html(ttHtml);
}
Expand Down Expand Up @@ -77,29 +81,32 @@ define(function (require) {
});
}

function placeToAvoidOverflow(pos, overflow) {
var placement = {};
function pickPlacement(prop, pos, overflow, prev, pref, fallback, placement) {
var stash = '_' + prop;

if (overflow.south > 0) {
if (overflow.north < 0) {
placement.top = pos.north;
} else {
placement.top = pos.south - overflow.south;
}
} else {
placement.top = pos.south;
}
// first choice
var first = prev[stash] || pref;
// second choice
var second = first === pref ? fallback : pref;

if (overflow.east > 0) {
if (overflow.west < 0) {
placement.left = pos.west;
if (overflow[first] > 0) {
if (overflow[second] < 0) {
placement[prop] = pos[second];
placement[stash] = second;
} else {
placement.left = pos.east - overflow.east;
placement[prop] = pos[first] - overflow[first];
placement[stash] = first;
}
} else {
placement.left = pos.east;
placement[prop] = pos[first];
placement[stash] = first;
}
}

function placeToAvoidOverflow(pos, prev, overflow) {
var placement = {};
pickPlacement('top', pos, overflow, prev, 'south', 'north', placement);
pickPlacement('left', pos, overflow, prev, 'east', 'west', placement);
return placement;
}

Expand Down
25 changes: 18 additions & 7 deletions src/kibana/components/vislib/components/tooltip/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,29 @@ define(function (require) {
self.container = d3.select(self.el).select('.' + self.containerClass);
}

self.$chart.on('mouseleave', function (event) {
// if the mouse moves fast enough, it can "leave"
// by entering the tooltip
if ($tooltip.is(event.relatedTarget)) return;

// only clear when we leave the chart, so that
// moving between points doesn't make it reposition
self.previousPlacement = null;
});

selection.each(function (d, i) {
var element = d3.select(this);

element
.on('mousemove.tip', function () {
var placement = self.getTooltipPlacement(
self.$window,
self.$chart,
$tooltip,
$sizer,
d3.event
);
var placement = self.previousPlacement = self.getTooltipPlacement({
$window: self.$window,
$chart: self.$chart,
$el: $tooltip,
$sizer: $sizer,
event: d3.event,
prev: self.previousPlacement
});
if (!placement) return;

var events = self.events ? self.events.eventResponse(d, i) : d;
Expand Down
Loading

0 comments on commit fb1484a

Please sign in to comment.