Reputation: 2411
I'm new to d3 but my next project will heavily depend on interactive charts. I read introductions and understand the concept of data binding, entering elements and then exit and remove as stated in the general update pattern. However, I'm not sure whether it is possible to just update a few elements of an existing svg plot (previously generated with d3) without re-rendering the whole svg. Let's say I want to transform a <g>
group or update an "x" coordinate of a rect
element.
I aim to write a customized timeline plugin. I started from this one. This plugin does not consider updating of data. Let's say I'd like to have a vertical bar indicating a specific time and I want to dynamically update the bar's position. Q1: do I have to draw the whole svg from scratch? In my ideal world I'd have a method updateCursor()
on the timeline function that accepts a time string. Q2: can one achieve that? Are there any tutorials dealing with this you are aware of?
In the examples I found, updating requires re-drawing of the whole svg. E.g: http://www.d3noob.org/2013/02/update-d3js-data-dynamically-button.html
Thank you so much for answers!
Best, A
Upvotes: 1
Views: 1058
Reputation: 108512
Q1: do I have to draw the whole svg from scratch? In my ideal world I'd have a method updateCursor() on the timeline function that accepts a time string.
Absolutely No, you do not need to draw the whole thing. You can update any piece of the svg after all they are just dom
elements that can be selected then moved, transformed, style, etc...
Q2: can one achieve that? Are there any tutorials dealing with this you are aware of?
Tons of tutorials, in fact the general update pattern, you link above is such an example. The key is in these lines:
// you've selected a bunch of text elements that already exist on the page
var text = svg.selectAll("text")
.data(data); //<-- you've now bound data to them
// text here is the elements already on the page, we just update them
text.attr("class", "update");
// if there's more data then previous existing elements
// these are returned by .enter()
text.enter().append("text")
// now you are operating on both existing and new elements
text.text(function(d) { return d; });
[Also, the d3 noob example, doesn't redraw the whole chart, it just redraws the line, after all that's what's updated]
Your situation sounds even easier, though, because it sounds like you are dealing with one element you want to re-position (and in that case you don't need data-binding). Initially you'll do:
var myCoolRect = svg.append('rect')
.attr('id', 'myCoolRect')
.attr('x', 100)
....;
Now you can keep a reference to it and then update it later using:
myCoolRect.attr('x', 250);
Or you can re-select it later, by the unique id
I gave it:
svg.select('#myCoolRect')
.attr('x', 100);
Upvotes: 1