CSS Only饼图-如何在切片之间添加间距/填充?

时间:2019-06-27 18:44:45

标签: css pie-chart css-shapes

我已经建立了一个仅CSS的饼图,但是我需要在每个切片之间添加空间,就好像它是一个边框一样。我试图为每个切片添加边框,但这实际上不起作用。

关于如何使此CSS饼形图看起来更像下图的任何想法?

enter image description here

这是我的代码:

.palette {
  height: 48px;
  width: 48px;
}
.palette .colorOuter1,
.palette .colorOuter2,
.palette .colorOuter3,
.palette .colorOuter4,
.palette .colorOuter5 {
  height: 200px;
  width: 200px;
  border-radius: 50%;
  position: absolute;
  top: 0;
  left: 0;
  clip: rect(0px, 200px, 200px, 100px);
}
.palette .colorOuter1 {
  clip: auto;
  background: #eee;
}
.palette .colorOuter2 {
  transform: rotate(0deg);
}
.palette .colorOuter2 {
  transform: rotate(72deg);
}
.palette .colorOuter3 {
  transform: rotate(144deg);
}
.palette .colorOuter4 {
  transform: rotate(216deg);
}
.palette .colorOuter5 {
  transform: rotate(288deg);
}
.palette .colorInner1,
.palette .colorInner2,
.palette .colorInner3,
.palette .colorInner4,
.palette .colorInner5 {
  position: absolute;
  top: 0;
  left: 0;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  transform: rotate(72deg);
}
.palette .colorInner1 {
  background: #5D5E63;
  clip: rect(0px, 100px, 200px, 0px);
}
.palette .colorInner2 {
  background-color: #AEADA9;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner3 {
  background-color: #D5C4A8;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner4 {
  background-color: #AA875F;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner5 {
  background-color: #B7CBC7;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .centerOverlay {
  position: absolute;
  border-radius: 50%;
  top: 60px;
  left: 60px;
  background: #fff;
  width: 80px;
  height: 80px;
  display: block;
  clip: auto;
}
<div class="palette">
  <div class="colorOuter1">
    <div class="colorInner1"></div>
  </div>
  <div class="colorOuter2">
    <div class="colorInner2"></div>
  </div>
  <div class="colorOuter3">
    <div class="colorInner3"></div>
  </div>
  <div class="colorOuter4">
    <div class="colorInner4"></div>
  </div>
  <div class="colorOuter5">
    <div class="colorInner5"></div>
  </div>
  <div class="centerOverlay"></div>
</div>

2 个答案:

答案 0 :(得分:3)

通过CSS旋转和剪切来实现饼图的方式使您无法真正知道“边界”实际上在哪里,而且我认为您不能使用BaseControllerborder在这里有很多帮助(也许clip-path和多边形,对我来说太难了!)

您可以在clip-path内放置更多divs以充当更多的剪切蒙版,然后对其进行定位,以使其中点位于精确的中心,旋转和平移(并非完全有趣,但)。我在这里做了两个例子:

.centerOverlay
.palette {
  height: 48px;
  width: 48px;
  position:relative;
}
.palette .colorOuter1,
.palette .colorOuter2,
.palette .colorOuter3,
.palette .colorOuter4,
.palette .colorOuter5 {
  height: 200px;
  width: 200px;
  border-radius: 50%;
  position: absolute;
  top: 0;
  left: 0;
  clip: rect(0px, 200px, 200px, 100px);
}
.palette .colorOuter1 {
  clip: auto;
  background: #eee;
}
.palette .colorOuter2 {
  transform: rotate(0deg);
}
.palette .colorOuter2 {
  transform: rotate(72deg);
}
.palette .colorOuter3 {
  transform: rotate(144deg);
}
.palette .colorOuter4 {
  transform: rotate(216deg);
}
.palette .colorOuter5 {
  transform: rotate(288deg);
}
.palette .colorInner1,
.palette .colorInner2,
.palette .colorInner3,
.palette .colorInner4,
.palette .colorInner5 {
  position: absolute;
  top: 0;
  left: 0;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  transform: rotate(72deg);
}
.palette .colorInner1 {
  background: #5D5E63;
  clip: rect(0px, 100px, 200px, 0px);
}
.palette .colorInner2 {
  background-color: #AEADA9;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner3 {
  background-color: #D5C4A8;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner4 {
  background-color: #AA875F;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .colorInner5 {
  background-color: #B7CBC7;
  clip: rect(0px, 100px, 100px, 0px);
}
.palette .centerOverlay {
  position: absolute;
  border-radius: 50%;
  top: 60px;
  left: 60px;
  background: #fff;
  width: 80px;
  height: 80px;
  display: block;
  clip: auto;
}
.palette .north {
  position:absolute;
  top: -60px;
  left: 50%;
  background-color:white;
  width:4px;
  height:100px;

}
.palette .northeast {
  position:absolute;
  top: -10px;
  left: 50%;
  background-color:white;
  width:4px;
  height:100px;
  transform: rotate(72deg) translate(0px, -50px)

}

答案 1 :(得分:3)

首先,我将以更少的代码依赖clip-path来重新创建它,如下所示:

