Как я могу контролировать размещение легенды моей круговой диаграммы Chart.JS, а также ее внешний вид?
Я могу создать круговую диаграмму, используя Chart.JS с этим кодом:
HTML
<div>
<canvas id="top10ItemsChart" style="padding-left:20px" width="320" height="320"></canvas>
<div id="top10Legend" class="chart-legend"></div>
</div>
JQuery
var data = [{
value: 2755,
color: "#FFE135",
label: "Bananas"
}, {
value: 2256,
color: "#3B5323",
label: "Lettuce, Romaine"
}, {
value: 1637,
color: "#fc6c85",
label: "Melons, Watermelon"
}, {
value: 1608,
color: "#ffec89",
label: "Pineapple"
}, {
value: 1603,
color: "#021c3d",
label: "Berries"
}, {
value: 1433,
color: "#3B5323",
label: "Lettuce, Spring Mix"
}, {
value: 1207,
color: "#046b00",
label: "Broccoli"
}, {
value: 1076,
color: "#cef45a",
label: "Melons, Honeydew"
}, {
value: 1056,
color: "#421C52",
label: "Grapes"
}, {
value: 1048,
color: "#FEA620",
label: "Melons, Cantaloupe"
}];
var optionsPie = {
legend: {
display: true,
position: 'right',
labels: {
fontColor: 'rgb(255, 99, 132)'
}
}
}
var ctx = $("#top10ItemsChart").get(0).getContext("2d");
var top10PieChart = new Chart(ctx).Pie(data, optionsPie);
document.getElementById('top10Legend').innerHTML = top10PieChart.generateLegend();
Проблема в том, что он помещает легенду в конец пирога, и даже проливает и истекает кровью за пределы границ div, которыми я хочу, чтобы пирог ограничил себя:
Он также представляет легенду в виде простого неупорядоченного списка. Я хочу контролировать цвет различных элементов в легенде ("Банан" должен быть того же цвета (#FFE135), что и кусок бананового пирога (так сказать) и т. Д.)
Как сделать так, чтобы отдельные элементы соответствовали цвету соответствующей точки данных?
ОБНОВИТЬ
Раздел "Настройка метки легенды" в официальных документах здесь указывает, что вы можете установить fontColor легенд, но это для всего шебанга; я хочу знать, как можно контролировать цвет каждого элемента?
ОБНОВЛЕНИЕ 2
В попытке хотя бы получить легенду, отображаемую в нужном месте, я добавил это в jQuery:
var optionsPie = {
legend: {
display: true,
position: 'right',
labels: {
fontColor: 'rgb(255, 99, 132)'
}
}
}
. . .
var myPieChart = new Chart(ctx).Pie(data, optionsPie);
document.getElementById("legendDiv").innerHTML = myPieChart.generateLegend();
... но это не имеет значения - легенда все еще висит на нижней части круговой диаграммы, а ее шрифт по-прежнему черный по умолчанию.
ОБНОВЛЕНИЕ 3
Я использовал предложенный код, но легенда по-прежнему подается гравитацией, а не свисает вправо:
Таким образом, легенда попадает на график под ней, а не ограничивается ее собственным соседством.
Кроме того, я не хочу, чтобы маркеры наводнили легенду - все, что мне нужно, это цветные квадраты (и словосочетание - но также и значения). Как я могу перенести легенду с юга пирога на восток пирога?
ОБНОВЛЕНИЕ 4
Я реорганизовал код, основанный на этом, и он выглядит лучше (я также добавил больше данных к значению "label" массива данных):
Тем не менее, как вы можете видеть, легенда нарушает сектор под ним. Хотя вокруг пирога есть "тонна" пустого / потраченного впустую пространства - я хочу переместить пирог влево, а легенду - справа от пирога. Это также позволило бы увеличить вертикальное пространство для роста пирога.
Как я могу это сделать? Вот код, который я использую сейчас:
HTML
<div>
<canvas id="top10ItemsChart" class="pie" style="padding-left:20px"></canvas>
<div id="top10Legend"></div>
</div>
CSS
.pie-legend {
list-style: none;
margin: 0;
padding: 0;
}
.pie-legend span {
display: inline-block;
width: 14px;
height: 14px;
border-radius: 100%;
margin-right: 16px;
margin-bottom: -2px;
}
.pie-legend li {
margin-bottom: 10px;
display: inline-block;
margin-right: 10px;
}
Jquery
var data = [{
value: 2755,
color: "#FFE135",
label: "Bananas: 2,755 (18%)"
}, {
. . .
}, {
value: 1048,
color: "#FEA620",
label: "Melons, Cantaloupe: 1,048 (7%)"
}];
var optionsPie = {
responsive: true,
scaleBeginAtZero: true,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
}
var ctx = $("#top10ItemsChart").get(0).getContext("2d");
var top10PieChart = new Chart(ctx).Pie(data, optionsPie);
$("#top10Legend").html(top10PieChart.generateLegend());
ПРИМЕЧАНИЕ: добавив это в optionsPie:
legend: {
display: true,
position: 'right'
},
... ничего не делает - легенда остается прижатой к полу, словно лягушка, попавшая в подбородок выстрелом перепела.
ОБНОВЛЕНИЕ 5
Я поигрался с примером Тео, пытаясь заставить его работать правильно, но, хотя это и лучше, пирог очень маленький, и легенда должна быть шире, но я не могу понять, как растянуть легенду по горизонтали и пирог во всех направлениях. Вот как это выглядит сейчас:
Это код сейчас (JQUERY такой же):
HTML
<div class="col-md-6">
<div class="topleft">
<h2 class="sectiontext">Top 10 Items</h2>
<br />
<div class="legendTable">
<div class="legendCell">
<canvas id="top10ItemsChart" class="pie" style="padding-left:20px"></canvas>
</div>
<div class="legendCell" id="top10Legend">
</div>
</div>
</div>
</div>
CSS
.topleft {
margin-top: -4px;
margin-left: 16px;
margin-bottom: 16px;
padding: 16px;
border: 1px solid black;
}
canvas {
width: 100% !important;
height: auto !important;
}
.legendTable {
border: 1px solid forestgreen;
display: table;
width: 100%;
table-layout: fixed;
}
.legendCell {
display: table-cell;
vertical-align: middle;
}
.pie-legend ul {
list-style: none;
margin: 0;
padding: 0;
width: 300px;
}
.pie-legend span {
display: inline-block;
width: 14px;
height: 12px;
border-radius: 100%;
margin-right: 4px;
margin-bottom: -2px;
}
.pie-legend li {
margin-bottom: 4px;
display: inline-block;
margin-right: 4px;
}
Что-то разбивает пирог и склеивает внешние края легенды.
ОБНОВЛЕНИЕ 6
Ochi и др. Вот что я вижу после Ochification моего кода:
Это мой код - я даже заказал jQuery так, как он у вас есть, хотя я сомневаюсь, что это действительно необходимо:
HTML
<div class="row" id="top10Items">
<div class="col-md-6">
<div class="topleft">
<h2 class="sectiontext">Top 10 Items</h2>
<br />
@*<div class="legendTable">
<div class="legendCell">
<canvas id="top10ItemsChart" class="pie" style="padding-left:20px"></canvas>
</div>
<div class="legendCell" id="top10Legend">
</div>
</div>*@
<div class="chart">
<canvas id="top10ItemsChart" class="pie"></canvas>
<div id="pie_legend"></div>
</div>
</div>
</div>
. . .
</div>
CSS
.pie-legend {
list-style: none;
margin: 0;
padding: 0;
}
.pie-legend span {
display: inline-block;
width: 14px;
height: 14px;
border-radius: 100%;
margin-right: 16px;
margin-bottom: -2px;
}
.pie-legend li {
margin-bottom: 10px;
display: block;
margin-right: 10px;
}
.chart,
#priceComplianceBarChart,
#pie_legend {
display: inline-flex;
padding: 0;
margin: 0;
}
Jquery
var optionsPie = {
responsive: true,
scaleBeginAtZero: true,
legendTemplate: "<ul class=\"<%=name.toLowerCase()%>-legend\"><% for (var i=0; i<segments.length; i++){%><li><span style=\"background-color:<%=segments[i].fillColor%>\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>"
}
var ctx = $("#top10ItemsChart").get(0).getContext("2d");
var data = [{
value: 2755,
color: "#FFE135",
label: "Bananas: 2,755 (18%)"
. . .
}, {
value: 1048,
color: "#FEA620",
label: "Melons, Cantaloupe: 1,048 (7%)"
}];
var top10PieChart = new Chart(ctx).Pie(data, optionsPie);
$("#pie_legend").html(top10PieChart.generateLegend());
... и все же пирог более эластичен, чем эластичные штаны на слоне.
ОБНОВЛЕНИЕ 7
Может быть, есть проблема с конфигурацией или что-то. Я решил "обновить" Chart.JS до версии 2.1.3 (началось с версии 1.0.2):
@*<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.min.js"></script>*@
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.3/Chart.js"></script>
... и скопировал почти точно CodePen Тео Драговича здесь.
Единственными вещами, которые я изменил, были имена двух CSS-классов ("таблица" стала "legendTable" и "ячейка" стала "legendCell") и цвет границы таблицы от красного до лесного, и я получил это сейчас:
Нужно ли ссылаться на CSS-файл Chart.JS или что-то в этом роде?
3 ответа
Вот что работает (более или менее), используя версию 2 Chart.JS:
HTML
<h2 class="sectiontext">Top 10 Items</h2>
<br />
<div class="chart">
<canvas id="top10ItemsChart" class="pie"></canvas>
<div id="pie_legend"></div>
</div>
Jquery
var data = {
labels: [
"Bananas: 2,755 (18%)",
"Lettuce, Romaine: 2,256 (14%)",
"Melons, Watermelon: 1,637 (10%)",
"Pineapple: 1,608 (10%)",
"Berries: 1,603 (10%)",
"Lettuce, Spring Mix: 1,433 (9%)",
"Broccoli: 1,207 (8%)",
"Melons, Honeydew: 1,076 (7%)",
"Grapes: 1,056 (7%)",
"Melons, Cantaloupe: 1,048 (7%)"
],
datasets: [
{
data: [2755, 2256, 1637, 1608, 1603, 1433, 1207, 1076, 1056, 1048],
backgroundColor: [
"#FFE135",
"#3B5323",
"#fc6c85",
"#ffec89",
"#021c3d",
"#3B5323",
"#046b00",
"#cef45a",
"#421C52",
"#FEA620"
],
}]
};
var optionsPie = {
responsive: true,
scaleBeginAtZero: true
}
var ctx = $("#top10ItemsChart").get(0).getContext("2d");
var top10PieChart = new Chart(ctx,
{
type: 'pie',
data: data,
options: optionsPie
});
$("#top10Legend").html(top10PieChart.generateLegend());
Я говорю "более или менее", потому что кусочки пирога все еще жалки
Я думаю, это то, что вы хотите: DEMO
Во-первых, вам нужно сделать canvas
отзывчив, переопределив фиксированную ширину и высоту, и оберните его div
это может быть использовано для позиционирования. я использовал display: table
для центрирующих элементов, но установка внутренних элементов в inline-block
также работает, если вы хотите, чтобы диаграмма и легенда занимали место, отличное от 50:50.
HTML:
<div class="table">
<div class="cell">
<canvas id="top10ItemsChart" class="pie"></canvas>
</div>
<div class="cell" id="top10Legend"></div>
</div>
CSS:
canvas {
width: 100% !important;
height: auto !important;
}
.table {
border: 1px solid red;
display: table;
width: 100%;
table-layout: fixed;
}
.cell {
display: table-cell;
vertical-align: middle;
}
ОБНОВЛЕНИЕ: Произведена некоторая корректировка на основе дополнительной информации от OP NEW DEMO
HTML:
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="topleft">
<h2 class="sectiontext">Top 10 Items</h2>
<br />
<div class="chart">
<div class="pie">
<canvas id="top10ItemsChart" class="pie"></canvas>
</div>
<div class="legend" id="top10Legend">
</div>
</div>
</div>
</div>
</div>
</div>
CSS:
.topleft {
margin-top: -4px;
margin-left: 16px;
margin-bottom: 16px;
padding: 16px;
border: 1px solid black;
}
canvas {
width: 100% !important;
height: auto !important;
margin-left: -25%;
}
.chart {
border: 1px solid forestgreen;
width: 100%;
overflow: hidden;
position: relative;
}
.pie {
position: relative;
padding: 10px 0;
// adjust as necessary
padding-left: 10px;
padding-right: 0;
}
.legend {
position: absolute;
right: 10px;
top: 10px;
height: 100%;
// adjust as necessary:
width: 48%;
}
@media (max-width: 480px) {
.legend {
position: relative;
width: 100%;
}
.pie {
margin: 0;
}
}
.pie-legend ul {
list-style: none;
margin: 0;
padding: 0;
width: 300px;
}
.pie-legend span {
display: inline-block;
width: 14px;
height: 12px;
border-radius: 100%;
margin-right: 4px;
margin-bottom: -2px;
}
.pie-legend li {
margin-bottom: 4px;
display: inline-block;
margin-right: 4px;
}
Как упомянул @B.ClayShannon, версия 2 немного отличается от версии 1. Вот пример того, как настроить шаблон легенды, используя версию 2.
options: {
legendCallback: function (chart) {
var text = [];
text.push('<ul class="' + chart.id + '-legend" style="list-style:none">');
for (var i = 0; i < chart.data.datasets[0].data.length; i++) {
text.push('<li><div style="width:10px;height:10px;display:inline-block;background:' + chart.data.datasets[0].backgroundColor[i] + '" /> ');
if (chart.data.labels[i]) {
text.push(chart.data.labels[i]);
}
text.push('</li>');
}
text.push('</ul>');
return text.join('');
},
legend: {display: false},
}
Он не показан непосредственно в принятом решении выше, но чтобы отобразить вашу легенду в другом месте, вам нужно позвонить:
$("#myChartLegend").html(myChart.generateLegend());
Наконец, немного HTML, чтобы собрать его вместе (обратите внимание, что clearfix - это класс Bootstrap, который:
<div class="chart">
<div style="float:left">
<canvas id="myChart" class="pie" style="max-width:300px;"></canvas>
</div>
<div class="legend" id="myChartLegend" style="float:left;"></div>
<div style="clear: both;"/>
</div>