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,...