• css实现双色饼图


    from:wx--前端早读课

    首先回想用css画三角形的方法:

    <div class="triangle"></div>
    .triangle {
      display: inline-block;
      border: 40px solid;
      border-color: red transparent transparent transparent;
    }

    得到一个斜边长为40px的三角形,如图所示:

     然后,我们用css的方式画一个1/4圆

    <div class="pie"></div>
    .pie {
      width: 0;
      height: 0;
      border-radius: 50%;
      border: 75px solid;
      border-color: #3c9 red #39c yellow;
    }

    得到图形如下:

     旋转45°后,

    .pie {
      width: 0;
      height: 0;
      border-radius: 50%;
      border: 75px solid;
      border-color: #3c9 red #39c yellow;
      transform: rotate(45deg);
    }

     在上述思路的基本上,进行给定比例的饼图绘制,思路如下:

    • 进行两个饼图图层的叠加;

    • 初始状态下,我们将这张饼图的右半边(即,上、右边框)的颜色设置为蓝色;左半边(即,下、左边框)的颜色设置为透明色。这样初始情况下,.pie元素右半边绿色的部分,被这一叠加层覆盖为蓝色,从视觉上看.pie元素此时的进度是0;

    • 根据需求,以不同角度旋转这个叠加层,这样就实现了不同百分比的饼图。

    首先,叠加的饼图可以用伪元素来实现:

    .pie {
      position: relative;
      width: 0;
      height: 0;
      border-radius: 50%;
      border: 75px solid;
      border-color: #3c9 #3c9 #39c #39c;
      transform: rotate(45deg);
      &::after {
        content: "";
        position: absolute;
        border-radius: 50%;
        border:75px solid;
        border-color: @base-color @base-color  transparent transparent;
      }
    }

     在上图的基础上平移,使两个图层重合。

    .pie {
      position: relative;
      width: 0;
      height: 0;
      border-radius: 50%;
      border: 75px solid;
      border-color: #3c9 #3c9 #39c #39c;
      transform: rotate(45deg);
      &::after {
        content: "";
        position: absolute;
        transform: translate(-50%, -50%); // 因为.pie元素的width和height都是0,所以content-box的左上角正好是.pie的中心点
        border-radius: 50%;
        border:75px solid;
        border-color: @base-color @base-color  transparent transparent;
      }
    }

    此时通过将伪元素旋转一个角度,比如转过10%,即可实现饼图效果。只要在伪元素的tranform属性上增加一个rotate,并让它的值等于0.1turn。

    .pie {
      position: relative;
      width: 0;
      height: 0;
      border-radius: 50%;
      border: 75px solid;
      border-color: #3c9 #3c9 #39c #39c;
      transform: rotate(45deg);
      &::after {
        content: "";
        position: absolute;
        transform: translate(-50%, -50%) rotate(0.1turn); // 在tranform属性上增加一个rotate,并让它的值等于0.1turn
        border-radius: 50%;
        border:75px solid;
        border-color: @base-color @base-color  transparent transparent;
      }
    }

     现在可以实现饼图比例为0~50%的范围。对于比例大于50%的,如果直接将伪元素旋转到0.6trun(也就是旋转了60%),这时饼图变成下面这个样子:

    要解决这个问题,我们需要调整伪元素的左右两半圆的颜色配置。将原来是蓝色的上、右边框设置为透明色,将原来是透明色的下、左边框设置为绿色,就能解决超过上面的问题。

     给超过50%进度的饼图元素定义为.pie2。在这个选择器里,我们将伪元素的上、右边框颜色设置为透明色,将下、左边框的颜色设置为绿色。

    @base: {
      border-color:  @base-color @base-color transparent transparent;
    }
    @base2: {
      border-color: transparent transparent @part-color @part-color;
    }
    // 声明mixin
    .pie(@rotate) {
      position: relative;
      width: 0;
      height: 0;
      border-radius: 50%;
      border: 75px solid;
      border-color: @part-color @part-color @base-color @base-color;
      transform: rotate(45deg);
      &::after {
        content: "";
        position: absolute;
        transform: translate(-50%, -50%) rotate(@rotate); // 相对位置(0,0)则在元素内容区(content-box)的左上角。因为.pie元素的width和height都是0,所以content-box的左上角正好是.pie的中心点
        border-radius: 50%;
        border: 75px solid;
      }
    }
    .pie {
      .pie(0.3turn);
      &::after {
        @base();
      }
    }
    
    .pie2 {
      .pie(0.6turn);
      &::after {
        @base2();
      }
    }

    在饼图上显示比例:

        <div class="pie1"><span class="on-pie">0.3</span></div>
        <div class="pie2"><span class="on-pie">0.6</span></div>
    .on-pie {
      position: absolute;
      transform: rotate(-45deg);
      z-index:1;
    }

    截至目前,实现了双色饼图,但仍存在以下问题:

    • 通常情况下,我们的统计数据都是来自服务器,是动态而不是静态的,所以饼图的进度比例是需要动态绑定而不是写死在CSS中。(伪元素并不好用JS操作,也不能被inline-css控制)
    • 我们只能显示双色饼图,如果要显示更多颜色,甚至任意多颜色的饼图,该如何做呢?
  • 相关阅读:
    2018.6.8 现代企业管理复习总结
    写时复制
    字符串类示例
    信号量示例
    对象赋值的语义
    对象复制的语义
    无用单元和悬挂引用
    初始化
    静态数据成员,静态成员函数
    同时找出最大数和最小数
  • 原文地址:https://www.cnblogs.com/ceceliahappycoding/p/12758746.html
Copyright © 2020-2023  润新知