Browse Source

Introduce tooltip.position callback function

to control the position of the tooltip programmatically
pull/833/head
Kentaro ku KUMAGAI 10 years ago
parent
commit
7062e0ab67
  1. 60
      spec/tooltip-spec.js
  2. 2
      src/arc.js
  3. 1
      src/config.js
  4. 6
      src/interaction.js
  5. 40
      src/tooltip.js

60
spec/tooltip-spec.js

@ -1,29 +1,38 @@
var describe = window.describe, var describe = window.describe,
expect = window.expect, expect = window.expect,
it = window.it, it = window.it,
jasmine = window.jasmine,
beforeAll = window.beforeAll,
beforeEach = window.beforeEach; beforeEach = window.beforeEach;
describe('c3 chart tooltip', function () { describe('c3 chart tooltip', function () {
'use strict'; 'use strict';
var chart, d3; var chart, d3;
var tooltipConfiguration;
var args = {
data: { var args = function () {
columns: [ return {
['data1', 30, 200, 100, 400, 150, 250], data: {
['data2', 50, 20, 10, 40, 15, 25], columns: [
['data3', 150, 120, 110, 140, 115, 125] ['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) { beforeEach(function (done) {
chart = window.initChart(chart, args, done); chart = window.initChart(chart, args(), done);
d3 = chart.internal.d3; d3 = chart.internal.d3;
}); });
describe('tooltip position', function () { describe('tooltip position', function () {
beforeAll(function () {
tooltipConfiguration = {};
});
describe('without left margin', function () { describe('without left margin', function () {
@ -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
src/arc.js

@ -273,7 +273,7 @@ c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransf
var updated = $$.updateAngle(d), var updated = $$.updateAngle(d),
arcData = $$.convertToArcData(updated), arcData = $$.convertToArcData(updated),
selectedData = [arcData]; selectedData = [arcData];
$$.showTooltip(selectedData, d3.mouse(this)); $$.showTooltip(selectedData, this);
} : null) } : null)
.on('mouseout', config.interaction_enabled ? function (d) { .on('mouseout', config.interaction_enabled ? function (d) {
var updated, arcData; var updated, arcData;

1
src/config.js

@ -183,6 +183,7 @@ c3_chart_internal_fn.getDefaultConfig = function () {
tooltip_format_title: undefined, tooltip_format_title: undefined,
tooltip_format_name: undefined, tooltip_format_name: undefined,
tooltip_format_value: undefined, tooltip_format_value: undefined,
tooltip_position: undefined,
tooltip_contents: function (d, defaultTitleFormat, defaultValueFormat, color) { tooltip_contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : ''; return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : '';
}, },

6
src/interaction.js

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

40
src/tooltip.js

@ -49,20 +49,12 @@ c3_chart_internal_fn.getTooltipContent = function (d, defaultTitleFormat, defaul
} }
return text + "</table>"; return text + "</table>";
}; };
c3_chart_internal_fn.showTooltip = function (selectedData, mouse) { c3_chart_internal_fn.tooltipPosition = function (dataToShow, tWidth, tHeight, element) {
var $$ = this, config = $$.config; var $$ = this, config = $$.config, d3 = $$.d3;
var tWidth, tHeight, svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight; var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;
var forArc = $$.hasArcType(), var forArc = $$.hasArcType(),
dataToShow = selectedData.filter(function (d) { return d && isValue(d.value); }); mouse = d3.mouse(element);
if (dataToShow.length === 0 || !config.tooltip_show) { // Determin tooltip position
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
if (forArc) { if (forArc) {
tooltipLeft = ($$.width / 2) + mouse[0]; tooltipLeft = ($$.width / 2) + mouse[0];
tooltipTop = ($$.height / 2) + mouse[1] + 20; tooltipTop = ($$.height / 2) + mouse[1] + 20;
@ -90,10 +82,28 @@ c3_chart_internal_fn.showTooltip = function (selectedData, mouse) {
if (tooltipTop < 0) { if (tooltipTop < 0) {
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 // Set tooltip
$$.tooltip $$.tooltip
.style("top", tooltipTop + "px") .style("top", position.top + "px")
.style("left", tooltipLeft + 'px'); .style("left", position.left + 'px');
}; };
c3_chart_internal_fn.hideTooltip = function () { c3_chart_internal_fn.hideTooltip = function () {
this.tooltip.style("display", "none"); this.tooltip.style("display", "none");

Loading…
Cancel
Save