0

I wrote some JavaScript code to generate Pie Charts for me, but when one Slice is bigger than half, the whole thing breaks. Using clip to make half-circles, it is not possible to display more than half, but I cannot understand, why the big part becomes smaller with white on either site.

I assume it would be easiest to change the code to recognize the biggest slice and jest make it a full circle in the bag of the others, but I really would prefer if there were another way.

image description

.pie_container {
  width: 500px;
  height: 500px;
  position: relative;
}

.inner-slice {
  position: absolute;
  width: 500px;
  height: 500px;
  border-radius: 50%;
  clip: rect(0px, 250px, 500px, 0px);
}

.outer-slice {
  position: absolute;
  width: 500px;
  height: 500px;
  border-radius: 50%;
  clip: rect(0px, 500px, 500px, 250px);
}
<div class="pie_container">
  <div class="outer-slice" style="transform: rotate(0deg);">
    <div class="inner-slice" style="background-color: blue;transform: rotate(40deg);"></div>
  </div>
  <div class="outer-slice" style="transform: rotate(40deg);">
    <div class="inner-slice" style="background-color: green;transform: rotate(40deg);"></div>
  </div>
  <div class="outer-slice" style="transform: rotate(80deg);">
    <div class="inner-slice" style="background-color: yellow;transform: rotate(40deg);"></div>
  </div>
  <div class="outer-slice" style="transform: rotate(120deg);">
    <div class="inner-slice" style="background-color: orange;transform: rotate(40deg);"></div>
  </div>
  <div class="outer-slice" style="transform: rotate(160deg);">
    <div class="inner-slice" style="background-color: red;transform: rotate(200deg);"></div>
  </div>
</div>
disinfor
  • 10,865
  • 2
  • 33
  • 44
Benito
  • 23
  • 2
  • 3
  • 9

2 Answers2

1

You could use a conic-gradient background image for the pie chart div instead.

This diagram enter image description here

was produced with CSS:

.pie_container {
  width: 500px;
  height: 500px;
  position: relative;
  border-radius: 50%;
  background-repeat: no-repeat no-repeat;
  background-size: 100% 100%;
  background-position: center center;
}

and a conic gradient background-image in the element itself:

<div class="pie_container" style="background-image: conic-gradient(blue, blue 40deg, green 40deg, green 80deg, yellow 80deg, yellow 120deg, orange 120deg, orange 160deg, red 160deg, red 360deg);">

No need for other elements.

.pie_container {
  width: 500px;
  height: 500px;
  position: relative;
  border-radius: 50%;
  background-repeat: no-repeat no-repeat;
  background-size: 100% 100%;
  background-position: center center;
}
<div class="pie_container" style="background-image: conic-gradient(blue, blue 40deg, green 40deg, green 80deg, yellow 80deg, yellow 120deg, orange 120deg, orange 160deg, red 160deg, red 360deg);"></div>
A Haworth
  • 30,908
  • 4
  • 11
  • 14
  • Using a gradient was my first approach as well. It does look good, but I thought about displaying the name of the slice on hover and that sort of shenanigans, therefore I need a solution with separate slices. – Benito May 01 '21 at 00:19
  • You could sense a mouseover or click on the pie chart and with a bit of calculation work out which segment it is in. – A Haworth May 01 '21 at 06:04
  • That sounds like the kind of additional work that I wanted to avoid. How would one go about and calculate the area that would be clickable with the curves and without overlap of the slices? – Benito May 03 '21 at 10:13
  • I've had a simpler thought! Put all your slices up as now when they are acute angled - the remaining slice doesn't have to exist at all, just have the background of the parent circle the right color and when that is clicked on (with a click that isn't seen by any of it's children) do whatever you would have done with the large sector. – A Haworth May 03 '21 at 11:19
0

I rewrote my code to give me points on a clip-path, as suggested in this answer to a different post: How to draw a circle sector in CSS?

I took the clip-path, made the background-color transparent and added a box-shadow to make it a ring peace instead of a pie slice.

.slice {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    position: absolute;
    background-color: transparent;
}
.slice:hover {
    transform: scale(1.1);
}
.ring {
    position: relative;
    width: 400px;
    height: 400px;
    margin: 25px;
}
.middleText {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    font-size: 18pt;
}
<div id="ring_diagram">
    <div class="ring">
        <span title="Data 1: 34 (52.31%)"><div class="slice slice1" style="box-shadow: red    0px 0px 0px 67px inset; clip-path: polygon(50% 50%, 50% 0%, 100% 0%, 100% 100%, 100% 100%, 100% 100%, 39.1633% 124.213%);"></div></span>
        <span title="Data 2: 26 (40%)">   <div class="slice slice2" style="box-shadow: blue   0px 0px 0px 67px inset; clip-path: polygon(50% 50%, 39.1633% 124.213%, 0% 100%, 0% 0%, 0% 0%, 0% 0%, 15.1458% -16.4092%);"></div></span>
        <span title="Data 3: 3 (4.62%)">  <div class="slice slice3" style="box-shadow: yellow 0px 0px 0px 67px inset; clip-path: polygon(50% 50%, 15.1458% -16.4092%, 35.5905% -23.6028%, 35.5905% -23.6028%, 35.5905% -23.6028%, 35.5905% -23.6028%, 35.5905% -23.6028%);"></div></span>
        <span title="Data 4: 2 (3.08%)">  <div class="slice slice4" style="box-shadow: green  0px 0px 0px 67px inset; clip-path: polygon(50% 50%, 35.5905% -23.6028%, 50% -25%, 50% -25%, 50% -25%, 50% -25%, 50% -25%);"></div></span>
        <div class="middleText"><h3>Text</h3>65</div>
    </div>
</div>
Benito
  • 23
  • 2
  • 3
  • 9