What is the difference between D3 and jQuery? - javascript

Referring to this example:
http://vallandingham.me/stepper_steps.html
it seems that the D3 and jQuery libraries are very similar in the sense that they both do DOM manipulation in an object-chaining way.
I'm curious as to know what functions D3 makes easier than jQuery and vice versa. There are plenty of graphing and visualization libraries that use jQuery as a basis (e.g., highcharts, flot, wijmo).
Please give specific examples of how they are different.

D3 is data-driven but jQuery is not: with jQuery you directly manipulate elements, but with D3 you provide data and callbacks through D3's unique data(), enter() and exit() methods and D3 manipulates elements.
D3 is usually used for data visualization but jQuery is used for creating web apps. D3 has many data visualization extensions and jQuery has many web app plugins.
Both are JavaScript DOM manipulation libraries, have CSS selectors and fluent API and are based on web standards which makes them look similar.
Following code is an example of D3 usage which is not possible with jQuery (try it in jsfiddle):
// create selection
var selection = d3.select('body').selectAll('div');
// create binding between selection and data
var binding = selection.data([50, 100, 150]);
// update existing nodes
binding
.style('width', function(d) { return d + 'px'; });
// create nodes for new data
binding.enter()
.append('div')
.style('width', function(d) { return d + 'px'; });
// remove nodes for discarded data
binding.exit()
.remove();

d3 has a silly description. jQuery and d3 are not at all similar, you just don't use them for the same things.
jQuery's purpose is to do general dom manipulation. It's a general purpose javascript toolkit for anything you might want to do.
d3 was primarily designed to make it easy to make shiny graphs with data. You should definitely use it (or something similar, or something built on top of it) if you want to make graphical visualizations of data.
If you want a general purpose JS library for all your interactive form needs, consider jQuery or proto or mootools. If you want something tiny, consider underscore.js. If you want something with dependency injection and testability, consider AngularJS.
A General comparison guide from wikipedia.
I can see why someone would think they are similar. They use a similar selector syntax -- $('SELECTOR'), and d3 is an extremely powerful tool for selecting, filtering, and operating on html elements, especially while chaining these operations together. d3 tries to explain this to you on its home page by claiming to be a general purpose library, but the fact is that most people use it when they want to make graphs. It is pretty unusual to use it for your average dom manipulation because the d3 learning curve is so steep. It is, however, a far more general tool than jQuery, and generally people build other more specific libraries (such as nvd3) on top of d3 rather than using it directly.
#JohnS's answer is also very good. Fluent API = method chaining. I also agree about where the plugins and extension lead you with the libraries.

I've been using a little of both lately. Since d3 uses Sizzle's selectors you can pretty much mix up selectors.
Just keep in mind d3.select('#mydiv') doesn't return quite the same as jQuery('#mydiv'). It's the same DOM element, but it's being instantiated with different constructors. For example, let's say you have the following element:
<div id="mydiv" rel="awesome div" data-hash="654687867asaj"/>
And let's grab some common methods:
> d3.select('#mydiv').attr('rel') ;
"awesome div"
> jQuery('#mydiv').attr('rel');
"awesome div"
Seems legit. But if you go a little further:
> d3.select('#mydiv').data();
[undefined]
> jQuery('#mydiv').data();
Object {hash: "654687867asaj"}

D3 is not just about visual graphs. Data Driven Documents. When you use d3, you bind data to dom nodes. Because of SVG we are able to make graphs, but D3 is so much more. You can replace frameworks like Backbone, Angular, and Ember with using D3.
Not sure who down voted, but let me add some more clarity.
Many websites request data from the server, which usually comes from a database. When the website receives this data, we have to do a page update of the new content. Many frameworks do this, and d3 does this as well. So instead of using a svg element, you can use html element instead. When you call the redraw, it'll quickly update the page with the new content. It's real nice to not have all the extra overhead like jquery, backbone + its plugins, angular, etc. You only need to know d3. Now d3 doesn't have a routing system baked into it. But you can always find one.
Jquery on the other hand, it's sole purpose is to write less code. It's just a short hand version of javascript that has been tested on many browsers. If you don't have a lot of jquery on your webpage. It's a great library to use. It's simple and takes a lotta pains out of javascript development for multiple browsers.
If you tried to implement jquery in a d3 like fashion, it'll be quite slow, as it wasn't designed for that task, likewise, d3 isn't design to post data to servers, it's designed just to consume and render data.

d3 is made for data visualization, it does this by filtering through DOM objects and applying transformations.
jQuery is made for DOM manipulation and making life easier for many basic JS tasks.
If you're looking to turn data into pretty, interactive pictures, D3 is awesome.
If you're looking to move, manipulate or otherwise modify your webpage, jQuery is your tool.

