如何在Chartjs中包装图例文本? [英] How to wrap legend text in Chartjs?

查看:82
本文介绍了如何在Chartjs中包装图例文本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我的ChartJs图例文本太长时,它在同一行中溢出。我可以使用任何参数来启用自动换行功能。

 图例:{
display:true,
position:'bottom',
fullWidth :false,
标签:{
fontColor:#000,
// boxWidth: 3
}
}

在其他图表库(如highcharts)中,您只需要设置宽度即可,如果文本超出宽度,则将自动换行。 ChartJS中有这样的选项吗?



Highcharts库示例:

 传奇:{
itemStyle:{
宽度:90 // //或自动换行
},
}

我尝试使用legendCallback,但是在那种情况下,我将松开ChartJS中现成的图例框的 onclick有用功能。所以我不想那样做。也不要使用图例模板。

解决方案

不幸的是,没有自动包裹长图例标签的选项。


您必须使用<$生成自定义 HTML图例 c $ c> legendCallback 以及一些 CSS 。以下代码期望 dataset.label string array 对于某些类型的图表(例如饼图),字符串图例中的code>表示,各个图例标签代表唯一的数据集。在这种情况下,代码看起来略有不同,如此答案 )所示。

  legendCallback:图表=> {
let html =’< ul>’;;
chart.data.datasets.forEach((ds,i)=> {
html + ='< li>'+
'< span style =" width:36px ;高度:14px; background-color:'+ ds.backgroundColor +'; border:'+ ds.borderWidth +'px solid'+ ds.borderColor +'" onclick =" onLegendClicked(event,\''+ i +'\')'>& nbsp; / span>'+
'< span id =" legend-label-'+ i +'" onclick =" onLegendClicked (event,\''+ i +'\')'>'+
(Array.isArray(ds.label)?ds.label.join('< br /&';)) :ds.label)+'< / span>'+
'< / li>';
});
return html +’< / ul>’;
},



要使其行为与标准Chart.js图表​​相同,在图例标签上单击鼠标时,将调用 onLegendClicked 函数。此功能可切换各个数据集的隐藏状态,并在普通和删除线之间更改标签文本样式。



 函数onLegendClicked(e,i){
const hidden =!chart.data.datasets [i] .hidden;
chart.data.datasets [i] .hidden =隐藏;
const legendLabelSpan = document.getElementById( legend-label- + i);
legendLabelSpan.style.textDecoration =隐藏? ‘直通’:’’;
chart.update();
};

请查看下面的可执行代码并查看其工作原理:


< preClass = snippet-code-js lang-js prettyprint-override> 函数onLegendClicked(e,i){
const hidden =!chart.data.datasets [i] .hidden;
chart.data.datasets [i] .hidden =隐藏;
const legendLabelSpan = document.getElementById( legend-label- + i);
legendLabelSpan.style.textDecoration =隐藏? ‘直通’:’’;
chart.update();
};

const chart = new Chart(document.getElementById( chart),{
type: bar,
数据:{
标签:['A ','B','C'],
数据集:[{
标签:['Legend标签','两行'],
数据:[5、8、4 ],
填充:false,
backgroundColor: rgba(255、99、132、0.2),
borderColor: rgb(255、99、132),
borderWidth:1
},
{
标签:['Legend label','spread over','三行'],
数据:[3,5,4] ,
填充:false,
backgroundColor: rgba(255、159、64、0.2),
borderColor: rgb(255、159、64),
borderWidth :1
},
{
标签:简短图例标签,
数据:[6、5、7],
填充:false,
backgroundColor: rgba(255,205,86,0.2),
borderColor: rgb(255,205,86),
borderWidth:1
}
]
},
选项:{
图例:{
display:false
},
legendCallback:chart => {
let html =’< ul>’;;
chart.data.datasets.forEach((ds,i)=> {
html + ='< li>'+
'< span style = width:36px;高度:14px;背景颜色:'+ ds.backgroundColor +';边框:'+ ds.borderWidth +'px solid'+ ds.borderColor +' onclick = onLegendClicked(event,\''+ i +' \')>& nbsp;< / span>'+
'< span id = legend-label-'+ i +' onclick = onLegendClicked(event,\'' + i +'\')>'+
(Array.isArray(ds.label)?ds.label.join('< br />'):ds.label)+'< ; / span>'+
'< / li>';
});
return html +’< / ul>’;
},
标度:{
y轴:[{
刻度:{
beginAtZero:真实
}
}]
}
}
});
document.getElementById( legend)。innerHTML = chart.generateLegend();

 #legend> ul {
display:flex;
justify-content:center;
}

#legend li {
cursor:指针;
保证金:0px 10px;
显示:flex;
}

#legend li span {
padding-left:8px;
字体家族:Arial,Helvetica,sans-serif;
font-size:12px;
}

 < script src = https ://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js< / script> 
