Skip to content

Instantly share code, notes, and snippets.

@lestoni
Created July 30, 2014 15:11

Revisions

  1. Tony Mutai created this gist Jul 30, 2014.
    3 changes: 3 additions & 0 deletions jsbin.losab.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    #canvas {
    border: 1px solid #ccc;
    }
    10 changes: 10 additions & 0 deletions jsbin.losab.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,10 @@
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>Piey</title>
    </head>
    <body>
    <div id="piechart"></div>
    </body>
    </html>
    188 changes: 188 additions & 0 deletions jsbin.losab.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,188 @@
    /**
    * Piey.js: A small rogue pie chart maker.
    *
    * MIT License.
    * Copyright (c) 2014 Tony Mutai.
    */

    /**
    * piey.draw(options, dataset);
    *
    * - options:
    * el - element to append pie chart to(default: document.body)
    * width - Draw area width(default: 600)
    * height - Draw area height(default: 480)
    * radius - Pie chart's radius(default: 150)
    * title - Pie chart's title(default: 'Title')
    * subtitle - Pie chart's subtitle(default: 'Subtitle')
    *
    * - Dataset format: [ { name: 'AA', size: 34 } ,...]
    */

    var piey = (function() {
    var slices = [],
    ctx = null,
    pad = 5,
    config = {
    el: document.body,
    width: 600,
    height: 480,
    radius: 150,
    title: 'Title',
    subtitle: 'subtitle'
    };

    function toRadians(deg) {
    return (Math.PI / 180) * deg;
    }

    function randColor(op) {
    var r = rand(0, 255) + ',';
    var g = rand(0, 255) + ',';
    var b = rand(0, 255) + ',';

    return 'rgba(' + r + g + b + (op || 1) + ')';
    }

    function rand(min, max) {
    return Math.floor((Math.random() * (max - min)) + min);
    }

    function merge(a, b) {
    for (var prop in b) {
    if (b.hasOwnProperty(prop)) {
    a[prop] = b[prop];
    }
    }
    }

    function parseDataset(dataset, draw) {
    var len = dataset.length,
    total = dataset.reduce(function(a, b) {
    return a + b.size;
    }, 0);


    var startAngle = 0,
    endAngle = 0,
    prevAngle = 0,
    sliceColor, data;

    for (var i = 0; i < len; i++) {


    data = (dataset[i]).size;

    startAngle = prevAngle;
    endAngle = ((data / total) * 360) + prevAngle;
    prevAngle = endAngle;
    sliceColor = randColor();

    slices.push({
    start: Math.floor(startAngle),
    end: Math.floor(endAngle),
    color: sliceColor,
    title: dataset[i].name
    });
    }

    draw();
    }

    function drawBar(slice) {
    var bx = config.width - 100,
    by = (120 + pad);

    ctx.fillStyle = slice.color;
    ctx.fillRect(bx, by, 20, 20);

    ctx.fillStyle = '#333';
    ctx.textAlign = 'left';
    ctx.font = 'bold normal 12px san-serif';
    ctx.textBaseline = 'middle';
    ctx.fillText(slice.title, (bx + 30), (by + 10));

    pad += 30;
    }


    function drawSlice(slice) {
    var cw = config.radius + 100,
    ch = (config.height / 2);


    ctx.fillStyle = slice.color;
    ctx.beginPath();
    ctx.moveTo(cw, ch);
    ctx.arc(cw, ch, config.radius,
    toRadians(slice.start), toRadians(slice.end), false);
    ctx.fill();
    ctx.closePath();
    }

    function makeTitles() {
    // Main title
    ctx.fillStyle = '#0099cc';
    ctx.font = 'bold normal 15px san-serif';
    ctx.textBaseline = 'middle';
    ctx.fillText(config.title, 100, 20);

    // Main subtitle
    ctx.fillStyle = '#aaa';
    ctx.font = 'bold italic 11px san-serif';
    ctx.textBaseline = 'middle';
    ctx.fillText(config.subtitle, 150, 40);
    }

    function draw() {
    makeTitles();
    for (var i = 0; i < slices.length; i++) {
    drawSlice(slices[i]);
    drawBar(slices[i]);
    }
    }



    function init(options, dataset) {
    merge(config, options);

    var canvas = document.createElement('canvas');

    config.el.appendChild(canvas);

    canvas.width = config.width;
    canvas.height = config.height;
    canvas.style.border = '1px solid #ccc';

    ctx = canvas.getContext('2d');

    parseDataset(dataset, draw);
    }

    return {
    draw: init
    };
    })();

    var el = document.getElementById('piechart');

    var dataset = [{
    name: 'A',
    size: 56
    }, {
    name: 'AA',
    size: 20
    }, {
    name: 'AAA',
    size: 305
    }, {
    name: 'AAAA',
    size: 167
    }];

    piey.draw({
    el: el,
    title: 'Pie charts for the masses forever',
    subtitle: 'Big data: In action now'
    }, dataset);