簡體   English   中英

使用 CSS 創建 static 餅圖

[英]Creating a static pie chart with CSS

我正在嘗試使用 css 和 html 創建餅圖。 我只是顯示一些 static 數字,因此我試圖保持相對簡單而不使用任何動畫。

我目前在如何創建我想要的外觀方面遇到了障礙。 下面的代碼片段完全按照我的意願工作,問題是 firefox 和 Internet Explorer 不支持conic-gradient ,這將是這個項目的一個問題。

 .progress-circle { --d: 50px; --color: #002F65; --progress: 40; border-radius: var(--d); height: var(--d); width: var(--d); background: conic-gradient( var(--color) calc(calc(var(--progress) / 100) * 360deg), transparent calc(calc(var(--progress) / 100) * 360deg)); }
 <div class="progress-circle"></div>


我一直在尋找類似於上面示例的替代方法,這使我看到了這篇文章: 設計簡單的餅圖與 css

我的問題是計算餅圖百分比增長的方式似乎與我想要完成的事情不兼容。 因為它是由transform: rotate(.1turn);

我的主要問題是可以使conic-gradient與其他瀏覽器兼容嗎? 如果不是,那么使用 css 制作餅圖以與第一個示例非常相似的最佳方法是什么?

對於上下文,我將從數組傳遞數據以確定餅圖的百分比。

 .pie { width: 100px; height: 100px; border-radius: 50%; background: yellowgreen; background-image: linear-gradient(to right, transparent 50%, #655 0); }.pie::before { content: ""; display: block; margin-left: 50%; height: 100%; border-radius: 0 100% 100% 0 / 50%; background: #655; transform-origin: left; transform: rotate(.1turn); }
 <div class="pie"></div>

這是基於此先前答案的想法

 .box { /* percentage to degree --s:0 for [0% 50%] --s:1 for [50% 100%] */ --v:calc( ((18/5) * var(--p) - 90)*1deg); width:100px; height:100px; display:inline-block; border-radius:50%; background: linear-gradient(var(--v), yellowgreen 50%,transparent 0) 0 /calc((1 - var(--s))*100%), linear-gradient(var(--v), transparent 50%,#655 0) 0 /calc(var(--s)*100%), linear-gradient(to right, yellowgreen 50%,#655 0); }
 <div class="box" style="--p:5;--s:0"></div> <div class="box" style="--p:20;--s:0"></div> <div class="box" style="--p:50;--s:0"></div> <div class="box" style="--p:70;--s:1"></div> <div class="box" style="--p:95;--s:1"></div>

我們可以使用min()優化代碼並保持只使用一個變量,但需要注意支持: https://caniuse.com/#feat=css-math-functions

 .box { /* percentage to degree */ --v:calc( ((18/5) * var(--p) - 90)*1deg); width:100px; height:100px; display:inline-block; border-radius:50%; background: linear-gradient(var(--v), yellowgreen 50%,transparent 0) 0 /min(100%,(50 - var(--p))*100%), linear-gradient(var(--v), transparent 50%,#655 0) 0 /min(100%,(var(--p) - 50)*100%), linear-gradient(to right, yellowgreen 50%,#655 0); }
 <div class="box" style="--p:5;"></div> <div class="box" style="--p:20;"></div> <div class="box" style="--p:50;"></div> <div class="box" style="--p:70;"></div> <div class="box" style="--p:95;"></div>

使用具有更多支持的偽元素的另一個想法:

 .box { /* percentage to degree */ --v: calc( ((18/5) * var(--p) - 180)*1deg); width: 100px; display: inline-flex; border-radius: 50%; overflow: hidden; background: linear-gradient(to right, yellowgreen 50%, #655 0); }.box::before, .box::after { content: ""; width: 50%; padding-top:100%; transform: rotate(var(--v)); }.box::before { background: linear-gradient(yellowgreen 0 0) 0 / calc((50 - var(--p))*1%); transform-origin: right; }.box::after { background: linear-gradient(#655 0 0) 0 / calc((var(--p) - 50)*1%); transform-origin: left; }
 <div class="box" style="--p:5;"></div> <div class="box" style="--p:20;width:150px;"></div> <div class="box" style="--p:50;width:120px;"></div> <div class="box" style="--p:70;"></div> <div class="box" style="--p:95;width:80px;"></div>

CSS 餅圖

CSS解決方案

基於改變stroke-dasharray屬性的參數

要根據扇區的張角設置所需的屬性值,您需要計算所選半徑處的總周長。

假設半徑是 50px

let radius = 50;
 let circumference = radius * 2 * Math.PI;
 console.log(circumference );

全周長 ~= 314px

例如,要繪制一個等於四分之一圓的線段:

計算破折號的長度: 314 * 0.25 = 78.5px

間隙長度: 314 * 0.75 = 235.5px

stroke-dasharray 公式: stroke-dasharray="78.5, 235.5"

類似地,為扇區的其他角設置了stroke-dasharray參數。

 circle { fill:#665555; } #p15,#p90,#p180,#p270 { fill:none; stroke:#9ACD32; stroke-width:100; } #p15 { stroke-dasharray:15.7,298.3; } #p90 { stroke-dasharray:78.5,235.5; } #p180 { stroke-dasharray:157,157; } #p270 { stroke-dasharray:235.5,78.5; }
 <svg width="200" height="200" style="border:1px solid"> <circle id="bg" r="100" cx="100" cy="100" /> <path id="p15" d="M100,50A50,50 0 0 1 100,150A50,50 0 0 1 100,50"> </path> </svg> <:-- 90deg --> <svg width="200" height="200" style="border.1px solid"> <circle r="100" cx="100" cy="100" /> <path id="p90" stroke-dasharray="78,5.235,5" d="M100,50A50,50 0 0 1 100,150A50,50 0 0 1 100:50"> </path> </svg> <,-- 180deg --> <svg width="200" height="200" style="border,1px solid"> <circle r="100" cx="100" cy="100" /> <path id="p180" d="M100,50A50,50 0 0 1 100,150A50:50 0 0 1 100,50"> </path> </svg> <,-- 270deg --> <svg width="200" height="200" style="border,1px solid"> <circle r="100" cx="100" cy="100" /> <path id="p270" d="M100,50A50,50 0 0 1 100,150A50,50 0 0 1 100,50"> </path> </svg>

SVG解決方案

如示例CSS solution使用更改stroke-dasharray屬性

 <svg width="200" height="200"> <circle id="bg" r="100" cx="100" cy="100" fill="#665555"/> <path stroke-dasharray="300 14" stroke-dashoffset="300" d="M100,50A50,50 0 0 1 100,150A50,50 0 0 1 100,50" id="p1" r="50" cx="100" cy="100" stroke="#9ACD32" stroke-width="100" fill="none" > </path> </svg> <svg width="200" height="200"> <circle r="100" cx="100" cy="100" fill="#665555"/> <path stroke-dasharray="235.5 78.5" stroke-dashoffset="235.5" d="M100,50A50,50 0 0 1 100,150A50,50 0 0 1 100,50" stroke="#9ACD32" stroke-width="100" fill="none" > </path> </svg> <svg width="200" height="200"> <circle id="bg" r="100" cx="100" cy="100" fill="#665555"/> <path stroke-dasharray="157 157" stroke-dashoffset="157" d="M100,50A50,50 0 0 1 100,150A50,50 0 0 1 100,50" stroke="#9ACD32" stroke-width="100" fill="none" > </path> </svg> <svg width="200" height="200"> <circle id="bg" r="100" cx="100" cy="100" fill="#665555"/> <path stroke-dasharray="78.5 235.5" stroke-dashoffset="78.5" d="M100,50A50,50 0 0 1 100,150A50,50 0 0 1 100,50" stroke="#9ACD32" stroke-width="100" fill="none" > </path> </svg>

以交互方式改變扇區角度的示例

作者的願望:

對於上下文,我將從數組傳遞數據以確定餅圖的百分比。

在此處輸入圖像描述

此過程使用inputjavascript建模:

  1. 顯示填充圖表的百分比

 let circumference = 50 * 2 * Math.PI, input = document.querySelector("[type='range']"), txt = document.querySelector("#txt1"); input.addEventListener("input",()=>{ pieChart(); }) window.addEventListener("load",()=>{ pieChart(); }) function pieChart(){ let val = Number(input.value); let dash = circumference * val / 100; let gap = circumference - dash; p15.style.strokeDasharray = dash + " " + gap txt.innerHTML = (val + '%'); }
 <svg width="200" height="200" > <circle id="bg" r="100" cx="100" cy="100" fill="#665555"/> <path id="p15" stroke-dasharray="15.7,298.3" d="M100,50A50,50 0 0 1 100,150A50,50 0 0 1 100,50" id="p1" fill="none" stroke="#9ACD32" stroke-width="100" > </path> <text id="txt1" y="60%" x="50%" text-anchor="middle" font-size="32px" fill="white">0</text> </svg> <div><input id="size" step="1" type="range" min="0" max = "100" value="0" /></div>

  1. 圖表填充角度 output

 let circumference = 50 * 2 * Math.PI, input = document.querySelector("[type='range']"), txt = document.querySelector("#txt1"); input.addEventListener("input",()=>{ pieChart(); }) window.addEventListener("load",()=>{ pieChart(); }) function pieChart(){ let val = Number(input.value); let dash = circumference * val / 360; let gap = circumference - dash; p15.style.strokeDasharray = dash + " " + gap txt.innerHTML = (val); }
 <svg width="200" height="200" > <circle id="bg" r="100" cx="100" cy="100" fill="#665555"/> <path id="p15" stroke-dasharray="15.7,298.3" d="M100,50A50,50 0 0 1 100,150A50,50 0 0 1 100,50" id="p1" fill="none" stroke="#9ACD32" stroke-width="100" > </path> <text id="txt1" y="60%" x="50%" text-anchor="middle" font-size="32px" fill="white">0</text> </svg> <div><input id="size" step="1" type="range" min="0" max = "360" value="0" /></div>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM