簡體   English   中英

簡單的條形進度指示器靜態或動畫

[英]Simple bar progress indicator static or animated

我需要制作一個簡單的條形進度指示器 - 實際上我只需要一個條形圖,其中綠色部分表示良好的數量,而另一個顏色部分表示不良金額和百分比在條形圖中間的某處。 假設條寬50px,高15px。 想想靜態進度條,如下例所示。

在此輸入圖像描述

我在使用jquery和背景div之前做了這個,然后在它上面放置了2個另外的div用於好的和壞的指示器,然后在它之上放置一個div來顯示文本。

但是我想知道是否有更簡單的HTML5畫布,SVG或CSS解決方案。 由於這個timy控件將出現在長表的每一行中,目的是減少對DOM的污染並提高可讀性和可重用性。

我知道有些圖書館可以做到這一點,但我想用它作為學習經驗。 解決方案應該是無腳本,或者只有JS,或者是帶有jquery的JS。

編輯:感謝積極的輸入人員。 我在下面的答案中提出了我自己的解決方案和工作片段,因為我認為值得單獨參加投票等等。沒有人提出過SVG解決方案 - 任何接受者?

我的道具形象:

在此輸入圖像描述

到目前為止編輯2:3優秀的解決方案(加上我的)。 事實證明這是一個非常有趣的周末挑戰。 還有嗎?

編輯 - 答案選擇:為了結束,我選擇並回答了獎勵積分。 但是,所有提出的答案在不同情況下似乎都是可行的。 就我的目的而言,Le Beau先生基於SVG的答案是最佳的。 我選擇的參數是我最初在服務器上進行頁面標記,因此可以設置渲染條形所需的所有值而無需執行代碼。 后來我允許更改完成百分比,我用ajax發布到服務器和簡單的jquery來更新文本和欄覆蓋。

我希望HTML5進度標記的回答能夠讓這個問題變得多余,但是我們可能會再次坐在開發人員休息的家里,在那里喝着雞尾酒(也許)。

謝謝大家的努力。

