JSFiddle - React, Tailwind, and code Playground

Animated Chart Cards

by Jennifer Perrin

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/packery/1.4.2/packery.pkgd.min.js"></script>
<div id="container">
    <div class="card chart-wrap bg ring">
        <h3>Triple Ring Chart</h3>
        <div class="chart">
            <div class="ring-chart" data-progress="80">
                <div class="circle">
                    <div class="mask full">
                        <div class="fill bg"></div>
                    </div>
                    <div class="mask half">
                        <div class="fill bg"></div>
                        <div class="fill bg fix"></div>
                    </div>
                </div>
                <div class="ring-fill bg"></div>
            </div>
            <div class="small ring-chart" data-progress="60">
                <div class="circle">
                    <div class="mask full">
                        <div class="fill bg"></div>
                    </div>
                    <div class="mask half">
                        <div class="fill bg"></div>
                        <div class="fill bg fix"></div>
                    </div>
                </div>
                <div class="ring-fill bg"></div>
            </div>
            <div class="mini ring-chart" data-progress="40">
                <div class="circle">
                    <div class="mask full">
                        <div class="fill bg"></div>
                    </div>
                    <div class="mask half">
                        <div class="fill bg"></div>
                        <div class="fill bg fix"></div>
                    </div>
                </div>
                <div class="ring-fill bg"></div>
            </div>
        </div>
        <div class="chart-legend">
            <p>This describes the value of the outer ring</p>
            <p>This describes the value of the middle ring</p>
            <p>This describes the value of the inner ring</p>
        </div>
    </div>
    <div class="card chart-wrap bg ring">
      ...

CSS

@import url(http://fonts.googleapis.com/css?family=Raleway:400,200);
* {
    box-sizing: border-box;
    font-family: 'Raleway', sans-serif;
}

html,
body {
    position: relative;
    float: left;
    margin: 0;
    width: 100%;
    height: 100%;
}

#container {
    position: relative;
    float: left;
    width: 100%;
    min-height: 100%;
    padding-left: 10px;
    padding-top: 10px;
    padding-bottom: 10px;
}

.card {
    position: relative;
    float: left;
    width: 280px;
    padding: 30px 30px 0 30px;
    box-sizing: border-box;
    border-radius: 0.2em;
    box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3);
    -webkit-transition: none;
    transition: none;
}

.card * {
    -webkit-transition: none;
    transition: none;
}

.card h3 {
    font-size: 22px;
    margin-top: 0;
    margin-bottom: 30px;
    text-align: center;
    font-weight: 400;
}

.card .chart-legend {
    position: relative;
    float: left;
    margin-top: 30px;
    margin-left: -30px;
    width: calc(100% + 60px);
    padding: 7px 30px 5px 30px;
    border-radius: 0 0 0.2em 0.2em;
}

.card .chart-legend h3,
.card .chart-legend p {
    font-size: 14px;
    text-align: center;
    font-weight: 200;
    letter-spacing: 1px;
    line-height: 25px;
}

.card .chart {
    position: relative;
    float: left;
    width: 100%;
    height: 220px;
    overflow: hidden;
}

.card.line .chart {
    overflow: visible;
}
/* COLOURS */

.card.bg,
.card .bg {
    background: #fff;
    color: #111;
}

.card.line canvas {
    border-color: #333;
}

.card.line-only canvas,
.card.quote p,
.card.quote p:before {
    border-color: #5CA8A6;
}

.card .chart-legend,
.card.list li:before,
.card .bar-chart .bar:nth-child(4),
.card .column-chart .column:nth-child(4) {
    background-color: #5CA8A6;
    color: #fff;
}

.card .ring-chart .ring-fill {
    border-color: #79D0CE;
}

.card .ring-chart .circle .mask .fill,
.card.ring .chart-legend p:nth-child(1):before,
.card .bar-chart .bar:nth-child(3),
.card .column-chart...

JavaScript

$.fn.drawColsLine = function drawLine(data, colour, cols) {
    
    var el = $(this);
    
    function calculate(data, index, d) {
        var valueRatio = data[index] / 100 * d;
        return d - valueRatio;
    };
    
    data['sorted'] = data.sort(function(a, b) {
        return parseFloat(a.x, 10) - parseFloat(b.x, 10);
    });
    
    data['y'] = new Array();
    
    for (var i = 0; i < data['sorted'].length; i++) {
        data['y'][i] = data['sorted'][i].y;
    }
    
    var canvas = el[0],
        ctx = canvas.getContext('2d');
    
    var t = 0;
    var interval = setInterval(function() {
        var x = ((canvas.width / cols.length) + parseInt(cols.css('margin-left')) / 2) * t + ((canvas.width / (cols.length * 2)) - parseInt(cols.css('margin-left')));
        var y = calculate(data['y'], t, canvas.height);
        ctx.lineTo(x, y);
        ctx.strokeStyle = colour;
        ctx.moveTo(x, y);
        ctx.stroke();
        t = t + 1;
        if (t > data['sorted'].length) {
            clearInterval(interval);
        }
    }, 800 / data['sorted'].length);
};

$.fn.drawLine = function drawLine(data, colour) {
    
    function calculate(data, index, d, max) {
        var valueRatio = data[index] / max * d - 10;
        return d - valueRatio;
    };
    
    function getMax(data) {
        return Math.max.apply(null, data);
    }
    
    data['sorted'] = data.sort(function(a, b) {
        return parseFloat(a.x, 10) - parseFloat(b.x, 10);
    });
    data['x'] = new Array();
    data['y'] = new Array();
    
    for (var i = 0; i < data['sorted'].length; i++) {
        data['x'][i] = data['sorted'][i].x;
        data['y'][i] = data['sorted'][i].y;
    }
    
    var canvas = $(this)[0],
        ctx = canvas.getContext('2d'),
        maxx = getMax(data['x']),
        maxy = getMax(data['y']);
    
    setTimeout(function() {
        var t = 0;
        var interval = setInterval(function() {
            var x = canvas.width - calculate(data['x'], t,...