
D4 – Declarative Data-Driven Documents - joelburget
https://d4.js.org
======
krebby
This is a good start but it glosses over the hardest part of making React work
with D3, which is animations. Most animations you want to do with D3 don't
fall neatly into categories you can use with CSS animation (namely updating
paths and entering / updating / exiting animations).

React as an ecosystem is pretty fantastic but the React animation story is
still pretty terrible unfortunately. "Portals" / "reparenting" is a majorly
hacky way of getting an element from one part of the DOM to another, and even
React Motion, which solves a few of the animation gripes, is hard to use,
slow, and brittle in my experience. There just isn't a good substitute for the
enter-update-exit selections that make up the core of D3.

My usual workflow is to get as much DOM building done in React as I can, with
D3 filling out the tricky bits. D3's lifecycles and direct DOM manipulation
are much more complicated to reason about than React, on the whole.

~~~
gedy
I've tried both, but between D3's odd imho data-binding and React animation
limitations, I gave up and found using RactiveJS with SVG directly was much
easier: [http://examples.ractivejs.org](http://examples.ractivejs.org)

RactiveJS uses virtual dom as well, so was quite performant and very easy
animations of properties.

~~~
krebby
I don't agree that D3's data binding is especially odd. It isn't as
straightforward as React's vdom descriptor, but it's not especially
complicated:
[https://bost.ocks.org/mike/circles/](https://bost.ocks.org/mike/circles/)

~~~
colinmegill
You are in the minority. Having taught it, I've seen students struggle.

Creating markup through chained functions executed as many times as there are
items in an array, where the convention is to name the array singularly:

ie., node.append('g')

is counterintuitive.

~~~
krebby
It's definitely a steeper learning curve than simply creating a node and
appending to the DOM (the d3-specific idioms are particularly obtuse) but it's
not insurmountable.

------
weego
Sorry, I don't get it. The code in any of the given example comparisons has no
less obvious complexity and just removes the abstraction that writes the SVG
nodes for you with having to explicitly write them in your JS which I
similarly have never understood why we're intent on going back to.

Different for the sake of different is fine, but "preferable" is a bold
statement that appears to have no evidence.

~~~
woah
I suppose that everything is a matter of opinion, but d3's syntax is the worst
combination of obtuse (".enter"???), cute (the incredibly obnoxious chained
api), and cumbersome (all the mutation, and the fact that d3 code always ends
up being a long string of procedural spaghetti).

Of course, it does have a lot of useful code around math, projections, etc.

This project looks like a very welcome step in the right direction, showing
that d3's great math can be used with obvious, declarative syntax.

~~~
dirtyaura
Can you explain why do you feel 'enter' is obtuse? I found enter/update/exit
pretty logical. I do agree that long-term value of Bostock's work is in other
parts than data-binding, but I didn't find enter/update/exit particularly hard

~~~
dimgl
I agree with you as well. The enter/update/exit cycle is actually very
intuitive although the documentation could do a better job of explaining what
the functions are doing to the DOM.

~~~
Bahamut
In this case, I think a little more verbosity in the names of these methods
would assist in understanding significantly. For example,
enterAnimation/enterTransition would increase the clarity for someone new to
d3, or who has been away from it for a while.

~~~
renlo
enter is used to insert elements into the DOM; if there is data in the data-
set which isn't represented in the DOM, then new elements will be inserted
which have that data. It doesn't have to do with animations really, though you
can animate those newly inserted elements if you wish.

~~~
Bahamut
I understand how enter works, but my point is that the naming is pretty poor.
If I haven't been around d3 for a while, it becomes very easy to forget how it
works because of exactly this. Its api isn't intuitive, which often indicates
either bad naming or design - in this case, I would pin it largely on the
naming, and the api design not facilitating understanding as easily.

------
deno
Hybrid approach:

> let React do all the migraine-inducing heavy lifting to figure out what to
> enter and exit, and have D3 take care of the updates.

[https://medium.com/@sxywu/on-d3-react-and-a-little-bit-of-
fl...](https://medium.com/@sxywu/on-d3-react-and-a-little-bit-of-
flux-88a226f328f3#.h143joihp)

------
colinmegill
Love this - awesome work.

Wrote an article on this concept last year:
[http://formidable.com/blog/2015/05/21/react-d3-layouts/](http://formidable.com/blog/2015/05/21/react-d3-layouts/)

and spoke about it at Reactive2015:
[https://www.youtube.com/watch?v=n8TwLWsR40Y](https://www.youtube.com/watch?v=n8TwLWsR40Y)

Have been doing data visualizations like this ever since, it works. Yes, the
hardest part is animation, which we had to address, as well as the axis
components and other higher order functionality that builds on d3 itself:

[https://github.com/FormidableLabs/victory-
animation](https://github.com/FormidableLabs/victory-animation)

[http://formidable.com/open-source/victory/docs/victory-
axis/](http://formidable.com/open-source/victory/docs/victory-axis/)

------
dechov
My team and I have been using and finding success with such a pattern for a
couple of years now.

As others are alluding to, transitions are not currently so easy to express
with React alone. We wrote and recently open-sourced a React component that
aims to encapsulate the power and simplicity of d3 transitions (feedback &
contributions welcome): [https://github.com/dechov/join-
transition/](https://github.com/dechov/join-transition/)

~~~
colinmegill
Nice - thanks for sharing this

------
otoburb
>> _There are some pieces of d3 that I would love to use but aren 't easily
portable. For example, d3-drag and d3-zoom smooth over a lot of the quirks
you'd have to deal with when implementing dragging and zooming, but they're
only designed to work with d3 selections [...] Ideally we could decouple these
libraries from selections, but it might also be possible to mock the selection
interface they expect while still using React._

According to the changelog for the recently released version 4.0.0 of D3.js by
Mike Bostock[1], one of the big shifts is for D3 v4.0.0 to be "composed of
many small libraries that"[2] can be used independently. So the author of
D4.js can now more easily examine Bostock's refactored code for Zoom and Drag
as they please.

[1]
[https://github.com/d3/d3/blob/master/CHANGES.md](https://github.com/d3/d3/blob/master/CHANGES.md)

[2]
[https://github.com/d3/d3/releases/tag/v4.0.0](https://github.com/d3/d3/releases/tag/v4.0.0)

~~~
ctvo
If you look at the example code, the author is aware of the new modules pulled
out of d3. He's actively using them. It doesn't change his comments re: those
two modules specifically.

------
aurelianito
I find that D3 is great, but it needs an abstraction for the general update
pattern
([https://bl.ocks.org/mbostock/3808218](https://bl.ocks.org/mbostock/3808218)).

I did that! One function that receives actions for update, create, delete,
etc. Now my code is easier to read. Check the function gupChildren (AKA:
General update pattern for child nodes of a selection) in my code, and feel
free to use it: [https://bitbucket.org/aurelito/sandro-
lib/src/83b81c4b556848...](https://bitbucket.org/aurelito/sandro-
lib/src/83b81c4b55684866fbab50ff98088822b1d42410/src/sandro/nadaMas/d3.js?at=default&fileviewer=file-
view-default)

At last, unless you understand what you are doing, use selectAll and no
select.

Cheers!

------
jordache
argh.. I hate the style of mixing JS with markup language....

~~~
intrasight
Agreed. Please tell me there's another syntax for this. Please don't tell me
that we're stuck with this sad relic of the past.

~~~
dcre
There is. You can write regular function calls like this:

    
    
      React.createElement('h1', {}, 'Hello')
    

Personally I like JSX a lot, but you don't have to use it.

~~~
kasbah
I prefer:

    
    
        h1('Hello')
    

[https://github.com/Jador/react-hyperscript-
helpers](https://github.com/Jador/react-hyperscript-helpers)

------
jtwaleson
I'm not sure if this is it, but the world needs a simple way to integrate D3
and React. Looks good at first sight though.

~~~
danieljoonlee
Here's a library that integrates the two
[https://github.com/react-d3-library/react-d3-library](https://github.com/react-d3-library/react-d3-library)

------
pathsjs
Shameless plug: I have been proposing this approach for long. I found that the
missing piece is how to generate the actual geometric information starting
from data, hence I wrote a library to this effect
[https://github.com/andreaferretti/paths-
js](https://github.com/andreaferretti/paths-js)

For the animations, it is often just a matter of continuosly updating the
state of some component, something that I did in this mixin
[https://github.com/andreaferretti/paths-js-react-
demo/blob/m...](https://github.com/andreaferretti/paths-js-react-
demo/blob/master/js/animate.jsx)

------
athenot
I've done the opposite: use d3 to provide React-like semantics.

\- Basically the data fetches get pushed to a lightweight queue/topic system
in the browser (using publish.js).

\- Each part of the page listens for messages it cares about and updates the
page accordingly.

There is still some of the d3 plumbing (I must specify how updates differ from
mere element creations, and handle the exits). But I still get a nice
decoupling between the different parts of my app. Coupled with browserify,
this ends up with semantics not unlike Erlang (I even named the listener
method "receive" and it acts on patterns of messages).

------
koopatrol
I'm excited to play with this. I wonder what kind of overhead it has. I
imagine it would be fairly low.

~~~
gavinpc
My CPU fan begs to differ. Or maybe you meant something different by overhead?

------
b34r
Intelligently-optimized JS animations are generally more performant than CSS
ones by an order of magnitude. See Greensock for relevant examples. Side note,
your examples don't assign keys to your array-mapped paths, which will emit
warnings.

------
FoeNyx
@joelburget, btw the "demos" link leads to a 404.

(
[https://github.com/joelburget/d4/demo](https://github.com/joelburget/d4/demo)
)

------
guylepage3
Very cool.. My only question is.. Is this "D4.js" a full feature replacement
for D3.js? Could be a bit misleading. Might want to have a new name for it?
Thoughts?

~~~
the_duke
The very second sentence of the article answers your question:

 _This is not a library, but rather a demonstration that it 's possible (and
preferable) to use React instead of the core of d3._

~~~
guylepage3
Yes. So then the title is very misleading and should not be called D4.js.

~~~
ctvo
Did the title get changed? Both on this post and the article, there's nowhere
that it says it's D4.js.

------
adamwong246
I've been working with a similar approach for a while and I give it my vote of
confidence. Much more elegant than d3's awkward data-binding.

------
nthitz
d3.transition works on element attributes not just CSS. Wish React had
something like that!

~~~
nathancahill
You can do that easily with [https://github.com/chenglou/react-
motion](https://github.com/chenglou/react-motion)

~~~
SamBam
I've played with ReactMotion, but I was under the impression that it _was_
only for styles, not for arbitrary component attributes.

In the Readme they say the `style` property is required, and they also don't
show any examples of animating something other than style.

~~~
nathancahill
It gives you a continuously changing variable that you can use for whatever
you want. The name _style_ is confusing, because it isn't actually a style. In
the very first example it's just displaying the changing value.

------
choward
What is this? I can't even scroll.

------
colemannerd
I need something exactly like this.

~~~
colinmegill
Check out:

[http://formidable.com/blog/2015/05/21/react-d3-layouts/](http://formidable.com/blog/2015/05/21/react-d3-layouts/)
[http://formidable.com/open-source/victory/docs/victory-
axis/](http://formidable.com/open-source/victory/docs/victory-axis/)