這是與您的產品相當的SVG。

 $("svg.tbc").each(function(i, item) { var $item = $(item); var rate = $item.parent().find(".country").attr("rate"); $item.find(".bar").attr("width", rate); $item.find("text").text(rate); }); 
 .tbc { width: 50px; height: 15px; } .tbc .bg { fill: gold; fill-opacity: 0.5; } .tbc .bar { fill: blue; fill-opacity: 0.5; } .tbc text { font-size: 8pt; font-family: Calibri, sans-serif; font-weight: bold; fill: blue; } .country { display: inline-block; width: 200px; } .info { margin-top: 20; font-size: 10px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <h1>Urban population rate by country </h1> <div> <div class="country" rate="57.6%">China</div> <svg class="tbc"><rect class="bg" width="100%" height="100%"/><rect class="bar" width="0%" height="100%"/><text x="50%" y="70%" text-anchor="middle">0%</text></svg> </div> <div> <div class="country" rate="32%">India</div> <svg class="tbc"><rect class="bg" width="100%" height="100%"/><rect class="bar" width="0%" height="100%"/><text x="50%" y="70%" text-anchor="middle">0%</text></svg> </div> <div> <div class="country" rate="82.1%">US</div> <svg class="tbc"><rect class="bg" width="100%" height="100%"/><rect class="bar" width="0%" height="100%"/><text x="50%" y="70%" text-anchor="middle">0%</text></svg> </div> <div> <div class="country" rate="73.2%">Russia</div> <svg class="tbc"><rect class="bg" width="100%" height="100%"/><rect class="bar" width="0%" height="100%"/><text x="50%" y="70%" text-anchor="middle">0%</text></svg> </div> <div> <div class="country" rate="81.2%">UK</div> <svg class="tbc"><rect class="bg" width="100%" height="100%"/><rect class="bar" width="0%" height="100%"/><text x="50%" y="70%" text-anchor="middle">0%</text></svg> </div> <div> <div class="country" rate="11.5%">Burundi</div> <svg class="tbc"><rect class="bg" width="100%" height="100%"/><rect class="bar" width="0%" height="100%"/><text x="50%" y="70%" text-anchor="middle">0%</text></svg> </div> <div class="info"><a href="http://www.worldometers.info/world-population/population-by-country/" target="">Source: www.worldometers.info/</a> 

編輯:添加靜態解決方案

我能想出的最低限度是:

 // p must be an INTEGER from 0 to 100 function bar(n, p) { document.getElementById("bar-" + n) .firstChild.style.width = (p * 2) + "px"; } var bars = [ 0, 0 ]; setInterval(function () { var i; for (i = 0; i < bars.length; i++) { bar(i, bars[i]); if (bars[i] < 100) { bars[i] += i + 1; } } }, 100); 
 div.bar { width: 200px; height: 15px; margin: 4px; background-color: #ffffc0; border: 1px solid #000000; border-radius: 3px; } div.bar div { height: 15px; background-color: #408040; } 
 <div id="bar-0" class="bar"><div></div></div> <div id="bar-1" class="bar"><div></div></div> 

這里是靜態解決方案:

 (function () { $("[data-bar]").each(function () { var p; p = parseInt($(this).data("bar"), 10); $(this) .append($("<div>").addClass("p").text(p + "%")) .append($("<div>").addClass("q").css("width", (2 * p) + "px")); }); }()); 
 div.bar { position: relative; width: 200px; height: 15px; margin: 4px; background-color: #ffffc0; border: 1px solid #000000; border-radius: 3px; text-align: center; } div.bar div.p { position: absolute; width: 100%; margin-top: 1px; font-size: 11px; font-weight: bold; font-family: monospace; } div.bar div.q { height: 15px; background-color: #408040; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="bar" data-bar="32"></div> <div class="bar" data-bar="78"></div> 

您可以使用progress元素:

<progress max="100" value="0" />

它很難造型,但易於使用:

var i=0;
setInterval(function(){
 document.getElementsByTagName("progress")[0].value=++i;
},100);

你可以只使用一個DIV和偽:before:after ,一個用於背景,一個用於文本,例如https://jsfiddle.net/3keey3t6/2/

.progress::before {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    bottom: 0;
    background: #eee;
    content: "";
    z-index: -1;
}

.progress {
    position:relative;
    width:75px;
    height:35px;
    background:green;
}

.progress:after {
    position: absolute;
    content: attr(data-progress) '%';
    width: 100%;
    line-height: 35px;
    text-align: center;
    color: white;
    text-shadow:1px 0 0 black, 0 1px 0 black, -1px 0 0 black, 0 -1px 0 black;
}

接着

<div id="pbar" class="progress" data-progress="20"/>

function setProgress(p) {
    var prg = document.getElementById("pbar");
    prg.style.width = p+"px";
    prg.setAttribute("data-progress", p);
}

setProgress(10);

只是一個非常簡單的例子,如果目標是盡可能少地污染DOM ......

這是我自己的產品。 請注意,腳本的很大一部分是從畫布生成透明度的背景圖像,您可能不需要這樣做。

該技術使用每個條形單個div,一些用於樣式的標准CSS和單個圖像。

條形背景圖像預先繪制在相同的高度和條形寬度的兩倍,兩個區段的寬度為50%,使用表示進度所需的顏色。 因此,如果條形圖為50px,則背景圖像為100px,例如50px藍色和50px黃色。

在此輸入圖像描述

在我的例子中,我使用腳本來讀取div中顯示的值,然后修改css background-position-x值以適當地移動圖像。 將它移動到x = 0並且條形圖都很好,移動到x = -25並且你有50/50好/壞等。

如果您知道條形大小並且可以提前生成圖像,並且在從DB生成頁面時,您可以完全跳過腳本,並在輸出html時在div上設置必要的元素css。

 const barW = 50; // display width of bar element on page. Note green-red bg image width must be 2 x barW /* This is where we apply the image to the bars. Because I create the image from a canvas, this is called as a callback from the image create process. If your image is just a plain web image and you know dimensions you could run this function in your document.ready() event. */ function makeBars(img) { // apply the bar background to each tiny bar class (tbc) $('.tbc').each(function() { var num = parseFloat($(this).html(), 10) / 100; // I stored the % in the element html - read that. var xPos = Math.round(-(barW * (1 - num))); // offset x by minus the bad proportion. $(this).css({ backgroundImage: 'url(' + img.src + ')', backgroundPositionX: xPos }); // apply to element. }) } /* Everything from here is optional - it generates an image via a canvas */ makeImg(makeBars); // call for the background image to be made // this is all to generate an image - made from a canvas. function makeImg(cbf) { // add a stage var s = new Konva.Stage({ container: 'container', width: 800, height: 200 }); // add a layer var l = new Konva.Layer(); s.add(l); // Add a good rect to the LAYER just to show the good amount. var green = new Konva.Rect({ fill: 'blue', width: 50, height: 15, x: 0, y: 0, opacity: 0.5 }); l.add(green); // Add a bad rect to the LAYER just to show the good amount. var red = new Konva.Rect({ fill: 'gold', width: 50, height: 15, x: 50, y: 0, opacity: 0.5 }); l.add(red); var bg; var catchImg = function(img) { cbf(img); // callback passing the new img } l.draw(); s.toImage({ callback: catchImg, x: 0, y: 0, width: 100, height: 15 }) $('#container').remove(); // now we have an image - trash the canvas. } 
 .tbc { display: inline-block; width: 50px; height: 15px; line-height: 15px; border: 1px solid #ccc; text-align: center; font-size: 8pt; font-family: Calibri, sans-serif; font-weight: bold; color: blue; } .country { display: inline-block; width: 200px; } .info { margin-top: 20; font-size: 10px; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <script src="https://cdn.rawgit.com/konvajs/konva/1.6.3/konva.min.js"></script> <h1>Urban population rate by country </h1> <div> <div class='country'>China</div> <div class='tbc'>57.6%</div> </div> <div> <div class='country'>India</div> <div class='tbc'>32%</div> </div> <div> <div class='country'>US</div> <div class='tbc'>82.1%</div> </div> <div> <div class='country'>Russia</div> <div class='tbc'>73.2%</div> </div> <div> <div class='country'>UK</div> <div class='tbc'>81.2%</div> </div> <div> <div class='country'>Burundi</div> <div class='tbc'>11.5%</div> </div> <div class='info'><a href='http://www.worldometers.info/world-population/population-by-country/' target=''>Source: www.worldometers.info/</a> <div id='container'>Temp: Used to contain canvas</div> 

暫無
暫無

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

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