9

我一直很难理解一些 D3 概念(我对 javascript 比较陌生,这无济于事)。我想做的是有一个状态指示灯,从绿色开始,慢慢变黄,然后慢慢变红。如果发生某些事件(按下按钮、收到消息等),我希望指示器返回绿色,重新开始转换。

这是一个简单的示例(在 jQuery 中),显示了基本的视觉效果(无法重置)http://jsfiddle.net/N4APE/

在 D3 中,我的想法是将背景颜色映射到经过的毫秒数。我试图创建这样的比例:

//10 sec is yellow, 30 sec is red
d3.scale.linear().domain([0, 10000, 30000]).range(["#00ff00", "#ffff00", "#ff0000"]);

但现在我有点迷路了。我一直在玩转场、补间和插值器的组合,但我似乎没有取得任何进展。这里有一些可悲的尝试让它工作http://jsfiddle.net/Ebuwa/

我的问题:

  • 我不知道如何将过渡的经过的毫秒与我的比例相关联,然后设置背景颜色
  • 我的过渡似乎在我创建它时运行,而不是在我调用它时运行,并且它在错误的元素上运行。
  • 一旦我克服了其他问题,我不确定如何重置过渡以使其保持绿色。

另一个注意事项,我可以很高兴使用 svg 圆圈或类似的东西,但我在操作 svg 填充属性时运气不佳,因为我有一个 html 背景属性。

谢谢

4

3 回答 3

17

你真的不需要对尺度做任何工作,.transition()将负责幕后的艰苦工作:

function changeElementColor(d3Element){
    d3Element
    .transition().duration(0)
      .style("background", "green")
    .transition().duration(1000)
      .style("background", "yellow")
    .transition().delay(1000).duration(5000)
      .style("background", "red");
}
changeElementColor(d3.select("#d3Color"));

要重置转换,只需向元素添加一个 onclick 事件:

d3.select("#d3Color")
  .on("click", function(){ changeElementColor(d3.select(this)) });

http://jsfiddle.net/N4APE/2/

我还包括了一个彩色的 svg 圆圈。我猜你试图用.style("color", "red")它来改变它的颜色;您需要.attr("fill", "red")用于非 CSS 属性。

于 2013-07-03T03:08:47.363 回答
2

我有同样的问题,但也想更改文本颜色以在最后提供更多对比度。我的还用经过的秒数更新消息(查看慢查询需要多长时间)

var duration = 30 * 1000;

// background color progression is smooth from lime to orange to red
var colorScale = d3.scale.linear().clamp(true)
    .domain([0, duration / 2, duration])
    .range(['lime', 'orange', 'red']);

// text color is mostly black but switches to yellow when there is good contrast
var textScale = d3.scale.quantile()
    .domain([0, 0.85 * duration, duration])
    .range(['black', 'yellow', 'yellow']);

var start = new Date();
var counterId = setInterval(function () {
    console.log("setInterval ID: " + counterId);
    var now = new Date();
    var elapsed = Math.round((now - start) / 1000);
    var message = "Querying... " + (elapsed) + " s";
    elapsed = 1000 * elapsed;
    d3.select('#progress')
    .style("color", textScale(elapsed))
        .style("background", colorScale(elapsed))
        .html(message)
    ;
}, 1000);

这里的工作示例:

http://jsfiddle.net/SKLUn/5/

于 2014-01-08T14:45:50.857 回答
0

我想我可能是想太多了。我突然想到我可以将我的 D3 秤与setInterval. 像这样的东西:

var step = 100;

var scale = d3.scale.linear()
                .domain([0, msToYellow, msToRed])
                .range([green, yellow, red]);

setInterval(function(){
    elapsed += step;     
    update(elapsed);    
}, step);

function update(e){
    d3.select("input")
        .style("background", scale(e));
}

完整的工作示例:http: //jsfiddle.net/WBAuT/1/

于 2013-07-03T17:02:08.530 回答