进度条:如何根据进度实现颜色过渡?

3
我一直在寻找一个D3 JS进度条,这是我找到的最佳匹配: https://bl.ocks.org/sarahob/1e291c95c4169ddabb77bbd10b6a7ef7 然而,这是一个具有三个状态的序数域,对于实际应用来说几乎不可重复使用。我想以一种方式改变它,使得无论我将其增加到任意百分比,从黄色到绿色之间的颜色都会按比例随新的进度/高度而变化。如何做到这一点?
2个回答

4
D3有许多非常有用的颜色方法(可以在这里看到),以及颜色方案(可以在这里看到)。
然而,你所询问的可以通过简单的线性比例尺来实现,就像这样(D3 v3,就像你的示例):
var colorScale = d3.scale.linear()
    .range(['yellow', 'limegreen']);

由于我们没有设置域,因此默认为[0, 1],这很方便,因为我们的进度从0%到100%。
您还可以使用三种颜色,相应地设置域:
var colorScale = d3.scale.linear()
    .domain([0, 0.5, 1])
    .range(['yellow', 'orange', 'limegreen']);

这是演示:

var svg = d3.select('body')
  .append('svg')
  .attr('height', 100)
  .attr('width', 500);

var segmentWidth = 300;

var colorScale = d3.scale.linear()
  .domain([0, 0.5, 1])
  .range(['yellow', 'orange', 'limegreen']);

svg.append('rect')
  .attr('class', 'bg-rect')
  .attr('rx', 10)
  .attr('ry', 10)
  .attr('fill', 'gray')
  .attr('height', 15)
  .attr('width', segmentWidth)
  .attr('x', 0);

var progress = svg.append('rect')
  .attr('class', 'progress-rect')
  .attr('fill', colorScale(0))
  .attr('height', 15)
  .attr('width', 0)
  .attr('rx', 10)
  .attr('ry', 10)
  .attr('x', 0);

progress.transition()
  .duration(5000)
  .attr('width', segmentWidth)
  .attrTween("fill", function() {
    return function(t) {
      return colorScale(t)
    }
  });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>


我需要为v4做哪些更改?例如,使用d3.scaleLinear().domain([0, 0.5, 1]).range(['yellow', 'orange', 'limegreen'])代替d3.scale.linear().domain([0, 0.5, 1]).range(['yellow', 'orange', 'limegreen']),还有什么其他的更改? - SkyWalker
仅返回翻译后的文本:没有别的,就是这样。 - Gerardo Furtado
它对我没有显示 :((( bg-rectprogress-rect 类在哪里定义的? - SkyWalker
这些类没有区别(我只是复制了你分享的代码)。你肯定有其他问题,与比例尺无关。 - Gerardo Furtado

2
你可以使用两个重叠的元素,背景为黄色的后面一个,前面为绿色的并且具有逐渐增加的 opacity
或者更好的方法是,你可以设置颜色在hls而不是rgb中,并随着进度的增加或减少改变 huelightness 组件:

const progressBar = document.getElementById('progressBar');
const range = document.getElementById('slider');

const hueStart = 60;
const hueEnd = 120;
const hueRange = hueEnd - hueStart;
const lStart = 50;
const lEnd = 32;
const lRange = lEnd - lStart;

range.oninput = () => {
  const percent = range.value;
  const alpha = percent / 100;
  const hue = hueStart + hueRange * alpha;
  const lightness = lStart + lRange * alpha;
  
  requestAnimationFrame(() => {
    progressBar.style.width = `${ percent }%`;
    progressBar.style.backgroundColor = `hsl(${ hue }, 100%, ${ lightness }%)`;
  });
};
body {
  text-align: center;
}

.progressBar__base {
  position: relative;
  height: 32px;
  border: 3px solid black;
  margin: 0 0 32px;
}

.progressBar__progress {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: yellow;
}
<div class="progressBar__base">
  <div class="progressBar__progress" id="progressBar"></div>
</div>

<input type="range" min="0" max="100" value="0" id="slider">


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接