web-dev-qa-db-ja.com

Chart.js丸みを帯びたドーナツ

Chart.jsを使用してドーナツグラフを作成しましたが、両端に丸みを帯びたエッジが必要です。私はそれをこのようにしたい:

The way I want it

しかし、私はそれをこのように、鋭いエッジで持っています:

I have this

私が見つけた最高のものはこの答えでした: Chart.js棒グラフに丸みを帯びた角を配置する方法 、しかしそれは棒グラフ用であり、ドーナツにそれを適応させる方法の手がかりがありません。

これが私のコードです:

[〜#〜] html [〜#〜]

<div class="modal-div-canvas js-chart">
  <div class="chart-canvas">
     <canvas id="openedCanvas" width="1" height="1"></canvas>
        <div class="chart-background"></div>
            <span class="chart-unique-value">
                 <span class="js-count">
                    85
                 </span>
                 <span class="cuv-percent">%</span>
            </span>
        </div>
  </div>

[〜#〜] js [〜#〜]

var deliveredData = {
        labels: [
            "Value"
        ],
        datasets: [
            {
                data: [85, 15)],
                backgroundColor: [
                    "#3ec556",
                    "rgba(0,0,0,0)"
                ],
                hoverBackgroundColor: [
                    "#3ec556",
                    "rgba(0,0,0,0)"
                ],
                borderWidth: [
                    0, 0
                ]
            }]
    };

    var deliveredOpt = {
        cutoutPercentage: 88,
        animation: {
            animationRotate: true,
            duration: 2000
        },
        legend: {
            display: false
        },
        tooltips: {
            enabled: false
        }
    };

   var chart = new Chart($('#openedCanvas'), {
        type: 'doughnut',
        data: deliveredData,
        options: deliveredOpt
    });
}};

誰かがこれを行う方法を知っていますか?

11
jpenna

@potatopeelingスニペットにいくつかの変更を加え、chart.jsの新しい(2.9.x)バージョンとの互換性を作り、「startArc」をレンダリングする場所と、この「startArc」に一致するように前のセグメントの色を修正しました。したがって、3つ以上のセグメントを持つことができます。結果は次のとおりです。

enter image description here

Chart.defaults.RoundedDoughnut    = Chart.helpers.clone(Chart.defaults.doughnut);
Chart.controllers.RoundedDoughnut = Chart.controllers.doughnut.extend({
    draw: function(ease) {
        var ctx           = this.chart.ctx;
        var easingDecimal = ease || 1;
        var arcs          = this.getMeta().data;
        Chart.helpers.each(arcs, function(arc, i) {
            arc.transition(easingDecimal).draw();

            var pArc   = arcs[i === 0 ? arcs.length - 1 : i - 1];
            var pColor = pArc._view.backgroundColor;

            var vm         = arc._view;
            var radius     = (vm.outerRadius + vm.innerRadius) / 2;
            var thickness  = (vm.outerRadius - vm.innerRadius) / 2;
            var startAngle = Math.PI - vm.startAngle - Math.PI / 2;
            var angle      = Math.PI - vm.endAngle - Math.PI / 2;

            ctx.save();
            ctx.translate(vm.x, vm.y);

            ctx.fillStyle = i === 0 ? vm.backgroundColor : pColor;
            ctx.beginPath();
            ctx.arc(radius * Math.sin(startAngle), radius * Math.cos(startAngle), thickness, 0, 2 * Math.PI);
            ctx.fill();

            ctx.fillStyle = vm.backgroundColor;
            ctx.beginPath();
            ctx.arc(radius * Math.sin(angle), radius * Math.cos(angle), thickness, 0, 2 * Math.PI);
            ctx.fill();

            ctx.restore();
        });
    }
});

