5

I really like this element,

this element

but how to create it? I am not sure what's the correct designation of the element...

Thank you very much.

user984621
  • 46,344
  • 73
  • 224
  • 412

5 Answers5

5

This effect can be achieved by layering a couple arc()s:

// bright blue full circle
d.beginPath();
d.arc(50, 50, 50, 0, 2 * Math.PI, false);
d.fillStyle = "#aaeeff";
d.fill();

// dark blue percentage circle
d.beginPath();
d.moveTo(50, 50);
d.arc(50, 50, 50, -0.5 * Math.PI, 0.78 * 2 * Math.PI - 0.5 * Math.PI, false);
d.fillStyle = "#00aaff";
d.fill();

// white inner filler
d.beginPath();
d.moveTo(50, 50);
d.arc(50, 50, 25, 0, 2 * Math.PI, false);
d.fillStyle = "#ffffff";
d.fill();

and finally rendering the text:

d.moveTo(50, 50);
d.fillStyle = "#606060";
d.font = "12pt sans-serif";
d.fillText("78%", 36, 56);

Fiddle: http://jsfiddle.net/j6NVg/

Cobra_Fast
  • 15,671
  • 8
  • 57
  • 102
4

Instead of using the <canvas> element, I have chosen to construct the pie chart relying on CSS and JS entirely. The HTML markup is as follow:

<div class="pie" data-percent="78">
    <div class="left">
        <span></span>
    </div>
    <div class="right">
        <span></span>
    </div>
</div>

The CSS is as follow. The trick is to split the circle into two halves (the nested .left and .right elements). The halves will have their overflowing content hidden, and contain nested <span> that we will manipulate with JS for rotation later. Add vendor prefixes when appropriate :)

.pie {
    background-color: #eee;
    border-radius: 50%;
    width: 200px;
    height: 200px;
    overflow: hidden;
    position: relative;
}
.pie > div {
    float: left;
    width: 50%;
    height: 100%;
    position: relative;
    overflow: hidden;
}
.pie span {
    background-color: #4a7298;
    display: block;
    width: 100%;
    height: 100%;
}
    .pie .left span {
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
        -webkit-transform-origin: 100% 50%;
        transform-origin: 100% 50%;
    }
    .pie .right span {
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
        -webkit-transform-origin: 0% 50%;
        transform-origin: 0% 50%;
    }
.pie:before,
.pie:after {
    border-radius: 50%;
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    -webkit-transform: translateX(-50%) translateY(-50%);
    transform: translateX(-50%) translateY(-50%);
}
    .pie:before {
        background-color: #fff;
        content: "";
        width: 75%;
        height: 75%;
        z-index: 100;
    }
    .pie:after {
        content: attr(data-percent) "%";
        z-index: 200;
        text-align: center;
    }

I have used the following with jQuery:

$(function() {
    $(".pie").each(function() {
        var percent = $(this).data("percent").slice(0,-1), // Removes '%'
            $left = $(this).find(".left span"),
            $right = $(this).find(".right span"),
            deg;

        if(percent<=50) {
            // Hide left
            $left.hide();

            // Adjust right
            deg = 180 - (percent/100*360)
            $right.css({
                "transform": "rotateZ(-"+deg+"deg)"
            });
        } else {
            // Adjust left
            deg = 180 - ((percent-50)/100*360)
            $left.css({
                "transform": "rotateZ(-"+deg+"deg)"
            });
        }
    });
});

Here is the fiddle: http://jsfiddle.net/Aw5Rf/7/

Terry
  • 63,248
  • 15
  • 96
  • 118
  • BTW, Your code needs some added browser-specific css to work in IE & FF. – markE Oct 26 '13 at 16:08
  • Yup, definitely. I'm just using `-webkit-` as an example. I concur that perhaps drawing onto `` is a more efficient solution. – Terry Oct 26 '13 at 16:29
3

Check the below links for more info (not an exact one.But you can get some idea).

<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Canvas Test</title>
</head>
<body>
<section>
<div>
<canvas id="canvas" width="400" height="300">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
</div>

<script type="text/javascript">

var myColor = ["#ECD078","#D95B43","#C02942","#542437","#53777A"];
var myData = [10,30,20,60,40];

function getTotal(){
var myTotal = 0;
for (var j = 0; j < myData.length; j++) {
myTotal += (typeof myData[j] == 'number') ? myData[j] : 0;
}
return myTotal;
}

function plotData() {
var canvas;
var ctx;
var lastend = 0;
var myTotal = getTotal();

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);

for (var i = 0; i < myData.length; i++) {
ctx.fillStyle = myColor[i];
ctx.beginPath();
ctx.moveTo(200,150);
ctx.arc(200,150,150,lastend,lastend+
  (Math.PI*2*(myData[i]/myTotal)),false);
ctx.lineTo(200,150);
ctx.fill();
lastend += Math.PI*2*(myData[i]/myTotal);
}
}

plotData();

</script>
</section>
</body>
</html>

For more info :Graphing Data in the HTML5 Canvas Element Simple Pie Charts

Another Link : Pure CSS3 Pie Charts effect

This is an online demo: http://jsbin.com/uFaSOwO/1/

Sampath
  • 63,341
  • 64
  • 307
  • 441
3

First of all what you need can be done exactly using jQuery knob plugin. Still interested in a CSS Solution, than here's what I have done

<div class="load_me"></div>

.load_me {
    margin: 100px;
    height: 50px;
    width: 50px;
    border: 5px solid #f00;
    border-radius: 50%;
    border-top-color: transparent;
}

Demo


Animating the Knob Credits


If you want to prevent the mouse alteration, you can simply add readOnly

$this.knob({
    readOnly: true
});

Demo

Mr. Alien
  • 153,751
  • 34
  • 298
  • 278
3

FIDDLE with ANIMATION

Here's my approach:

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


/*
 * in canvas, 0 degrees angle is on the right edge of a circle,
 * while we want to start at the top edge of the circle.
 * We'll use this variable to compensate the difference.
 */
var relativeAngle = 270;

function drawCanvas() {

    ctx.clearRect(0, 0, 90, 90);
    //light blue circle
    ctx.lineWidth = 20;
    ctx.strokeStyle = '#D8E8F7';
    ctx.beginPath();
    ctx.arc(45, 45, 35, 0, 2*Math.PI);
    ctx.stroke();

    //dark blue circle
    ctx.strokeStyle = '#66ADF4';
    ctx.beginPath();
    //notice the angle conversion from degrees to radians in the 5th argument
    ctx.arc(45, 45, 35, 1.5*Math.PI, ((angle + relativeAngle) / 180) * Math.PI);
    ctx.stroke();

    //text
    ctx.textBaseline = 'middle';
    ctx.textAlign = 'center';
    ctx.fillStyle = '#666';
    ctx.font = 'bold 14px serif';
    // angle conversion to percentage value
    ctx.fillText(parseInt(100 * angle / 360).toString() + '%', 45, 45);
}

var angle;
function timeout() {
    angle = parseInt(360 * percent / 100);
    drawCanvas();

    if (angle > 360) {
        document.getElementById('run').disabled = false;
        percent = 0;
        return;
    }

    percent++;
    setTimeout(timeout, 10);
};

var percent = 0;

/* START the ANIMATION */
timeout();

At the bottom of the code you'll find a self evaluating function timeout which calls the drawCanvas function every 10 miliseconds and increments the blue circle angle. I hope everything is clear here. If not, feel free to ask!

Enjoy it!

matewka
  • 9,912
  • 2
  • 32
  • 43