CSS实现渐变仪表盘的简单尝试

2023-05-16

在“CSS锥形渐变实现环形进度条”一章中,讲解了实现渐变进度条的一点思路,基于此思路,本章节尝试性的使用CSS实现一个简单的渐变仪表盘,给大家提供一些借鉴。实现角向渐变,不得不提一下conic-gradient属性,这个属性是实现角向渐变的关键;其次,数据可视化开发中,以图表的形式展示数据,这就离不开对数据进行处理,将对应的指标数据映射到图表上,也是可视化开发的一项重要工作;另外,图形的展示形式多种多样,高度还原设计师的设计稿,还需要我们对图形有一定的空间想象力。俗话说“条条大道通罗马”,针对设计图形来说,实现方式也有多种多样,只要能达到预期的效果,都是值的学习的。本章节实现效果如图

 实现本案例功能,难点在于绘制表盘的刻度线和数字刻度的定位,这里巧妙使用了CSS中transform中的相关知识点,基于旋转解决定位问题,表盘的渐变区域是基于conic-gradient进行数据计算而展示的,表盘指针同样是基于transform进行旋转实现的,下面有四分之一的空白区域是通过CSS中的clip-path属性裁剪而成。话说代码是原理的最好解释,这里结合vue,简单封装一个组件,贴一下具体实现逻辑

<template>
  <div class="dash-box" :style="styObj">
    <!-- 外边框 -->
    <div class="outer-border">
      <div class="inner-wrapper">
        <!-- 内边框 -->
        <div class="inner-border">
          <!-- 中间边框 -->
          <div class="center-box"></div>
        </div>
      </div>
    </div>
    <!-- 中间白圆点 -->
    <div class="center-dot"></div>
    <!-- 中间指针 -->
    <div class="center-pointer-wrapper">
      <div class="center-pointer"></div>
    </div>
    <!-- 刻度线及刻度数字 -->
    <div class="line-tick line-tick1">
      <div class="tick"></div>
      <div class="num">0</div>
    </div>
    <div class="line-tick line-tick2">
      <div class="tick"></div>
      <div class="num">20</div>
    </div>
    <div class="line-tick line-tick3">
      <div class="tick"></div>
      <div class="num">40</div>
    </div>
    <div class="line-tick line-tick4">
      <div class="tick"></div>
      <div class="num">60</div>
    </div>
    <div class="line-tick line-tick5">
      <div class="tick"></div>
      <div class="num">80</div>
    </div>
    <div class="line-tick line-tick6">
      <div class="tick"></div>
      <div class="num">100</div>
    </div>
    <div class="slot-content">
      <slot></slot>
    </div>
  </div>
</template>
<script>
export default {
  name: "DashBoardDemo",
  props: {
    rate: {
      default: 0,
    },
  },
  computed: {
    styObj() {
      let rotateDeg = "";
      let conicDeg = "";
      if (this.rate <= 0) {
        rotateDeg = "rotate(0deg)";
        conicDeg = "0%";
      } else if (this.rate > 100) {
        rotateDeg = "rotate(270deg)";
        conicDeg = "0%";
      } else {
        rotateDeg = `rotate(${(this.rate / 100) * 270}deg)`;
        conicDeg = `${(this.rate / 100) * (270 / 360) * 100}%`;
      }
      return {
        "--pointer-rotate": rotateDeg,
        "--background-wrapper": `conic-gradient(#1c9df8 0%, #1c9df8 ${conicDeg}, transparent ${conicDeg})`,
        "--background-inner": `conic-gradient(#073358 0%, #12a2ff ${conicDeg}, transparent ${conicDeg})`,
      };
    },
  },
};
</script>
<style scoped>
.dash-box {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
.outer-border {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 80%;
  height: 80%;
  border-radius: 50%;
  border: 2px solid #178be2;
  clip-path: polygon(50% 50%, 0 100%, 0 0, 100% 0, 100% 100%);
}
.inner-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 90%;
  height: 90%;
  border-radius: 50%;
  background-image: var(--background-wrapper);
  transform: rotate(-135deg);
}
.inner-border {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 90%;
  height: 90%;
  border-radius: 50%;
  background-image: var(--background-inner);
}

