diff --git a/src/axis.js b/src/axis.js index eb9c27e389..2a5318ee94 100644 --- a/src/axis.js +++ b/src/axis.js @@ -1,4 +1,4 @@ -import {axisTop, axisBottom, axisRight, axisLeft, create, format, utcFormat} from "d3"; +import {axisTop, axisBottom, axisRight, axisLeft, create, format, select, utcFormat} from "d3"; import {formatIsoDate} from "./format.js"; import {boolean, take, number, string, keyword, maybeKeyword, constant, isTemporal} from "./mark.js"; import {impliedString} from "./style.js"; @@ -66,6 +66,7 @@ export class AxisX { return create("svg:g") .attr("transform", `translate(0,${ty})`) .call(createAxis(axis === "top" ? axisTop : axisBottom, x, this)) + .call(g => g.selectAll("text").each(splitText())) .call(maybeTickRotate, tickRotate) .attr("font-size", null) .attr("font-family", null) @@ -90,6 +91,20 @@ export class AxisX { } } +function splitText() { + const repeats = []; + return function() { + const cur = this.textContent; + const lines = cur.split("\n"); + if (lines.length > 1) { + select(this).text(lines.shift()) + .selectAll().data(lines).join("tspan") + .text((d, i) => d[0] === "?" ? d === repeats[i] ? " " : (repeats[i] = d).slice(1) : d) + .attr("x", 0) + .attr("dy", "1.2em"); + } + }; +} export class AxisY { constructor({ name = "y", diff --git a/test/output/availability.svg b/test/output/availability.svg index 849c0d04a1..a27d10a78c 100644 --- a/test/output/availability.svg +++ b/test/output/availability.svg @@ -13,52 +13,43 @@ } - + 0 - - 1 - - + 2 - - 3 - - + 4 - - - 5 ↑ value - + - 2020 + Jan2020 - April + Apr - July + Jul - October + Oct - 2021 + Jan2021 - April + Apr - + - + - + \ No newline at end of file diff --git a/test/plots/availability.js b/test/plots/availability.js index 4b88e01b6e..e5a8a8c099 100644 --- a/test/plots/availability.js +++ b/test/plots/availability.js @@ -6,6 +6,8 @@ export default async function() { const sum = d => d.length ? d3.sum(d) : NaN; // force gaps return Plot.plot({ height: 180, + marginBottom: 45, + x: {tickFormat: "%b\n?%Y"}, marks: [ Plot.areaY( data,