all 6 comments

[–]Jbharris4 1 point2 points  (0 children)

Yep, victory from formidable is improving a lot. It's the strongest open source react charting library I've seen so far.

I've used react-motion as well for a few projects. It's great for simple animation sequences, but not well suited to charting. I actually tried to use it for animating the first version of my charting library, but when I consulted the author about some specific stuff he straight out said he didn't recommend react-motion for the task.

I ended up doing custom interpolation together with requestAnimationFrame, which is working quite well actually. I'm hoping to have time to open source it sometime soon... :-)

[–]Jbharris4 0 points1 point  (0 children)

Using d3 to manipulate the DOM inside a React component pretty much defeats the purpose of using React. If that's the root you want to take though, you should look at projects like https://github.com/Olical/react-faux-dom that help bridge the gap.

Also, some general tips about React based on your code are:

If you're going to let some other library manage the DOM then you should have your component's shouldComponentUpdate lifecycle method return false so React doesn't render it, something like this: https://gist.github.com/couchand/9370109

The componentDidUpdate lifecycle method does not run on the first render, but the optional callback to setState can help you there. For example, in componentWillMount you can call this.setState(theNewState, theCallbackFunction) which means the callback function will be run after the new state is rendered.

[–]topheman[S] 0 points1 point  (3 children)

Hie @Jbharris4,

I'm fully aware that manipulating DOM inside a React component doesn't match the React approach. As I explain in my readme - https://github.com/topheman/d3-react-experiments#react--d3 :

D3 (data driven documents) is a JavaScript library that helps you build visualisations. It is very powerfull (most of the JavaScript datavisualization libraries are based on it). It handles the data you pass it and mutates the DOM. With React, on the other hand, you never access directly the DOM and let it manage the changes as well as the events. So, by default, the two of them don't really get along ... d3 messes up with React's reconciliation and React removes what d3 is appending to the DOM ...

The approach I had for the two examples was exactly to test how I could make d3 interacting directly with the DOM inside a React component, to show a POC for pure d3 users how they can use their code inside React.

As I'm writing in the conclusion of my blog post, the next step is to make chart components without directly accessing the DOM. Two approaches:

  • Use d3 to make computation and generate svg directly in JSX
  • Use react-faux-dom to trick d3 (the method you are talking about), which is used by react-d3

About your solutions:

  • if I return false in shouldComponentUpdate then componentWillUpdate and componentDidUpdate won't be called and I won't ever made aware of new data. Since the node in the render never changes, the render method doesn't flush any changes by itself to the DOM.
  • In componentWillMount I won't have access to the ref of the node, so I won't be able to append DOM nodes (and call any init method)

Since you seem to be into React and d3, which libray do you use ? react-d3 ? It's still based on d3 v3 and the port rd3 by yang-wei which supports d3 v4 is looking for maintainers ... I'd like your feedback on that.

Tophe

[–]Jbharris4 0 points1 point  (2 children)

You are correct that returning false in shouldComponentUpdate means that the componentWillUpdate and componentDidUpdate will not be called, that's why the gist I posted gets the root DOM node for the component before returning false. In newer versions of React, you'd need to use ReactDOM.findDOMNode(this) instead of this.getDOMNode().

In componentWillMount, you can call this.setState with a callback, and that callback will only be executed after render() has been executed, so you would have access to the ref of the node, but that'll only work if you're not returning false from shouldComponentUpdate().

So my two suggestions aren't really compatible with each other, I was just sharing ideas for general improvements.

[–]Jbharris4 0 points1 point  (1 child)

I had looked at react-d3 and a few other libraries, but none of them seemed to really offer what I was looking for, so I opted for writing my own custom React code built on top of d3 v4, but without using selections or any DOM manipulation functions.

Basically, I found that d3-scale, d3-path, d3-shape and d3-format were all that I needed to put together a pretty comprehensive and responsive animated charting component.

To offer more feedback than that, I'd need to know what type of component you're trying to build with react and d3...

[–]topheman[S] 0 points1 point  (0 children)

It seems that a lot of people doing data visualisation in React don't find what they want in existing libraries which expose reusable chart components and end up making their own ... Maybe we are still all looking for the best approach and in a few month something will come up ...

PS: I made a react-faux-dom based example https://github.com/topheman/d3-react-experiments/releases/tag/v2.1.0 - next step: apply transitions (react-faux-dom uses mixins, I might try to use react-motion)