Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions js/src/50_chartview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4304,6 +4304,14 @@ export class ChartView {
// instead of covering the chrome line drawn behind it (grid lines stay on
// the chrome canvas, behind the data). Rebuilt with the labels; static
// between throttled zoom frames since the plot rect doesn't move on zoom.
const tickParts = (axis) => {
const length = Math.max(0, this._axisStyleNumber(axis, "tick_length", 0));
const width = Math.max(0.5, this._axisStyleNumber(axis, "tick_width", 1));
const direction = String(this._axisStyleValue(axis, "tick_direction") || "out");
if (direction === "in") return { inward: length, outward: 0, width };
if (direction === "inout") return { inward: length / 2, outward: length / 2, width };
return { inward: 0, outward: length, width };
};
if (updateLabels) {
const rule = (styleAxis, left, top, w, h, colorKey = "axis_color") => {
const d = document.createElement("div");
Expand Down Expand Up @@ -4339,14 +4347,6 @@ export class ChartView {
rule(axis, x, p.y, w, p.h);
}

const tickParts = (axis) => {
const length = Math.max(0, this._axisStyleNumber(axis, "tick_length", 0));
const width = Math.max(0.5, this._axisStyleNumber(axis, "tick_width", 1));
const direction = String(this._axisStyleValue(axis, "tick_direction") || "out");
if (direction === "in") return { inward: length, outward: 0, width };
if (direction === "inout") return { inward: length / 2, outward: length / 2, width };
return { inward: 0, outward: length, width };
};
if (!hideX) {
const tick = tickParts(xAxis);
const side = xAxis.side || "bottom";
Expand Down Expand Up @@ -4480,9 +4480,13 @@ export class ChartView {
"tick_label_size",
this._axisStyleNumber(xAxis, "tick_size", 11),
);
const xTickGap = tickParts(xAxis).outward
+ this._axisStyleNumber(xAxis, "tick_padding", 0);
for (const item of this._layoutTickLabels(xAxis, "x", xLabelCandidates)) {
const rowOffset = Number(item.row || 0) * (Math.max(8, tickLabelSize) + 4);
const top = xAxis.side === "top" ? p.y - 18 - rowOffset : p.y + p.h + 6 + rowOffset;
const top = xAxis.side === "top"
? p.y - xTickGap - Math.max(8, tickLabelSize) * 1.2 - rowOffset
: p.y + p.h + xTickGap + rowOffset;
const placement = this._xTickLabelTransform(xAxis, item.angle);
label(
item.text,
Expand All @@ -4508,8 +4512,12 @@ export class ChartView {
"tick_label_size",
this._axisStyleNumber(axis, "tick_size", 11),
);
const tickGap = tickParts(axis).outward
+ this._axisStyleNumber(axis, "tick_padding", 0);
const rowOffset = Number(item.row || 0) * (Math.max(8, tickLabelSize) + 4);
const top = axis.side === "top" ? p.y - 18 - rowOffset : p.y + p.h + 6 + rowOffset;
const top = axis.side === "top"
? p.y - tickGap - Math.max(8, tickLabelSize) * 1.2 - rowOffset
: p.y + p.h + tickGap + rowOffset;
const placement = this._xTickLabelTransform(axis, item.angle);
label(
item.text,
Expand Down Expand Up @@ -4538,7 +4546,9 @@ export class ChartView {
// tick. Unset defaults to the tick-side edge — mpl `ha`: "end" left of
// the plot, "start" right of it — reproducing the classic layout.
const yLabelPlacement = (axis, onRight, item) => {
const pin = onRight ? p.x + p.w + 8 : p.x - 8;
const tickGap = tickParts(axis).outward
+ this._axisStyleNumber(axis, "tick_padding", 0);
const pin = onRight ? p.x + p.w + tickGap : p.x - tickGap;
const anchor = this._axisTickLabelAnchor(axis) ?? (onRight ? "start" : "end");
const angle = Number(item.angle || 0);
const shift = anchor === "end" ? "-100%" : anchor === "start" ? "0%" : "-50%";
Expand Down
12 changes: 10 additions & 2 deletions python/xy/_raster.py
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,10 @@ def emit_tick_labels(
)
font_size = _axis_tick_font_size(axis)
side = axis.get("side", "bottom" if is_x else "left")
length = max(0.0, float(axis_style.get("tick_length", 0)))
direction = str(axis_style.get("tick_direction", "out"))
outward = 0.0 if direction == "in" else length / 2 if direction == "inout" else length
gap = outward + float(axis_style.get("tick_padding", 0))
# An explicit tick_label_anchor (axis spec or style) overrides the
# side-derived default, matching the browser client and SVG export.
explicit_anchor = _tick_label_anchor(axis, axis_style, "")
Expand All @@ -951,10 +955,14 @@ def emit_tick_labels(
if is_x:
row_offset = float(item["row"]) * (font_size + 4)
x = float(item["pos"])
y = py0 - 7 - row_offset if side == "top" else py1 + 15 + row_offset
y = (
py0 - gap - 0.2 * font_size - row_offset
if side == "top"
else py1 + gap + 0.8 * font_size + row_offset
)
anchor = _TEXT_ANCHOR_CODES[explicit_anchor] if explicit_anchor else 1
else:
x = px1 + 8 if side == "right" else px0 - 8
x = px1 + gap if side == "right" else px0 - gap
y = float(item["pos"]) + 4
default_anchor = 0 if side == "right" else 2
anchor = _TEXT_ANCHOR_CODES[explicit_anchor] if explicit_anchor else default_anchor
Expand Down
10 changes: 7 additions & 3 deletions python/xy/_svg.py
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,10 @@ def append_tick_labels(
)
font_size = _axis_tick_font_size(axis)
side = axis.get("side", "bottom" if is_x else "left")
length = max(0.0, float(axis_style.get("tick_length", 0)))
direction = str(axis_style.get("tick_direction", "out"))
outward = 0.0 if direction == "in" else length / 2 if direction == "inout" else length
gap = outward + float(axis_style.get("tick_padding", 0))
# An explicit tick_label_anchor (axis spec or style) overrides the
# angle/side-derived default. Anchored labels rotate about the tick
# point (the rotate() pivot below), so anchor and rotation compose —
Expand All @@ -1496,9 +1500,9 @@ def append_tick_labels(
row_offset = float(item["row"]) * (font_size + 4)
x = float(item["pos"])
y = (
plot["y"] - 7 - row_offset
plot["y"] - gap - 0.2 * font_size - row_offset
if side == "top"
else plot["y"] + plot["h"] + 16 + row_offset
else plot["y"] + plot["h"] + gap + 0.8 * font_size + row_offset
)
if explicit_anchor:
anchor = _TEXT_ANCHORS[explicit_anchor]
Expand All @@ -1509,7 +1513,7 @@ def append_tick_labels(
else:
anchor = "start"
else:
x = plot["x"] + plot["w"] + 8 if side == "right" else plot["x"] - 8
x = plot["x"] + plot["w"] + gap if side == "right" else plot["x"] - gap
y = float(item["pos"]) + 4
if explicit_anchor:
anchor = _TEXT_ANCHORS[explicit_anchor]
Expand Down
Loading
Loading