0

0

CSS如何制作环形统计图表?conic-gradient渐变应用

看不見的法師

看不見的法師

发布时间:2025-08-04 17:04:01

|

757人浏览过

|

来源于php中文网

原创

要使用conic-gradient制作环形统计图表,1. 首先创建一个正方形元素并设置border-radius: 50%使其变为圆形;2. 利用conic-gradient的色标(color stops)按百分比或角度定义每个数据段的起止范围,实现扇形分区;3. 通过累加百分比确保扇区连续,可结合css变量提升灵活性;4. 添加中心孔洞的方法包括:使用border属性形成实色孔洞、通过伪元素覆盖中心区域(推荐,灵活且兼容性好)、或使用mask-image配合radial-gradient实现透明孔洞;5. 动态数据可通过javascript计算各段百分比并更新css变量或直接设置background值;6. 可访问性方面需提供role="img"、aria-labelledby、aria-describedby等属性,并辅以隐藏的表格或文本描述数据内容,同时确保图例为可读文本。该方案实现了纯css驱动的环形图,兼具视觉效果与功能完整性。

CSS如何制作环形统计图表?conic-gradient渐变应用

conic-gradient
是CSS中一个非常强大的工具,它能让我们在不依赖SVG或Canvas的情况下,直接用CSS实现环形统计图表。它的核心在于能够创建沿着中心点旋转的颜色渐变,这完美契合了饼图或环形图的扇形结构,使得纯CSS绘制这类图表成为可能,而且通常代码量很小。

解决方案

要用

conic-gradient
制作环形统计图表,核心思路是利用其颜色停止点(color stops)来定义每个数据段的起始和结束角度。想象一下一个圆心,颜色从某个角度开始,沿着圆周顺时针或逆时针扩散,直到遇到下一个颜色停止点。

一个基础的环形图,比如一个饼图,通常需要一个正方形的容器,并将其

border-radius
设置为50%使其变成圆形。然后,关键就在于它的
background
属性:

立即学习前端免费学习笔记(深入)”;

.pie-chart {
    width: 200px;
    height: 200px;
    border-radius: 50%;
    /* 假设数据:A占30%,B占50%,C占20% */
    background: conic-gradient(
        #ff6347 0% 30%,    /* A: 从0%到30%(即0度到108度)是红色 */
        #4682b4 30% 80%,    /* B: 从30%到80%(即108度到288度)是蓝色 */
        #3cb371 80% 100%    /* C: 从80%到100%(即288度到360度)是绿色 */
    );
}

这里,

conic-gradient
的参数是颜色和角度范围。每个颜色后面可以跟两个百分比或角度值。第一个值是该颜色开始的角度,第二个是结束的角度。如果只给一个值,比如
#ff6347 30%
,那么它表示该颜色在30%处达到纯色,然后平滑过渡到下一个颜色。但对于统计图表,我们通常需要颜色之间有明确的界限,所以使用两个百分比(或角度)来定义一个实心的扇形区域。

默认情况下,

conic-gradient
从顶部中心(12点钟方向)开始,并顺时针绘制。如果你想改变起始位置,可以使用
from 
,例如
from 90deg
会从3点钟方向开始。如果你想改变中心点,可以使用
at  
,但对于标准的饼图,通常不需要修改。

如何精确控制
conic-gradient
的扇区比例和颜色?

精确控制扇区比例和颜色,是制作可信统计图的关键。我个人觉得,理解百分比和角度的换算,是玩转

conic-gradient
的第一步。一个完整的圆是360度,或者说是100%。所以,如果你有一个数据点占总量的X%,那么它对应的角度就是
X% * 3.6deg

conic-gradient
中,我们可以直接使用百分比来定义角度,这非常方便,因为数据通常就是以百分比形式存在的。

/* 假设我们有以下数据:
   - 产品A: 25%
   - 产品B: 40%
   - 产品C: 15%
   - 产品D: 20%
*/
.data-chart {
    width: 250px;
    height: 250px;
    border-radius: 50%;
    /* 可以使用CSS变量来动态控制,更灵活 */
    --pA: 25%;
    --pB: 40%;
    --pC: 15%;
    --pD: 20%;

    background: conic-gradient(
        #a8e6cf 0% var(--pA),                               /* A: 从0%到25% */
        #dcedc1 var(--pA) calc(var(--pA) + var(--pB)),      /* B: 从25%到25%+40%=65% */
        #ffd3b6 calc(var(--pA) + var(--pB)) calc(var(--pA) + var(--pB) + var(--pC)), /* C: 从65%到65%+15%=80% */
        #ffaaa5 calc(var(--pA) + var(--pB) + var(--pC)) 100% /* D: 从80%到100% */
    );
}

