views:

76

answers:

2

A way that doesn't hog resources, just stops execution for 1 second then executes?

What I want to do is dynamically move a Google gauge from one value to another, creating the effect of it moving to the value instead of jumping to it.

i.e. -

for(original_value; original_value < new_value; original_value++)
{
    data.setValue(0, 1, original_value);
    delay half a second here in JavaScript?
}  

Is this an OK way of doing this or is something closer to what the demo is doing is extremely better? :
http://stackoverflow.com/questions/3485095/how-to-dynamically-move-google-gauge

+5  A: 

No. JavaScript in web browsers is not only single threaded, but it shares the same thread with the browser rendering. If your JavaScript code were to block, the browser UI would become unresponsive during that period.

The typical way to tackle time-based events in JavaScript is by using asynchronous timers. John Resig wrote an intresting article a while ago called "How JavaScript Timers Work", which you may want to check out.


UPDATE:

Are you using the Google Visualization API for the guages? If so, it seems to me that Google already handles the smooth animation that you're trying to achieve. Try the following in the Google Code Playground (keep an eye on the Network gauge):

function drawVisualization() {
  // Create and populate the data table.
  var data = new google.visualization.DataTable();
  var chart;

  data.addColumn('string', 'Label');
  data.addColumn('number', 'Value');
  data.addRows(3);
  data.setValue(0, 0, 'Memory');
  data.setValue(0, 1, 80);
  data.setValue(1, 0, 'CPU');
  data.setValue(1, 1, 55);
  data.setValue(2, 0, 'Network');
  data.setValue(2, 1, 68);

  // Change the value of the Network Gauge after 3 seconds.
  setTimeout(function () { data.setValue(2, 1, 20); chart.draw(data); }, 3000);

  // Create and draw the visualization.
  chart = new google.visualization.Gauge(document.getElementById('visualization'));
  chart.draw(data);
}
Daniel Vassallo
@Daniel Vassallo: is setTimeOut() the (only) way to go (without jQuery)?
Greg McNulty
Yes, `setTimeout` will not block the UI thread.
SimpleCoder
@Greg: Yes, [setTimeout()](https://developer.mozilla.org/en/window.setTimeout) and [setInterval()](https://developer.mozilla.org/en/window.setInterval) do not block execution. They will let you define a callback function, which will be called when the timeout expires. In general, this is the way to go for most time-based events in JavaScript.
Daniel Vassallo
@Daniel Vassallo: is it OK to call a function that doesn't do anything in the setTimeout? I would imagine that is not a good thing, will check out article...
Greg McNulty
@Greg: If you do `setTimeout(function () { }, 1000);` nothing will happen. The `setTimeout()` function will return immediately, and JavaScript execution continues. After 1 second, the timeout will trigger the callback that does nothing... Keep in mind, that JavaScript (in web browsers) is event driven. A timer is an event, just like a mouse click. JavaScript execution is triggered by events. If no event happens, no JavaScript code is executed. If JavaScript blocks execution, the browser will freeze.
Daniel Vassallo
@Greg: Are you using the Google Visualization API?... In that case, check out my updated answer :)
Daniel Vassallo
@Daniel Vassallo: yes, I am, let me try this...
Greg McNulty
@Daniel Vassallo: the problem with this is that it jumps to the value after the time out. The demo uses some crazy timer functions to change the values dynamically...see the link in my post.
Greg McNulty
@Greg: I'm not sure I understand. Isn't this the effect you're after? http://jsbin.com/elufe4 (Wait 3 seconds after loading it) ... In Chrome and Firefox, I see the Network gauge move smoothly from 68 to 20.
Daniel Vassallo
@Daniel Vassallo: hmmm...that link looks right, mine is not doing that, let me try again...is it running the same code you have here?
Greg McNulty
@Daniel Vassallo: ok, it works! thank you!
Greg McNulty
@Greg: Glad you solved it :) ... Yes, that jsbin link was running the same code. You can see the code here: http://jsbin.com/elufe4/edit
Daniel Vassallo
+4  A: 

This should work.

var id, value = original_value;
id = setInterval(function() {
    if (value < new_value) {
        data.setValue(0, 1, value++);
    } else {
        clearInterval(id);
    }
}, 1000);
ChaosPandion
@ChaosPandion: Nice, great example, thank you.
Greg McNulty