使用时间过去d3中的颜色转换

时间:2013-07-03 01:37:31

标签: javascript d3.js

我一直很难绕过一些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 fill属性的运气差,因为我有一个html背景属性。

谢谢

3 个答案:

答案 0 :(得分:15)

你真的不需要做任何尺度的工作,.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属性。

答案 1 :(得分: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/

答案 2 :(得分: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/