5 ms·
Most intros to D3 (including D3’s own home page, for now) focus first on selections for DOM manipulation. Selections are great, but given how many viable approa
by mbostock 7y ago
Most intros to D3 (including D3’s own home page, for now) focus first on selections for DOM manipulation. Selections are great, but given how many viable approaches there are today for DOM (React, Svelte, hypertext literals, etc.), I wanted to emphasize the modularity of D3. So selections and joins aren’t introduced until part 7 where they’re framed as a tool for animation and interaction: efficient, incremental DOM transforms. I think that’s a better way of thinking about joins, and hopefully helps people focus first on building effective static visualizations before getting into dynamic graphics.
- sktrdie 7y agoThanks Mike for giving us d3! I was always curious about your thoughts about how d3's paradigm is similar to React/Svelte/SwiftUI/<any other UI lib>. I feel that d3's approach is similar in the sense that you have some data, and you describe in code how you want the data to be map to a UI (DOM in this case). With selection/joins it seems that d3 adds an extra capability that allows one to "do something" before and after data changes. In a way of analogy this would be similar to have finer grained control to when props change in React: d3 is similar in being able to transition specific prop numerical values (or something of this kind?). Anyway would love a TLDR on what you think about d3 and its similarity to other libs.
- mbostock 7y agoFirst, D3 is not primarily a DOM library or UI framework; it’s a loose collection of tools for data visualization, and is designed to work with other UI libraries. Second, the main difference with d3-selection (the part of D3 that does focus on the DOM) is that it focuses on transformation rather than representation. You describe changes that you want to apply to the DOM, rather than the desired current state of the DOM. This makes it harder to use (more complexity) than more declarative frameworks (UI as pure functions of state) such as React. But the advantage is that you can control exactly what happens as you change the DOM, which can make it faster, and makes it easier to animate transitions.
- sktrdie 7y agoCan you comment on why you think d3 is harder to use than a paradigm like react? Isn’t UI also a function of data in d3? When you make changes to the data the tree (DOM) is also updated. That’s why the differences are blurry to me. I would be curious to see how d3 scales in complexity for reactive UI apps... such as todo lists, forms, pages with buttons, etc.
- mbostock 7y agoI’m saying selections are harder than React, not that D3 is harder than React (because you can use React with D3 without selections). And selections are harder because, although they are functions of data, they are used to apply transformations (deltas) rather than declare representation (state). And as I say in the tutorial, thinking in terms of transformations is most useful when you want animated transitions and to optimize incremental updates. So for example I try to let Observable’s dataflow handle as much state as possible, rather than doing everything in event listeners.
- terpimost 7y agoThank you so much for Observable and D3! Could you tell how it’s possible to render D3 on a backend if it’s possible at all.?
- mbostock 7y agoMuch of D3 doesn’t require the DOM, so if you want to do things like generate SVG on the server, you can use d3-shape, d3-scale, d3-path, and the like as-is. If you do want to use the DOM on the server, you could use JSDOM. d3-selection and d3-transition use JSDOM heavily for unit testing and it’s worked well, but I’ve never used it for server-side rendering.
- thibautg 7y agoI’ve tried to use d3 without importing d3-selection (in Vue) but I still need it for d3-axis. Would it be possible to make d3-axis more DOM-agnostic?
- mbostock 7y agoEverything is possible but it’s work. I’m not planning on rewriting d3-axis to be DOM-agnostic (especially because d3-axis also supports transitions). As the tutorial shows, you can use d3-axis with Observable’s hypertext literal without selections because you’re allowed to embed arbitrary DOM elements in expressions. There are ways to inject arbitrary DOM content when using Vue or React, too, but perhaps not as convenient as hypertext literal.
- thibautg 7y agoA custom directive in a Vue template[0], is quite similar to your example with an inline expression in an hypertext literal. Maybe a little less elegant. But d3.select is still needed to select the bound dom element ;-) [0] https://stackoverflow.com/questions/48726636/draw-d3-axis-without-direct-dom-manipulation https://stackoverflow.com/questions/48726636/draw-d3-axis-wi...
- oroul 7y agoHi Mike! I really like what you've done with D3. I've been hesitant to include D3 in my personal projects though just because of how complex both DOM manipulation and async data binding through APIs can get. Most tutorials focus on D3 itself, but I haven't been able to find much on how to properly integrate D3 into a complete web application (e.g. a REST API build on Express/Koa serving data to a React/Vue frontend). Is this an area where you think there is a lack of tooling, or perhaps simply a lack of information? Given how many companies use D3 I feel like I must be missing something!
- wattenberger 7y agoone thing that might help is this blog post I'm (slowly) putting together: https://wattenberger.com/blog/react-and-d3 https://wattenberger.com/blog/react-and-d3 I've done a lot of work that uses d3 within a JS framework (React, Vue, Svelte, & Angular), and the key is to understand 1. how to create shapes in plain SVG, and 2. how to use the parts of d3 that don't do DOM manipulation. I've found the least-hacky way is to handle DOM manipulation with the framework, and use d3 for things like data manipulation, creating SVG path strings, creating scales to map from the data domain to the visual properties, etc.
- oroul 7y agoThis is a great resource, thanks for putting this together.
- mbostock 7y agoI would first focus on the overall design of the web application (so, look for React tutorials etc.). Treat D3 as a modular, low-level component within that application. You could start by creating static visualizations, say just using d3-array, d3-scale and d3-shape, and only opt-in to d3-selection and d3-transition when you add animation or interaction, if at all.
- noughtme 7y agoThis is the best and most recent series of tutorials i’ve seen on integrating D3 into React, and it uses up to date Hooks and React Functional Components: https://www.youtube.com/playlist?list=PLDZ4p-ENjbiPo4WH7KdHjh_EMI7Ic8b2B https://www.youtube.com/playlist?list=PLDZ4p-ENjbiPo4WH7KdHj...
- austincheney 7y agoThe interaction with the DOM is what turned me off to D3. The charts, graphs, user interactions, and even the API (aside from the DOM integration) are great. D3 tries to force an opinionated declarative abstraction to the DOM on the developer. I don't have any problems interacting with the DOM and don't need a tool like D3 dictating to me how that interaction should work or how to write code/interfaces outside of the graphs/charts it generates.
- mirekrusin 7y agoBut it’s all low level functions so you can use your dom manipulation, right?
- mbostock 7y agoExactly. Here’s a quick example of D3 without joins (and more are in the introduction): https://observablehq.com/@d3/d3-without-joins https://observablehq.com/@d3/d3-without-joins
- rhodysurf 7y agoUsing d3 (without selections) with react has enabled me to make some awesome visualizations for my react/react-native apps and I just wanted to say thank you. d3 makes it hard to go back to doing similar things in other languages.
- hashmal 7y agoI must admit that when I combine D3 with modern general-purpose frameworks I prefer to use the provided views/components as simple containers and use only d3 inside. I love the "transformative" approach (as opposed to the "state description" approach you mentioned elsewhere). It's just too good to "re-join" existing DOM elements with new layout rules to build crazy advanced visualizations. The widespread data/DOM binding pattern is easier for simple stuff but becomes convoluted for more adventurous uses.
- hashmal 7y agoAnother comment, at the risk of sounding like a crazy fanboy. After years of use, I still can't get enough of D3, it doesn't feel like JavaScript yet it fully embraces the best parts of the language. It is indeed a lot more difficult to learn than other solutions, but with the experience it becomes second nature to "think in it" and explore data iteratively, building visualizations along the way all while having fun (and its concepts map very nicely with how Edward Tufte lays out things in his books). All this to say: thank you.
- tlbsofware 7y agoThanks for the library! My very first professional project was making a choropleth map for the USGS and I used d3 to do it! Hella complicated though given it was also my first javascript project too haha https://tlbsoftware.github.io/streamgage_costs.html https://tlbsoftware.github.io/streamgage_costs.html It’s not very mobile friendly given I had yet to learn about bootstrap!
- talolard 7y agoAh wow that's a great insight, looking forward to diving into this
- NelsonMinar 7y agoIt's funny; when D3 was brand new it was selections and joins that were the big new unique feature, the thing that allowed the magic for D3. It's interesting to hear they're still important but that you'd de-emphasize them a bit in favor of other D3 features.
- nightski 7y agoI've used React and D3 a lot lately and while I do use React for DOM rendering - I still think D3's built in DOM manipulation/rendering is better at this specific task. This is especially true when dealing with animations and complex items like axes.