Anna
Anna

Reputation: 21

How to animate this peak chart?

I'm new to CSS and Javascript, so I am struggeling trying to animate a peak (bar) chart I found on codepen... : http://codepen.io/Anna_123/pen/QbQqQb

/* Pie chart based on the pen by aaronlsilber (http://codepen.io/aaronlsilber/pen/IqrkL) which is based on an article by James Litten (http://html5.litten.com/graphing-data-in-the-html5-canvas-element-part-iv-simple-pie-charts/) */



/* Peak Chart Javascript
=====================================================================*/
var peakColors = ['rgb(236, 208, 120)', 'rgba(217, 91, 67, 0.7)', 'rgba(192, 41, 66, 0.7)', 'rgba(84, 36, 55, 0.7)', 'rgba(83, 119, 122, 0.7)', 'rgba(119, 146, 174, 0.7)'];

function drawPeakChart( canvasId ) {
    var i, start, peakPoint,
        canvas = document.getElementById( canvasId ),
        peakData = canvas.dataset.values.split(',').map( function(x){ return parseInt( x, 10 )}),
        ctx = canvas.getContext( '2d' ),
        max = Math.max.apply( Math, peakData ),
        plotBase = canvas.width / peakData.length,
        overlap = plotBase * .4;
        plotBase += canvas.width * .05;
    
    ctx.clearRect( 0, 0, canvas.width, canvas.height );
    
    for( i = 0; i < peakData.length; i++) {
        start = i === 0 ? 0 : i * plotBase - i * overlap;
        peakPoint = canvas.height - Math.round( canvas.height * ( peakData[i] / max ) );
        ctx.fillStyle = peakColors[i];
        ctx.beginPath();
        ctx.moveTo( start, canvas.height );
        ctx.lineTo( start + plotBase * .5, peakPoint );
        ctx.lineTo( start + plotBase, canvas.height );
        ctx.lineTo( start, canvas.height );
        ctx.fill();
    }
}

drawPeakChart('canPeak');
body {
  font: normal normal 400 1rem/1.5 "Segoe UI", "Helvetica Neue", "DejaVu Sans", Helvetica, Arial, sans-serif;
}
aside {
  float: left;
  margin-right: 100px;
}
.chart {
  margin-bottom:0;
  margin-top:0;
}
.vert > canvas, .vert > ol {
  display:inline-block
}
.horiz > li {
  display: inline;
  padding-right: 20px;
}
.legend {
  vertical-align:top;
  padding-left:15px;
  list-style: none;
}
.key {
  position:relative;
}
.key:before {
  content:"";
  position:absolute;
  top:35%;
  left:-15px;
  width:10px;
  height:10px;
}
.one:before{background:rgb(236, 208, 120)}
.two:before{background:rgba(217, 91, 67, 0.7)}
.three:before{background:rgba(192, 41, 66, 0.7)}
.four:before{background:rgba(84, 36, 55, 0.7)}
.five:before{background:rgba(83, 119, 122, 0.7)}
.six:before{background:rgba(119, 146, 174, 0.7)}
<aside class="chart">
  <canvas id="canPeak" width="300" height="200" data-values='40, 30, 20, 60, 10, 50'>
    This browser does not support HTML5 Canvas.
  </canvas>
  <ol class="legend horiz">
    <li class="key one">One</li>
    <li class="key two">Two</li>
    <li class="key three">Three</li>
    <li class="key four">Four</li>
    <li class="key five">Five</li>
    <li class="key six">Six</li>
  </ol>
</aside>

I would like to create the same graph animation as in following example: http://codepen.io/boars/pen/bnAfC, but after quite some trial and errors, I don't succeed to get it working... Can anyone help me out here? thanks ! :-)

Upvotes: 2

Views: 231

Answers (1)

potatopeelings
potatopeelings

Reputation: 41075

Just add an animation loop around the part that draws the triangular bars, like so

var animationSteps = 60;
var animationStepCounter = 0;
var animation = setInterval(function () {
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    for (i = 0; i < peakData.length; i++) {
        start = i === 0 ? 0 : i * plotBase - i * overlap;
        peakPoint = canvas.height - Math.round(canvas.height * (peakData[i] / max) * animationStepCounter / animationSteps);
        ctx.fillStyle = peakColors[i];
        ctx.beginPath();
        ctx.moveTo(start, canvas.height);
        ctx.lineTo(start + plotBase * .5, peakPoint);
        ctx.lineTo(start + plotBase, canvas.height);
        ctx.lineTo(start, canvas.height);
        ctx.fill();
    }

    if (animationStepCounter === animationSteps)
        clearInterval(animation);
    else
        animationStepCounter++;
}, 10);

All it does is draw the bars 60 times (waiting 10 ms between redraws), each time increasing the height of the bar till it reaches the actual height.

You can change the 60 or 10ms if you want the animation to proceed faster (reduce either or both) / smoother, etc.


CodePen - http://codepen.io/anon/pen/MwQOVG

Upvotes: 1

Related Questions