.center-box {
  position: relative;
  width: 35%;
  height: 35%;
  background: #091629;
  border-radius: 50%;
}
.center-box::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 80%;
  height: 80%;
  border: 2px solid #188ff3;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.center-dot {
  position: absolute;
  width: 16px;
  height: 16px;
  left: 50%;
  top: 50%;
  background: #fff;
  transform: translate(-50%, -50%);
  border-radius: 50%;
}
.center-pointer-wrapper {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 60%;
  height: 4px;
  transform: translate(-50%, -50%) rotate(-45deg);
}
.center-pointer {
  width: 50%;
  height: 100%;
  background: #fff;
  clip-path: polygon(0% 50%, 100% 0%, 100% 100%);
  transform-origin: right center;
  transform: var(--pointer-rotate);
}
.line-tick {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 80%;
  height: 2px;
}
.tick {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 8px;
  background: #5b6376;
}
.num {
  position: absolute;
  width: 30px;
  left: -32px;
  top: 50%;
  text-align: center;
  transform: translateY(-50%);
  color: #073a6f;
  font-size: 18px;
}
.line-tick1 {
  transform: translate(-50%, -50%) rotate(-45deg);
}
.line-tick2 {
  transform: translate(-50%, -50%) rotate(9deg);
}
.line-tick3 {
  transform: translate(-50%, -50%) rotate(63deg);
}
.line-tick4 {
  transform: translate(-50%, -50%) rotate(117deg);
}
.line-tick5 {
  transform: translate(-50%, -50%) rotate(171deg);
}
.line-tick6 {
  transform: translate(-50%, -50%) rotate(225deg);
}
.line-tick1 .num {
  transform: translateY(-50%) rotate(45deg);
}
.line-tick2 .num {
  transform: translateY(-50%) rotate(-10deg);
}
.line-tick3 .num {
  transform: translateY(-50%) rotate(-64deg);
}
.line-tick4 .num {
  transform: translateY(-50%) rotate(-115deg);
}
.line-tick5 .num {
  transform: translateY(-50%) rotate(-171deg);
}
.line-tick6 .num {
  transform: translateY(-50%) rotate(134deg);
}
.slot-content {
  position: absolute;
  bottom: 10%;
  left: 50%;
  transform: translateX(-50%);
}
</style>

相关实现方式,大家可以查阅源码,这里不做深入解释,贴一下组件的引用逻辑

<template>
  <div class="container">
    <div class="module-box">
      <demo :rate="rate">
        <span class="slot-text">{{ `${rate}%` }}</span>
      </demo>
    </div>
    <div class="module-box">
      <demo :rate="92.66">
        <span class="slot-text">{{ `${92.66}%` }}</span>
      </demo>
    </div>
  </div>
</template>
<script>
import Demo from "./demo.vue";
export default {
  name: "DashBoard",
  components: {
    Demo,
  },
  data() {
    return {
      rate: 85.56,
    };
  },
};
</script>
<style scoped>
.container {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  height: 100%;
  background: #091629;
}
.module-box {
  width: 320px;
  height: 320px;
}
.slot-text {
  color: #fff;
  font-size: 24px;
  font-weight: bold;
}
</style>

总之,使用CSS实现渐变仪表盘并不复杂,其实就是对常用的CSS属性进行了一个综合运用,对于CSS扎实的同学可以实现更加复杂和多样化的图表。这里不得不提一下,如果在图表的实现过程中使用了大量的dom结点,势必会影响页面的渲染速度和页面操作的流畅度,因此,大家可以根据实际情况,不同的场景,不同的技术选型。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CSS实现渐变仪表盘的简单尝试 的相关文章

