Skip to content

Commit

Permalink
fix(data): Fix data label position on inverted axis
Browse files Browse the repository at this point in the history
Adjust y coordinate values when axis is inverted

Fix #2700
  • Loading branch information
netil committed May 30, 2022
1 parent 7b7ee08 commit b024d83
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 9 deletions.
43 changes: 34 additions & 9 deletions src/ChartInternal/internals/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,27 @@ function getRotateAnchor(angle: number): Anchor {

/**
* Set rotated position coordinate according text.labels.rotate angle
* @param {number} value Data value
* @param {object} d Data object
* @param {object} pos Position object
* @param {object} pos.x x coordinate
* @param {object} pos.y y coordinate
* @param {string} anchor string value
* @param {boolean} isRotated If axis is rotated
* @param {boolean} isInverted If axis is inverted
* @returns {object} x, y coordinate
* @private
*/
function setRotatePos(value: number, pos: Coord, anchor: Anchor, isRotated: boolean): Coord {
function setRotatePos(
d: IDataRow, pos: Coord, anchor: Anchor, isRotated: boolean, isInverted: boolean
): Coord {
const $$ = this;
const {value} = d;
const isCandlestickType = $$.isCandlestickType(d);
const isNegative = value < 0 || (
isCandlestickType && !$$.getCandlestickData(d)?._isUp
);

let {x, y} = pos;
const isNegative = value < 0;
const gap = 4;
const doubleGap = gap * 2;

Expand All @@ -71,6 +80,10 @@ function setRotatePos(value: number, pos: Coord, anchor: Anchor, isRotated: bool
x -= gap;
isNegative && (y += doubleGap * 2);
}

if (isInverted) {
y += isNegative ? -17 : (isCandlestickType ? 13 : 7);
}
}

return {x, y};
Expand Down Expand Up @@ -244,7 +257,7 @@ export default {
*/
redrawText(getX, getY, forFlow?: boolean, withTransition?: boolean): true {
const $$ = this;
const {$T, config} = $$;
const {$T, axis, config} = $$;
const t = <string>getRandom(true);
const isRotated = config.axis_rotated;
const angle = config.data_labels.rotate;
Expand All @@ -259,13 +272,14 @@ export default {
.each(function(d: IDataRow, i: number) {
// do not apply transition for newly added text elements
const node = $T(this, !!(withTransition && this.getAttribute("x")), t);
const isInverted = config[`axis_${axis?.getId(d.id)}_inverted`];
let pos = {
x: getX.bind(this)(d, i),
y: getY.bind(this)(d, i)
};

if (angle) {
pos = setRotatePos(d.value, pos, anchorString, isRotated);
pos = setRotatePos.bind($$)(d, pos, anchorString, isRotated, isInverted);
node.attr("text-anchor", anchorString);
}

Expand Down Expand Up @@ -413,7 +427,6 @@ export default {
const isRotated = config.axis_rotated;
let xPos = points[0][0];


if ($$.isCandlestickType(d)) {
if (isRotated) {
xPos = $$.getCandlestickData(d)?._isUp ?
Expand Down Expand Up @@ -459,8 +472,10 @@ export default {
*/
getYForText(points, d, textElement): number {
const $$ = this;
const {config, state} = $$;
const {axis, config, state} = $$;
const isRotated = config.axis_rotated;
const isInverted = config[`axis_${axis?.getId(d.id)}_inverted`];
const isBarType = $$.isBarType(d);
const r = config.point_r;
const rect = getBoundingRect(textElement);
let {value} = d;
Expand All @@ -477,6 +492,10 @@ export default {
yPos = value && value._isUp ?
points[2][2] - baseY :
points[2][1] + (baseY * 4);

if (isInverted) {
yPos += 15 * (value._isUp ? 1 : -1);
}
}
} else {
if (isRotated) {
Expand All @@ -489,16 +508,22 @@ export default {
}

if (value < 0 || (value === 0 && !state.hasPositiveValue && state.hasNegativeValue)) {
yPos += rect.height + ($$.isBarType(d) ? -baseY : baseY);
yPos += isInverted ? (isBarType ? -3 : -5) : (
rect.height + (isBarType ? -baseY : baseY)
);
} else {
let diff = -baseY * 2;

if ($$.isBarType(d)) {
if (isBarType) {
diff = -baseY;
} else if ($$.isBubbleType(d)) {
diff = baseY;
}

if (isInverted) {
diff = isBarType ? 10 : 15;
}

yPos += diff;
}
}
Expand Down
86 changes: 86 additions & 0 deletions test/internals/text-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1315,6 +1315,92 @@ describe("TEXT", () => {
});
});

describe("Labels' postion on inverted axis", () => {
before(() => {
args = {
data: {
columns: [
["data1",
[1027, 1369, 1289, 1348],
[1348, 1371, 1314, 1320],
]

],
type: "candlestick",
labels: {
rotate: 0
},
},
axis: {
y: {
inverted: true
}
}
};
});

it("check for candlestick type", () => {
const expectedY = [390, 321];

chart.$.text.texts.each(function(d, i) {
expect(+this.getAttribute("y")).to.be.closeTo(expectedY[i], 2);
});
});

it("set options", () => {
args.data.columns = [["data1", 90, -100]];
args.data.type = "line";
});

it("check for line type", () => {
const expectedY = [394, 42];

chart.$.text.texts.each(function(d, i) {
expect(+this.getAttribute("y")).to.be.closeTo(expectedY[i], 2);
});
});

it("set options: data.type='bar'", () => {
args.data.type = "bar";
});

it("check for bar type", () => {
const expectedY = [389, 44];

chart.$.text.texts.each(function(d, i) {
expect(+this.getAttribute("y")).to.be.closeTo(expectedY[i], 2);
});
});

it("set options: data.labels.rotate = 270", () => {
args.data.labels.rotate = 270;
});

it("check for bar type with rotate option", () => {
const expectedY = [396, 43];

chart.$.text.texts.each(function(d, i) {
const y = +this.getAttribute("transform").match(/\s(\d+\.\d+)/)[1];

expect(y).to.be.closeTo(expectedY[i], 2);
});
});

it("set options: data.type = 'line'", () => {
args.data.type = "line";
});

it("check for line type with rotate option", () => {
const expectedY = [401, 41];

chart.$.text.texts.each(function(d, i) {
const y = +this.getAttribute("transform").match(/\s(\d+\.\d+)/)[1];

expect(y).to.be.closeTo(expectedY[i], 2);
});
});
});

describe("labels.colors callback", () => {
let ctx = [];

Expand Down

0 comments on commit b024d83

Please sign in to comment.