Great question!
While both libraries share many of the same features, it seems to me that the greatest difference between jQuery and D3 is the focus.
jQuery is a general purpose library with a focus on being cross-browser and being easy to use.
D3 is focused on data (manipulation and visualisation) and supports only modern browsers. And while it does look like jQuery, it's a lot more difficult to use.

Both can solve the same purpose of creating and manipulating a DOM (whether it be HTML or SVG). D3 surfaces an API that simplifies common tasks you would take when generating/manipulating a DOM based on data. It does this through it's native support for data binding via the data() function. In jQuery you would have to manually process the data and define how to bind to the data in order to generate a DOM. Because of this, your code becomes more procedural and harder to reason and follow. With D3, it's less steps/code and more declarative. D3 also provides some higher level functions that aid in generating data visualization in SVG. Functions like range(),domain(), and scale() make it easier to take data and plot them on a graph. Functions like axis() also make it easier to draw common UI elements you would expect in a chart/graph. There are many other higher-level api libraries that sit on top of D3 to aid in more complex visualizations of data including interactive behavior and animation.

Related

Is it possible to create d3 nodes with multiple edge ports?

I'd like to achieve something similar to this diagram using d3:
https://gojs.net/latest/samples/records.html
I was trying to look it up on the web but I hardly found any resources to get started with.
I'm quite new to d3 so I don't know how to approach this task, any help or guidance would be appreciated!
This is another one of those questions where people need to implement a sophisticated diagram visualization and they think just because D3 is a lot about visualization, it will be a good fit.
IMHO it is not.
D3 could be a part of the solution, but it certainly cannot be the solution alone: It's almost like asking whether JavaScript can be used to create this kind of diagram. Of course it can! D3 is just a very thin (but very useful) layer on top of the DOM+JavaScript, that can help you with crunching numbers, work with colors, coordinate systems, create DOM elements, and simplifies working with the DOM. Think of it as jquery for DOM and data plus a lot of very nice demos. But the value very often is in the demos, rather than in D3 itself: You need to implement a lot of things to get from a simple mapping from data to dom elements to a sophisticated diagram visualization like the one you are referring to.
If you don't want to implement and maintain most of the low-level diagram logic yourself, you should rather be looking at a diagramming solution, rather than a tool that will help you create SVG elements elegantly with less code.
Look at this question to see a list of graph and diagram visualization software. Agreed, D3 is also on this list (for the same reason you are asking this question), but there are also far more capable tools on that list that you should be looking at, my recommendation being either the one that you've found already or preferrably this one if your requirements are more sophisticated.

JavaScript Drawing library for Flow charts and attaching data to the view dynamically

I am looking for a JavaScript Library where in I can make a simple flow chart, that includes,
A Start Point,
A End Point,
Few conditions,
Changing the data, and adding it to the view when you double click the box,
Can Fork the flow.
Went through few libraries.
D3.js is not suited very well for this kind of visualization.
Other libraries, JSplumb, Cytoscape, jointJS (And not rappid. Looking for an Open Source)
Any suggestions.
The solutions you listed are either generic graph theory libraries or generic Visio/Dia-like diagramming libraries. For each, you'll have to add your own logic on top for the restricted flow chart case.
Or, you'll have to do some in-depth searching to find something that's only for flow charts.

Simplest way of integrating Angular-created elements with D3

