5 ms·
Replacing most of D3.js with pure SVG and AngularJS
- danso 13y agoThis is a good detailed guide but I think I'm missing something here. I can't quite formalize it but it has something to do with this: > You may be wondering how we'll go about adding Axises to our graph, but here be dragons, so I'll leave that aside for the moment. Uh, OK...having axes (and labels) is pretty integral to many charts and is pretty trivial in D3. If Angular is to replace much of the data-binding in D3, as the OP proposes, then I think there has to be less ad hoc hacking of Angular things to do what's relatively easy in D3. This reads more like a guide of how to get D3 (or rather, SVG charts) in a situation in which you cannot really use D3.
- alexandros 13y agoThink of d3 as a framework and a standard library. This post is about replacing the framework. However, d3 still has a load of ready made controls such as the axes. These don't exist for this new approach yet, at least not natively. But I have released code (see the bottom of the post or just https://github.com/resin-io/triangular.js https://github.com/resin-io/triangular.js ) that allows Angular/SVG graphs to add axes. Just didn't want to go deeper into documenting that too as I've gone past 2000 words already. Hopefully in the future this will be done in pure angular, as these directives use more or less the old approach of encapsulating d3 in a directive. But at least they are re-usable.
- dmak 13y agoWell obviously it is not perfect. OP was just introducing the idea.
- coherentpony 13y agoI can't seem to play with any of the graphs interactively. Is that intentional? Also, this site completely hi-jacks my 'Back' button.
- alexandros 13y agoApologies for the 'back' hijack. It could have something to do with the plnkr.co embeds? Otherwise the page is pretty simple. The graphs aren't interactive in their current state (but there's nothing stopping them from being made interactive).
- 1wheel 13y agoThis is interesting, but I'm not really sure what you get from it. d3 and direct manipulation of SVGs are both so low level that make a decent looking chart requires a bit of boilerplate. That boilerplate should get wrapped inside of a directive and once you've done that, the specifics of how the directive is implemented don't matter too much. It would be nice to use one language for data binding; I think angular would end up being a lot more verbose and prevent some of the nice things you can do with .call() and .transition() though. Additionally, I don't think 'creating a hole in the DOM' is necessary a bad thing. Sending graphs only the information that they need separates concerns nicely, resulting in more modular and maintainable code. If you haven't read it, http://bleedingedgepress.com/our-books/developing-a-d3-js-edge/ http://bleedingedgepress.com/our-books/developing-a-d3-js-ed... is pretty good.
- alexandros 13y agoEven if it all gets buried under high-level visualisations, it's better to have fewer moving parts and a smaller cognitive model in case you do need to dive in. But the premise of d3 is that you tweak your visualisations. There are other libraries like raphael that are supposed to be higher level. But there are many times you need to create something new. At least I've had to, maybe I'm atypical. And when that time comes, I prefer manipulating familiar HTML and AngularJS that I also already know, than needing to understand yet another toolkit's approach to bindings.
- tmcw 13y agoFor the opposite: http://macwright.org/2013/07/07/d3-for-html.html http://macwright.org/2013/07/07/d3-for-html.html
- almost 13y agoReally cool, I'm sure there are projects where this would be very helpful (although I don't see either of Angular or D3 replacing each other any time soon). The ng-attr-x thing is a neat hack but it's a bit unwieldy. How about adding a d3-svg directive that turns itself into an svg element once Angular is done loading. You can hide it with CSS so it doesn't flash up random garbage on the screen and within it you can use regular SVG attributes.
- jarpineh 13y agoAwesome stuff. I’ve been going through JS libraries looking for better approaches to DOM manipulation. Previous examples of Angular with D3 were hard to use for my needs (though my lack of Angular as well as D3 skills didn’t help). I decided to implement Angular parts by myself (data binding, event bus), since the integration gave me headache with few returns. I saw in twitter that you already got a ping from Rich Harris of Ractive fame. Hopefully you have time to blog about your experience on that front. I really liked working with Ractive, but couldn’t figure out how to combine D3’s functionality with it (like path and axis objects). Your post certainly gave me great pointers. Also, I did not manage to build complex tables with Mustache templates. On that front I hope React from Facebook is even better, but my testing is till ongoing. I’d like to see a library on top of D3 that would use its extensive algorithms without the DOM manipulation. Your approach seems great for Angular use, where I probably shall return also. Still, with Ractive getting visualization going was really easy (not to mention fun) and React promises great performance in addition of strong component structure. D3 however has so much more for visualization at this point (geo module, scales to name a few).
- alexandros 13y agoThanks for the kind words. Truth be told, I didn't expect this post to do this well, and also I am learning a lot from all the responses. Unfortunately I do run a startup, so I am not sure how much more time I have to put on this. Hopefully the ideas herein will ignite someone to actually get that proper d3/angular integration going. Fingers crossed.
- kayoone 13y agoi love angular but i dont really like the notion of having to reinvent the wheel with it. I read about how one should ditch jquery plugins and rewrite them the "pure angular way" which makes sense for smaller stuff but there are so many very useful jquery plugins that have been around for years with alot of people working on them. D3 is not a jquery plugin but why would i want to rewrite it for use in a specific framework ? When the next framework comes along that rewrite is more or less useless..If Angular is going to be the same standard as jQuery has become this is fine, but with current crop of competitors and the fast moving market i doubt it.
- coldtea 13y ago>I read about how one should ditch jquery plugins and rewrite them the "pure angular way" which makes sense for smaller stuff but there are so many very useful jquery plugins that have been around for years with alot of people working on them. Actually it's supposed to make sense for the larger stuff -- Angular is not something to just replace a few small bindings in a your page while you do the rest of the stuff in 2005 way. As for those "jQuery plugins that have been around for years" most of them are badly coded rubbish compared to what you're supposed to write in Angular style.
- wwweston 13y ago> Angular is not something to just replace a few small bindings in a your page while you do the rest of the stuff in 2005 way. If we're talking about the jQuery way, let's at least say "2006", since that's when it was released, though it arguably didn't become "the" way for another few years afterwards. The big news in 2005/2006 was still Prototype.js. > most of them are badly coded rubbish compared to what you're supposed to write in Angular style. Or we don't have the benefit of 5 years of hindsight about what's problematic (or, "rubbish", if you will) when it comes to Angular style.
- kayoone 13y agoFrom my understanding other frameworks like Ember rely heavily on jQuery, unfortunately i havent really worked with them so i dont know what that means for plugins. We can not reuse angular directives in Ember/Backbone/Meteor so it doesnt make sense to spend the effort to reimplment bigger plugins/libraries imo. It would actually be the other way round, you build your app in angular and for some specific view related code you use a proven and stable jQuery plugin, which imo still makes sense. Furthermore you are being hyberbolic, jQ wasnt even released in 2005. In reality, when i have a client project with tight deadlines to finish and i need drag and drop functionality (as an example), i have little motivation to rewrite that just to avoid a jquery plugin that does the same thing and is much more mature.
- ricardobeat 13y agoWhy would you want to rewrite a stable, complete and extensive visualization framework within your MVC framework? d3 should sit at a lower level, the approach of containing the implementation to a directive looks much sounder.
- beefsack 13y agoI went along the path that using a directive to trigger D3 updates when $scope changes in AngularJS is a much better idea that throwing the baby out with the bathwater. D3 is incredibly powerful for visualisations, and it benefits greatly from simply tying it into the automatic $scope updates in AngularJS. https://github.com/beefsack/angular-d3 https://github.com/beefsack/angular-d3
- milroc 13y agoAlexandros, I think you're missing a lot of the core concepts around visualisation. d3 aside (for now) you need to consider what visualisation is. Your focus is on charts alone will prevent this from getting any traction. d3 is a framework but it is also in a way, a visualisation kernel. This means that it gives the individual flexibility to create and design interactive information visualisations without being hindered by whatever is enforced by some charting library (only limited by the DOM or whatever scene graph it is working with). d3 can also be viewed as an extension of the concept of 'grammar of graphics' (for a reference implementation of the grammar of graphics see vega (http://trifacta.github.io/vega http://trifacta.github.io/vega) or ggplot2). If you're plan around this is to build a system in which angular handles a lot of the data binding work, I would recommend re-implementing something like vega in angular. Because this would be more compelling than creating yet another charting library that is just built using some combination of d3's data manipulation and angular DOM style. nvd3.js, chart.js, yui-chart, etc. all run into this point where the libraries are simple tools for developers to use but do not have the extensibility of a framework like d3 that allows more freedom in the design. Now lets say you create a competitor to vega, the key differentiator would be animation, assuming transitions are trivial as you've explained in this post, I have very minimal experience aside slides and videos in angular to comment. While vega will have: canvas scene graph support, potential to build on top of systems like WebGL, native iOS, or native Android. You will then be tasked to figure out the 'grammar of interactions' (https://github.com/trifacta/vega/issues/28 https://github.com/trifacta/vega/issues/28) in order to allow attributes to differentiate yourself from vega which is going to be a very hard (but fun!) task. Aside: d3's line function isn't refreshed as new data is inputed (meaning that you would either have to do this inside of some custom directive (towards the vega style implementation) or do some hack-ish 'tick' style system (the reason force directed is being updated is due to the fact that it has it's own very small physics model which you are leveraging on tick, (also 'ticks' do not harness angular's or d3's data binding concept well))). I do think there is space for a true competitor to d3.js that takes a more OOP and stateful approach (what the root of your annoyance with d3 seems to be). While there may be room for this, I also feel (note emotion not backed with fact) like these concepts are also what will build too many limitations that will hinder the project itself. This competitor will likely live within the web components community once it's no longer dependent on angular.js, but will likely hit walls (just different walls than the ones you're currently frustrated with d3.js) that are going to be hard to get through. I have thought about this stuff in the past (http://bl.ocks.org/milroc/5519819 http://bl.ocks.org/milroc/5519819 http://youtu.be/Hd2rye9a9kk http://youtu.be/Hd2rye9a9kk) and recommended a wrapped directive approach for angular.js (and other MV*) but as I said above the next steps are going to be MUCH more difficult than we expect. Cheers, Miles @milr0c