3 ms·
I don't have a benchmark but I was referring to the case where some D3 APIs (e.g. zoom, force) seem to create more animation frames than needed, and interfere w
by tracyhenry 6y ago
I don't have a benchmark but I was referring to the case where some D3 APIs (e.g. zoom, force) seem to create more animation frames than needed, and interfere with other React state changes. I probably should do this experiment myself now that I see the elegant solution proposed in the OP. Also, if you use Ref, you are re-rendering the entire thing on every state change whereas React can do the diff with vdom. Ofc you can do the diff yourself with D3 code but it is less automatic.
- hogFeast 6y agoBingo. Even when you aren't doing animation frames, if you want to structure your app in a reusable way then you are (if you aren't careful) going to get lots of re-renders. If you are using hooks, and have useState/useEffect/useReducer it is very easy to go wrong. It also isn't re-inventing the wheel. d3 and React are based on fundamentally different models of programming (d3 is very imperative). I have done two or three pretty complex charting apps, and the only way to really break that cycle is to use the dispatcher which allows you to break up the flow of d3...you still end up with a ton of cruft, and lots of confusing constructs (you have to be very specific about what state is needed where and when...for example, some constructs in d3 require data immediately i.e. an axis, and others do not i.e. line, and some constructs require other constructs i.e. the dependency between lines and axis...clearly this conflicts with the data flow of your typical React app quite heavily).
- tptacek 6y agoI think you can more easily convince me that D3 and React don't go together at all, because their models conflict, than that it makes sense to code directly to D3's guts and replace a lot of its logic with React's. But you all have more experience with this than I do (I've used both in anger independently, but not together). There's a point in this article where they've replaced D3's axes code with a new React implementation. "Okay! So this is definitely more code. But that makes sense, since we're basically duplicating some of the d3 library code, in our own code base." I mean, yes. It makes sense. But it is, ceteris paribus, way worse than D3, where axes generation is kind of a fundamental basic idiom of the library, which we're here replacing with idiosyncratic new code. I get that the code might be better in some other direction, but just as code, it's worse. The claim is that it's more readable, but: it's only more readable if you don't do a lot of D3. To me this is shades of people trying to talk about Lisp function names or APL or whatever.
- chrisweekly 6y ago"ceteris paribus" -> "all else equal"
- totololo 6y agoDid you mean, at iso-circumjacentium? :p
- hogFeast 6y agoI think the issue is that when you try to make reusable charts, you end up doing this stuff anyway. You aren't replacing logic but you are coding around d3's logic. I 100% agree though, it is very janky. The issues aren't limited to the points you mention: state everywhere, errors getting swallowed, problems when you update (for example, the Axis component has a useMemo that renders once on load and doesn't change...this isn't a good idea because, presumably, you have to re-render on every update), on and on. The issue isn't d3 but making components reusable within React. d3's dispatch model fits well with React. But the data flow/dependencies just don't work with React at all (i.e. having to declare operations in a certain order). I am not 100% sure that the component library approach works. I get the idea but you need to actually tackle the problem of state and updating, which means working with the imperative model (i.e. not declaring your chart elements in React but using d3's imperative code, and hooking that into React's update cycle...for example, how would you use d3-brush with declarative code? Maybe I am missing something but it doesn't seem possible). I have no idea whether it is possible to integrate these two approaches fully...probably is but I surely don't know how (my approach so far is largely imperative, relies heavily on dispatching events, and splits state between data/chart constants/individual charts...I think it is possible to go further with hooks but I haven't had time to explore this fully...the declarative approach of actually writing svg elements and g elements seems too brittle).