【问题标题】:Multiple progress bar circles on single row单行上的多个进度条圆圈
【发布时间】:2019-08-01 20:58:39
【问题描述】:

我正在使用这个例子来创建一个圆形进度条: https://codepen.io/shellbryson/pen/KzaKLe

但是,我希望将多个元素放在一起。我已经通过添加两个单独的 div 和两个单独的 css ID(都带有display: inline-block;)来尝试对两个元素进行此操作。

这成功地同时创建了两个进度条,但第一个进度条保持在 0%。在这种情况下,第一个应该达到 90%,第二个应该达到 95%(在 js 中使用 var end 定义)。

var wrapper = document.getElementById('progress1');
    	var start = 0;
    	var end = 90;
    
    	var colours = {
    	  fill: '#' + wrapper.dataset.fillColour,
    	  track: '#' + wrapper.dataset.trackColour,
    	  text: '#' + wrapper.dataset.textColour,
    	  stroke: '#' + wrapper.dataset.strokeColour,
    	}
    
    	var radius = 100;
    	var border = wrapper.dataset.trackWidth;
    	var strokeSpacing = wrapper.dataset.strokeSpacing;
    	var endAngle = Math.PI * 2;
    	var formatText = d3.format('.0%');
    	var boxSize = radius * 2;
    	var count = end;
    	var progress = start;
    	var step = end < start ? -0.01 : 0.01;
    
    	//Define the circle
    	var circle = d3.arc()
    	  .startAngle(0)
    	  .innerRadius(radius)
    	  .outerRadius(radius - border);
    
    	//setup SVG wrapper
    	var svg = d3.select(wrapper)
    	  .append('svg')
    	  .attr('width', boxSize)
    	  .attr('height', boxSize);
    
    	// ADD Group container
    	var g = svg.append('g')
    	  .attr('transform', 'translate(' + boxSize / 2 + ',' + boxSize / 2 + ')');
    
    	//Setup track
    	var track = g.append('g').attr('class', 'radial-progress');
    	track.append('path')
    	  .attr('class', 'radial-progress__background')
    	  .attr('fill', colours.track)
    	  .attr('stroke', colours.stroke)
    	  .attr('stroke-width', strokeSpacing + 'px')
    	  .attr('d', circle.endAngle(endAngle));
    
    	//Add colour fill
    	var value = track.append('path')
    	  .attr('class', 'radial-progress__value')
    	  .attr('fill', colours.fill)
    	  .attr('stroke', colours.stroke)
    	  .attr('stroke-width', strokeSpacing + 'px');
    
    	//Add text value
    	var numberText = track.append('text')
    	  .attr('class', 'radial-progress__text')
    	  .attr('fill', colours.text)
    	  .attr('font-size', '30px')
    	  .attr('text-anchor', 'middle')
    	  .attr('dy', '.5rem');
    
    	function update(progress) {
    	  //update position of endAngle
    	  value.attr('d', circle.endAngle(endAngle * progress));
    	  //update text value
    	  numberText.text(formatText(progress));
    	} 
    
    	(function iterate() {
    	  //call update to begin animation
    	  update(progress);
    	  if (count > 0) {
    	    //reduce count till it reaches 0
    	    count--;
    	    //increase progress
    	    progress += step;
    	    //Control the speed of the fill
    	    setTimeout(iterate, 10);
    	  }
    	})();
    
    var wrapper = document.getElementById('progress2');
    	var start = 0;
    	var end = 95;
    
    	var colours = {
    	  fill: '#' + wrapper.dataset.fillColour,
    	  track: '#' + wrapper.dataset.trackColour,
    	  text: '#' + wrapper.dataset.textColour,
    	  stroke: '#' + wrapper.dataset.strokeColour,
    	}
    
    	var radius = 100;
    	var border = wrapper.dataset.trackWidth;
    	var strokeSpacing = wrapper.dataset.strokeSpacing;
    	var endAngle = Math.PI * 2;
    	var formatText = d3.format('.0%');
    	var boxSize = radius * 2;
    	var count = end;
    	var progress = start;
    	var step = end < start ? -0.01 : 0.01;
    
    	//Define the circle
    	var circle = d3.arc()
    	  .startAngle(0)
    	  .innerRadius(radius)
    	  .outerRadius(radius - border);
    
    	//setup SVG wrapper
    	var svg = d3.select(wrapper)
    	  .append('svg')
    	  .attr('width', boxSize)
    	  .attr('height', boxSize);
    
    	// ADD Group container
    	var g = svg.append('g')
    	  .attr('transform', 'translate(' + boxSize / 2 + ',' + boxSize / 2 + ')');
    
    	//Setup track
    	var track = g.append('g').attr('class', 'radial-progress');
    	track.append('path')
    	  .attr('class', 'radial-progress__background')
    	  .attr('fill', colours.track)
    	  .attr('stroke', colours.stroke)
    	  .attr('stroke-width', strokeSpacing + 'px')
    	  .attr('d', circle.endAngle(endAngle));
    
    	//Add colour fill
    	var value = track.append('path')
    	  .attr('class', 'radial-progress__value')
    	  .attr('fill', colours.fill)
    	  .attr('stroke', colours.stroke)
    	  .attr('stroke-width', strokeSpacing + 'px');
    
    	//Add text value
    	var numberText = track.append('text')
    	  .attr('class', 'radial-progress__text')
    	  .attr('fill', colours.text)
    	  .attr('font-size', '30px')
    	  .attr('text-anchor', 'middle')
    	  .attr('dy', '.5rem');
    
    	function update(progress) {
    	  //update position of endAngle
    	  value.attr('d', circle.endAngle(endAngle * progress));
    	  //update text value
    	  numberText.text(formatText(progress));
    	} 
    
    	(function iterate() {
    	  //call update to begin animation
    	  update(progress);
    	  if (count > 0) {
    	    //reduce count till it reaches 0
    	    count--;
    	    //increase progress
    	    progress += step;
    	    //Control the speed of the fill
    	    setTimeout(iterate, 10);
    	  }
    	})();
	#progress1 {
	  	display: inline-block;
	  	padding: 20px;
	}

	#progress2 {
		display: inline-block;
	  	padding: 20px;
	}

	.radial-progress { 
	  &__text {
	    font-family: Arial, sans-serif;
	    font-size: 2rem;
	    font-weight: bold;
	  }  
	}
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="progress1"
        data-track-width="15" 
        data-track-colour="555555" 
        data-fill-colour="228B22" 
        data-text-colour="383838" 
        data-stroke-colour="FFFFFF" 
        data-stroke-spacing="1"> 
    </div>
    
    <div id="progress2" 
    	data-track-width="15" 
        data-track-colour="555555" 
        data-fill-colour="228B22" 
        data-text-colour="383838" 
        data-stroke-colour="FFFFFF" 
        data-stroke-spacing="1"> 
    </div>

