var canvas = document.getElementById("can");
var ctx = canvas.getContext("2d");
var lastend = 0;
var data = [60,210,90];
var myTotal = 0;
var myColor = ['#afcc4c', '#95b524','#c1dd54'];
var labels = ['B', 'A', 'C'];
for(var e = 0; e < data.length; e++)
{
myTotal += data[e];
}
// make the chart 10 px smaller to fit on canvas
var off = 10
var w = (canvas.width - off) / 2
var h = (canvas.height - off) / 2
for (var i = 0; i < data.length; i++) {
ctx.fillStyle = myColor[i];
ctx.strokeStyle ='white';
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(w,h);
var len = (data[i]/myTotal) * 2 * Math.PI
var r = h - off / 2
ctx.arc(w , h, r, lastend,lastend + len,false);
ctx.lineTo(w,h);
ctx.fill();
ctx.stroke();
ctx.fillStyle ='white';
ctx.font = "20px Arial";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
var mid = lastend + len / 2
ctx.fillText(labels[i],w + Math.cos(mid) * (r/2) , h + Math.sin(mid) * (r/2));
lastend += Math.PI*2*(data[i]/myTotal);
}
/*
make each pie piece a rectangle twice as high as it is wide.
move the transform origin to the middle of the left side.
Also ensure that overflow is set to hidden.
*/
.pie {
position:absolute;
width:100px;
height:200px;
overflow:hidden;
left:150px;
-moz-transform-origin:left center;
-ms-transform-origin:left center;
-o-transform-origin:left center;
-webkit-transform-origin:left center;
transform-origin:left center;
}
/*
unless the piece represents more than 50% of the whole chart.
then make it a square, and ensure the transform origin is
back in the center.
NOTE: since this is only ever a single piece, you could
move this to a piece specific rule and remove the extra class
*/
.pie.big {
width:200px;
height:200px;
left:50px;
-moz-transform-origin:center center;
-ms-transform-origin:center center;
-o-transform-origin:center center;
-webkit-transform-origin:center center;
transform-origin:center center;
}
/*
this is the actual visible part of the pie.
Give it the same dimensions as the regular piece.
Use border radius make it a half circle.
move transform origin to the middle of the right side.
Push it out to the left of the containing box.
*/
.pie:BEFORE {
content:"";
position:absolute;
width:100px;
height:200px;
left:-100px;
border-radius:100px 0 0 100px;
-moz-transform-origin:right center;
-ms-transform-origin:right center;
-o-transform-origin:right center;
-webkit-transform-origin:right center;
transform-origin:right center;
}
/* if it's part of a big piece, bring it back into the square */
.pie.big:BEFORE {
left:0px;
}
/*
big pieces will also need a second semicircle, pointed in the
opposite direction to hide the first part behind.
*/
.pie.big:AFTER {
content:"";
position:absolute;
width:100px;
height:200px;
left:100px;
border-radius:0 100px 100px 0;
}
/*
add colour to each piece.
*/
.pie:nth-of-type(1):BEFORE,
.pie:nth-of-type(1):AFTER {
background-color:blue;
}
.pie:nth-of-type(2):AFTER,
.pie:nth-of-type(2):BEFORE {
background-color:green;
}
.pie:nth-of-type(3):AFTER,
.pie:nth-of-type(3):BEFORE {
background-color:red;
}
.pie:nth-of-type(4):AFTER,
.pie:nth-of-type(4):BEFORE {
background-color:orange;
}
/*
now rotate each piece based on their cumulative starting
position
*/
.pie[data-start="30"] {
-moz-transform: rotate(30deg); /* Firefox */
-ms-transform: rotate(30deg); /* IE */
-webkit-transform: rotate(30deg); /* Safari and Chrome */
-o-transform: rotate(30deg); /* Opera */
transform:rotate(30deg);
}
.pie[data-start="60"] {
-moz-transform: rotate(60deg); /* Firefox */
-ms-transform: rotate(60deg); /* IE */
-webkit-transform: rotate(60deg); /* Safari and Chrome */
-o-transform: rotate(60deg); /* Opera */
transform:rotate(60deg);
}
.pie[data-start="100"] {
-moz-transform: rotate(100deg); /* Firefox */
-ms-transform: rotate(100deg); /* IE */
-webkit-transform: rotate(100deg); /* Safari and Chrome */
-o-transform: rotate(100deg); /* Opera */
transform:rotate(100deg);
}
/*
and rotate the amount of the pie that's showing.
NOTE: add an extra degree to all but the final piece,
to fill in unsightly gaps.
*/
.pie[data-value="30"]:BEFORE {
-moz-transform: rotate(31deg); /* Firefox */
-ms-transform: rotate(31deg); /* IE */
-webkit-transform: rotate(31deg); /* Safari and Chrome */
-o-transform: rotate(31deg); /* Opera */
transform:rotate(31deg);
}
.pie[data-value="40"]:BEFORE {
-moz-transform: rotate(41deg); /* Firefox */
-ms-transform: rotate(41deg); /* IE */
-webkit-transform: rotate(41deg); /* Safari and Chrome */
-o-transform: rotate(41deg); /* Opera */
transform:rotate(41deg);
}
.pie[data-value="260"]:BEFORE {
-moz-transform: rotate(260deg); /* Firefox */
-ms-transform: rotate(260deg); /* IE */
-webkit-transform: rotate(260deg); /* Safari and Chrome */
-o-transform: rotate(260deg); /* Opera */
transform:rotate(260deg);
}
/*
NOTE: you could also apply custom classes (i.e. .s0 .v30)
but if the CSS3 attr() function proposal ever gets implemented,
then all the above custom piece rules could be replaced with
the following:
.pie[data-start] {
transform:rotate(attr(data-start,deg,0);
}
.pie[data-value]:BEFORE {
transform:rotate(attr(data-value,deg,0);
}
*/
<!--
for each piece of the pie chart create one div and give it
a data-value attribute that represents the amount (in degrees) that
represents its total visible portion, and a data-start attribute
that matches the amount rotation for the starting (the cumulative value amount of all the previous pieces).
-->
<div class="pie" data-start="0" data-value="30"></div>
<div class="pie highlight" data-start="30" data-value="30"></div>
<div class="pie" data-start="60" data-value="40"></div>
<div class="pie big" data-start="100" data-value="260"></div>
8条答案
按热度按时间k5ifujac1#
我看到一些人选择谷歌开发者工具,它非常难,它也使用JS,你只需要CSS。所以这里是最简单的方法,纯CSS,通过使用背景渐变。
lztngnrs2#
我发现this是最简单的纯CSS解决方案。
ryoqjall3#
天啊!你看过谷歌图表工具吗?
https://google-developers.appspot.com/chart/interactive/docs/gallery/piechart
这是愚蠢的容易实现,但我的问题是“外部API”的一部分。如果谷歌决定可以这一点或谷歌走了,再见图表!但至于美丽和其他图表的选择,谷歌图表是一个有点酷的发现。
70gysomp4#
据我所知,这在css3中是不可能的,但是新的html5
canvas
元素提供了你想要的一切,它可以很容易地通过javascript访问和使用,在here中可以找到一个关于基本用法的小教程。另一个关于stackoverflow的问题也是关于同一主题的,参见"HTML5 Canvas pie chart"(在关于使用画布元素的饼图的教程的第一个答案中有"Graphing Data in the HTML5 Canvas Element Part IV Simple Pie Charts")
ufj5ltwl5#
通常用纯css创建图表并不是最好的方法,使用画布或外部库会更好。
下面是一个饼图,没有使用外部库,使用html5画布(fiddle):
fiddle(基于this解决方案编写代码)
但是最好使用库来绘制图表。在
apex-charts
中有一个名为sparkline
的选项,它可以帮助您删除多余的东西,并绘制一个最小和干净的图表。下面是一个使用
apex-charts
库的干净的圆环图。(使用sparkline
选项删除额外的内容):See it on codepen
kpbpu0086#
我尝试了一些答案,但在我看来,这些答案太复杂,难以采用动态数据集。我不需要在图表中打印数据,所以我最终选择了最简单的解决方案:
它不需要css类,可以嵌入到任何html中,并且conic-gradient中的字符串可以很容易地从值列表中构造出来。
希望这将是有用的作为一个简单的方法来构造一个饼图。
mm9b1k5b7#
只使用HTML和CSS的最简单方法是使用以下代码:
只需在
div class='graph'
中添加一个新的div class='pie no-round'
,就可以添加任意多个切片。div饼图块中的--p属性将设置饼图块的大小,rotate属性将设置饼图块的起始点。例如,如果您想要一个包含两个切片的图表,一个切片占60%,另一个切片占40%,则第一个切片的值为
--p:60
,第二个切片的值为:--p:40;rotate:0.60turn
.如果需要3个切片(50%、40%、10%),则必须对前2个值求和,以便为第三个切片设置正确的旋转属性,结果如下所示:
第一个饼图:
--p:50
第二个饼图:--p:40;rotate:0.50turn
第三个饼图:--p:10;rotate:0.90turn # 0.90 being 50 + 40
你可以从那里定制,你可以像这样在每个切片里添加标签:
一个二个一个一个
如果需要,您可以添加一个中心标签,b如下所示:
wz3gfoph8#
我在CodePen上找到了这个解决方案。你可以改变数据属性中的值,这正是我一直在寻找的:
来源:https://codepen.io/AtomicNoggin/pen/fEish