最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to give fixed width to legend in plotly.js - Stack Overflow

programmeradmin6浏览0评论

I am using plotly.js to create charts. Some charts have long text inside legend, so these text make legend unnecessary bigger. I want to give legend fixed width and if a length of text is long, I want it to be wrapped.

I have been trying to do this by manipulating svg element on DOM, but since legend is svg:g tag, I can not really do much. I also try give textLength to <text>, but it does wrap text but it does not make a new line.

Is there a way to give legend fixed width?

I am using plotly.js to create charts. Some charts have long text inside legend, so these text make legend unnecessary bigger. I want to give legend fixed width and if a length of text is long, I want it to be wrapped.

I have been trying to do this by manipulating svg element on DOM, but since legend is svg:g tag, I can not really do much. I also try give textLength to <text>, but it does wrap text but it does not make a new line.

Is there a way to give legend fixed width?

Share Improve this question asked Feb 2, 2017 at 11:56 kaykay 1,4294 gold badges16 silver badges27 bronze badges 1
  • did you figure out any better solutions now. – Punita Ojha Commented Apr 22, 2021 at 20:19
Add a ment  | 

3 Answers 3

Reset to default 2

Perhaps just adding </br> to the legend text would be an easy solution to get a fixed width? You could use any text wrapping trick in Javascript to do so, e.g.

for (i = 0; i < data.length; i += 1) {
  data[i].name = data[i].name.replace(/([\w\s,]{13,}?)\s?\b/g, "$1</br>");
}

var numbers = [];
var total = 10000;
var i = 0;
var data = [];

for (i = 0; i < total; i++) {
  numbers[i] =  ((Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random()) - 3) / 3;
}

data.push({
  x: numbers,
  name: "that's a histogram with lots of points, it therefore needs lots of text as well",
  type: 'histogram',
  marker: {color: 'blue'}
});

numbers = [];
for (var i = 0; i < total; i++) {
  numbers[i] =  0.25 + ((Math.random() + Math.random() + Math.random() + Math.random() + Math.random() + Math.random()) - 3) / 3;
}
data.push({
  x: numbers,
  name: "that's yet another histogram with lots of points, it therefore needs lots of text as well, like for example that it was shifted by 0.25",
  type: 'histogram',
  marker: {color: 'red'}
});

for (i = 0; i < data.length; i += 1) {
  data[i].name = data[i].name.replace(/([\w\s,]{13,}?)\s?\b/g, "$1<br>");
}

Plotly.newPlot('myDiv', data, {showlegend: true});
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv"></div>

Maximilian's answer almost works with the current version of Plotly.js. There doesn't seem to be a property for setting the width of the legend, but you can rig it by inserting breaks (</br>) into the legend text manually. For some reason Plotly seems to mishandle the first break in the text, however; to get around this, you can add a "ghost" break at the beginning of the text. For instance:

// Rudimentary function to break a string on spaces
// attempting to get no more than `maxChars` characters in a line
const breakString = (str, maxChars) => {
  if (str.length > maxChars && str.includes(' ')) {
    let index = str.lastIndexOf(' ', maxChars);
    if (index === -1) index = str.indexOf(' ', maxChars + 1);
    return str.substr(0, index) + '</br>' + breakString(str.substr(index + 1), maxChars);
  } else {
    return str;
  }
}

const original_text = "Respondents who think Tenet is Christopher Nolan's most interesting movie";
const final_text = '</br>' + breakString(original_text, 20);

The color symbols next to each legend entry by default are aligned to the center of the corresponding text; with multiline legend text, you'll probably want to change the symbols to be aligned to the top of the text. To do that, add this to your layout:

legend: {
  valign: 'top',
}

This works for me using Plotly with javascript.

title: 'first part' + '<br>' + 'Second part'

eg

yaxis2: {
  domain: [0.7, 1],  
  title: 'Sea Surface' + '<br>' + 'Temperature',
  showgrid: true,
  showline: true,
  titlefont: {color: 'blue'},
  tickfont: {color: 'blue'},
  side: 'right',
  anchor: 'free',
  position: 0.91
},
发布评论

评论列表(0)

  1. 暂无评论