1

This is a pure CSS solution.

I have created a series of circles using pure CSS3, and am now trying to dynamically populate those areas with smaller circles, to create a pie chart-like appearance.

Here is an example of what I am trying to accomplish: enter image description here

Here is the relevant code for me making the large circles: https://jsfiddle.net/z6vt7r10/

#circle {
    position: relative;
    height: 150px;
    width: 150px;
    border-radius: 50%;
    display: block;
    background-color: rgba(112, 48, 160);
}

<div id="circle"></div>

Here is my attempt to populate with smaller circles: https://jsfiddle.net/z6vt7r10/1/

.bubble {
    position: relative;
    height: 25px;
    width: 25px;
    border-radius: 50%;
    display: block;
    /*display: inline;
    margin: 0; */  /*This doesn't work*/
    background-color: black;
    z-index: 99;
}

  <div class="circle" id="circle2">
    <span class="bubble"></span>
    <span class="bubble"></span>
    <span class="bubble"></span>
    <span class="bubble"></span>
    <span class="bubble"></span>
    <span class="bubble"></span>
    <span class="bubble"></span>
    <span class="bubble"></span>
  </div>

As you can see, it just spits out smaller circles but doesn't actually fill the div in the circle shape.

Any ideas on how I can accomplish this? I have tried using the Highcharts library to create a pie chart and then using the pattern fill addon to fill it with a polka-dot pattern, but that's not what I am trying to create. I am open to using some other library like chartjs or doing it via html5 canvas, but a pure css solution would be great, too.

Bad Programmer
  • 893
  • 1
  • 13
  • 27

1 Answers1

1

One approximation is to consider the use of shape-outside to contain the circles then a gradient as coloration.

Here is an idea based on this previous answer

div.box {
  --s: 9em; /*Size of the circle */
  text-align: center;
  height: var(--s);
  width: var(--s);
  border-radius: 50%;
  overflow: hidden;
  position: relative;
}

.box>div {
  height: 100%;
}

.box:before,
.box>div:before {
  content: '';
  float: left;
  height: 100%;
  width: 50%;
  shape-outside: radial-gradient(farthest-side at var(--d, right), transparent 99%, red 0);
}

.box>div:before {
  float: right;
  --d: left;
}

div.box {
  display: inline-block;
  vertical-align: middle;
  margin: 5px;
  font-size: 20px;
}

.box i {
  display: inline-block;
  vertical-align: top;
  border-radius: 50%;
  width: 1.12em;
  height: 1.12em;
  background: red;
}

.box::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: inherit;
  background: conic-gradient(from -90deg, transparent 0 70deg, #fff 71deg);
  mix-blend-mode: exclusion;
}
<div class="box" style="--s:17em;--p:15px">
  <div><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
</div>

<div class="box" style="--s:10em;">
  <div><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
</div>

To go further you can replace the gradient/mix-blend-mode coloration with a JS script that will select the cirle individually to correct them.

Here is a very basic example:

$('.box i').each(function() {
  var c = $(this).offset();
  var p = $(this).parent().offset();
  if((c.top - p.top) > ($(this).parent().height()/2) && (c.left - p.left)> ($(this).parent().width()/2)) {
    $(this).addClass('color')
  }
}); 
div.box {
  --s: 9em; /*Size of the circle */
  text-align: center;
  height: var(--s);
  width: var(--s);
  border-radius: 50%;
  overflow: hidden;
  position: relative;
}

.box>div {
  height: 100%;
}

.box:before,
.box>div:before {
  content: '';
  float: left;
  height: 100%;
  width: 50%;
  shape-outside: radial-gradient(farthest-side at var(--d, right), transparent 99%, red 0);
}

.box>div:before {
  float: right;
  --d: left;
}

div.box {
  display: inline-block;
  vertical-align: middle;
  margin: 5px;
  font-size: 20px;
}

.box i {
  display: inline-block;
  vertical-align: top;
  border-radius: 50%;
  width: 1.12em;
  height: 1.12em;
  background: red;
}
.box i.color {
  background:green;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box" style="--s:17em;--p:15px">
  <div><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
</div>

<div class="box" style="--s:10em;">
  <div><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
</div>

To make the circles a bit scrambled you can add some transformation like below:

$('.box i').each(function() {
  var c = $(this).offset();
  var p = $(this).parent().offset();
  if((c.top - p.top) > ($(this).parent().height()/2) && (c.left - p.left)> ($(this).parent().width()/2)) {
    $(this).addClass('color')
  }
});
div.box {
  --s: 9em; /*Size of the circle */
  text-align: center;
  height: var(--s);
  width: var(--s);
  border-radius: 50%;
  overflow: hidden;
  position: relative;
}

.box>div {
  height: 100%;
}

.box:before,
.box>div:before {
  content: '';
  float: left;
  height: 100%;
  width: 50%;
  shape-outside: radial-gradient(farthest-side at var(--d, right), transparent 99%, red 0);
}

.box>div:before {
  float: right;
  --d: left;
}

div.box {
  display: inline-block;
  vertical-align: middle;
  margin: 5px;
  font-size: 20px;
}

.box i {
  display: inline-block;
  vertical-align: top;
  border-radius: 50%;
  width: 1.12em;
  height: 1.12em;
  background: red;
}
.box i.color {
  background:green;
}

.box i:nth-child(3n + 1) {
  transform:translate(2px,-1px);
}
.box i:nth-child(3n + 2) {
  transform:translate(-2px,1px);
}
.box i:nth-child(3n + 3) {
  transform:translate(-1px,-2px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box" style="--s:17em;--p:15px">
  <div><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
</div>

<div class="box" style="--s:10em;">
  <div><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415