< div>
< canvas id = chart height = 60>< / canvas>
< div id = legend>< / div>
< / div>


My ChartJs legend text is overflowing in the same line when the text is too long. Is there any parameter that I can use to enable text-wrap.

legend : {
    display : true,
    position : 'bottom',
    fullWidth: false,
    labels : {
        fontColor : "#000",
        //  boxWidth  : "3"
    }
}

In other chart libraries like highcharts, you just have to set width and the text will be wrapped if it exceeds the width. Is there such an option in ChartJS?

Highcharts Library Example:

legend: {
    itemStyle: {
        width: 90 // or whatever, auto-wrap
    },
}

I tried using legendCallback, but in that case I will loose the 'onclick' useful functionalities of the legend boxes that come out of the box in ChartJS. So I don't want to do that. Don't want use legend template either.

解决方案

Unfortunately there is no option for automatically wrap long legend labels.

You'll have to generate custom HTML legend using legendCallback together with some CSS. The following code expects that dataset.label to be either a string or an array of strings in case of a multi-line label (For some types of charts (i.e. pie chart), individual legend labels represent a value from a unique dataset. In such cases, the code looks slightly different as shown in this answer).

legendCallback: chart => {
  let html = '<ul>';
  chart.data.datasets.forEach((ds, i) => {
    html += '<li>' +
      '<span style="width: 36px; height: 14px; background-color:' + ds.backgroundColor + '; border:' + ds.borderWidth + 'px solid ' + ds.borderColor + '" onclick="onLegendClicked(event, \'' + i + '\')">&nbsp;</span>' +
      '<span id="legend-label-' + i + '" onclick="onLegendClicked(event, \'' + i + '\')">' +
      (Array.isArray(ds.label) ? ds.label.join('<br/>') : ds.label) + '</span>' +
      '</li>';
  });
  return html + '</ul>';
},

To make this behave the same as standard Chart.js charts, the function onLegendClicked is invoked when a mouse click occurs on a legend label. This function toggles the hidden state of individual datasets and changes label text style between normal and strike-through.

function onLegendClicked(e, i) {
  const hidden = !chart.data.datasets[i].hidden;
  chart.data.datasets[i].hidden = hidden;
  const legendLabelSpan = document.getElementById("legend-label-" + i);
  legendLabelSpan.style.textDecoration = hidden ? 'line-through' : '';
  chart.update();
};

Please take a look at the executable code below and see how it works in action:

function onLegendClicked(e, i) {
  const hidden = !chart.data.datasets[i].hidden;
  chart.data.datasets[i].hidden = hidden;
  const legendLabelSpan = document.getElementById("legend-label-" + i);
  legendLabelSpan.style.textDecoration = hidden ? 'line-through' : '';
  chart.update();
};

const chart = new Chart(document.getElementById("chart"), {
  type: "bar",
  data: {
    labels: ['A', 'B', 'C'],
    datasets: [{
        label: ['Legend label', 'on two lines'],
        data: [5, 8, 4],
        fill: false,
        backgroundColor: "rgba(255, 99, 132, 0.2)",
        borderColor: "rgb(255, 99, 132)",
        borderWidth: 1
      },
      {
        label: ['Legend label', 'spread over', 'three lines'],
        data: [3, 5, 4],
        fill: false,
        backgroundColor: "rgba(255, 159, 64, 0.2)",
        borderColor: "rgb(255, 159, 64)",
        borderWidth: 1
      },
      {
        label: "Short legend label",
        data: [6, 5, 7],
        fill: false,
        backgroundColor: "rgba(255, 205, 86, 0.2)",
        borderColor: "rgb(255, 205, 86)",
        borderWidth: 1
      }
    ]
  },
  options: {
    legend: {
      display: false
    },
    legendCallback: chart => {
      let html = '<ul>';
      chart.data.datasets.forEach((ds, i) => {
        html += '<li>' +
          '<span style="width: 36px; height: 14px; background-color:' + ds.backgroundColor + '; border:' + ds.borderWidth + 'px solid ' + ds.borderColor + '" onclick="onLegendClicked(event, \'' + i + '\')">&nbsp;</span>' +
          '<span id="legend-label-' + i + '" onclick="onLegendClicked(event, \'' + i + '\')">' +
          (Array.isArray(ds.label) ? ds.label.join('<br/>') : ds.label) + '</span>' +
          '</li>';
      });
      return html + '</ul>';
    },
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true
        }
      }]
    }
  }
});
document.getElementById("legend").innerHTML = chart.generateLegend();

#legend>ul {
  display: flex;
  justify-content: center;
}

#legend li {
  cursor: pointer;
  margin: 0px 10px;
  display: flex;
}

#legend li span {
  padding-left: 8px;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 12px;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<div>  
  <canvas id="chart" height="60"></canvas>
  <div id="legend"></div>
</div>

这篇关于如何在Chartjs中包装图例文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