What I like most about D3.js is the complete freedom it gives you. I used it to build a dashboard that showed different types of data, how each item was progressing, and its status across the team, all updating dynamically as new data came in. Unlike ready-made chart libraries, D3 didn't box me into fixed chart types. I could design exactly the visuals we needed, like custom progress bars, status breakdowns, and trend charts, and make them match our app's look instead of settling for defaults.
The way D3 handles dynamic data is really powerful. Its data binding and enter-update-exit pattern made it easy to update charts smoothly when data changed, and the built-in transitions made progress changes feel alive instead of just jumping from one value to the next. It also worked well inside our Angular app once I set it up as a reusable component, and since it's free and open source with a huge community and tons of examples online, I could almost always find a starting point for what I wanted to build. Review collected by and hosted on G2.com.
The biggest downside is that D3 is really hard to learn. It's intense, and even a simple chart means thinking about scales, domains, ranges, axes, and a lot of math to position everything correctly. The naming doesn't help either. Terms like scaleBand, scaleOrdinal, d3.stack, or the enter-update-exit pattern aren't intuitive at first, and it took me a while before things really clicked. Something that takes a few lines in a ready-made chart library can easily take a hundred lines in D3.
Integrating it with Angular was also tricky. D3 wants to control the DOM directly, while Angular also manages the DOM, so you have to be careful to keep them from stepping on each other, especially when data updates or components re-render. Making charts responsive wasn't automatic either. I had to handle resizing and redrawing myself. The TypeScript typings can feel clunky, and debugging is hard because when a chart looks wrong, it's often a small math or scale issue that doesn't throw any error.
Another frustration is that many examples online are written for older versions of D3, and the API has changed quite a bit over the years, so copying an example often meant rewriting parts of it. Performance can also drop with very large datasets since everything is SVG, and things like accessibility and tooltips have to be built by hand. It's incredibly powerful, but you really pay for that flexibility in time and effort.
Maintainability was a real challenge too. D3 code is very personal to whoever wrote it, since there are so many ways to build the same chart. When a fellow developer needed to make a change, even something small like adjusting an axis or adding a new status, they often had to spend a lot of time understanding the scales, the math, and how everything was wired together. In practice, the person who designed the chart became the only one who could comfortably change it, which is risky for a team. Review collected by and hosted on G2.com.