这里我用了CSS自定义属性(变量),这在处理动态数据时尤其有用。通过JavaScript改变这些变量的值,图表就能立即更新,无需重新渲染整个DOM。注意看,每个扇区的起始点都是前一个扇区的结束点。这种累加的方式确保了扇区之间紧密连接,不会出现缝隙。

颜色选择上,除了常见的十六进制或RGB值,你也可以使用

hsl()
hsla()
,它们在调整颜色饱和度和亮度时更直观,有时能帮助你快速找到和谐的配色方案。

conic-gradient
环形图中添加中心孔洞(甜甜圈效果)有哪些方法?

制作一个甜甜圈(donut)图,也就是在饼图中间挖个洞,有几种常见的CSS技巧。我个人比较喜欢用伪元素或

mask-image
,它们能提供更灵活的控制,但最直接的可能还是
border

  1. 利用

    border
    属性(最简单但限制多): 这是最直接粗暴的方式。给你的圆形容器添加一个足够粗的
    border
    ,并让
    border-color
    与背景色(或你想让孔洞呈现的颜色)相同。
    conic-gradient
    会填充元素的背景区域,而
    border
    则会覆盖在背景之上,形成一个环形。

    .donut-chart-border {
        width: 200px;
        height: 200px;
        border-radius: 50%;
        border: 40px solid #fff; /* 孔洞的颜色和大小 */
        background: conic-gradient(#ff6347 0% 30%, #4682b4 30% 80%, #3cb371 80% 100%);
        /* background-clip: padding-box; /* 确保渐变只在内容区域显示,但这里不加也行 */
    }

    缺点是孔洞的颜色必须是实色,且不能是透明的,因为它是边框色。

  2. 利用伪元素(常用且灵活): 这是我比较推荐的方法。在饼图容器内部创建一个伪元素(

    ::before
    ::after
    ),让它也成为一个圆形,并将其定位在容器的中心,颜色设置为你想要的孔洞色。

    .donut-chart-pseudo {
        position: relative; /* 为伪元素定位提供参考 */
        width: 200px;
        height: 200px;
        border-radius: 50%;
        background: conic-gradient(#ff6347 0% 30%, #4682b4 30% 80%, #3cb371 80% 100%);
    }
    
    .donut-chart-pseudo::before {
        content: '';
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%); /* 居中 */
        width: 100px; /* 孔洞大小 */
        height: 100px; /* 孔洞大小 */
        border-radius: 50%;
        background-color: #fff; /* 孔洞的颜色 */
        z-index: 1; /* 确保在渐变之上 */
    }

    这种方法的好处是孔洞颜色可以独立控制,甚至可以是透明的(如果背景是其他元素)。

    Cutout老照片上色
    Cutout老照片上色

    Cutout.Pro推出的黑白图片上色

    下载
  3. 利用

    mask-image
    (最强大但兼容性略差):
    mask-image
    属性允许你用一个图像(可以是渐变)来遮罩元素。我们可以创建一个
    radial-gradient
    来作为遮罩,中心是透明的,外部是不透明的。

    .donut-chart-mask {
        width: 200px;
        height: 200px;
        border-radius: 50%;
        background: conic-gradient(#ff6347 0% 30%, #4682b4 30% 80%, #3cb371 80% 100%);
        /* 遮罩:中心透明,外部不透明 */
        mask-image: radial-gradient(circle at center, transparent 0 30%, black 30% 100%);
        -webkit-mask-image: radial-gradient(circle at center, transparent 0 30%, black 30% 100%); /* 兼容性 */
    }

    这里的

    transparent 0 30%
    表示从中心到半径30%的地方是透明的,
    black 30% 100%
    表示从半径30%到100%的地方是黑色的(黑色表示显示,透明表示隐藏)。这种方法非常灵活,可以制作各种异形孔洞,但需要注意浏览器兼容性。

综合来看,伪元素的方法在灵活性和兼容性之间找到了一个很好的平衡点。

如何处理
conic-gradient
环形图的动态数据和可访问性?

用CSS制作的图表,最大的挑战之一就是如何处理动态数据和确保可访问性。毕竟,CSS只是负责渲染,数据逻辑和语义化需要额外处理。

动态数据处理:

对于动态数据,我通常会倾向于使用JavaScript来计算和更新CSS自定义属性。这样,我们就能在不直接操作样式表规则的情况下,灵活地改变图表的呈现。

  1. 数据计算: 假设你从后端获取了一组数据,比如

    [{ label: '销售', value: 30 }, { label: '市场', value: 50 }, { label: '研发', value: 20 }]
    。 首先,你需要计算总和,然后计算每个部分的百分比,并累加得到每个扇区的结束百分比。

    const data = [
        { label: '销售', value: 30, color: '#ff6347' },
        { label: '市场', value: 50, color: '#4682b4' },
        { label: '研发', value: 20, color: '#3cb371' }
    ];
    
    const total = data.reduce((sum, item) => sum + item.value, 0);
    let currentPercentage = 0;
    const gradientSegments = data.map(item => {
        const percentage = (item.value / total) * 100;
        const start = currentPercentage;
        const end = currentPercentage + percentage;
        currentPercentage = end;
        return `${item.color} ${start}% ${end}%`;
    }).join(', ');
    
    const chartElement = document.querySelector('.dynamic-chart');
    chartElement.style.background = `conic-gradient(${gradientSegments})`;
  2. 更新CSS自定义属性: 如果你的图表结构比较固定,只是数据比例变化,用CSS变量会更优雅。

    // HTML: 
    // CSS: background: conic-gradient(var(--c1) 0% var(--p1), var(--c2) var(--p1) var(--p2), var(--c3) var(--p2) var(--p3)); const data = [ /* 同上 */ ]; const total = data.reduce((sum, item) => sum + item.value, 0); let accumulatedPercentage = 0; const chartElement = document.querySelector('.dynamic-chart'); let gradientString = ''; data.forEach((item, index) => { const percentage = (item.value / total) * 100; const start = accumulatedPercentage; const end = accumulatedPercentage + percentage; gradientString += `${item.color} ${start}% ${end}%${index < data.length - 1 ? ',' : ''}`; accumulatedPercentage = end; }); chartElement.style.background = `conic-gradient(${gradientString})`;

    这种方式避免了直接操作复杂的

    conic-gradient
    字符串,而是通过变量间接控制。当然,直接拼接字符串也是完全可行的,取决于你的偏好和项目的复杂性。

可访问性处理:

纯CSS的图表对屏幕阅读器来说是“不可见”的。它只是视觉上的呈现。为了确保所有用户都能理解图表传达的信息,可访问性是不可或缺的。

  1. 提供文本替代方案: 最基本也最重要的是,为图表提供清晰的文本描述或数据表格。屏幕阅读器用户可以通过这些文本内容来理解图表的含义和具体数据。

    
    

    2023年销售额构成

    销售额数据详情
    类别 占比
    产品A 30%
    产品B 50%
    产品C 20%

    这里,我使用了

    role="img"
    来告诉辅助技术这是一个图像,
    aria-labelledby
    aria-describedby
    分别指向图表的标题和详细数据表格。那个
    table
    的样式是经典的“visually hidden”模式,让它在视觉上不可见,但对屏幕阅读器依然可用。

  2. 使用

    aria-label
    aria-valuetext
    (如果每个扇区可交互):
    如果你的图表每个扇区是可点击或有交互的,可以考虑为每个扇区(或其对应的容器)添加
    aria-label
    来描述其数据点。但这对于一个纯CSS绘制的
    conic-gradient
    来说,每个扇区本身没有独立的DOM元素,实现起来会比较复杂。通常,我们会把整个图表视为一个整体,然后提供整体的描述。

  3. 图例和标签: 无论如何,图例(legend)是必不可少的。它将颜色与数据类别关联起来。这些图例本身应该是可访问的文本。

    • 产品A: 30%
    • 产品B: 50%
    • 产品C: 20%

    确保图例中的文本是实际可读的,而不是图片。

总的来说,

conic-gradient
在视觉上提供了极大的便利和创意空间,但作为开发者,我们不能止步于此。动态数据和可访问性是任何前端组件的基石,特别是在数据可视化领域,这需要我们结合JavaScript和语义化的HTML来共同完成。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

536

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

372

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

706

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

470

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

388

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

989

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

652

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

537

2023.09.20

笔记本电脑卡反应很慢处理方法汇总
笔记本电脑卡反应很慢处理方法汇总

本专题整合了笔记本电脑卡反应慢解决方法,阅读专题下面的文章了解更多详细内容。

1

2025.12.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.7万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.6万人学习

CSS教程
CSS教程

共754课时 | 16.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号