Closed BryanHunt closed 8 years ago
@BryanHunt awesome! I think there probably is a possibility to collaborate. ember-cli-d3-shape
, apart from being poorly named, was originally intended to provide a shim for d3-shape
, the primitives library which is part of D3 v4. One thing I never liked about working with the other Ember D3 addons was the dependency on Bower. I think this is inflexible, so I set about making a loader for D3 V4, which uses ES6 modules transpiled to UMD. There's a few hacks to make them work with Ember (look in index.js), but once they're loaded it means you can use only what you need. d3-array for example provides some very useful array methods.
I'm not certain on the end direction of this project yet, but I'd like to make it the most natural and flexible way to use D3 with ember at both a low level (primitives) and possibly at a charting level, with components.
The components aspect I think really depends on figuring out a flexible and easy to learn API for describing visualisations and reusing components.
A lot of the work in this project and another which I haven't released yet are the basis for my EmberConf talk this year.
So, maybe my components could be a layer on top of your shim? One thing I'm trying not to do at the component level is obfuscate the d3 API. There is a 1:1 correspondence between component and d3 properties. If you get a chance, have a look at my code and see if this makes sense.
I've actually been following your work for a few months while I've been building charts for Flood.io
One pattern I've started to notice is that mapping directly to D3 isn't quite the right approach. You end up with components which have too many assumptions about how they're used with other components and no real structure to how to construct a reusable visualisation.
Borrowing from the Grammar of Graphics, and the DDAU paradigm, I've been working at it like this:
[Data handling component] => [Plot] => [Elements, Guides, etc]
At the top level we have a component which accepts data from your route, applies transforms as needed, and computes scales (I've written some computed helpers for quickly creating scales from d3-scale
). These then get passed down to the Plot component, which is essentially the SVG element, with a bunch of contextual components attached. These components represent Elements and Guides in GoG parlance, and the thinking is that they would be Ember wrappers around all that is exposed by d3-shape.
The API for this would look something like this (where plaid is the name of my graphing add-on :smile:):
{{#plaid-plot xScale yScale width height as |plot|}}
{{plot.bottom-axis}}
{{plot.left-axis}}
{{plot.line values}}
{{/plaid-plot}}
Plot itself handles the private context of each primitive component such they they receive the correct inputs, greatly simplifying the public API surface. We also don't need to observe scales or data because each primitive will be re-rendered if any of them change.
A few notable short falls of this approach:
pie
s or donuts
, or essentially anything with polar coordinates.d3-transition
can now be synced much more easily than in v3. This might also make it possible to use liquid-fire
.ember-run-raf
.
FYI, I'm also working on ember components around d3. I think my approach is quite different from yours in that I'm providing data bindings to the components. I was wondering if there was any room for collaboration between our projects (I'm not exactly understanding what your code is providing). Here are the links to what I'm working on:
https://github.com/BryanHunt/ember-d3-components - low-level d3 components https://github.com/BryanHunt/ember-d3-charts - high-level chart components based on d3-components