About

Examples of pie Charts made with CSS and SVG. Animatable. Very wide support, with tiny JS to make it animate.

Alternatives

See conic-gradient for decorative conical gradient (not widely supported at present)

Accessibility

2019-07-01: Like a background SVG image (inline SVG)

Requirements

Issues

Examples

Pre compiled HTML

Static HTML pie charts

0%
5%
23%
45%
71%
95%
<div class="c-pie" data-test="sm">
    <span class="c-pie__t">0%</span>
    <svg viewBox="0 0 100 100" class="c-pie__c">
        <circle r="25" cx="50" cy="50" class="c-pie__s" style="stroke-dasharray: 0, 158; stroke: rgb(245, 0, 0);"></circle>
        <circle r="42" cx="50" cy="50" class="c-pie__i"></circle>
    </svg>
</div>

<div class="c-pie" data-test="sm">
    <span class="c-pie__t">5%</span>
    <svg viewBox="0 0 100 100" class="c-pie__c">
        <circle r="25" cx="50" cy="50" class="c-pie__s" style="stroke-dasharray: 7.9, 158; stroke: rgb(245, 0, 0);"></circle>
        <circle r="42" cx="50" cy="50" class="c-pie__i"></circle>
    </svg>
</div>

<div class="c-pie" data-test="sm">
    <span class="c-pie__t">23%</span>
    <svg viewBox="0 0 100 100" class="c-pie__c">
        <circle r="25" cx="50" cy="50" class="c-pie__s" style="stroke-dasharray: 36.34, 158; stroke: rgb(245, 167, 0);"></circle>
        <circle r="42" cx="50" cy="50" class="c-pie__i"></circle>
    </svg>
</div>

<div class="c-pie" data-test="sm">
    <span class="c-pie__t">45%</span>
    <svg viewBox="0 0 100 100" class="c-pie__c">
        <circle r="25" cx="50" cy="50" class="c-pie__s" style="stroke-dasharray: 71.1, 158; stroke: rgb(245, 167, 0);"></circle>
        <circle r="42" cx="50" cy="50" class="c-pie__i"></circle>
    </svg>
</div>

<div class="c-pie" data-test="sm">
    <span class="c-pie__t">71%</span>
    <svg viewBox="0 0 100 100" class="c-pie__c">
        <circle r="25" cx="50" cy="50" class="c-pie__s" style="stroke-dasharray: 112.18, 158; stroke: rgb(0, 158, 8);"></circle>
        <circle r="42" cx="50" cy="50" class="c-pie__i"></circle>
    </svg>
</div>

<div class="c-pie" data-test="sm">
    <span class="c-pie__t">95%</span>
    <svg viewBox="0 0 100 100" class="c-pie__c">
        <circle r="25" cx="50" cy="50" class="c-pie__s" style="stroke-dasharray: 150.1, 158; stroke: rgb(0, 160, 0);"></circle>
        <circle r="42" cx="50" cy="50" class="c-pie__i"></circle>
    </svg>
</div>

Dynamically generated SVG

HTML text, with dynamic SVG generated via JS. The stroke-dasharray is the length of the SVG path around the shape. Which is why we need to calculate a percentage of this length to accurately show on the pie chart.

0%
5%
23%
45%
71%
95%
250%
-250%
(function () {
    var total = 158,// stroke length
        el = document.querySelector('main'),
        c1 = null,
        c2 = null,
        pie = document.querySelectorAll('.c-pie[data-size]'),
        fragment = document.createDocumentFragment(),
        good = "rgb(30, 175, 0)",
        bad = "rgb(245, 167, 0)",
        ugly = "rgb(218, 0, 0)",
        blank = "rgba(0, 0, 0, 0)";

    var numberPercent = function (num) {
        // If a negative number, make entire circle red
        if (num < 0) {
            num = 100;
        }
        var result = ((num * total) / 100);
        return result;
    }

    var colourPercent = function (num) {
        if (num >= 70) { return good; }
        else if (num > 40) { return bad; }
        else if ((num >= 0) || (num < 0)) { return ugly; }
        else { return blank; }
    }

    var colourPercent = function (num) {
        if (num >= 70) { return good; }
        else if (num > 40) { return bad; }
        else if ((num >= 0) || (num < 0)) { return ugly; }
        else { return blank; }
    }

    Array.prototype.forEach.call(pie, function (pie, i) {
        var number = pie.getAttribute('data-percent');
        var fixedNumber = numberPercent(number);
        var result = fixedNumber + ' ' + total;

        // If a large (3 digit) positive or negative number, reduce text size
        if ((number > 99) || (number < -30)) {
            pie.classList.add('c-pie--small');
        }

        el = document.createElementNS("http://www.w3.org/2000/svg", "svg");
        el.setAttribute('viewBox', '0 0 100 100');
        el.setAttribute('class', 'c-pie__c');

        // Create colour circle
        c1 = document.createElementNS("http://www.w3.org/2000/svg", 'circle');
        c1.setAttribute('r', '25');
        c1.setAttribute('cx', '50');
        c1.setAttribute('cy', '50');
        c1.setAttribute('class', 'c-pie__s');
        c1.style.strokeDasharray = result;
        c1.style.stroke = colourPercent(number);

        // Create inner circle
        c2 = document.createElementNS("http://www.w3.org/2000/svg", 'circle');
        c2.setAttribute('r', '42');
        c2.setAttribute('cx', '50');
        c2.setAttribute('cy', '50');
        c2.setAttribute('class', 'c-pie__i');

        // Build SVG
        el.appendChild(c1);
        el.appendChild(c2);
        fragment.appendChild(el);
        pie.appendChild(fragment);
    });

})();

JS - Parameters

References / inspiration