Chart.js传奇占据了太多空间

时间:2017-08-11 08:23:17

标签: javascript chart.js legend

我在使用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。

5 个答案:

答案 0 :(得分:2)

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

可能是他们可以在下一版本中介绍它。 目前解决方案是删除原生图例并绘制自定义图例

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

答案 1 :(得分:2)

首先,使用原生属性设置canvas 宽度和高度(使用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 :(得分:1)

在使用条形图时,在图例中位于底部的多个项目遇到了类似的问题,我设置了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>

答案 3 :(得分:0)

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

  

Chart.defaults.global.maintainAspectRatio = false;

答案 4 :(得分:0)

没有可以定义的选项来轻松实现您想要的目标。自2016年以来,存在针对此类选项的开放feature request

您必须使用my_array[i,:,1]和一些legendCallback来生成自定义HTML legend。以下代码期望将多行标签定义为CSS中的数组。它旨在用于具有唯一data.labels且每个图例标签表示其数据值的图表(如果您需要具有多个数据集的图表的解决方案,请查看this answer )。

dataset

为使其行为与标准Chart.js图表​​相同,在图例标签上单击鼠标时将调用功能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>'; } 。此功能可切换各个甜甜圈切片的隐藏状态,并在普通和删除线之间更改标签文本样式。

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;
}