【问题标题】:Chart.js legend took up too much spacesChart.js 图例占用太多空间
【发布时间】:2017-08-11 08:23:16
【问题描述】:

我在使用 chart.js 图例时遇到了一些问题。长文本的图例占用了太多空间,导致我的饼图尺寸减小:

另一个例子是这样的:

如果我得到更多的图例,圆环图最终会变得越来越小。

我尝试设置 maxWidth 但无济于事。

var options = {
            layout: {
                padding: {
                  top: 5
                }
            },
            responsive: true,
            maintainAspectRatio: false,
            legend: {
                display: true,
                position: 'right',
                maxWidth: 100,
                onClick: null
            },
            animation: {
                animateScale: true,
                animateRotate: true
            },

        };

有什么想法吗?

我尝试按照这个 [解决方案][3] 创建一个 html 图例:

<div class="box-body" style="height:350px;">
<div class="float-left">
<div class="float-left" style="width:70%">

<canvas id="brandChart" style="position: relative; height: 350px;"></canvas>
</div>
<div class="float-left" style="width:30%">

<div id="js-legend" class="chart-legend">
</div>

</div>
</div>

它确实限制了图例的宽度,但这导致了另一个问题,即在我折叠并展开 div 之后,画布丢失了,我只剩下图例 div。

【问题讨论】:

  • 您是否尝试将图例位置更改为底部或顶部?
  • 嗯,我希望它在右手边,因为它更整洁

标签: javascript chart.js legend


【解决方案1】:

首先,使用它原生属性设置画布宽度和高度(不要使用style属性),像这样:

<canvas id="brandChart" width="700" height="350"></canvas>

注意:宽度应该是高度的两倍

然后,在图表选项中将 responsive 属性设置为 false,如下所示:

options: {
   responsive: false,
   ...
}

ᴅᴇᴍᴏ

var chart = new Chart(brandChart, {
   type: 'doughnut',
   data: {
      labels: ['Etronin Home Appliances Service & trading Pte Ltd', 'Giant'],
      datasets: [{
         data: [30, 70],
         backgroundColor: ['#2196f3', '#4caf50']
      }]
   },
   options: {
      responsive: false,
      legend: {
         display: true,
         position: 'right',
         onClick: null
      },
   }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<canvas id="brandChart" width="700" height="350"></canvas>

【讨论】:

    【解决方案2】:

    长图例 nowrap 是一个已知问题检查 https://github.com/chartjs/Chart.js/issues/3641

    也许他们可以在下一个版本中涵盖它。 目前的解决方案是删除本地图例并绘制您的自定义图例

    我创建了这个 plunk 作为带有自定义图例的甜甜圈图表的示例 https://embed.plnkr.co/5nuGS2KEV6hvESwGrOse/

    【讨论】:

    • 我创建了 HTML 图例,但这导致了另一个问题,即在我折叠并展开最外面的 div 之后,画布丢失了,但图例 div 没有。另外,在我用 div 包裹画布后,绘制图表的动画也丢失了
    • 动画因为包装器有浮动所以这个标记应该让动画工作
      这不是很清楚我澄清它“在我折叠并展开最外面的 div 后,画布丢失但不是图例 div"
    【解决方案3】:

    我在使用底部有几个图例项目的条形图时遇到了类似的问题,我设置了responsive:true

     options: {
        responsive: true,
        legend: {
          display: true,
          position: "bottom",
          labels: {
            fontColor: "#3f5761"
          }
        },
        scales: {
          yAxes: [
            {
              ticks: {
                beginAtZero: true
              },
              scaleLabel: {
                display: true,
                labelString: "No. of tasks",
                fontSize: 10
              }
            }
          ]
        }
      }
    

    并将高度设置为画布,因为我希望宽度能够响应。现在看起来好多了。

    <canvas #taskCountsChart height="350"></canvas>
    

    【讨论】:

      【解决方案4】:

      没有可以定义的选项来轻松实现您正在寻找的东西。自 2016 年以来,此类选项的开放feature request 存在。

      您必须使用legendCallback 和一些CSS 生成自定义HTML legend。以下代码需要将多行标签定义为data.labels 内的数组。它旨在用于具有唯一 dataset 并且每个图例标签代表其数据值的图表(如果您需要具有多个数据集的图表的解决方案,请查看 @987654323 @)。

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

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

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

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

      function onLegendClicked(e, i) {
        let hidden = !chart.getDatasetMeta(0).data[i].hidden;
        chart.getDatasetMeta(0).data[i].hidden = hidden;
        const legendLabelSpan = document.getElementById("legend-label-" + i);
        legendLabelSpan.style.textDecoration = hidden ? 'line-through' : '';
        chart.update();
      };
      
      const chart = new Chart('chart', {
        type: 'doughnut',
        data: {
          labels: [
            ['Label on', 'two lines'],     
            ['Legend label', 'spread over', 'three lines'],
             'A short label'
          ],
          datasets: [{
            data: [4, 5, 3],
            backgroundColor: ['rgba(255, 99, 132, 0.2)', 'rgba(255, 159, 64, 0.2)', 'rgba(54, 162, 235, 0.2)'],
            borderColor: ['rgb(255, 99, 132)', 'rgb(255, 159, 64)', 'rgb(54, 162, 235)'],
            borderWidth: 1
          }]
        },
        options: {
          legend: {
            display: false
          },
          tooltips: {
            callbacks: {
              title: (tooltipItems, data) => data.labels[tooltipItems[0].index],
              label: (tooltipItems, data) => 'Count: ' + data.datasets[0].data[tooltipItems.index]
            }
          },
          legendCallback: chart => {      
            let html = '<ul>';
            chart.data.labels.forEach((l, i) => {
              const ds = chart.data.datasets[0];
              const bgColor = ds.backgroundColor[i];
              const border = ds.borderWidth + 'px solid ' + ds.borderColor[i];
              html += '<li>' +
              '<span style="width: 36px; height: 14px; background-color:' + bgColor + '; border:' + border + '" onclick="onLegendClicked(event, \'' + i + '\')">&nbsp;</span>' +
              '<span id="legend-label-' + i + '" onclick="onLegendClicked(event, \'' + i + '\')">' +
              (Array.isArray(l) ? l.join('<br/>') : l) +'</span>' +
              '</li>';
            });
            return html + '</ul>';
          }
        }
      });
      document.getElementById("legend").innerHTML = chart.generateLegend();
      #legend>ul {
        display: flex;
        justify-content: center;
      }
      
      #legend li {
        cursor: pointer;
        margin: 10px 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>
        <div id="legend"></div>
        <canvas id="chart" height="90"></canvas>
      </div>

      【讨论】:

        【解决方案5】:

        这篇文章已有 9 个月的历史,但对于那些正在寻找解决方案的人,请使用以下内容,这将使馅饼/甜甜圈在移动/响应视图中更大

        Chart.defaults.global.maintainAspectRatio = false;

        【讨论】:

          猜你喜欢
          • 2012-05-15
          • 1970-01-01
          • 2011-09-08
          • 1970-01-01
          • 2022-07-13
          • 1970-01-01
          • 2020-05-12
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多