[vislib/tooltip] generalize calculation of bounds

This commit is contained in:
Spencer Alger 2014-10-20 16:50:00 -07:00
parent e5ee8125a9
commit ab0dafb70e
2 changed files with 22 additions and 57 deletions

View file

@ -14,10 +14,7 @@ define(function (require) {
var size = getTtSize($tooltip);
var pos = getBasePosition(size, event);
var overflow = getOverflow(size, pos, [
getChartBounds($chart),
getViewportBounds($window)
]);
var overflow = getOverflow(size, pos, [$chart, $window]);
return placeToAvoidOverflow(pos, overflow);
}
@ -54,35 +51,28 @@ define(function (require) {
};
}
function getChartBounds($chart) {
var pos = $chart.offset();
pos.right = pos.left + $chart.outerWidth();
pos.bottom = pos.top + $chart.outerHeight();
return pos;
}
function getViewportBounds($window) {
var offset = $window.offset();
var pos = {
top: offset.top + $window.scrollTop(),
left: offset.left + $window.scrollLeft(),
};
pos.bottom = pos.top + $window.height();
pos.right = pos.left + $window.width();
return pos;
function getBounds($el) {
// in testing, $window is not actually a window, so we need to add
// the offsets to make it work right.
var bounds = $el.offset() || { top: 0, left: 0 };
bounds.top += $el.scrollTop();
bounds.left += $el.scrollLeft();
bounds.bottom = bounds.top + $el.outerHeight();
bounds.right = bounds.left + $el.outerWidth();
return bounds;
}
function getOverflow(size, pos, containers) {
var overflow = {};
containers.forEach(function (container) {
containers.map(getBounds).forEach(function (bounds) {
// number of pixels that the toolip would overflow it's far
// side, if we placed it that way. (negative === no overflow)
mergeOverflows(overflow, {
north: container.top - pos.north,
east: (pos.east + size.width) - container.right,
south: (pos.south + size.height) - container.bottom,
west: container.left - pos.west
north: bounds.top - pos.north,
east: (pos.east + size.width) - bounds.right,
south: (pos.south + size.height) - bounds.bottom,
west: bounds.left - pos.west
});
});
@ -126,8 +116,7 @@ define(function (require) {
positionTooltip.getTtSize = getTtSize;
positionTooltip.getBasePosition = getBasePosition;
positionTooltip.getOverflow = getOverflow;
positionTooltip.getChartBounds = getChartBounds;
positionTooltip.getViewportBounds = getViewportBounds;
positionTooltip.getBounds = getBounds;
positionTooltip.placeToAvoidOverflow = placeToAvoidOverflow;
positionTooltip.removeClone = function () {
$clone && $clone.remove();

View file

@ -93,22 +93,9 @@ define(function (require) {
});
});
describe('getChartBounds()', function () {
it('returns the offsets for the tlrb of the chart', function () {
var cbounds = posTT.getChartBounds($chart);
bounds.forEach(function (b) {
expect(cbounds).to.have.property(b);
});
expect(cbounds.top).to.be.lessThan(cbounds.bottom);
expect(cbounds.left).to.be.lessThan(cbounds.right);
});
});
describe('getViewportBounds()', function () {
it('returns the offsets for the bounds of the window/viewport', function () {
var cbounds = posTT.getViewportBounds($window);
describe('getBounds()', function () {
it('returns the offsets for the tlrb of the element', function () {
var cbounds = posTT.getBounds($chart);
bounds.forEach(function (b) {
expect(cbounds).to.have.property(b);
@ -130,11 +117,7 @@ define(function (require) {
// position the element based on a mouse that is in the middle of the chart
var pos = posTT.getBasePosition(size, makeEvent(0.5, 0.5));
var overflow = posTT.getOverflow(size, pos, [
posTT.getChartBounds($chart),
posTT.getViewportBounds($window)
]);
var overflow = posTT.getOverflow(size, pos, [$chart, $window]);
positions.forEach(function (p) {
expect(overflow).to.have.property(p);
@ -148,11 +131,7 @@ define(function (require) {
// position the element based on a mouse that is in the bottom right hand courner of the chart
var pos = posTT.getBasePosition(size, makeEvent(0.99, 0.99));
var overflow = posTT.getOverflow(size, pos, [
posTT.getChartBounds($chart),
posTT.getViewportBounds($window)
]);
var overflow = posTT.getOverflow(size, pos, [$chart, $window]);
positions.forEach(function (p) {
expect(overflow).to.have.property(p);
@ -170,10 +149,7 @@ define(function (require) {
it('chooses a final placement for the tooltip, based on the calculated overflows', function () {
var size = posTT.getTtSize($tooltip);
var pos = posTT.getBasePosition(size, makeEvent());
var overflow = posTT.getOverflow(size, pos, [
posTT.getChartBounds($chart),
posTT.getViewportBounds($window)
]);
var overflow = posTT.getOverflow(size, pos, [$chart, $window]);
var placement = posTT.placeToAvoidOverflow(pos, overflow);
expect(Object.keys(placement)).to.eql(['top', 'left']);