Легенда Chart.js заняла слишком много места
У меня были некоторые проблемы с легендой 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.
3 ответа
Во-первых, установите ширину и высоту холста, используя его собственные атрибуты (не используйте 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>
Длинная легенда в настоящее время является проверкой известной проблемы https://github.com/chartjs/Chart.js/issues/3641
Может быть, они могут осветить это в следующих выпусках. На данный момент решение состоит в том, чтобы удалить родную легенду и нарисовать вашу собственную.
Я создал этот план в качестве примера для диаграммы контуров с пользовательской легендой https://embed.plnkr.co/5nuGS2KEV6hvESwGrOse/
Я столкнулся с аналогичной проблемой при использовании гистограммы с несколькими элементами в легенде, расположенными внизу, я установил 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>
Нет варианта, который можно было бы определить, чтобы легко достичь того, что вы ищете. Открытый запрос функции существует для такой опции с 2016 года.
Вам нужно будет создать собственную легенду HTML, используяlegendCallback
вместе с некоторыми CSS
. В следующем коде предполагается, что многострочные метки будут определены как массивы внутриdata.labels
. Он предназначен для использования в диаграммах с уникальнымdataset
и где каждая метка легенды представляет собой значение своих данных (если вам нужно решение для диаграммы с несколькими наборами данных, взгляните на этот ответ).
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 + '\')"> </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 + '\')"> </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>
Этому сообщению 9 месяцев, но для тех, кто ищет решение, используйте следующее, и это сделает пирог / пончик больше в мобильном / адаптивном представлении
Chart.defaults.global.maintainAspectRatio = false;