Is there an option to reflow long text labels?
<br> in the code that I'd like to have Plotly be able to do with a simple wrap: true optionJS code for this chart
var data = [{
// first screenshot labels
//x: ['giraffes', 'orangutans', "Very Long Text Label That Doesn't Fit Properly"],
// second screenshot labels
x: ['giraffes', 'orangutans', "Very Long<br>Text Label That<br>Doesn't Fit<br>Properly"],
y: [20, 14, 23],
type: 'bar'
}]
Plotly.newPlot('PlotlyDivSimple', data, {})
Unfortunately, there isn't this option built into plotly.js at the moment. The text labels are created using SVG elements, or in WebGL where text-reflow is done manually and it's not _quite_ as easy just constraining the width.
This likely won't be of high priority for us in the _immediate_ future, but we're always open to pull requests and are happy to help on them!
Ok, understood. Would help with a PR if I had a clue how to do that :)
Pardon my ignorance, but is there no way to introduce a JavaScript function that would be applied to all labels before they're fed to SVG/WebGL, where it becomes complicated?
For example, I've google-found this function (it's not great since there is an issue with long words, but just as an illustration)
function stringDivider(str, width, spaceReplacer) {
if (str.length>width) {
var p=width
for (;p>0 && str[p]!=' ';p--) {
}
if (p>0) {
var left = str.substring(0, p);
var right = str.substring(p+1);
return left + spaceReplacer + stringDivider(right, width, spaceReplacer);
}
}
return str;
}
that I can use internally to shorten the labels
var label = "Very Long Text Label That Doesn't Fit Properly"
x: ['giraffes', 'orangutans', stringDivider( label, 20, "<br>") ],
Also, as a side question — is there a way to read the bar width in plotly so I don't have to adjust the width manually and can make it reflow properly when chart size is adjusted.
Any update on this?
@mdtusz I'm happy to try to help with this if you're able to point me in the right direction in the codebase.
https://github.com/plotly/plotly.js/pull/1834 should see some foundation work on this.
A workaround is to line break svg elements after rendering. This assumes that there are <br/> tags in the text, and splits text elements into multiple text elements.
var insertLinebreaks = function (d) {
if (typeof d.text === 'string') {
var words = d.text.split(/<br[/]?>/);
var el = d3.select(this);
el.text('')
for (var i = 0; i < words.length; i++) {
var tspan = el.append('tspan').text(words[i]);
if (i > 0)
tspan.attr('x', 0).attr('dy', '15');
}
}
};
Then it's a matter of selecting svg text elements and calling the above function:
d3.select('#c_Q1 svg').selectAll('g text').each(insertLinebreaks);
You can get fancier with the selector so line break just axis labels for instance.
It could also be used in conjunction with above method by @eugenesvk to evaluate long strings and insert such line break markers.
Most helpful comment
Ok, understood. Would help with a PR if I had a clue how to do that :)
Pardon my ignorance, but is there no way to introduce a JavaScript function that would be applied to all labels before they're fed to SVG/WebGL, where it becomes complicated?
For example, I've google-found this function (it's not great since there is an issue with long words, but just as an illustration)
that I can use internally to shorten the labels
Also, as a side question — is there a way to read the bar width in plotly so I don't have to adjust the width manually and can make it reflow properly when chart size is adjusted.