我尝试将 js 中的变量重新命名为每个元素的唯一名称(即wrapper1wrapper2end1end2),但我似乎无法让第一个元素引起注意到 90% 结束设置。

【问题讨论】:

    标签: javascript html css d3.js


    【解决方案1】:

    为什么会有这么多代码重复?您可以简单地将 JS 概括为一个函数,然后在任意数量的进度圈上使用它,只需为进度添加另一个数据属性,例如 data-progress:

    var renderProgress = function(el) {
      var start = 0;
      var end = el.dataset.progress;
      
      var colours = {
        fill: '#' + el.dataset.fillColour,
        track: '#' + el.dataset.trackColour,
        text: '#' + el.dataset.textColour,
        stroke: '#' + el.dataset.strokeColour,
      }
      
      var radius = 100;
      var border = el.dataset.trackWidth;
      var strokeSpacing = el.dataset.strokeSpacing;
      var endAngle = Math.PI * 2;
      var formatText = d3.format('.0%');
      var boxSize = radius * 2;
      var count = end;
      var progress = start;
      var step = end < start ? -0.01 : 0.01;
      
      //Define the circle
      var circle = d3.arc()
        .startAngle(0)
        .innerRadius(radius)
        .outerRadius(radius - border);
      
      //setup SVG wrapper
      var svg = d3.select(el)
        .append('svg')
        .attr('width', boxSize)
        .attr('height', boxSize);
      
      // ADD Group container
      var g = svg.append('g')
        .attr('transform', 'translate(' + boxSize / 2 + ',' + boxSize / 2 + ')');
      
      //Setup track
      var track = g.append('g').attr('class', 'radial-progress');
      track.append('path')
        .attr('class', 'radial-progress__background')
        .attr('fill', colours.track)
        .attr('stroke', colours.stroke)
        .attr('stroke-width', strokeSpacing + 'px')
        .attr('d', circle.endAngle(endAngle));
      
      //Add colour fill
      var value = track.append('path')
        .attr('class', 'radial-progress__value')
        .attr('fill', colours.fill)
        .attr('stroke', colours.stroke)
        .attr('stroke-width', strokeSpacing + 'px');
      
      //Add text value
      var numberText = track.append('text')
        .attr('class', 'radial-progress__text')
        .attr('fill', colours.text)
        .attr('font-size', '30px')
        .attr('text-anchor', 'middle')
        .attr('dy', '.5rem');
      
      function update(progress) {
        //update position of endAngle
        value.attr('d', circle.endAngle(endAngle * progress));
        //update text value
        numberText.text(formatText(progress));
      };
      
      function iterate() {
        //call update to begin animation
        update(progress);
        
        if (count > 0) {
          //reduce count till it reaches 0
          count--;
          //increase progress
          progress += step;
          //Control the speed of the fill
          setTimeout(iterate, 10);
        }
      };
      
      iterate();
    }
    
    Array.prototype.slice.call(document.querySelectorAll('.progress')).forEach(el => {
      renderProgress(el);
    });
      .progress {
          display: inline-block;
          padding: 20px;
      }
    
      .radial-progress { 
        &__text {
          font-family: Arial, sans-serif;
          font-size: 2rem;
          font-weight: bold;
        }  
      }
    <script src="https://d3js.org/d3.v5.min.js"></script>
    <div
      data-progress="90"
      data-track-width="15" 
      data-track-colour="555555" 
      data-fill-colour="228B22" 
      data-text-colour="383838" 
      data-stroke-colour="FFFFFF" 
      data-stroke-spacing="1"
      class="progress"> 
    </div>
    
    <div
      data-progress="95"
      data-track-width="15" 
      data-track-colour="555555" 
      data-fill-colour="228B22" 
      data-text-colour="383838" 
      data-stroke-colour="FFFFFF" 
      data-stroke-spacing="1"
      class="progress"> 
    </div>

    【讨论】:

    • 快速跟进:将变量传递给data-progress= 的最佳方式是什么?即,如果我在 &lt;script&gt; 标记中定义了 var
    • 您可以将其作为参数添加到 renderProgress() 函数中,例如renderProgress(el, value) { ... } 然后代替var end = el.dataset.progress;var end = value;
    猜你喜欢
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多