.palette {
  height: 200px;
  width: 200px;
  position:relative;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:50px solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(50% 50%, 50% 0%, 100% 0%,100% 33.745%); 
}
.color1 {
  transform:rotate(72deg);
  --c:blue;
}
.color2 {
  transform:rotate(144deg);
  --c:orange;
}
.color3 {
  transform:rotate(-72deg);
  --c:green;
}
.color4 {
  transform:rotate(-144deg);
  --c:purple;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

然后,您可以对元素进行翻译以创建空白:

.palette {
  height: 200px;
  width: 200px;
  position:relative;
  margin:20px;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:50px solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(50% 50%, 50% 0%, 100% 0%,100% 33.745%); 
}
.color1 {
  transform:rotate(72deg) translate(5px,-5px);
  --c:blue;
}
.color2 {
  transform:rotate(144deg) translate(5px,-5px);
  --c:orange;
}
.color3 {
  transform:rotate(-72deg) translate(5px,-5px);
  --c:green;
}
.color4 {
  transform:rotate(-144deg) translate(5px,-5px);
  --c:purple;
}
.color5 {
  transform:rotate(0) translate(5px,-5px);
  --c:red;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

或者,如果要创建缺失部分的效果以保持圆形(如屏幕截图所示),则必须调整剪切路径

.palette {
  height: 200px;
  width: 200px;
  position:relative;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:50px solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + 5px) 50%, 
    calc(50% + 5px) 0%, 
    100% 0%,
    100% calc(33.745% - 5px),
    50% calc(50% - 5px)); 
}
.color1 {
  transform:rotate(72deg);
  --c:blue;
}
.color2 {
  transform:rotate(144deg);
  --c:orange;
}
.color3 {
  transform:rotate(-72deg);
  --c:green;
}
.color4 {
  transform:rotate(-144deg);
  --c:purple;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

借助CSS变量,我们可以轻松处理所有事情

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,
    100% calc(33.745% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
}
.color1 {
  transform:rotate(72deg);
  --c:blue;
}
.color2 {
  transform:rotate(144deg);
  --c:orange;
}
.color3 {
  transform:rotate(-72deg);
  --c:green;
}
.color4 {
  transform:rotate(-144deg);
  --c:purple;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
</div>

CSS pie chart

使用相同的代码,您可以轻松缩放到任意数量的切片:

有8片:

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,
    100% calc(0% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
}
.color1 {
  transform:rotate(45deg); /* 360/8 */
  --c:blue;
}
.color2 {
  transform:rotate(90deg);
  --c:orange;
}
.color3 {
  transform:rotate(135deg);
  --c:green;
}
.color4 {
  transform:rotate(180deg);
  --c:purple;
}
.color5 {
  transform:rotate(-45deg); /* 360/8 */
  --c:orange;
}
.color6 {
  transform:rotate(-90deg);
  --c:lightblue;
}
.color7 {
  transform:rotate(-135deg);
  --c:pink;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
</div>

CSS pie chart - 8 slices

一分为三:

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    100% 0%,
    100% calc(78.665% - var(--g)/2),
    50% calc(50% - var(--g)/2)); 
}
.color1 {
  transform:rotate(120deg);
  --c:blue;
}
.color2 {
  transform:rotate(-120deg);
  --c:orange;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
</div>

CSS pie chart - 3 slices


以下是clip-path中使用的魔术数字背后的公式:

  • 5片:33.75% = 50% - tan(90deg - 72deg)*50%
  • 8片:0% = 50% - tan(90deg - 45deg)*50%
  • 3片:78.665% = 50% - tan(90deg - 120deg)*50%

因此,N个切片的通用公式为50%*(1 - tan(90deg - 360deg/N)) with N in [3 8]。如果N < 3的琐碎情况,我们不需要复杂的代码。对于N > 8,我们需要一个不同的clip-path和一个不同的公式:50%*(1 + tan(360deg/N))

具有10个切片的示例:

.palette {
  --g:10px; /* The gap between shapes*/
  --s:50px; /* the size*/

  height: 200px;
  width: 200px;
  position:relative;
  display:inline-block;
  overflow:hidden;
}
.palette > * {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  border:var(--s) solid var(--c,red);
  border-radius:50%;
  clip-path:polygon(
    calc(50% + var(--g)/2) 50%, 
    calc(50% + var(--g)/2) 0%, 
    calc(86.327% - var(--g)/2) 0%,
    50% calc(50% - var(--g)/2)); 
}
.color1 {
  transform:rotate(36deg);
  --c:blue;
}
.color2 {
  transform:rotate(72deg);
  --c:orange;
}
.color3 {
  transform:rotate(108deg);
  --c:green;
}
.color4 {
  transform:rotate(144deg);
  --c:purple;
}
.color5 {
  transform:rotate(180deg);
  --c:lightblue;
}
.color6 {
  transform:rotate(-36deg);
  --c:silver;
}
.color7 {
  transform:rotate(-72deg);
  --c:black;
}
.color8 {
  transform:rotate(-108deg);
  --c:darkgreen;
}
.color9 {
  transform:rotate(-144deg);
  --c:pink;
}
<div class="palette">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

<div class="palette" style="--s:40px;--g:20px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

<div class="palette" style="--s:60px;--g:0px">
  <div class="color1"></div>
  <div class="color2"></div>
  <div class="color3"></div>
  <div class="color4"></div>
  <div class="color5"></div>
  <div class="color6"></div>
  <div class="color7"></div>
  <div class="color8"></div>
  <div class="color9"></div>
  <div class="color10"></div>
</div>

CSS pie chart - 10 slices