Skip to content

Commit

Permalink
Make index mode only work with the horizontal distance to an element (#…
Browse files Browse the repository at this point in the history
…3471)

Make index mode only work with the horizontal distance to an element if intersect is off
  • Loading branch information
etimberg authored Oct 15, 2016
1 parent a86c47c commit 6ec6a92
Show file tree
Hide file tree
Showing 2 changed files with 211 additions and 112 deletions.
14 changes: 11 additions & 3 deletions src/core/core.interaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,24 @@ module.exports = function(Chart) {
* @param chart {Chart} the chart to look at elements from
* @param position {Point} the point to be nearest to
* @param intersect {Boolean} if true, only consider items that intersect the position
* @param distanceMetric {Function} Optional function to provide the distance between
* @return {ChartElement[]} the nearest items
*/
function getNearestItems(chart, position, intersect) {
function getNearestItems(chart, position, intersect, distanceMetric) {
var minDistance = Number.POSITIVE_INFINITY;
var nearestItems = [];

if (!distanceMetric) {
distanceMetric = helpers.distanceBetweenPoints;
}

parseVisibleItems(chart, function(element) {
if (intersect && !element.inRange(position.x, position.y)) {
return;
}

var center = element.getCenterPoint();
var distance = Math.round(helpers.distanceBetweenPoints(position, center));
var distance = distanceMetric(position, center);

if (distance < minDistance) {
nearestItems = [element];
Expand All @@ -78,7 +83,10 @@ module.exports = function(Chart) {

function indexMode(chart, e, options) {
var position = helpers.getRelativePosition(e, chart.chart);
var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false);
var distanceMetric = function(pt1, pt2) {
return Math.abs(pt1.x - pt2.x);
};
var items = options.intersect ? getIntersectItems(chart, position) : getNearestItems(chart, position, false, distanceMetric);
var elements = [];

if (!items.length) {
Expand Down
309 changes: 200 additions & 109 deletions test/core.tooltip.tests.js
Original file line number Diff line number Diff line change
@@ -1,118 +1,209 @@
// Test the rectangle element
describe('tooltip tests', function() {
it('Should display in label mode', function() {
var chartInstance = window.acquireChart({
type: 'line',
data: {
datasets: [{
label: 'Dataset 1',
data: [10, 20, 30],
pointHoverBorderColor: 'rgb(255, 0, 0)',
pointHoverBackgroundColor: 'rgb(0, 255, 0)'
describe('Core.Tooltip', function() {
describe('index mode', function() {
it('Should only use x distance when intersect is false', function() {
var chartInstance = window.acquireChart({
type: 'line',
data: {
datasets: [{
label: 'Dataset 1',
data: [10, 20, 30],
pointHoverBorderColor: 'rgb(255, 0, 0)',
pointHoverBackgroundColor: 'rgb(0, 255, 0)'
}, {
label: 'Dataset 2',
data: [40, 40, 40],
pointHoverBorderColor: 'rgb(0, 0, 255)',
pointHoverBackgroundColor: 'rgb(0, 255, 255)'
}],
labels: ['Point 1', 'Point 2', 'Point 3']
},
options: {
tooltips: {
mode: 'index',
intersect: false
}
}
});

// Trigger an event over top of the
var meta = chartInstance.getDatasetMeta(0);
var point = meta.data[1];

var node = chartInstance.chart.canvas;
var rect = node.getBoundingClientRect();

var evt = new MouseEvent('mousemove', {
view: window,
bubbles: true,
cancelable: true,
clientX: rect.left + point._model.x,
clientY: 0
});

// Manully trigger rather than having an async test
node.dispatchEvent(evt);

// Check and see if tooltip was displayed
var tooltip = chartInstance.tooltip;
var globalDefaults = Chart.defaults.global;

expect(tooltip._view).toEqual(jasmine.objectContaining({
// Positioning
xPadding: 6,
yPadding: 6,
xAlign: 'left',
yAlign: 'center',

// Body
bodyFontColor: '#fff',
_bodyFontFamily: globalDefaults.defaultFontFamily,
_bodyFontStyle: globalDefaults.defaultFontStyle,
_bodyAlign: 'left',
bodyFontSize: globalDefaults.defaultFontSize,
bodySpacing: 2,

// Title
titleFontColor: '#fff',
_titleFontFamily: globalDefaults.defaultFontFamily,
_titleFontStyle: 'bold',
titleFontSize: globalDefaults.defaultFontSize,
_titleAlign: 'left',
titleSpacing: 2,
titleMarginBottom: 6,

// Footer
footerFontColor: '#fff',
_footerFontFamily: globalDefaults.defaultFontFamily,
_footerFontStyle: 'bold',
footerFontSize: globalDefaults.defaultFontSize,
_footerAlign: 'left',
footerSpacing: 2,
footerMarginTop: 6,

// Appearance
caretSize: 5,
cornerRadius: 6,
backgroundColor: 'rgba(0,0,0,0.8)',
opacity: 1,
legendColorBackground: '#fff',
displayColors: true,

// Text
title: ['Point 2'],
beforeBody: [],
body: [{
before: [],
lines: ['Dataset 1: 20'],
after: []
}, {
label: 'Dataset 2',
data: [40, 40, 40],
pointHoverBorderColor: 'rgb(0, 0, 255)',
pointHoverBackgroundColor: 'rgb(0, 255, 255)'
before: [],
lines: ['Dataset 2: 40'],
after: []
}],
labels: ['Point 1', 'Point 2', 'Point 3']
},
options: {
tooltips: {
mode: 'label'
}
}
});

// Trigger an event over top of the
var meta = chartInstance.getDatasetMeta(0);
var point = meta.data[1];

var node = chartInstance.chart.canvas;
var rect = node.getBoundingClientRect();
afterBody: [],
footer: [],
caretPadding: 2,
labelColors: [{
borderColor: 'rgb(255, 0, 0)',
backgroundColor: 'rgb(0, 255, 0)'
}, {
borderColor: 'rgb(0, 0, 255)',
backgroundColor: 'rgb(0, 255, 255)'
}]
}));

var evt = new MouseEvent('mousemove', {
view: window,
bubbles: true,
cancelable: true,
clientX: rect.left + point._model.x,
clientY: rect.top + point._model.y
expect(tooltip._view.x).toBeCloseToPixel(269);
expect(tooltip._view.y).toBeCloseToPixel(155);
});

// Manully trigger rather than having an async test
node.dispatchEvent(evt);

// Check and see if tooltip was displayed
var tooltip = chartInstance.tooltip;
var globalDefaults = Chart.defaults.global;

expect(tooltip._view).toEqual(jasmine.objectContaining({
// Positioning
xPadding: 6,
yPadding: 6,
xAlign: 'left',
yAlign: 'center',

// Body
bodyFontColor: '#fff',
_bodyFontFamily: globalDefaults.defaultFontFamily,
_bodyFontStyle: globalDefaults.defaultFontStyle,
_bodyAlign: 'left',
bodyFontSize: globalDefaults.defaultFontSize,
bodySpacing: 2,

// Title
titleFontColor: '#fff',
_titleFontFamily: globalDefaults.defaultFontFamily,
_titleFontStyle: 'bold',
titleFontSize: globalDefaults.defaultFontSize,
_titleAlign: 'left',
titleSpacing: 2,
titleMarginBottom: 6,

// Footer
footerFontColor: '#fff',
_footerFontFamily: globalDefaults.defaultFontFamily,
_footerFontStyle: 'bold',
footerFontSize: globalDefaults.defaultFontSize,
_footerAlign: 'left',
footerSpacing: 2,
footerMarginTop: 6,

// Appearance
caretSize: 5,
cornerRadius: 6,
backgroundColor: 'rgba(0,0,0,0.8)',
opacity: 1,
legendColorBackground: '#fff',
displayColors: true,

// Text
title: ['Point 2'],
beforeBody: [],
body: [{
before: [],
lines: ['Dataset 1: 20'],
after: []
}, {
before: [],
lines: ['Dataset 2: 40'],
after: []
}],
afterBody: [],
footer: [],
caretPadding: 2,
labelColors: [{
borderColor: 'rgb(255, 0, 0)',
backgroundColor: 'rgb(0, 255, 0)'
}, {
borderColor: 'rgb(0, 0, 255)',
backgroundColor: 'rgb(0, 255, 255)'
}]
}));

expect(tooltip._view.x).toBeCloseToPixel(269);
expect(tooltip._view.y).toBeCloseToPixel(155);
it('Should only display if intersecting if intersect is set', function() {
var chartInstance = window.acquireChart({
type: 'line',
data: {
datasets: [{
label: 'Dataset 1',
data: [10, 20, 30],
pointHoverBorderColor: 'rgb(255, 0, 0)',
pointHoverBackgroundColor: 'rgb(0, 255, 0)'
}, {
label: 'Dataset 2',
data: [40, 40, 40],
pointHoverBorderColor: 'rgb(0, 0, 255)',
pointHoverBackgroundColor: 'rgb(0, 255, 255)'
}],
labels: ['Point 1', 'Point 2', 'Point 3']
},
options: {
tooltips: {
mode: 'index',
intersect: true
}
}
});

// Trigger an event over top of the
var meta = chartInstance.getDatasetMeta(0);
var point = meta.data[1];

var node = chartInstance.chart.canvas;
var rect = node.getBoundingClientRect();

var evt = new MouseEvent('mousemove', {
view: window,
bubbles: true,
cancelable: true,
clientX: rect.left + point._model.x,
clientY: 0
});

// Manully trigger rather than having an async test
node.dispatchEvent(evt);

// Check and see if tooltip was displayed
var tooltip = chartInstance.tooltip;
var globalDefaults = Chart.defaults.global;

expect(tooltip._view).toEqual(jasmine.objectContaining({
// Positioning
xPadding: 6,
yPadding: 6,

// Body
bodyFontColor: '#fff',
_bodyFontFamily: globalDefaults.defaultFontFamily,
_bodyFontStyle: globalDefaults.defaultFontStyle,
_bodyAlign: 'left',
bodyFontSize: globalDefaults.defaultFontSize,
bodySpacing: 2,

// Title
titleFontColor: '#fff',
_titleFontFamily: globalDefaults.defaultFontFamily,
_titleFontStyle: 'bold',
titleFontSize: globalDefaults.defaultFontSize,
_titleAlign: 'left',
titleSpacing: 2,
titleMarginBottom: 6,

// Footer
footerFontColor: '#fff',
_footerFontFamily: globalDefaults.defaultFontFamily,
_footerFontStyle: 'bold',
footerFontSize: globalDefaults.defaultFontSize,
_footerAlign: 'left',
footerSpacing: 2,
footerMarginTop: 6,

// Appearance
caretSize: 5,
cornerRadius: 6,
backgroundColor: 'rgba(0,0,0,0.8)',
opacity: 0,
legendColorBackground: '#fff',
displayColors: true,
}));
});
});

it('Should display in single mode', function() {
Expand Down

0 comments on commit 6ec6a92

Please sign in to comment.