diff --git a/src/marks/axis.js b/src/marks/axis.js index 8e966bd09cc..39b287520fd 100644 --- a/src/marks/axis.js +++ b/src/marks/axis.js @@ -547,6 +547,7 @@ function axisMark(mark, k, ariaLabel, data, options, initialize) { const [start, stop] = extent(data); if (interval) { data = maybeRangeInterval(interval, type).range(start, stop); + data = data.map(scale.interval.floor, scale.interval); } else { if (ticks === undefined) { const [min, max] = extent(scale.range()); diff --git a/src/time.js b/src/time.js index 8870e4d4de9..4cf8fe84c24 100644 --- a/src/time.js +++ b/src/time.js @@ -145,11 +145,12 @@ export function formatTimeTicks(scale, data = scale.domain(), ticks, anchor) { // the ticks show the field that is changing. If the ticks are not available, // fallback to an approximation based on the desired number of ticks. function getTimeTicksInterval(scale, data, ticks) { - const medianStep = median(pairs(data, (a, b) => Math.abs(b - a) || NaN)); - if (medianStep > 0) return formats[bisector(([, step]) => step).right(formats, medianStep, 1, formats.length) - 1][0]; - const [start, stop] = extent(scale.domain()); - const count = typeof ticks === "number" ? ticks : 10; - const step = Math.abs(stop - start) / count; + let step = median(pairs(data, (a, b) => Math.abs(b - a) || NaN)); + if (!(step > 0)) { + const [start, stop] = extent(scale.domain()); + const count = typeof ticks === "number" ? ticks : 10; + step = Math.abs(stop - start) / count; + } return formats[bisector(([, step]) => Math.log(step)).center(formats, Math.log(step))][0]; } diff --git a/test/output/timeAxisOrdinalIrregular.svg b/test/output/timeAxisOrdinalIrregular.svg new file mode 100644 index 00000000000..07a68339c61 --- /dev/null +++ b/test/output/timeAxisOrdinalIrregular.svg @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + 0 + 20 + 40 + 60 + 80 + 100 + 120 + 140 + 160 + + + ↑ Close + + + + + + + + + + 2013 + 2014 + 2015 + 2016 + 2017 + + + 2013-05-13 + 2013-05-20 + 2013-06-17 + 2013-07-15 + 2013-08-12 + 2013-09-09 + 2013-10-07 + 2013-11-04 + 2013-12-02 + 2013-12-30 + 2014-01-27 + 2014-02-24 + 2014-03-24 + 2014-04-21 + 2014-05-19 + 2014-06-16 + 2014-07-14 + 2014-08-11 + 2014-09-08 + 2014-10-06 + 2014-11-03 + 2014-12-01 + 2014-12-29 + 2015-01-26 + 2015-02-23 + 2015-03-23 + 2015-04-20 + 2015-05-18 + 2015-06-15 + 2015-07-13 + 2015-08-10 + 2015-09-08 + 2015-10-05 + 2015-11-02 + 2015-11-30 + 2015-12-28 + 2016-01-25 + 2016-02-22 + 2016-03-21 + 2016-04-18 + 2016-05-16 + 2016-06-13 + 2016-07-11 + 2016-08-08 + 2016-09-06 + 2016-10-03 + 2016-10-31 + 2016-11-28 + 2016-12-27 + 2017-01-23 + 2017-02-21 + 2017-03-20 + 2017-04-17 + 2017-05-15 + 2017-06-12 + 2017-07-10 + 2017-08-07 + 2017-09-05 + 2017-10-02 + 2017-10-30 + 2017-11-27 + 2017-12-26 + 2018-01-22 + 2018-02-20 + 2018-03-19 + 2018-04-16 + + \ No newline at end of file diff --git a/test/plots/time-axis.ts b/test/plots/time-axis.ts index f06a58bcd1a..6ef22686612 100644 --- a/test/plots/time-axis.ts +++ b/test/plots/time-axis.ts @@ -91,6 +91,14 @@ export async function timeAxisOrdinal() { }); } +export async function timeAxisOrdinalIrregular() { + const aapl = await d3.csv("data/aapl.csv", d3.autoType); + return Plot.plot({ + x: {interval: "4 weeks", ticks: "year"}, + marks: [Plot.barY(aapl, Plot.groupX({y: "median", title: "min"}, {title: "Date", x: "Date", y: "Close"}))] + }); +} + export async function timeAxisOrdinalTicks() { const aapl = await d3.csv("data/aapl.csv", d3.autoType); return Plot.plot({