Skip to content

Commit

Permalink
refactor(axis): Efficiently generate axis label node
Browse files Browse the repository at this point in the history
Generate axis label node when is necessary only

Ref #3951

Co-authored-by: netil <[email protected]>
  • Loading branch information
netil and netil authored Feb 18, 2025
1 parent c1c39e7 commit 1abdfc9
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 32 deletions.
57 changes: 32 additions & 25 deletions src/ChartInternal/Axis/Axis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,12 @@ class Axis {
init() {
const $$ = this.owner;
const {config, $el: {main, axis}, state: {clip}} = $$;
const isRotated = config.axis_rotated;
const target = ["x", "y"];

config.axis_y2_show && target.push("y2");

target.forEach(v => {
const classAxis = this.getAxisClassName(v);
const classLabel = $AXIS[`axis${v.toUpperCase()}Label`];

axis[v] = main.append("g")
.attr("class", classAxis)
Expand All @@ -157,13 +155,6 @@ class Axis {
.attr("transform", $$.getTranslate(v))
.style("visibility", config[`axis_${v}_show`] ? null : "hidden");

axis[v].append("text")
.attr("class", classLabel)
.attr("transform", ["rotate(-90)", null][
v === "x" ? +!isRotated : +isRotated
])
.style("text-anchor", () => this.textAnchorForAxisLabel(v));

this.generateAxes(v);
});
}
Expand Down Expand Up @@ -806,27 +797,43 @@ class Axis {
return maxOverflow + tickOffset;
}

/**
* Update axis label text
* @param {boolean} withTransition Weather update with transition
* @private
*/
updateLabels(withTransition: boolean): void {
const $$ = this.owner;
const {$el: {main}, $T} = $$;

const labels = {
x: main.select(`.${$AXIS.axisX} .${$AXIS.axisXLabel}`),
y: main.select(`.${$AXIS.axisY} .${$AXIS.axisYLabel}`),
y2: main.select(`.${$AXIS.axisY2} .${$AXIS.axisY2Label}`)
};
const {config, $el: {main}, $T} = $$;
const isRotated = config.axis_rotated;

Object.keys(labels).filter(id => !labels[id].empty())
.forEach((v: AxisType) => {
const node = labels[v];
["x", "y", "y2"].forEach((id: AxisType) => {
const text = this.getLabelText(id);
const selector = `axis${capitalize(id)}`;
const classLabel = $AXIS[`${selector}Label`];

if (text) {
let axisLabel = main.select(`text.${classLabel}`);

// generate eleement if not exists
if (axisLabel.empty()) {
axisLabel = main.select(`g.${$AXIS[selector]}`)
.insert("text", ":first-child")
.attr("class", classLabel)
.attr("transform", ["rotate(-90)", null][
id === "x" ? +!isRotated : +isRotated
])
.style("text-anchor", () => this.textAnchorForAxisLabel(id));
}

// @check $$.$T(node, withTransition)
$T(node, withTransition)
.attr("x", () => this.xForAxisLabel(v))
.attr("dx", () => this.dxForAxisLabel(v))
.attr("dy", () => this.dyForAxisLabel(v))
.text(() => this.getLabelText(v));
});
$T(axisLabel, withTransition)
.attr("x", () => this.xForAxisLabel(id))
.attr("dx", () => this.dxForAxisLabel(id))
.attr("dy", () => this.dyForAxisLabel(id))
.text(text);
}
});
}

/**
Expand Down
2 changes: 1 addition & 1 deletion test/api/flow-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ describe("API flow", () => {
interval = setInterval(function() {
const translateX = util.parseNum(
chart.internal.$el.axis.x.select(".tick")
.filter(":nth-child(2)")
.filter(":nth-child(1)")
.attr("transform")
);

Expand Down
4 changes: 2 additions & 2 deletions test/api/zoom-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ describe("API zoom", function() {
setTimeout(() => {
const tick = chart.$.main.selectAll(`.${$AXIS.axisX} .tick`);

expect(+tick.filter(`:nth-child(${tick.size() + 1})`).attr("transform").match(/\d+/)[0]).to.be.below(500);
expect(+tick.filter(`:nth-child(${tick.size()})`).attr("transform").match(/\d+/)[0]).to.be.below(500);
done(1);
}, 300);
}));
Expand All @@ -399,7 +399,7 @@ describe("API zoom", function() {
setTimeout(() => {
const tick = main.selectAll(`.${$AXIS.axisX} .tick`);

expect(+tick.filter(`:nth-child(${tick.size() + 1})`).attr("transform").match(/\d+/)[0]).to.be.below(5);
expect(+tick.filter(`:nth-child(${tick.size()})`).attr("transform").match(/\d+/)[0]).to.be.below(5);
done(1);
}, 300);
}));
Expand Down
2 changes: 1 addition & 1 deletion test/interactions/zoom-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ describe("ZOOM", function() {
expect(
getX(`.${$GRID.xgrids} line:nth-child(2)`)
).to.be.equal(
getX(`.${$AXIS.axisX} g.tick:nth-child(5) line`)
getX(`.${$AXIS.axisX} g.tick:nth-child(4) line`)
);

done(1);
Expand Down
62 changes: 59 additions & 3 deletions test/internals/axis-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,63 @@ describe("AXIS", function() {
});
});

describe("axis label", () => {
describe("axis label #1", () => {
beforeAll(() => {
args = {
data: {
columns: [
["data1", 30, 200, 100, 170, 150, 250]
]
},
axis: {
y: {
label: "Y Axis Label"
},
y2: {
show: true
}
}
};
});


it("sholudn't generate unnecessary axis label", () => {
let cnt = 0;

["x", "y", "y2"].forEach(id => {
const axisLabel = chart.internal.$el.axis[id].select("text:first-child");

if (!axisLabel.empty()) {
expect(id).to.be.equal("y");
cnt++;
}
});

expect(cnt).to.be.equal(1);
});

it("should generate axis label text node when api is called.", () => {
let cnt = 0;

// when
chart.axis.labels({
x: "New X Axis Label"
});

["x", "y", "y2"].forEach(id => {
const axisLabel = chart.internal.$el.axis[id].select("text:first-child");

if (!axisLabel.empty()) {
expect(/^(x|y)$/.test(id)).to.be.true;
cnt++;
}
});

expect(cnt).to.be.equal(2);
});
});

describe("axis label #2", () => {
beforeAll(() => {
args = {
data: {
Expand Down Expand Up @@ -2747,7 +2803,7 @@ describe("AXIS", function() {
const axisY = chart.$.main.select(`.${$AXIS.axisY}`);

expect(axisY.node().getBoundingClientRect().width).to.be.equal(
axisY.select(".tick:nth-child(12)").node().getBoundingClientRect().width
axisY.select(".tick:nth-child(11)").node().getBoundingClientRect().width
);
});

Expand Down Expand Up @@ -3269,7 +3325,7 @@ describe("AXIS", function() {
const {max} = internal.getMinMaxValue();

expect(internal.scale.y.domain()[1]).to.be.closeTo(max, 10);
expect(+internal.$el.axis.y.select(".tick:nth-child(10) tspan").text()).to.be.closeTo(max, 10);
expect(+internal.$el.axis.y.select(".tick:nth-child(9) tspan").text()).to.be.closeTo(max, 10);
});
});

Expand Down

0 comments on commit 1abdfc9

Please sign in to comment.