如何在 Chartjs 中包装图例文本?

Dha*_*S V 8 javascript legend word-wrap chart.js

当文本太长时,我的 ChartJs 图例文本在同一行中溢出。是否有任何参数可用于启用文本换行。

legend : {
    display : true,
    position : 'bottom',
    fullWidth: false,
    labels : {
        fontColor : "#000",
        //  boxWidth  : "3"
    }
}
Run Code Online (Sandbox Code Playgroud)

在像 highcharts 这样的其他图表库中,你只需要设置宽度,如果超过宽度,文本将被换行。ChartJS 中有这样的选项吗?

Highcharts 库示例:

legend: {
    itemStyle: {
        width: 90 // or whatever, auto-wrap
    },
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用legendCallback,但在这种情况下,我将失去ChartJS中开箱即用的图例框的“onclick”有用功能。所以我不想那样做。也不想使用图例模板。

umi*_*der 6

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

您必须legendCallback一些CSS. 以下代码期望在多行标签的情况下为dataset.labelastring或 an of 字符串(对于某些类型的图表(即饼图),各个图例标签表示来自 unique 的值。在这种情况下,代码看起来如本答案所示略有不同)。arraydataset

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>';
},
Run Code Online (Sandbox Code Playgroud)

为了使其行为与标准 Chart.js 图表相同,onLegendClicked当鼠标单击图例标签时会调用该函数。此函数切换各个数据集的隐藏状态,并在正常和删除线之间更改标签文本样式。

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();
};
Run Code Online (Sandbox Code Playgroud)

请看一下下面的可执行代码,看看它是如何工作的:

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>';
},
Run Code Online (Sandbox Code Playgroud)
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();
};
Run Code Online (Sandbox Code Playgroud)
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();
Run Code Online (Sandbox Code Playgroud)