CSS - 如何创建像这样的圆形饼图画布?

5
我真的很喜欢这个元素,
但是怎么创建它呢?我不确定这个元素的正确称呼...
非常感谢。

这是一个干净的解决方案:https://codepen.io/dgca/pen/jwZGqv - thadeuszlay
5个回答

5

通过叠加几个arc(),可以实现此效果:

// 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();

最后渲染文本:

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

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


4

我选择完全依赖CSS和JS来构建饼图,而不是使用<canvas>元素。HTML标记如下:

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

CSS如下所示。关键是将圆形分为两个半圆(嵌套的.left.right元素)。这些半圆将隐藏其溢出内容,并包含我们稍后将用JS进行旋转操作的嵌套<span>。在适当的情况下添加供应商前缀 :)

.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;
    }

我曾经使用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)"
            });
        }
    });
});

这是一个fiddle代码示例:http://jsfiddle.net/Aw5Rf/7/

顺便提一下,你的代码需要添加一些特定于浏览器的CSS才能在IE和FF中正常工作。 - markE
是的,绝对没错。我只是用“-webkit-”作为一个例子。我同意在<canvas>上绘制可能是更有效的解决方案。 - Terry

3

查看以下链接以获取更多信息(不是确切的链接,但您可以获得一些想法)。

<!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>

更多信息:在HTML5画布元素中绘制数据:简单的饼图 另一个链接:纯CSS3饼图效果 这是一个在线演示:http://jsbin.com/uFaSOwO/1/

3

首先,您可以使用jQuery旋钮插件完美地实现所需功能。如果仍然想要CSS解决方案,请看我所做的:

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

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

演示


旋钮动画 来源


如果您想要防止鼠标更改,您可以简单地添加readOnly

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

演示


3

这里是带有动画效果的代码示例

以下是我的方法:

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();

在代码底部,你会发现一个自我评估函数timeout,它每10毫秒调用一次drawCanvas函数并增加蓝色圆圈的角度。希望这里的一切都很清楚。如果不清楚,请随时询问!
祝您愉快!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接