Chartjs嵌套的饼图/甜甜圈图,具有共享的分解部分/部分

时间:2019-02-27 12:09:22

标签: javascript html canvas chart.js pie-chart

我正在尝试复制this chart design  使用Chart.js(v2),我无法弄清楚。

我正在使用“嵌套”甜甜圈图,该图从两个数据集中提取数据,同时还使用datalabels和labels插件的组合来标记单个块(datalabels)和外部标签(labels)。

            // 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>

我的问题是,我需要能够按照两个图表的设计来分解外部和内部的部分,同时使它们看起来像是组合在一起的。我试图在各个部分上设置边界,但是找不到解决方法。 我为任何认为自己可以提供帮助的人提供了this pen的帮助。

谢谢!

0 个答案:

没有答案