I've been having a hard time wrapping my head around some D3 concepts (it does not help that I am relatively new to javascript). What I am trying to do is have a status indicator that begins green, slowly turning yellow, and then slowly turning red. If some event occurs (button press, message received, whatever), I want the indicator to return to green, restarting the transition.
Here's a simple example (in jQuery) showing the basic visual effect (without the ability to reset) http://jsfiddle.net/N4APE/
In D3, my idea was to map the background color to the number of milliseconds passed. I tried to create a scale like this:
//10 sec is yellow, 30 sec is red
d3.scale.linear().domain([0, 10000, 30000]).range(["#00ff00", "#ffff00", "#ff0000"]);
But now I'm a bit lost. I have been playing with combinations of transitions, tweens, and interpolators, but I don't seem to be getting anywhere. Here's some pathetic attempts to get it working http://jsfiddle.net/Ebuwa/
My issues:
One other note, I could be happy using an svg circle or something like that instead, but I have had just as poor luck manipulating an svg fill attribute as I have an html background attribute.
Thank you
You don't really need to do any work with scales, .transition() will take care of the hard work behind the scenes:
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"));
To reset the transition, just add an onclick event to the element:
d3.select("#d3Color")
.on("click", function(){ changeElementColor(d3.select(this)) });
http://jsfiddle.net/N4APE/2/
I've also included a colored svg circle. I'm guessing you were trying to use .style("color", "red")
to change its color; you need to use .attr("fill", "red")
for non CSS properties.
I had the same question but wanted to change the text colour as well to provide more contrast toward the end. Mine also updates the message with the elapsed seconds (to see how long slow queries take)
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);
Working Example Here:
http://jsfiddle.net/SKLUn/5/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With