plot icon indicating copy to clipboard operation
plot copied to clipboard

Multi-line tick labels

Open yurivish opened this issue 3 years ago • 11 comments

It would be useful to be able to make axes like this:



image

One way would be to support multi-line text labels.

Another option would be to allow SVG nodes to be used as ticks rather than coercing the output of tickFormat to a string, which is the current behavior.

Here is a notebook which "almost works": https://observablehq.com/d/7de079c962f419f8

yurivish avatar Jul 23 '21 18:07 yurivish

Datawrapper does this well (see multi-line axis ticks):

https://blog.datawrapper.de/new-axis-ticks/

mbostock avatar Aug 12 '21 00:08 mbostock

The code is not a problem once we agree on a spec. It's not clear to me if datawrapper's format is the way to go, but I can see how we would extend tickFormat to support \n for multiline, and \n? for a non-repeating second line, enabling this:

x: {tickFormat: "%b\n?%Y"}

and getting this: Capture d’écran 2021-12-11 à 00 57 29

thumb up, down, or provide alternative ideas :)

I'll send the PR tomorrow because it's already too late in this time zone.

This should arguably be done in d3-axis instead of Plot. Acting on a \n in tick formats might be considered as a breaking change (at least visually speaking)—but it seems like a highly useful change?

Fil avatar Dec 11 '21 00:12 Fil

related: #327 #506

Fil avatar Dec 11 '21 08:12 Fil

I think supporting \n is probably the way to go, yeah. I don’t understand how \n? works in your example above. How does it know not to render the year outside of January? I think more likely we’d implement a “multi-scale” format that’s similar to what d3-scale does, but using new lines.

mbostock avatar Dec 11 '21 13:12 mbostock

The ? will avoid repetitions, like DataWrapper does:

In the example above it's not clear because the first tick is January, but if it was, say, "Apr Jul Oct Jan Apr" we'd show 2020 under the first Apr, and 2021 under Jan.

A multiscale format would work too but differently; maybe by introducing a notation %0Y which would show the year only for January. Then, in datawrapper's example, we'd have no notion of the year 2020, only 2021 would be labeled.

I'll send my PR as a draft so we can tinker a bit.

Fil avatar Dec 11 '21 13:12 Fil

Ah, I see! Neat. I like that. The repetition rule applies to each line distinctly, then (not to % fields)?

mbostock avatar Dec 11 '21 13:12 mbostock

Yes the rule applies separately to each line. I made it avoid repetitions (i.e. remove consecutive labels, rather than enforce unicity), so that we can, for example, use it to display half-years or quarters:

Jan Mar May Jul Sep Nov Jan Mar May Jul Sep Nov Jan
2020                    2021                    2022
H1.         H2.         H1.         H2.         H1.

Fil avatar Dec 11 '21 14:12 Fil

Related #393, when the ticks represent a (time) interval, it’d be nice if the tick label were aligned to the start of the interval, rather than centered around the interval.

image

mbostock avatar Jan 01 '22 22:01 mbostock

Most of the examples here are for axisBottom. Does not have much side-effect in current plot version. When axisTop is applied it renders over the tick marks. Screen Shot 2022-02-28 at 13 53 22

hashg avatar Feb 28 '22 20:02 hashg

Related #393, when the ticks represent a (time) interval, it’d be nice if the tick label were aligned to the start of the interval, rather than centered around the interval.

image

In this example the year is show at for Q1, Let's assume the axis starts rendering from mid of Q1 or Q2. Do we add the year at Q2 or omit it?

The timeline below starts from middle of the month. Still would prefer month and year to be part of the axis. stacked_axis

hashg avatar Feb 28 '22 20:02 hashg

Thank you for the feedback! The "non-repeat" rule, which I'm exploring here, means that 2020 and Dec would show in your example, even thought the 1st day of the year (or month) isn't present.

Fil avatar Mar 01 '22 14:03 Fil

As this was closed with #1197: can we now use x: {tickFormat: "%b\n?%Y"} as proposed above?

I am doing this right now, but the formatting stays the same as without the \n...

glennDittmann avatar Aug 29 '23 19:08 glennDittmann

@glennDittmann No, the conditional formatting is implemented internally to the default axes. You can see the formatConditional implementation in the source for how it works. We could file a separate feature request if you want shorthand for a conditional format.

mbostock avatar Aug 29 '23 20:08 mbostock

Thanks for the quick reply! For now I am fine with as it is now, thanks anyways. :)

glennDittmann avatar Aug 30 '23 13:08 glennDittmann