Make pie charts with CSS and SVG_html/css_WEB-ITnose
WBOYOriginal
2016-06-24 11:38:541062browse
Original source: lulux’s blog Welcome to share the original to Bole Headlines
When it comes to CSS technology, no one is more persistent than Lea Verou, but smart enough to work hard. Find various solutions to problems. Recently, Lea wrote, designed and published a book - CSS Secrets. This book is very interesting and includes some CSS tips and techniques for solving common problems. If you think your CSS skills are pretty good, read this book and you will be surprised. In this post, we post some snippets from the book, which were also featured in Lea’s recent talk at SmashingConf New York: Designing a Simple Pie Chart with CSS. Note that some demos may not run properly due to limited browser support. ??Edit
Pie chart , even the simplest form with only two colors is not simple to create using Web technology, although they are all common information content, ranging from simple Statistics include progress bar indicators and timers. This is usually achieved by using an external image editor to create multiple images for multiple values, or using a large JavaScript framework to design more complex charts.
Although this is not as difficult to achieve as it once seemed, there is no direct and easy way. However, there are better, more maintainable ways to do it.
Transform-based solution
This solution is the best from an HTML perspective: it only requires one element, and everything else can be done using pseudo-elements, transforms, and CSS gradients. We start with this simple element:
1
1
Now, let’s say we want to display a 20% scale pie chart. We will solve the issue of flexibility later. We first add a style to the element to make it a circle, which is our background:
Figure 1: The first step is to draw a circle (or to display 0 % scale pie chart)
Our pie chart shows percentages in green (specifically yellowgreen ) and brown ( #655 ). You might try using skew in transform for the proportional part, but after a few experiments it turns out that this is a very confusing solution. So we color the left and right parts of this pie chart with these two colors, and then for the percentage we want, we use a rotated pseudo-element to achieve that. We use a simple linear gradient to color the right half brown: CSS
Picture 2: Use a simple linear gradient to color the right semicircle brown
As shown in Figure 2, you are done. Now, we can go ahead and add styles to the pseudo-element to make it a mask:
CSS
1
2
3
4
5
6
.pie::before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
}
1
2
3
4
5
6
.pie:: before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
}
Figure 3: The content within the dotted line indicates that the pseudo element will be used as a mask Area of version
You can see in Figure 3 that our pseudo-element is currently positioned relative to our pie element. Currently, it's not styled and doesn't cover anything, it's just a transparent rectangle. Before we start adding styles, let's analyze it first:
1
2
3
4
5
6
7
8
9
.pie::before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
}
Because we want it to cover the brown part of the circle, we need to apply a green background to it, using background-color: inherit to avoid repeated definitions, because We originally wanted it to be consistent with the background color of the parent element. We want it to rotate around the center point of the circle, which is on the left side of the pseudo element, so we need to apply a 0 50% to its transform-origin, or directly left. We don’t want it to be a rectangle, as it will extend past the edge of the pie, so we need to apply overflow: hidden to .pie , or a proper border-radius to make it a semicircle. To sum up, the CSS styles of pseudo-elements are as follows: CSS
Figure 4: Pseudo-element after adding style (indicated by dotted lines here)
Note: Do not use background: inherit; , use background-color : inherit ;, otherwise the gradient on the background image of the parent element will also be inherited
Our pie chart is currently as shown in Figure 4. Now the fun starts! We can start rotating the pseudo-element by applying a rotate() transform to it. To show a 20% scale, we could give it a 72deg (0.2 x 360 = 72), or .2turn, which is more readable. You can see the results for different rotation angle values in Figure 5.
Figure 5: Pie charts showing different percentages, from left to right: 10% ( 36deg or .1turn ), 20% ( 72deg or .2turn ), 40% ( 144deg or .4turn )
You might think we’re done, but it’s not that simple. Our pie chart has no problem displaying content from 0 to 50% size, but if we want to depict a 60% rotation (by applying .6turn ), the situation in Figure 6 will occur. But don't worry, we can fix this!
Figure 6: For proportions exceeding 50%, our pie chart falls flat (here it is 60%)
If we put 50%-100 % scale case As a separate question, it may be noted that one can use an inverted version of the previous solution: a brown pseudo-element rotated from 0 to .5turn. So, for a 60% pie chart, the CSS code for the pseudo-element is as follows:
You can see the results in Figure 7. Since we've developed a method that can plot any percentage, we can even animate the pie chart from 0% to 100%, creating a fun progress bar:
See the Pen zGbNLJ by Airen (@airen) on CodePen. There is no problem with the display, but what if we add styles to multiple static pie charts with different percentages? What is the most common use case? Ideally, we would like to be able to simply enter something like:
1 2
20%
60%
Then you can get two pie charts, one representing 20% and one representing 60%. First, let's study how to do it using inline styles. Then we can write a short script to parse the text content, add inline styles accordingly, and make the code elegant, encapsulated, maintainable, and most importantly One point, accessibility.
One difficulty with using inline styles to control pie chart percentages is that the CSS code for setting the percentages is done with pseudo-elements. And as you know, we can't style pseudo-elements inline, so we need to innovate.
Note: If the values you want to use are within a range that does not require repeated complex calculations, you can use the same techniques, including debugging the animation step by step through them. Look at a simple example of this technique.
See the Pen YXgNOK by Airen (@airen) on CodePen.
The solution comes from one of the unlikeliest of places. We're going to use the animation we've already introduced, but in a paused state. Instead of making it run like a normal animation, we're going to use negative delay so that it can statically pause at a certain point. Weird? A negative animation-delay value is not only allowed by the specification, but also very useful in cases like this:
Negative delays are valid. Similar to the delay of 0s, it means that the animation will be executed immediately, but it will run automatically based on the absolute value of the delay, so if the animation has started running before the specified time, it will run directly from the active time. . ?CSS Animations Level 1
Because our animation is paused, its first frame is the only one we show (defined by our animation-delay). The percentage shown on the pie chart will be the total time of our animation-delay. For example, the current duration is 6s, and our animation-delay value is -1.2s to display a percentage of 20%. To simplify calculations, we set a duration of 100s. Remember that because our animation is paused forever, the delay size we assign to it has no effect.
There is one last problem: the animation is assigned to the pseudo element, but we want to set the inline style for the .pie element. Since there is no animation on the
, we can set animation-delay to it as an inline style, and then apply animation-delay: inherit; to the pseudo-element. To sum up, the HTML codes for the 20% and 60% pie charts are as follows:
1
2
1 2
The CSS code for the animation just proposed is as follows (the .pie rule is omitted as there is no change):
CSS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@keyframes spin {
to { transform: rotate(.5turn); }
}
@keyframes bg {
50% { background: #655; }
}
.pie::before {
/* [Rest of styling stays the same] */
animation: spin 50s linear infinite, bg 100s step-end infinite;
At this time, you can Change the HTML tag to use percentages as content, as originally intended, and then add animation-delay inline styles to it through a simple script. JavaScript
1 2 3 4
$$('.pie').forEach(function(pie) { var p = parseFloat(pie.textContent); pie.style.animationDelay = '-' p 's'; });
Figure 8: Picture before hidden text
Convert the height of the pie chart to line-height (or add a line with the same height value -height, but this value is meaningless duplication of code, since line-height automatically calculates the value of height).
Set the size and position of the pseudo-element using absolute positioning so it doesn't crowd the text.
Add text-align: center; to center the text horizontally.
SVG makes a lot of graphics work It gets even simpler, and pie charts are no exception. However, creating a pie chart using a path requires complex mathematical calculations. We can use a little trick instead.
We start with a circle:
1
2
3
1
2
3
Now, apply some basic styles to it:
1
2
3
4
5
circle {
fill: yellowgreen;
stroke: #655;
stroke-width: 30;
}
CSS
1
2
3
4
5
circle {
fill: yellowgreen;
1
stroke-dasharray: 20 10;
stroke: #655;
stroke-width: 30;
}
Note: As you may know, these CSS properties can also be used as attributes on SVG elements, which may be convenient if portability is taken into consideration .
Figure 9: Starting with a green SVG circle with a fat #655 stroke
You can see what we drew in Figure 9 A stroked circle. SVG strokes have more than just stroke and stroke-width attributes. There are also a number of less popular stroke-related properties that can be used to fine-tune strokes. One of them is stroke-dasharray, which is used to create dashed strokes. For example, we can use the following:
1
stroke-dasharray: 0 189;
CSS
1
stroke-dasharray: 20 10;
Figure 10: A simple dashed stroke, Create through the stroke-dasharray attribute. What this line of code means is that our dashed line is a length of 20 plus a margin of 10, as shown in Figure 10. Here, you may be curious about what the relationship between this SVG stroke attribute and the pie chart is. It might be clearer if we applied a dash width of 0 to the stroke, and a margin greater than or equal to the circumference of our current circle (calculating the circumference: C = 2πr , so here C = 2π × 30 ≈ 189): CSS
1
stroke -dasharray: 0 189;
Figure 11: Effects corresponding to different stroke-dasharray values; from left to right: 0 189; 40 189; 95 189; 150 189
Such as As shown in the first circle in Figure 11, its stroke has been removed, leaving only a green circle. But when we start increasing the first value, something interesting happens (Figure 11): because the margin is too long, we don’t have a dashed stroke, just a stroke covering the circumference of the circle we specified. Percentage of length.
You may have started to figure out what's going on: if we reduce the radius of the circle to a certain point, it may become completely covered by its stroke, and end up with something very similar to Something about pie charts. For example, you can see in Figure 12: When applying a radius of 25 and a stroke-width of 50, it looks like this:
Figure 12: Our SVG The image starts to look like a pie chart O(∩_∩)O
Remember: SVG strokes are always half inside and half outside (centered) relative to the edge of the element. It should be possible to control this behavior in the future.
Now, it’s very easy to turn it into something like the pie chart we made in the previous solution: Just add a larger green circle below the stroke and rotate it 90° counterclockwise so that its starting point is in the top middle. Because the
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn