有什么方法可以将 jquery UI 进度条分成不同的部分并支持 > 100%?

Is there any way to breakout the jquery UI progress bar into different sections as well as support > 100%?

我正在考虑使用 jquery 进度条,但我有两个请求ui似乎不​​受支持:

  1. 能够将不同的部分放入进度条中。例如,而不是仅仅拥有:

总共100个,当前50个(所以进度条的1/2已经填满了)。看起来像这样:

我希望能够展示:

总计 100 个,当前 50 个(分为项目 A 的 20 个,项目 B 的 30 个和项目 C 的 10 个),其中 A 和 B 部分可以有一些不同的可视化效果,如下所示:

  1. 显示数字的能力 > 100%。我正在使用它来跟踪筹款活动,因此赚取的 $$ 可能大于目标,因此希望进度指示器继续超出进度条的边界。

jqueryui进度条是否支持这些用例?是否有其他 javascript 推荐用于此用例的插件或控件?

这是完成问题第一部分的方法。

工作示例:http://jsfiddle.net/Twisty/03yuc3un/

HTML

<div id="progressbar"></div>
<div class="form">
  Add Funds:
  <input type="" id="funds" />
  <button id="addBtn">Add</button>
</div>

CSS

.form {
  padding: 20px;
}

.ui-progressbar-value {
  float: left;
  text-align: center;
  padding-top: .25em;
}

.form input {
  width: 4em;
}

#progressbar div.ui-progressbar-value.ui-widget-header:first-of-type {
  z-index: -1;
  display: none;
}

.color-1 {
  background: #FF0000;
}

.color-2 {
  background: #FFA500;
}

.color-3 {
  background: #FFFF00;
}

.color-4 {
  background: #00FF00;
}

.color-5 {
  background: #0000FF;
}

.color-6 {
  background: #FF00FF;
}

jQuery

$(function() {
  var $pgbr = $("#progressbar").progressbar({
    value: 0,
    max: 100,
    change: function(e, ui) {
      $(this).find(".ui-progressbar-value").eq(0).css("display", "none");
    }
  });
  $("#addBtn").button().click(function(e) {
    var funds = parseInt($("#funds").val());
    var cValue = $pgbr.progressbar("value");
    var sum = cValue + funds;
    if (sum > $pgbr.progressbar("option", "max")) {
      return false;
    }
    $pgbr.progressbar("value", sum);
    if (funds) {
      var $chunk = $("<div>", {
        class: "ui-progressbar-value ui-widget-header",
        width: ((funds / $pgbr.progressbar("option", "max")) * 100) + "%"
      });
      var count = $("#progressbar .ui-progressbar-value").length;
      if (count == 0) {
        $chunk.addClass("ui-corner-left");
      }
      if (count <= 6) {
        $chunk.addClass("color-" + count);
      } else {
        $chunk.addClass("color-" + count % 6);
      }
      $chunk.html(funds);
      $pgbr.append($chunk);
    }
  });
});

如您所见,无法使用 progressbar() 自然地制作部分。此示例允许我们向进度条添加金额。如果目标是 100 或 2000,这可以在初始化时设置为 max。此示例假设您将一天内收集的钱加到一个目标中。示例测试:第 1 天 30 美元,第 2 天 10 美元,第 3 天 20 美元。

添加资金时,它会添加另一个 div,宽度设置为百分比。这将有助于根据目标正确表示价值。如果目标是 100 美元,宽度就是 30%。如果目标是 2000 美元,则宽度为 1.5%。

使用CSS,您可以指定特定的颜色。我选择了 6 种颜色并根据已添加的部分数量轮换使用它们。您可以通过多种不同的方法来执行此操作。

现在假设您的延伸目标是 5000 美元,您的最低目标是 2000 美元,最初这可能是 max2000。如果收集的金额超过 2000 美元……这里有点后勤问题。您可以迭代每个部分并将其调整为适当的百分比。我个人认为最好缩小进度条本身的宽度,并创建一个可以跟踪盈余的第二个进度条。

有问题欢迎评论。

这是一个纯粹的 Javascript 解决方案。

这是一个函数,它将分段作为数字数组,总计作为数字,CSS 容器选择器(字符串)和可选的颜色数组(作为字符串)。

段数和总数是数字,不是百分比。 该函数将线段转换为百分比并绘制条形。

对于您的用例,如果您有溢出,只需添加第 4 段,这是计算出的溢出(在总数中),具有不同的颜色(示例 2)。

您可以使用 CSS 设置段边界的样式,这样溢出在视觉上是明显的

function progress_bar(segments, total, selector, colors) {
  //if no colors default to these 3 colors
  colors = colors || 'green black red'.split(' ');

  //find the container DOM element
  var bar = document.querySelector(selector);
  for (var i = 0; i < segments.length; i++) {
    child = document.createElement('DIV');

    //compute width in percents relative to total
    var relativeW = total ? segments[i] / total * 100 : 0;
    child.innerHTML = Math.floor(relativeW);
    child.className = 'bar-segment bar-segment--' + (i + 1);
    child.style = 'float:left; height:100%; background: ' + colors[i] + '; width: ' + relativeW + '%;';
    bar.appendChild(child);
  }
}

progress_bar([20, 50, 10], 100, '.progress-demo');

progress_bar([40, 100, 20, 30], 200, '.progress-demo-2', ['green','black','red', 'yellow']);
.bar-segment{
  text-align:center;
  overflow:hidden;  
}

.bar-segment--2{
  color:white;
}
<h4>1.</h4>

<div class="progress-demo" 
     style="height:20px; width:300px; border: 1px solid gray">
  </div>

<h4>2.</h4>

<div class="progress-demo-2" 
     style="height:20px; width:300px; border: 1px solid gray">
  </div>

这是 Css 免费 覆盖 jqueryUi 进度条:

  • multimize 获取进度条 id 和最喜欢的颜色数组,此函数将原始进度条分解为根据颜色数组长度具有多条的新版本。
  • multiUpdate 调用此方法更新进度条,此函数给出 progressbarId 和一个 Array 条值。

我做的差一点: 只需将原始栏克隆到许多其他栏并使用 table 显示每个栏的统计信息。代码的长度是因为包含的样式,但您可以将其压缩到至少 30%。

编辑:

增加了对大于 100 的数字的支持


 // this method overrides jqueryUi progress bar
 // the length of <colors> will be number of breakes
 // this method also add a table that presents percentage in position 
function multimize(progressBarId, colors, max) {
 var pbar = $("#"+progressBarId);
 pbar.progressbar({ value: 100 });
 pbar.data('max', max);
 pbar.css("position", "relative");
 $("#"+progressBarId+" div").css({"position": "absolute", "background": colors[colors.length-1],"border":"none"}).attr("id", progressBarId+"_sub"+(colors.length-1));
 var textTable = $('<table></table>').css({"border":"none", "position":"absolute", "color":"white", "width":"100%", "height":"100%"}).attr("id", progressBarId+"_tbl");
 var textRow = textTable.append($('<tr></tr>')).css({"text-align":"center"});
 textRow.append($('<td>d</td>'));
 for (var i=colors.length-2; i>=0; i--) {
  $("#"+progressBarId+" div").clone().appendTo("#"+progressBarId)
   .css({"position": "absolute", "background": colors[i], "border-radius": "0", "width": "1%"})
   .attr("id", progressBarId+"_sub"+i);
   textRow.append($('<td>d</td>')).css({"text-align":"center"});
 }
 pbar.append(textTable);
}
 // this method will be update multimized progressbars
 // this method automatically finalize progressbar
