Skip to content

Commit

Permalink
feat: ✨ add ruleLabelVerticalSeparate
Browse files Browse the repository at this point in the history
  • Loading branch information
lloydrichards committed Oct 25, 2024
1 parent 127ce92 commit 70a5cb4
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/annotation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export { default as annotationLine } from "./line.js";
export { default as annotationRangeFlag } from "./rangeFlag.js";
export { default as annotationRangeRuler } from "./rangeRuler.js";
export { default as annotationRectangle } from "./rectangle.js";
export { default as annotationRuler } from "./ruler.js";
export { annotationRuler, rulerLabelVerticalSeparate } from "./ruler.js";
export { default as tooltip } from "./tooltip.js";
export { default as tooltipAnchor } from "./tooltipAnchor.js";
export { default as fitTooltip } from "./fitTooltip.js";
Expand Down
57 changes: 54 additions & 3 deletions src/annotation/ruler.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ import { halfPixel } from "../svgUtils/crisp.js";
import translateString from "../svgUtils/translateString.js";
import { component } from "../d3-component.js";

export default function () {
return component()
export const annotationRuler = () =>
component()
.prop("top")
.prop("bottom")
.prop("x", fn.functor)
Expand Down Expand Up @@ -173,4 +173,55 @@ export default function () {
});
}
});
}

export const rulerLabelVerticalSeparate = (cAcc) => (g) => {
const THRESHOLD = 2;
let labelBounds = [];

// Reset vertical shift
g.selectAll("text").each(function () {
select(this).attr("y", "");
});

// Calculate bounds
g.selectAll(".sszvis-ruler__label").each(function (d) {
const bounds = this.getBoundingClientRect();
labelBounds.push({
category: cAcc(d),
top: bounds.top,
bottom: bounds.bottom,
dy: 0,
});
});

// Sort by vertical position (only supports labels of same height)
labelBounds = labelBounds.sort((a, b) => ascending(a.top, b.top));

// Calculate overlap and correct position
for (let i = 0; i < 10; i++) {
for (let j = 0; j < labelBounds.length; j++) {
for (let k = j + 1; k < labelBounds.length; k++) {
if (j === k) continue;
const firstLabel = labelBounds[j];
const secondLabel = labelBounds[k];
const overlap = firstLabel.bottom - secondLabel.top;
if (overlap >= THRESHOLD) {
firstLabel.bottom -= overlap / 2;
firstLabel.top -= overlap / 2;
firstLabel.dy -= overlap / 2;
secondLabel.bottom += overlap / 2;
secondLabel.top += overlap / 2;
secondLabel.dy += overlap / 2;
}
}
}
}

// Shift vertically to remove overlap
g.selectAll("text").each(function (d) {
const label = fn.find((l) => l.category === cAcc(d), labelBounds);
if (label) {
select(this).attr("y", label.dy);
}
});
};

0 comments on commit 70a5cb4

Please sign in to comment.