Skip to content

Commit

Permalink
feat(tooltip): Intent to ship tooltip.position.unit
Browse files Browse the repository at this point in the history
Implementation of tooltip.position.unit to set position's unit value as '%'.

Fix #1239
  • Loading branch information
netil authored Feb 20, 2020
1 parent c5abd54 commit ac078a7
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 12 deletions.
27 changes: 27 additions & 0 deletions spec/internals/tooltip-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,33 @@ describe("TOOLTIP", function() {
expect(top).to.be.equal(tooltipPos.top);
expect(left).to.be.equal(tooltipPos.left);
});

it("set option tooltip.position", () => {
args.tooltip.position = () => ({top: "10%", left: 20});
});

it("check tooltip's position unit", () => {
const pos = args.tooltip.position();
util.hoverChart(chart);

["top", "left"].forEach(v => {
expect(chart.$.tooltip.style(v)).to.be.equal(
pos[v] + (v === "left" ? "px" : "")
);
});
});

it("set option tooltip.position={unit: '%'}", () => {
args.tooltip.position = {unit: "%"};
});

it("check tooltip's position unit as percentage", () => {
util.hoverChart(chart);

["top", "left"].forEach(v => {
expect(/^\d+(\.\d+)?%$/.test(chart.$.tooltip.style(v))).to.be.true;
});
});
});

describe("tooltip order", () => {
Expand Down
13 changes: 11 additions & 2 deletions src/config/Options.js
Original file line number Diff line number Diff line change
Expand Up @@ -3723,8 +3723,10 @@ export default class Options {
* @property {Function} [tooltip.format.value] Set format for the value of each data in tooltip.<br>
* Specified function receives name, ratio, id and index of the data point to show. ratio will be undefined if the chart is not donut/pie/gauge.
* If undefined returned, the row of that value will be skipped.
* @property {Function} [tooltip.position] Set custom position for the tooltip.<br>
* @property {Function} [tooltip.position] Set custom position function for the tooltip.<br>
* This option can be used to modify the tooltip position by returning object that has top and left.
* @property {String} [tooltip.position.unit="px"] Set tooltip's position unit.
* - **NOTE:** This option can't be used along with `tooltip.position` custom function. If want to specify unit in custom function, return value with desired unit.
* @property {Function|Object} [tooltip.contents] Set custom HTML for the tooltip.<br>
* Specified function receives data, defaultTitleFormat, defaultValueFormat and color of the data point to show. If tooltip.grouped is true, data includes multiple data points.
* @property {String|HTMLElement} [tooltip.contents.bindto=undefined] Set CSS selector or element reference to bind tooltip.
Expand Down Expand Up @@ -3772,7 +3774,14 @@ export default class Options {
* value: function(value, ratio, id, index) { return ratio; }
* },
* position: function(data, width, height, element) {
* return {top: 0, left: 0}
* // return with unit or without. If the value is number, is treated as 'px'.
* return {top: "10%", left: 20} // top:10%; left: 20px;
* },
*
* position: {
* // set tooltip's position unit as '%', rather than 'px'.
* // ex) If want to keep the position on mobile device rotation, set as '%'.
* unit: "%"
* },
*
* contents: function(d, defaultTitleFormat, defaultValueFormat, color) {
Expand Down
36 changes: 28 additions & 8 deletions src/internals/tooltip.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,16 +287,14 @@ extend(ChartInternal.prototype, {
const bindto = config.tooltip_contents.bindto;
const forArc = $$.hasArcType(null, ["radar"]);
const dataToShow = selectedData.filter(d => d && isValue($$.getBaseValue(d)));
const positionFunction = config.tooltip_position || $$.tooltipPosition;

if (dataToShow.length === 0 || !config.tooltip_show) {
return;
}

const datum = $$.tooltip.datum();
const dataStr = JSON.stringify(selectedData);
let width = (datum && datum.width) || 0;
let height = (datum && datum.height) || 0;
let {width = 0, height = 0} = datum || {};

if (!datum || datum.current !== dataStr) {
const index = selectedData.concat().sort()[0].index;
Expand Down Expand Up @@ -325,13 +323,35 @@ extend(ChartInternal.prototype, {
}

if (!bindto) {
let fn = config.tooltip_position;
let unit;

if (!isFunction(fn)) {
unit = fn && fn.unit;
fn = $$.tooltipPosition;
}

// Get tooltip dimensions
const position = positionFunction.call(this, dataToShow, width, height, element);
const pos = fn.call(this, dataToShow, width, height, element);

// Set tooltip position
$$.tooltip
.style("top", `${position.top}px`)
.style("left", `${position.left}px`);
["top", "left"].forEach(v => {
let value = pos[v];

// when value is number
if (/^\d+(\.\d+)?$/.test(value)) {
if (unit === "%") {
const size = $$[v === "top" ? "currentHeight" : "currentWidth"];

value = value / size * 100;
} else {
unit = "px";
}

value += unit;
}

$$.tooltip.style(v, value);
});
}
},

Expand Down
7 changes: 5 additions & 2 deletions types/options.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -861,15 +861,18 @@ export interface TooltipOptions {
order?: string | any[] | ((data1: any, data2: any) => number) | null;

/**
* Set custom position for the tooltip.
* Set custom position function for the tooltip.
* This option can be used to modify the tooltip position by returning object that has top and left.
*
* Or set tooltip's position unit.
* This option can't be used along with `tooltip.position` custom function. If want to specify unit in custom function, return value with desired unit.
*/
position?(
data: any,
width: number,
height: number,
element: any
): { top: number; left: number };
): { top: number; left: number } | { unit: string; };

/**
* Set custom HTML for the tooltip.
Expand Down

0 comments on commit ac078a7

Please sign in to comment.