function multiUpdate(progressBarId, values) {
 var pbar = $("#"+progressBarId);
 var i,total = 0;
 var percentes = [];
 for (i=0; i<values.length; i++) total += values[i];
 $("#"+progressBarId+"_tbl").css("width", (total*(100/pbar.data('max')))+"%")
 for (i=0; i<values.length; i++) {
  var perc = values[i]/total*100*(total/100)*(100/pbar.data('max'));
  percentes.push((i==0)?perc:perc+percentes[i-1]);
  $("#"+progressBarId+"_sub"+i).css({"width": percentes[i]+"%"});
  $("#"+progressBarId+"_tbl td:eq("+i+")").text(Math.floor(values[i])).css("width", (values[i]/total)+"%");
 }
 if (total >= pbar.data('max')) {
  finilize(progressBarId);
 }
}

function finilize(progressBarId) {
 // removing demo timer
 clearInterval(timer);
 
 var pbar = $("#"+progressBarId);
 pbar.empty();
 pbar.text("compete "+pbar.data('max')+"%").css({"color":"black", "background":"lightgreen", "text-align":"center"});
}
 
 
// Demo
// here is a demo of progress bar update and finilize
 $(function() {
 multimize("progressbar", ["#06AF8F","#000000","#F94443"], 200);
 });
var classA=0, classB=0, classC=0;
var timer = setInterval(function(){
 classA += (Math.round(Math.random() * (20 - 2) + 2))/30;
 classB += (Math.round(Math.random() * (20 - 1) + 1))/15;
 if (classC<20) classB = Math.min(classB, 15);
 classC += (Math.round(Math.random() * (20 - 7) + 7))/60;
 classC = Math.min(classC, 40);
 multiUpdate("progressbar", [classA,classB,classC]);
}, 100);
<link href = "https://code.jquery.com/ui/1.10.4/themes/ui-lightness/jquery-ui.css"
         rel = "stylesheet">
<script src = "https://code.jquery.com/jquery-1.10.2.js"></script>
<script src = "https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>

<div id="page">
 <div id = "progressbar"></div> 
</div>

我想你可能会喜欢multiprogressbar.js

CSS

#styled{
    margin: 30px;
    width: 50%;
    font-size: 1em;
}
.green {background: green}
.black {background: black}
.red {background: red}

HTML

<div id="styled"></div>

JQuery

$('#styled').multiprogressbar({
    parts:[{value: 30, text: true, barClass: "green", textClass: "whiteText"},
            {value: 10, text: true, barClass: "black", textClass: "whiteText"},
            {value: 20, text: true, barClass: "red", textClass: "whiteText"}]
});

结果

演示 JsFiddle

您可以使用简单的html和css实现多进度条。不需要任何插件

<div class="container">
  <h2>Stacked Progress Bars</h2>
  <p>Create a stacked progress bar by placing multiple bars into the same div with class .progress:</p> 
  <div class="progress">
    <div class="progress-bar progress-bar-40" role="progressbar">
     40%
    </div>
    <div class="progress-bar progress-bar-10" role="progressbar">
     10%
    </div>
    <div class="progress-bar progress-bar-20" role="progressbar">
     20%
    </div>
  </div>
</div>

<style>
.progress {
  height: 20px;
  overflow: hidden;
  background-color: #f5f5f5;
  border-radius: 4px;
  -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
  box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
}
.progress-bar {
  float: left;
  width: 0;
  height: 100%;
  color: #fff;
  font-size: 12px;
  text-align: center;
  line-height: 20px;
  background-color: #337ab7;
  -webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
  box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
  -webkit-transition: width .6s ease;
  -o-transition: width .6s ease;
  transition: width .6s ease;
}
.progress-bar-40 {
  width: 40%;
  background-color: #5cb85c;
}
.progress-bar-10 {
  width: 10%;
  background-color: #f0ad4e;
}
.progress-bar-20{
  width: 20%;
  background-color: #d9534f;
 }
 </style>

检查这个fiddle https://jsfiddle.net/zLxxmact/2/

