Я пытаюсь повторить этот дизайн диаграммы , используя Chart.js (v2), и я не могу понять это.
Я использую «вложенные» кольцевые диаграммы, которые извлекают данные из двух наборов данных, а также используют комбинацию меток данных и плагинов меток для маркировки как отдельных частей (меток данных), так и внешних меток (меток).
<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-js lang-js prettyprint-override"><code> // var testOuterData = [5, 20];
var testNotSubmittedData = [4, 1];
var testSubmittedData = [5, 6, 6, 3];
window.onload = function () {
outerLabels = [
"Not Submitted",
"Submitted"
];
innerLabels = [
"Overdue",
"Due",
"Not Reviewed yet",
"Accepted with Comments",
"Returned",
"Accepted"
];
buildTestChart(outerLabels, innerLabels);
};
function buildTestChart(outerLabels, innerLabels) {
var testInnerData = testNotSubmittedData.concat(testSubmittedData);
var testConfig = {
type: 'doughnut',
data: {
datasets: [{
data: [12, 23, 10, 72],
backgroundColor: [
'rgb(168, 187, 208)',
'rgb(232, 241, 254)',
'rgb(211, 225, 242)',
'rgb(0, 37, 105)'
],
}],
},
data: {
datasets: [
{
data: [5, 20],
explodeSection: 0,
backgroundColor: ["#c34258", "#34bfa2"],
borderWidth: [0, 0],
borderColor: ["white", "transparent"],
label: 'Outer Data',
labels: [
"Not Submitted",
"Submitted"
]
},
{
data: testInnerData,
explodeSection: 0,
backgroundColor: [
"#f2676a",
"#fdca6e",
"#fff",
"#36a3f6",
"#f4516c",
"#7fd8bc"
],
borderWidth: [0, 0, 0, 0, 0, 0],
label: 'Inner Data',
labels: [
"Overdue",
"Due",
"Not Reviewed yet",
"Accepted with Comments",
"Returned",
"Accepted"
]
}
],
labels: ['Not Submitted', 'Submitted']
},
options: {
legend: {
display: false
},
responsive: true,
maintainAspectRatio: false,
cutoutPercentage: 0,
tooltips: {
callbacks: {
label: function (tooltipItem, data) {
var label = data.datasets[tooltipItem.datasetIndex].labels[tooltipItem.index];
var value = data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
return label + ': ' + value;
}
}
},
plugins: {
labels: [
{
render: function (data) {
if (data.dataset.label === 'Outer Data') {
return data.label;
}
else {
return '';
}
},
position: 'outside',
fontFamily: "'Lato', 'Lato', 'Arial', sans-serif",
fontSize: 14,
textMargin: 8,
fontColor: '#808080'
},
{
render: function (data) {
if (data.dataset.label === 'Inner Data') {
return '';
}
},
render: 'value',
fontSize: 12,
position: 'border',
textMargin: 4,
fontColor: [
"#fff",
"#fff",
"#000",
"#fff",
"#fff",
"#fff"
],
fontFamily: "'Lato', 'Lato', 'Arial', sans-serif"
}
],
datalabels: {
display: false
}
},
}
};
var ctxTest = document.getElementById('test').getContext('2d');
window.myPie = new Chart(ctxTest, testConfig);
testSubmittalsChart = window.myPie;
}
var helpers = Chart.helpers;
Chart.controllers.doughnut = Chart.controllers.doughnut.extend({
// function to increase inner charts diameter
update: function (reset) {
var me = this;
if (me.index === 0) {// Outer chart
var chart = me.chart,
chartArea = chart.chartArea,
opts = chart.options,
arcOpts = opts.elements.arc,
availableWidth = chartArea.right - chartArea.left - arcOpts.borderWidth,
availableHeight = chartArea.bottom - chartArea.top - arcOpts.borderWidth,
minSize = Math.min(availableWidth, availableHeight),
offset = {
x: 0,
y: 0
},
meta = me.getMeta(),
cutoutPercentage = 70,
circumference = opts.circumference;
chart.borderWidth = me.getMaxBorderWidth(meta.data);
chart.outerRadius = Math.max((minSize - chart.borderWidth) / 2, 0);
chart.innerRadius = Math.max(cutoutPercentage ? (chart.outerRadius / 100) * (cutoutPercentage) : 0, 0);
chart.radiusLength = ((chart.outerRadius - chart.innerRadius) / chart.getVisibleDatasetCount()) + 25;
chart.offsetX = offset.x * chart.outerRadius;
chart.offsetY = offset.y * chart.outerRadius;
meta.total = me.calculateTotal();
me.outerRadius = chart.outerRadius - (chart.radiusLength * me.getRingIndex(me.index));
me.innerRadius = Math.max(me.outerRadius - chart.radiusLength, 0);
}
else if (me.index === 1) { // Inner chart
var chart = me.chart;
opts = chart.options,
meta = me.getMeta(),
cutoutPercentage = opts.cutoutPercentage,
circumference = opts.circumference;
meta.total = me.calculateTotal();
me.outerRadius = 90;
me.innerRadius = 0;
// factor in the radius buffer if the chart has more than 1 dataset
if (me.index > 0) {
me.outerRadius = 90;
}
}
helpers.each(meta.data, function (arc, index) {
me.updateElement(arc, index, reset);
});
}
});
<html>
<body>
<canvas id="test" style="width: 300px; height: 300px"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/emn178/chartjs-plugin-labels/src/chartjs-plugin-labels.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@0.5.0"></script>
</body>
</html>
Моя проблема заключается в том, что мне нужно иметь возможность разбить секцию как для внешней, так и для внутренней части согласно дизайну для обеих диаграмм, показаставляя их казаться сгруппированными вместе.Я пытался установить границу для отдельных частей, но не мог найти способ сделать это.Я собрал эту ручку для всех, кто думает, что может помочь.
Заранее спасибо!