随机推荐

  • VIO学习总结

    VIO xff08 visual inertial odometry xff09 即视觉惯性里程计 xff0c 有时也叫视觉惯性系统 xff08 VINS xff0c visual inertial system xff09 xff0c 是
  • 单应性(Homography)变换

    我们已经得到了像素坐标系和世界坐标系下的坐标映射关系 xff1a 其中 xff0c u v表示像素坐标系中的坐标 xff0c s表示尺度因子 xff0c fx fy u0 v0 xff08 由于制造误差产生的两个坐标轴偏斜参数 xff0c
  • senmantic slam mapping

    basicStructure hpp common h 定义一些常用的结构体 以及各种可能用到的头文件 xff0c 放在一起方便include 相机内参模型 增加了畸变参数 xff0c common headers h各种可能用到的头文件
  • Ubuntu 20.04 VNC 安装与设置

    原链接 VNC是一个远程桌面协议 按照本文的说明进行操作可以实现用VNC对Ubuntu 20 04进行远程控制 一般的VNC安装方式在主机没有插显示器的时候是无法使用的 下面的操作可以在主机有显示器和没有显示器时都能够正常工作 首先安装x1
  • opencv中类型转换问题

    记录一下最近困惑我的问题 方便以后查阅 在学习立体匹配算法中BM算法时 xff0c 出现在了关于类型转换的问题 xff1a disp convertTo disp8u CV 8U 255 numberOfDisparities 16 不知道
  • 最大似然估计MLE与贝叶斯估计

    最大似然估计 Maximum Likehood Estimation MLE 最大似然估计的核心思想是 xff1a 找到参数 的一个估计值 xff0c 使得当前样本出现的可能性最大 用当年博主老板的一句话来说就是 xff1a 谁大像谁 xf
  • 大疆Livox_mid 40雷达初体验

    为了解决无人车上镭神雷达FOV小而导致的车前3m内无法看到锥形桶问题 东家给公司邮寄了一台大疆的mid40雷达 不得不说 颜值真的高 光看颜值 就甩镭神几条街 昨天重新配置镭神的激光雷达 官方给的配置软件 真的是 用的我心碎啊 算了 不提了
  • 地铁供电系统的构成

    地铁供电系统一般划分为以下几部分 xff1a 外部电源 xff1b 主变电所 xff1b 牵引供电系统 xff1b 动力照明系统和杂散电流腐蚀防护系统 xff1b 电力监控系统 外部电源地铁供电系统的外部电源就是地铁供电系统主变电所供电的外
  • C++ Vector常用函数

    C 43 43 Vector常用函数 begin 函数 原型 xff1a iterator begin const iterator begin 功能 xff1a 返回一个当前vector容器中起始元素的迭代器 end 函数 原型 xff1
  • STM32使用ADC获取内部温度传感器数据输出(直接读取/DMA两种方式实现)

    STM32使用ADC获取内部温度传感器数据输出 xff08 直接读取 DMA两种方式实现 xff09 前言一 内部温度传感器的使用 xff1f 二 代码操作讲解1 直接读取2 DMA处理 总结 前言 STM32F1系列 xff08 本代码基
  • fp32/fp64精度,4/8字节16进制转float/double十进制

    1 IEEE 754 32位单精度浮点数 xff08 4字节 xff09 1 1 32位单精度浮点数 其中 xff0c 32位16进制数包括1位符号位 SIGN xff0c 8位指数位 EXPONENT 和 23位尾数位 MANTISSA
  • SVG绘制圆环进度条

    在我们的大屏可视化项目中 xff0c 经常会用到各种各样的图表 与传统的表格展示 枯燥的文字阐述相比 xff0c 图表展示则使用户看起来更加直观 数据的展示则更加一目了然 本文基于svg绘图技术结合前端技术栈vue xff0c 以工作中常用
  • Canvas绘制地图

    在我们的大屏可视化项目中 xff0c 地图数据可视化是最常见功能 地图数据可视化目前的实现方案有很多 xff0c 其中最具有代表性的莫过于使用echarts xff0c 引入一个js文件 xff0c 再加上一些简单的配置 xff0c 这样一
  • 滚动动画(跑马灯动画)的几种实现方式

    在大屏可视化应用中 xff0c 滚动动效 xff08 跑马灯效果 xff09 也是常见的一种数据展现方式 xff0c 本章节针对字幕滚动和列表滚动效果做一个小小的总结 xff0c 结合vue框架 xff0c 具体展示效果如下 xff0c 从
  • 如何在Ubuntu上安装CUDA

    原链接 在Ubuntu上安装CUDA一直是比较麻烦的事情 由于不同版本的CUDA对显卡驱动有着不同的需求 而在有些电脑上安装最新的Nvidia闭源显卡驱动会导致无法进入图形界面 CUDA中也自带了Nvidia的显卡驱动 xff0c 但是如果
  • 加载loading动画

    提起加载 xff08 loading xff09 效果 xff0c 想必大家都不会陌生 xff0c 在目前的移动端 PC端 各类app均广泛使用 xff0c 使用loading动画能显著提升用户的交互体检 xff0c 尤其是在页面加载速度比
  • CSS锥形渐变实现环形进度条

    10月份因为疫情原因 又开启了居家办公模式 xff0c 空闲之余 xff0c 与其选择 躺平 xff0c 不如去做一些有意义的事情 xff0c 内心的想法驱使着我去做些什么 xff0c 但是又没有合适的素材 xff0c 直到接手了最近的一个
  • CSS实现个性化水球图

    在可视化应用中 xff0c 水球图也是一种常见的数据展示形式 xff0c 关于使用CSS实现个性化水球 xff0c 在相当长的一段时间并没有找到比较简洁的实现方式 xff0c 因此在以往的可视化作品中 xff0c 大多采用echarts插件
  • CSS实现3D球面字符云

    在大屏可视化应用中 xff0c 使用3D的场景有很多 xff0c 复杂的交互动画通常是使用Three js或echarts gl来实现 xff0c 但是在一些简单的3D场景中 xff0c CSS也可以实现一些不错的展示效果 本文使用CSS相
  • CSS实现渐变仪表盘的简单尝试

    在 CSS锥形渐变实现环形进度条 一章中 xff0c 讲解了实现渐变进度条的一点思路 xff0c 基于此思路 xff0c 本章节尝试性的使用CSS实现一个简单的渐变仪表盘 xff0c 给大家提供一些借鉴 实现角向渐变 xff0c 不得不提一