Because I can’t leave well enough alone, I’ve been trying a couple other approaches. So far, everything runs into the relative scaling issue, even the (to my mind) most promising approach of using a text mode trace.
Some code with invented data:
var label = {
x: ["",""], y: [50,150],
mode: 'text', showlegend: false, hoverinfo: "skip",
text: ["World Record", "Casual Average"],
textposition: "bottom right"
};
var trace2 = {
x: ['A', 'B', 'C', 'D', 'E', 'F'],
y: [50, 60, 70, 78, 78, 78],
type: 'bar', name: 'PB'
};
var trace3 = {
x: ['A', 'B', 'C', 'D', 'E', 'F'],
y: [70, 62, 78, 84, 84, 84],
type: 'bar', name: 'Average'
};
var data = [label, trace2, trace3];
var layout = {
margin: { l: 0, r: 0, t: 0, b: 0 },
autosize: true,
height: 300,
xaxis: {
title: { text: "Runner", standoff: 10, font: { size: 14 }},
automargin: true,
},
yaxis: { title: "Minutes", automargin: true },
shapes: [
{ name: "WR", xref: 'paper', yref: 'y', type: "rect",
x0: 0, x1: 1, y0: 50, y1: 0,
layer: "below", fillcolor: "#80ff80", line: {width: 0}},
{ name: "Casual", xref: 'paper', yref: 'y', type: "rect",
x0: 0, x1: 1, y0: 50, y1: 150,
layer: "below", fillcolor: "#ffee80", line: {width: 0}}
]
};
Plotly.newPlot('myDiv', data, layout, {responsive: true});
If you throw this up in a browser and resize it a bit or add more elements to trace2/3, I think it becomes clear that this isn’t a viable solution across the whole range of possible inputs.
Also note the textposition
. The default is to draw the text centred both horizontally and vertically at the coordinates, but the position of the x axis is not adjusted to account for the bounding boxes of the text elements, so preventing clipping with the left edge or the chart elements to the right is difficult, and controlling their justification at the same time is effectively impossible.
I started on a subplot approach, but ran into the same issues with everything being relative, only with the added problem of convincing it to even render everything.
As an addendum, I noticed a render bug in my tinkering where the legend sometimes gets pushed off the right edge on redraw when changing thetextposition
of the label trace. I haven’t pinned down a good repro, though, and I’m moving on for now. If anyone has other suggestions for guaranteeing the needed horizontal buffer for labels/annotations programmatically, or suggestions for alternative ways to express what’s shown, please feel free to chime in!
Cheers,
Wyatt