I'm playing around with different ways of integrating D3 and Angular, in the context of learning both of these frameworks, and am hoping for some input:
My client application receives a JSON array of nodes and an array of edges from my server.
The central component of the client is a graph visualization implemented as a D3 force-directed layout: For each node in the nodes array, a (SVG) circle element is added to this visualization, and lines between these circles are added for each edge in the edges array.
Of course, D3's selection.data( ) makes it trivial to add these elements and bind each to the data it represents, but the graph visualization is only part of a much larger application: I need to create different types of elements representing these same nodes and edges in different parts of the application (which D3 has nothing to do with), and I'd like to keep all of these elements bound to a single dataset.
My primary goal is minimizing code complexity, and - although I've fallen in love with the simplicity and elegance of D3's data-binding functionality - I've arrived at the tentative conclusion that using it in one part of the application while using Angular to do the same in other parts is creating unnecessary complexity, and that the simplest approach would be to use Angular to handle the data-binding/element-creation
In other words, instead of using selection.data( ).enter( ).append( ) to create SVG elements, I'm thinking I should do so using a ng-repeat="node in nodes", perhaps creating each as a custom directive to allow for custom functionality. Having done so, I would then need to get these elements "into" D3, i.e. managed by its force-directed layout.
Is my reasoning here sound? In particular, I'm worried that I'm overlooking complications this will create with regard to object constancy, which is an important requirement as nodes will be entering, exiting and moving about the screen constantly and I need these transitions to be smooth. How would you recommend I go about integrating my angular-created elements into D3 (more precisely, getting them into my force.nodes{ } and force.links( ) arrays) to avoid any such complications?
Finally, I'm also considering a strategy that I'm hoping might give me the best of both worlds: I could use D3 to create my SVG elements and bind them to their respective datum, but rather than executing that code in the link function of visualization directive (as I've been doing, and as all the Angular/D3 tutorials I've found do), I could run it in the compile function, and do something like this:
d3.select('SVG')
.selectAll('.node')
.data('nodeDataArray')
.enter( )
.append('circle')
.attr("class", "node-icon"); //...other attributes/styles etc
where node-icon is the normalized name of a directive with a restrict property that includes C. If this runs in the compile method, angular should then compile all of these directives as normal, adding any additional functionality / interfaces with other directives (etc.), the same way it does with any other type of element. Right?
This is the option I'm most attracted to intuitively - are there any pitfalls of it I might be overlooking, which might make the former strategy preferable?
I have been pondering pretty much the same problem for a while and come to the following conclusion.
The simplest way to integrate Angular created elements with d3 is to add the directives with .attr and then .call the compile service on the d3 generated elements. Like this:
mySvg.selectAll("circle")
.data(scope.nodes)
.enter()
.append("circle")
.attr("tooltip-append-to-body", true)
.attr("tooltip", function(d){
return d.name;
})
.call(function(){
$compile(this[0].parentNode)(scope);
});
Here is a Plunker.
I think the idea of generating elements with Angular ngRepeat rather than d3 is working against the frameworks. D3 does not expect to be handed a bunch of elements. It wants to be handed data - almost always an array. It then has a stack of excellent functions to convert that data into various SVG or HTML elements. Let it do that.
It seems from this quote...
D3 makes it trivial to add elements and bind each to the data it represents, but the graph visualization is only part of a much larger application: I need to create different types of elements representing these same nodes and edges in different parts of the application (which D3 has nothing to do with), and I'd like to keep all of these elements bound to a single dataset.
... you are implying that generating elements with d3 somehow prevents you from binding the same data to different parts of the application. I can't see why. Just have d3 generate elements from a scope array (as is done in the linked Plunker). Then use the same dataset wherever you want in the usual Angular way. Other parts of the application can update the dataset and a $watch callback can re-render the d3 graphic.

BackboneJS and JQuery plugins architecture playing together in a MiniPhotoshop project

I'm rather new with BackboneJS.
it is exciting stuff for somebody who worked with plain JSONs until now. :)
I am used to design JQuery Widgets and plugins to encapsulate logic / presentation.
Backbone seems much more flexible with its MV* approach.
I am redesigning a "mini-photoshop" project for work. a javascript/html page which you can add elements like labels, images, buttons, change their properties, drag&drop them around and change their z-index, etc.
I took an approach of having a Backbone collection of elements that represents the drawing.
I thought of using a jquery plugin to be able to create this workspace in everypage i'd like.
so i could do something like:
$('.wrapper').miniPhotoshop({
elements:elements, // BB collection
painter:painter // an object that knows how to draw
});
the painter is seperated from plugin so i could easily change the way the collection is drawn.
So the objects here are:
miniPhotoshop - a jquery plugin that gets a BB collection
painter - an object consisting of methods that know how to draw the elements.
propertyBox - a jquery widget that when an element is clicked on shows its properties.
My question is does this jquery-backbone salad make any sence?
Apologies if this is an open-ended question, just hoping someone tried something similar before and be able to point me in the right direction.
Thanks!
I don't about others, but I wouldn't take jQuery for the structure of your app. I think Backbone is really good for structuring code, and jQuery is great for playing around with the dom.
My approach would be to use Backbone views to control the flow of your App and jQuery to play with/manipulate the dom inside Backbone views.

Good Ajax Chart/Graphic Library

I know there has been several discussions on JavaScript chart/graphics libraries, and there is many out there. What I need is one that can:
Zooming and panning
Data point manipulation (like when click on a data point, highlight other data points within the data series with the same certain parameter of the clicked one)
Dynamically change data point values (e.g.: dragging a data point dynamically updating the line shape)
Error bar support, horizontally and vertically
Select data points on the chart
Seems like Flot may have most of the features, if not all(not sure about 3, and 4), but would like to see if I don't miss out on there nice libraries.
Check out the awesome Visualization API on Google's AJAX APIs Playground
Take a look at http://raphaeljs.com/ library.
It has a plugin called gRaphaƫl which is charting plugin.
Look good but personally didn't use it.
Good luck and share you expirience if you try it.
The Dojo Charting Engine has a pretty astonishing featureset. Sadly dojo seems to suffer from a general lack of evangelism.
I dont know if there are good introductory tuts, maybe the best way is to learn from examples.

Categories