Skip to content

Commit

Permalink
Introduce tooltip.position callback function
Browse files Browse the repository at this point in the history
to control the position of the tooltip programatically
  • Loading branch information
ku committed Dec 17, 2014
1 parent 5c91898 commit 8d98131
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 29 deletions.
60 changes: 50 additions & 10 deletions spec/tooltip-spec.js
@@ -1,29 +1,38 @@
var describe = window.describe,
expect = window.expect,
it = window.it,
jasmine = window.jasmine,
beforeAll = window.beforeAll,
beforeEach = window.beforeEach;

describe('c3 chart tooltip', function () {
'use strict';

var chart, d3;

var args = {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25],
['data3', 150, 120, 110, 140, 115, 125]
]
}
var tooltipConfiguration;

var args = function () {
return {
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25],
['data3', 150, 120, 110, 140, 115, 125]
],
},
tooltip: tooltipConfiguration
};
};

beforeEach(function (done) {
chart = window.initChart(chart, args, done);
chart = window.initChart(chart, args(), done);
d3 = chart.internal.d3;
});

describe('tooltip position', function () {
beforeAll(function () {
tooltipConfiguration = {};
});

describe('without left margin', function () {

Expand Down Expand Up @@ -66,4 +75,35 @@ describe('c3 chart tooltip', function () {

});

describe('tooltip positionFunction', function () {
var topExpected = 37, leftExpected = 79;

beforeAll(function () {
tooltipConfiguration = {
position: function (data, width, height, element) {
expect(data.length).toBe(args().data.columns.length);
expect(data[0]).toEqual(jasmine.objectContaining({
index: 2,
value: 100,
id: 'data1'
}));
expect(width).toBeGreaterThan(0);
expect(height).toBeGreaterThan(0);
expect(element).toBe(d3.select('.c3-event-rect-2').node());
return {top: topExpected, left: leftExpected};
}
};
});

it('should be set to the coordinate where the function returned', function () {
var eventRect = d3.select('.c3-event-rect-2').node();
window.setMouseEvent(chart, 'mousemove', 100, 100, eventRect);

var tooltipContainer = d3.select('.c3-tooltip-container'),
top = Math.floor(+tooltipContainer.style('top').replace(/px/, '')),
left = Math.floor(+tooltipContainer.style('left').replace(/px/, ''));
expect(top).toBe(topExpected);
expect(left).toBe(leftExpected);
});
});
});
2 changes: 1 addition & 1 deletion src/arc.js
Expand Up @@ -273,7 +273,7 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf
var updated = $$.updateAngle(d),
arcData = $$.convertToArcData(updated),
selectedData = [arcData];
$$.showTooltip(selectedData, d3.mouse(this));
$$.showTooltip(selectedData, this);
} : null)
.on('mouseout', config.interaction_enabled ? function (d) {
var updated, arcData;
Expand Down
1 change: 1 addition & 0 deletions src/config.js
Expand Up @@ -183,6 +183,7 @@ c3_chart_internal_fn.getDefaultConfig = function () {
tooltip_format_title: undefined,
tooltip_format_name: undefined,
tooltip_format_value: undefined,
tooltip_position: undefined,
tooltip_contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : '';
},
Expand Down
6 changes: 3 additions & 3 deletions src/interaction.js
Expand Up @@ -175,7 +175,7 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
});

if (config.tooltip_grouped) {
$$.showTooltip(selectedData, d3.mouse(this));
$$.showTooltip(selectedData, this);
$$.showXGridFocus(selectedData);
}

Expand Down Expand Up @@ -206,7 +206,7 @@ c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
eventRect.style('cursor', 'pointer');
}
if (!config.tooltip_grouped) {
$$.showTooltip([d], d3.mouse(this));
$$.showTooltip([d], this);
$$.showXGridFocus([d]);
if (config.point_focus_expand_enabled) { $$.expandCircles(index, d.id, true); }
$$.expandBars(index, d.id, true);
Expand Down Expand Up @@ -289,7 +289,7 @@ c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter)
selectedData = sameXData.map(function (d) {
return $$.addName(d);
});
$$.showTooltip(selectedData, mouse);
$$.showTooltip(selectedData, this);

// expand points
if (config.point_focus_expand_enabled) {
Expand Down
40 changes: 25 additions & 15 deletions src/tooltip.js
Expand Up @@ -49,20 +49,12 @@ c3_chart_internal_fn.getTooltipContent = function (d, defaultTitleFormat, defaul
}
return text + "</table>";
};
c3_chart_internal_fn.showTooltip = function (selectedData, mouse) {
var $$ = this, config = $$.config;
var tWidth, tHeight, svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;
c3_chart_internal_fn.tooltipPosition = function (dataToShow, tWidth, tHeight, element) {
var $$ = this, config = $$.config, d3 = $$.d3;
var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;
var forArc = $$.hasArcType(),
dataToShow = selectedData.filter(function (d) { return d && isValue(d.value); });
if (dataToShow.length === 0 || !config.tooltip_show) {
return;
}
$$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block");

// Get tooltip dimensions
tWidth = $$.tooltip.property('offsetWidth');
tHeight = $$.tooltip.property('offsetHeight');
// Determin tooltip position
mouse = d3.mouse(element);
// Determin tooltip position
if (forArc) {
tooltipLeft = ($$.width / 2) + mouse[0];
tooltipTop = ($$.height / 2) + mouse[1] + 20;
Expand Down Expand Up @@ -90,10 +82,28 @@ c3_chart_internal_fn.showTooltip = function (selectedData, mouse) {
if (tooltipTop < 0) {
tooltipTop = 0;
}
return {top: tooltipTop, left: tooltipLeft};
};
c3_chart_internal_fn.showTooltip = function (selectedData, element) {
var $$ = this, config = $$.config;
var tWidth, tHeight, position;
var forArc = $$.hasArcType(),
dataToShow = selectedData.filter(function (d) { return d && isValue(d.value); }),
positionFunction = config.tooltip_position || c3_chart_internal_fn.tooltipPosition;
if (dataToShow.length === 0 || !config.tooltip_show) {
return;
}
$$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block");

// Get tooltip dimensions
tWidth = $$.tooltip.property('offsetWidth');
tHeight = $$.tooltip.property('offsetHeight');

position = positionFunction.call(this, dataToShow, tWidth, tHeight, element);
// Set tooltip
$$.tooltip
.style("top", tooltipTop + "px")
.style("left", tooltipLeft + 'px');
.style("top", position.top + "px")
.style("left", position.left + 'px');
};
c3_chart_internal_fn.hideTooltip = function () {
this.tooltip.style("display", "none");
Expand Down

0 comments on commit 8d98131

Please sign in to comment.