18 ms·
React and D3.js
- zappo2938 6y agoI can't imagine d3 being performant with dynamic data input when all the d3 code inside the useEffect() is rerun over and over again. Also, how do you handle the data flow with events such as tracking mouse movements and sharing that event data between d3 and react? I wonder if is better to have the d3 function inside of useCallback() and pass data as a parameter where the function isn't re evaluated rather than in useEffect where the function is run from the top again?
- uhoh-itsmaciek 6y agoI think this is partly why Amelia suggests rewriting these examples to let React handle the rendering and avoid DOM manipulation in D3. I rewrote a bunch of charting components at work a while ago, and that general approach worked really well for us. In fact, I barely ended up using d3 at all, but the bits that I did use were very handy. I found some of Amelia's other writing very useful in the process, and I blogged about what I learned [1] (for what it's worth, I do talk a bit about handling mouse interactions there). This is really the central point: >The crux of the issue is that they both want to handle the DOM. If you want to use D3 and React together, you need to figure out how to handle this, and there are several reasonable ways to do that. Letting React handle rendering is a natural approach, and works especially well if you are embedding your SVG components in an existing React application. But the "hand a ref off to D3 and keep React out of that element" approach can also work, especially if you are more familiar with D3 DOM manipulation already. [1]: https://pganalyze.com/blog/building-svg-components-in-react https://pganalyze.com/blog/building-svg-components-in-react
- zappo2938 6y agoEspecially if the developer is building with React Native which doesn't have canvas or svg natively but rather requires a shim for svg. I'm starting a desktop project with lots of data and I'm currently making some architecture decisions. I'm trying to answer what is the fastest path to MVP without getting locked with tech debt? These posts have been helpful.
- deleted 6y ago[deleted]
- knuthsat 6y agoGiven that all of the code uses React.FC instead of React.PureComponent or regular React.Component the efficiency obviously lacks, there's no props diffing and everything will be rerendered.
- superfamicom 6y agoOne of the best explanations and examples of mixing React and D3 I have ever seen, not to mention the presentation is beautiful and well thought out.
- revskill 6y agoThe article code examples lack of import statements. What's useSpring ?
- rozenmd 6y agohttps://www.react-spring.io/docs/hooks/use-spring https://www.react-spring.io/docs/hooks/use-spring
- batterylow 6y agoI enjoyed the presentation on that page - and D3.js is great. For anyone interested, here's an early access and practical book on visualisation with D3.js https://datacrayon.com/shop/product/visualisation-with-d3/ https://datacrayon.com/shop/product/visualisation-with-d3/
- cube2222 6y agoAfter regularly reading about D3 I've recently got the occasion to use it at my employer[0] to visualize users' infra resources, and it's been such a pleasure! Here's a small demo if anyone's interested: https://youtu.be/N9haFA_MwdM https://youtu.be/N9haFA_MwdM The simplicity of the declarative approach, where you just specify the desired state, and it will animate everything is really great to work with. If anyone would like to play around with it, I recommend this tutorial series on observablehq very much: https://observablehq.com/collection/@sxywu/introduction-to-d3-js https://observablehq.com/collection/@sxywu/introduction-to-d... Had lots of fun going through it. [0]:https://spacelift.io https://spacelift.io
- hahahahe 6y agoThe entire site is an absolute delight. Very nicely done.
- niceairport 6y agoWhile I agree that it looks sleek, it also made my 2019 MBP lag slightly on load, which... just shouldn't happen.
- shishy 6y agoMy 2015 is fine, fwiw... on firefox.
- madeofpalk 6y agoI know its a HN trope criticising the site rather than article, i found it ironic that an article about visualisation had terrible colour choices in the code snippets. the function names are next to unreadable for me. https://i.imgur.com/hApspGP.png https://i.imgur.com/hApspGP.png
- tptacek 6y agoThis feels a lot like rewriting a big chunk of D3 in React, for purity's sake. Maybe there's something to that, but the code is comparably long in both cases, and if I have to load a bunch of concepts into my brain's resident set, I wonder if I wouldn't prefer those concepts to be D3's, which work in a bunch of different places, and not an idiosyncratic set of React components, which only work in a small set of codebases. So for me, I feel like I got most of the answer from: get a ref from useRef, and use a useEffect to watch a data set and map the data to the ref using D3 itself.
- tracyhenry 6y agoNo, it's not for purity's sake. Integrating D3 with React is a real pain, because you essentially have a split brain problem where both D3 and React control the DOM. In complex cases involving things like transitions, you should wish yourself the best in not messing up the order in which DOM operations happen. And there is also huge performance benefits in letting only React control the DOM. I think the post has been amazing at illustrating how to translate D3 operations into JSX to get the best of both worlds.
- codethief 6y ago> Integrating D3 with React is a real pain, because you essentially have a split brain problem where both D3 and React control the DOM. I agree with you here but > there is also huge performance benefits in letting only React control the DOM. Compared to using d3 to operate on the DOM directly?[0] Do you have any benchmarks to back that up? Because in my experience, d3 is incredibly fast. Then again, maybe we're thinking about different applications? (Most of my experience is with animating stuff with d3.) [0]: Whether or not React is used alongside with it should not matter much, I think, as long as one doesn't trigger re-rendering of the React DOM.
- tracyhenry 6y agoI 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.
- dvt 6y agoI absolutely despise writing any kind of GUI/graphics/layout code in React's clunky long-form declarative style, but for whatever reason it's really starting to take off. I guess it's a sign of the times: there are developers these days that have quite literally grown up on React. It's starting to feel like XML (used everywhere, even when it might not make much sense). But to me, the code is longer, more unwieldly, more prone to error, and to top it off, it also inherits all of React's annoying idiosyncrasies. It's weird to even type this out, but Java's Swing felt more intuitive than seeing D3 on top of React. For example: <circle cx="150" cy="77" r="40" /> Just the fact that this could technically be written as draw.circle(150, 77, 40) in any sane programming language should give you some pause.
- thitcanh 6y agoYour example really does not help your cause. What’s 150? No idea, gotta look into the docs. The “insane” SVG example is much more readable, its JSX version would actually even maintain types (cx={150} since it’s a number). I generally agree with the rest of your comment, but that’s just a bad way to show your point.
- ggregoire 6y agoI tend to agree with you about the "JSX used everywhere", I hate plain logic wrapped inside a component that doesn't render anything but is still designed to be called in a render() (think something like <Fetch url={url} />). It doesn't seem that common anymore, but people used to do it just because it was technically possible, although it didn't make any sense. But the example you chose doesn't shock me that much. Why do you think draw.circle(150, 77, 40) is saner and more intuitive than <Circle cx="150" cy="77" r="40" />? It's fine to me if it renders a <svg> inside its parent node. Also the named parameters on the second function is a great addition for code clarity.
- genericstorage3 6y agoI'm the opposite, I despise anything angular, vue, knockout, that makes devs learn a new language. React just uses js, almost plain.
- villasv 6y agoInstead of baking your own glue, my personal recommendation is to use Semiotic by Elijah Meeks.
- tracyhenry 6y agoFor simple charting, for sure use Semiotic. But D3 is a low-level library for complicated, highly customized data visualizations.
- frob 6y agoSemiotic goes WAY beyond simple charting. It has a wide variety of visualization frameworks which serve as bases for highly customizable graphics. I will agree that there are things one can do in d3 alone that are not supported directly by Semiotic, but I would also argue that once one plays with it a bit, Semiotic can produce the vast majority of complicated and highly customized visualizations. And I don't need to worry about DOM battles.
- tracyhenry 6y agoI agree that Semiotic serves probably 80% of data vis use cases in real world. But at the end of the day it is a high-level template-based library that's less expressive than D3. If you take a random vis from observable's "trending notebooks", chances are that it is not reproducible with Semiotic. Those two libraries are really for different purposes.
- tunesmith 6y agoI wish there were more (free) options for interactive Sugiyama-type graphs. So far I only know of dagre and cytoscape.
- ggregoire 6y agoAlthough I haven't used Semiotic but Echarts [1], I agree with the sentiment. D3 is regularly on top of HN and I always wonder if its popularity is due to people not knowing there are easier alternatives, or because plotting with a low-level library is intellectually more interesting (gotta do some maths), or because they really need a library as low-level as D3 for plotting their data. I have been using Echarts for the last 4 years on a near daily basis and I've yet to find a visualization I couldn't do with it. [1] https://github.com/apache/echarts https://github.com/apache/echarts + https://github.com/hustcc/echarts-for-react https://github.com/hustcc/echarts-for-react Some examples here: https://echarts.apache.org/examples https://echarts.apache.org/examples
- purplecats 6y agoI really want to learn D3, and I've tried to learn it once before, but I just can't make it click in my head. I can find something and modify it to fit my needs, but I can't get the paradigm of it. This is such a beautifully and well written article and it's probably as close as I'll get to a digestible tutorial on it, so idk why I'm having such a tough time. I am very proficient at React and have been told multiple times that I'm a top performer at FAANG so idk what's so hard about D3.
- hogFeast 6y agoIt is fairly simple imperative code: you just call functions on everything. Where it gets more complex is data and fitting that into an imperative model with very few flow control constructs: updating, creating multiple elements at once, doing weird things like calling select on elements that don't exist yet, and for most chart types there is a topological ordering on the graph of actions required to create a chart (i.e. you have to create an axis before you create a line because you need the axis that maps your data points to x,y positions)...combined with the fact that d3 throws almost no errors or misleading errors with bad inputs, and it can definitely great pretty tricky. The saving grace is the dispatcher which you can use dispatch events, and this does make it possible to break up your code. Also, it is nothing like React. Trying to get d3 working with React is like trying to stuff a sausage through the eye of a needle. It is a great package but it is becoming a bit outdated as the world moves towards things like React. Also, for most users it is superfluous. I still use chart.js, and only move things over when I have problems.
- brailsafe 6y agoIf you're coming from React and haven't done much classic JS procedural DOM programming, you're just coming from a bit of a different level of abstraction that would be hard to click with or justify the necessity of doing so. In the reverse I personally never jived with React and procrastinated like hell in learning it. I find something about it uninteresting, as if all the tricky bits about js sort of turned into just assembling blocks.
- brundolf 6y ago
- dimmke 6y agoVisx basically solves this problem: https://airbnb.io/visx/ https://airbnb.io/visx/
- gsserge 6y agovisx is great! It hides a lot of D3 complexity and provides a very composable React API. The D3 API are still there if and when you need them.
- realPubkey 6y agoThis. I also used it, works great.
- dimitrisnl 6y agoExcept when it doesn't. D3 can do some work with text (legend) truncation, clamping etc, while visx cannot.
- fermienrico 6y agoWe need to show some restraint towards extremely bright fully saturated colors, especially for text. Observe contrast and don't just go around cranking up the saturation slider. It's the HDR of website design, stop doing this please.
- zz865 6y agoIts worth checking learn D3 on the observable site https://observablehq.com/@d3/learn-d3 https://observablehq.com/@d3/learn-d3. We talked about it here, with mbostock too https://news.ycombinator.com/item?id=22675551 https://news.ycombinator.com/item?id=22675551
- wly_cdgr 6y agoI don't understand why people use D3 over something sane and simple like Pixi
- Ronsenshi 6y agoAlmost entirely different usecases. D3 is a data visualization tool. PixiJS is a rendering engine. You can see a good example of what D3 is used for: https://observablehq.com/@d3/gallery https://observablehq.com/@d3/gallery
- wly_cdgr 6y agoI'm reasonably familiar with D3 as a frontend engineer who has used it for standard use cases at my current company. My question is why don't we use something like PixiJS instead, given that its API is much simpler / more straightforward / less idiosyncratic I don't see that it matters that it's not marketed as a dataviz library the way D3 is, given that it can clearly do everything D3 can (I guess aside from manipulating the DOM but why would that be necessary when every relevant browser supports canvas WebGL at this point?). So what is the issue? -... Accessibility, maybe? Seems pretty surmountable to me at first glance, if that's what it is. Or is there a performance gap? I guess that could be the case, although it would be kinda weird given that PixiJS is fast enough to handle 30+ FPS of richly graphical interaction
- locallost 6y agoI started working on a Vue project that needed to add a couple visualizations, and initially I didn't overcomplicate, and did it just with d3 and "DOM manipulation". Later on I also tried this approach because it's what Vue expects and otherwise has quirks if you don't use its templating, but in the end stayed with d3 because some things seemed just really simpler (e.g. transitions). The complexity doesn't really change if you go from .append('circle').attr('r'...) to <circle r="... />. It's definitely from a previous era, and feels a bit dated, but this also has its advantages. For example, SVGs don't have z-index, and so it's done by the order of the children nodes. With a template you would have to copy a large chunk of code and paste it somewhere else if you want to change the order, but with d3 it could be a one line change (e.g. take this .append('g') and move it below that .append('g')). But either way, the real value in d3 are all the layouting functions, where you dump in your data, and it gives you a path to draw. How you then draw this data is really less important.
- austincheney 6y ago> For example, SVGs don't have z-index, and so it's done by the order of the children nodes. That isn’t correct. SVG is an XML island that composes into DOM nodes with each receiving the benefits of CSS plus the visual rendering instructions SVG provides. You can even walk the interior of an SVG in your browser developer tools and experimentally add CSS as you wish.
- locallost 6y agoyou can't use css z-index to control how shapes (circle, rect, path...) inside an svg overlap. those later in the tree are the ones on top.
- austincheney 6y agoHere is the answer from the specification: https://www.w3.org/TR/SVG2/render.html#EstablishingStackingContex https://www.w3.org/TR/SVG2/render.html#EstablishingStackingC...
- darepublic 6y agoFrom the article: > Animating elements out is not very straightforward in React, so let's keep all of the <circle>s rendered, and give them an opacity if they're not in the currently shown circles. ...Which is the crux of the problem I always run into trying to do complicated animations in React
- throwaway4good 6y agoUse css.
- a_humean 6y agoCSS is pretty terrible for interactive and cancellable animations, and React does not make it easy to do exit transitions for which CSS provides no solution. Hence the existence of libraries like react-transition-group, react-motion, and react-spring. Letting D3 control DOM rendering is another solution to this problem.
- throwaway4good 6y agoI am pretty sure that this particular example can be done with css in a fairly straight-forward manner. In general case I agree with you. CSS only will take you so far.