We've been running with d3 instead of jQuery for almost 2 years. Some notes so far:
- d3.selectAll is more verbose than $() but in my opinion, that's not a bad thing as I try to minimize DOM selections anyways;
- transitions are another area where D3 really shines, for cases where you don't/can't use CSS transitions, like displaying a discreet popup status message.
- d3 data binding is oh so convenient, and that's where the real magic happens. Combined with a queueing system like postal.js, we pretty much have the same thinking model as React. The DOM is now an expression of the data, and D3's joins figure out what DOM elements need to be updated. It's slightly lower level than React, in that you specify what happens on enter/update/exit, but in terms of efficiency, it seems great (disclaimer: we haven't run benchmarks);
- if you happen to like CoffeeScript, D3 turns into a very elegant DSL that is consistent for DOM editing, styling and event handling. Here's a simple lightbox modal dialog:
> - d3 data binding is oh so convenient, and that's where the real magic happens
It's great, but it has limitations. It only ever binds to a single `__data__` property on the DOM nodes (making it very very difficult to associate multiple sets of data through a single DOM tree) and which needs to be carefully re-bound to each sub-node if you wish to substitute the objects with new ones.
And acting on the data (basically two-way binding) and then updating the d3 selection has to be done very carefully too.
I've run into many subtle errors that stem from this fairly primitive method of binding.
It probably could use some additional abstractions to make replaying updates on object replacement/modification easier.
A great reference for someone starting out with D3 looking to replace some basic jQuery incantations with D3 ones. I think this code sample is particularly telling:
Consistency has nothing to do with it. In jQuery you could just as well do:
$.find('.foo').find('.bar')
It's just a different way of invoking it. The short-hand is more convenient since it accepts a selector as well as a plain DOM node and converts that to a jQuery elements. This makes things very easy and idiomatic.
jQuery's bad api naming shouldn't come as a surprise to anyone who followed JavaScript in the past 10 years. They used bind for event handling, proxy for binding, grep as some kind of filtering, keys and indexes are flipped in the looping construct, etc. etc. It really mirrors PHP's interfaces in a lot of ways.
D3 is an amazing library. At first glance thought it's a charting library. Upon further usage realized it's more of a DOM manipulation library just like JQuery, with the additional support on SVG, which happens to do chart.
The main reason I still use jQuery is that they unify their promise type with their ajax. It's easy to create code that works with any promise, ajax or otherwise.
It's easy enough (as others have mentioned) to wrap d3.xhr() in a promise. I actually like that d3 uses callbacks here, leaving async control flow concerns to other libraries.
No, my main quibble here is that d3.xhr() is still short on convenience and flexibility as compared to $.ajax(). (For instance: you have to build GET URLs manually? No .contentType() as a shorthand for the header? No automatic JSON.stringify() when POSTing application/json data? No HTTP basic auth support? etc.)
About the topic of replacing jQuery I really enjoyed reading "Weaning yourself off jQuery"[0] by James Halliday. It shows how to replace some of the jQuery features with the DOM API and/or with npm libraries such hyperquest[1].
I think it would be harder to use from the perspective of a new developer trying to learn D3. selectAll already has way too many responsibilities in my opinion, making it totally opaque what d3(...) really does. OTOH I guess it's kind of the same with jQuery(..), since it can do both selectors as well as create new Elements.
D3 is one of those libraries that I really admire from a conceptual point of view, but boy do I wish the API was more newbie-friendly.
It's rather indicative of an API that has room for improvement when you start noticing just how many tutorials, videos and books that have to explain D3.selectAll.
"Well, you see — sometimes it doesn't really select anything, instead it does this other thing"
Not to mention the source code. Very sparsely commented.
Event listeners in d3 are not delegated listeners. Implementing this feature actually is not an easy matter as you need to preserve the d3 data binding context and also attach to the nearest svg element because svg events don't bubble through it.
I use d3.select for data binding with DOM elements. For DOM manipulation, I prefer jQuery. That's the distinction. I don't see advantage of d3.select over jQuery DOM manipulation.
[+] [-] athenot|11 years ago|reply
- d3.selectAll is more verbose than $() but in my opinion, that's not a bad thing as I try to minimize DOM selections anyways;
- transitions are another area where D3 really shines, for cases where you don't/can't use CSS transitions, like displaying a discreet popup status message.
- d3 data binding is oh so convenient, and that's where the real magic happens. Combined with a queueing system like postal.js, we pretty much have the same thinking model as React. The DOM is now an expression of the data, and D3's joins figure out what DOM elements need to be updated. It's slightly lower level than React, in that you specify what happens on enter/update/exit, but in terms of efficiency, it seems great (disclaimer: we haven't run benchmarks);
- if you happen to like CoffeeScript, D3 turns into a very elegant DSL that is consistent for DOM editing, styling and event handling. Here's a simple lightbox modal dialog:
- we've added a `.div` function that's shorthand for d3.append and automatically adds an id and/or class, to feel a bit more like Jade;- one downside we found with D3 is that we can't just grab any jquery plugin and throw it in our app.
[+] [-] the8472|11 years ago|reply
It's great, but it has limitations. It only ever binds to a single `__data__` property on the DOM nodes (making it very very difficult to associate multiple sets of data through a single DOM tree) and which needs to be carefully re-bound to each sub-node if you wish to substitute the objects with new ones. And acting on the data (basically two-way binding) and then updating the d3 selection has to be done very carefully too.
I've run into many subtle errors that stem from this fairly primitive method of binding.
It probably could use some additional abstractions to make replaying updates on object replacement/modification easier.
[+] [-] couchand|11 years ago|reply
jQuery
D3 The D3 API consistency is so juicy and delicious.[+] [-] aleem|11 years ago|reply
[+] [-] chrtze|11 years ago|reply
$('.foo').append('<div class="bar" data-selected="true"/>');
in d3 I have to go the long way:
d3.select('.foo') .append('div') .classed('bar', true) .attr('data-selected', true);
I have recently worked a lot with this plugin https://github.com/gka/d3-jetpack which includes some very nice helper functions!
[+] [-] talmand|11 years ago|reply
[+] [-] emehrkay|11 years ago|reply
[+] [-] ww520|11 years ago|reply
[+] [-] Tloewald|11 years ago|reply
[+] [-] gnud|11 years ago|reply
The main reason I still use jQuery is that they unify their promise type with their ajax. It's easy to create code that works with any promise, ajax or otherwise.
[+] [-] couchand|11 years ago|reply
[+] [-] candu|11 years ago|reply
No, my main quibble here is that d3.xhr() is still short on convenience and flexibility as compared to $.ajax(). (For instance: you have to build GET URLs manually? No .contentType() as a shorthand for the header? No automatic JSON.stringify() when POSTing application/json data? No HTTP basic auth support? etc.)
[+] [-] acconrad|11 years ago|reply
[+] [-] frik|11 years ago|reply
http://vanilla-js.com/
[SPOILER: it's not a framework, it's simply native JS5]
[+] [-] aikah|11 years ago|reply
[+] [-] potomak|11 years ago|reply
[0] http://substack.net/weaning_yourself_off_jquery
[1] https://www.npmjs.com/package/hyperquest
[+] [-] me_myself_and_I|11 years ago|reply
It bothers me that I'm already using superagent for ajax stuff in a React project, and if I want to use D3 I will need to live with that extra bloat.
D3 is really amazing, and I'll be integrating it anyway.
[+] [-] xiphias|11 years ago|reply
[+] [-] Nemcue|11 years ago|reply
I think it would be harder to use from the perspective of a new developer trying to learn D3. selectAll already has way too many responsibilities in my opinion, making it totally opaque what d3(...) really does. OTOH I guess it's kind of the same with jQuery(..), since it can do both selectors as well as create new Elements.
D3 is one of those libraries that I really admire from a conceptual point of view, but boy do I wish the API was more newbie-friendly.
It's rather indicative of an API that has room for improvement when you start noticing just how many tutorials, videos and books that have to explain D3.selectAll. "Well, you see — sometimes it doesn't really select anything, instead it does this other thing"
Not to mention the source code. Very sparsely commented.
[+] [-] dheera|11 years ago|reply
[+] [-] candu|11 years ago|reply
[+] [-] rip747|11 years ago|reply
[+] [-] chrtze|11 years ago|reply
[+] [-] lightblade|11 years ago|reply
Event listeners in d3 are not delegated listeners. Implementing this feature actually is not an easy matter as you need to preserve the d3 data binding context and also attach to the nearest svg element because svg events don't bubble through it.
[+] [-] based2|11 years ago|reply
[+] [-] _7fvc|11 years ago|reply
[+] [-] unknown|11 years ago|reply
[deleted]
[+] [-] Pinatubo|11 years ago|reply
[+] [-] mbostock|11 years ago|reply