由于 jQuery 品牌的成功,许多人最终使用 jQuery UI,即使 jQuery 和 jQuery UI 是两种完全不同的产品。虽然 jQuery 很棒,但 jQuery UI 往往有很多粗糙的边缘。 Bootstrap 还包括进度条,通常更易于扩展和定制。 Check out this example of the Bootstrap progress bar, for example.

如果您选择坚持使用 jQuery UI,您可以扩展 $.ui.progressbar,并像这样使用它:

pb = $( "#progressbar" ).progressbar({
    values: [30,10,20]
});

$.widget("custom.progressbar", $.ui.progressbar, {

    _create: function() {

        // Constrain initial value
        this.oldValue = this.options.value = this._constrainedValue();

        this.element.attr( {
            role: "progressbar",
            "aria-valuemin": this.min
        } );

        this._addClass( "ui-progressbar", "ui-widget ui-widget-content" );
        val_bar = $( "<div><span class='progress-label'></span></div>" ).addClass("ui-progressbar-value ui-widget-header");
        
        var bar_sections = this.options.values;
        for (i in bar_sections) {
            var bar_section = val_bar.clone();
            this.element.append(bar_section.addClass('bar_' + i));
        }

        this.valueDivs = this.element.find('.ui-progressbar-value');

        this._refreshValue();
    },

    _refreshValue: function() {
        var values = this.options.values,
            percentage = this._percentage(),
            _total = this.options.values.reduce(function(a, b) {return a + b;}, 0)

        if (_total > 100) {
            this.options.max = _total;
        } else {
            this.options.max = 100;
        }

        for (index = 0; index < values.length; ++index) {
            this.options.value = values[index];
            this.valueDiv = this.valueDivs.eq(index);
            $('.progress-label', this.valueDiv).text(values[index] + '%')
            this._super();
            this.valueDiv
            .width( percentage + "%" );
        }
    },

    _values: function( newValues ) {
        this.options.values = newValues;
        this._refreshValue();
    }
});

initial_values = [30,10,20]

var pb = $( "#progressbar" ).progressbar({
 values: [30,10,20]
});

function progress(pb) {
  // var val = pb.progressbar("value") || 0;

    initial_values.map(function(x, i, ar){
        if (initial_values[i] < 100) { 
            initial_values[i] = initial_values[i] + 1;
        }
    });

    $( "#progressbar" ).progressbar({
        values: initial_values
    });

  setTimeout(progress, 100);
}
progress(pb);
 body{
  font-family: "Trebuchet MS", sans-serif;
  margin: 50px;
 }
 .demoHeaders {
  margin-top: 2em;
 }
 #dialog-link {
  padding: .4em 1em .4em 20px;
  text-decoration: none;
  position: relative;
 }
 #dialog-link span.ui-icon {
  margin: 0 5px 0 0;
  position: absolute;
  left: .2em;
  top: 50%;
  margin-top: -8px;
 }
 #icons {
  margin: 0;
  padding: 0;
 }
 #icons li {
  margin: 2px;
  position: relative;
  padding: 4px 0;
  cursor: pointer;
  float: left;
  list-style: none;
 }
 #icons span.ui-icon {
  float: left;
  margin: 0 4px;
 }
 .fakewindowcontain .ui-widget-overlay {
  position: absolute;
 }
 select {
  width: 200px;
 }

    #progressbar {
        white-space: nowrap;
        overflow:hidden;
     border: 1px solid #dddddd;
     
    }

    html .ui-progressbar-value {
        display: inline-block;
        
    }

    .bar_0 {
        background: #06af8f;
    }
    .bar_1 {
        background: #000;
    }
    .bar_2 {
        background: #fc4242;
    }
    .progress-label {
        display: block;
        height: 100%;
        line-height: 30px;
        vertical-align: middle;
        text-align: center;
    }
    .bar_1 .progress-label {
        color: #fff;
    }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.12.0/jquery-ui.min.js"></script>
<div id="progressbar"></div>