window.onload = function() {
    new Chart(document.getElementById('usersChart'), {
        type   : 'RoundedDoughnut',
        data   : {
            datasets: [
                {
                    data           : [40, 20, 20, 20],
                    backgroundColor: [
                        '#e77099',
                        '#5da4e7',
                        '#8f75e7',
                        '#8fe768'
                    ],
                    borderWidth    : 0
                }]
        },
        options: {
            cutoutPercentage: 70
        }
    });
};
<script src="https://github.com/chartjs/Chart.js/releases/download/v2.9.3/Chart.min.js"></script>
<link rel="stylesheet" href="https://github.com/chartjs/Chart.js/releases/download/v2.9.3/Chart.min.css">
<div style="width: 200px; height: 200px;">
<canvas id="usersChart" width="1" height="1"></canvas>
</div>

これを行うためにチャートを拡張できます


プレビュー

enter image description here


スクリプト

Chart.defaults.RoundedDoughnut = Chart.helpers.clone(Chart.defaults.doughnut);
Chart.controllers.RoundedDoughnut = Chart.controllers.doughnut.extend({
    draw: function (ease) {
        var ctx = this.chart.chart.ctx;

        var easingDecimal = ease || 1;
        Chart.helpers.each(this.getDataset().metaData, function (arc, index) {
            arc.transition(easingDecimal).draw();

            var vm = arc._view;
            var radius = (vm.outerRadius + vm.innerRadius) / 2;
            var thickness = (vm.outerRadius - vm.innerRadius) / 2;
            var angle = Math.PI - vm.endAngle - Math.PI / 2;

            ctx.save();
            ctx.fillStyle = vm.backgroundColor;
            ctx.translate(vm.x, vm.y);
            ctx.beginPath();
            ctx.arc(radius * Math.sin(angle), radius * Math.cos(angle), thickness, 0, 2 * Math.PI);
            ctx.arc(radius * Math.sin(Math.PI), radius * Math.cos(Math.PI), thickness, 0, 2 * Math.PI);
            ctx.closePath();
            ctx.fill();
            ctx.restore();
        });
    },
});

その後

...
type: 'RoundedDoughnut',
...

スタックスニペット

Chart.defaults.RoundedDoughnut = Chart.helpers.clone(Chart.defaults.doughnut);
        Chart.controllers.RoundedDoughnut = Chart.controllers.doughnut.extend({
            draw: function (ease) {
                        var ctx = this.chart.chart.ctx;
                
                var easingDecimal = ease || 1;
                Chart.helpers.each(this.getDataset().metaData, function (arc, index) {
                    arc.transition(easingDecimal).draw();

                    var vm = arc._view;
                    var radius = (vm.outerRadius + vm.innerRadius) / 2;
                    var thickness = (vm.outerRadius - vm.innerRadius) / 2;
                    var angle = Math.PI - vm.endAngle - Math.PI / 2;
                    
                    ctx.save();
                    ctx.fillStyle = vm.backgroundColor;
                    ctx.translate(vm.x, vm.y);
                    ctx.beginPath();
                    ctx.arc(radius * Math.sin(angle), radius * Math.cos(angle), thickness, 0, 2 * Math.PI);
                    ctx.arc(radius * Math.sin(Math.PI), radius * Math.cos(Math.PI), thickness, 0, 2 * Math.PI);
                    ctx.closePath();
                    ctx.fill();
                    ctx.restore();
                });
            },
        });

        var deliveredData = {
            labels: [
                "Value"
            ],
            datasets: [
                {
                    data: [85, 15],
                    backgroundColor: [
                        "#3ec556",
                        "rgba(0,0,0,0)"
                    ],
                    hoverBackgroundColor: [
                        "#3ec556",
                        "rgba(0,0,0,0)"
                    ],
                    borderWidth: [
                        0, 0
                    ]
                }]
        };

        var deliveredOpt = {
            cutoutPercentage: 88,
            animation: {
                animationRotate: true,
                duration: 2000
            },
            legend: {
                display: false
            },
            tooltips: {
                enabled: false
            }
        };

        var chart = new Chart($('#openedCanvas'), {
            type: 'RoundedDoughnut',
            data: deliveredData,
            options: deliveredOpt
        });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.0.1/Chart.bundle.min.js"></script>

<canvas id="openedCanvas" height="230" width="680"></canvas>
12
potatopeelings