A developer recently documented spending 50 hours building what sounds like a trivial feature: a line graph. No third-party charting library. Just raw canvas or SVG, a dataset, and the slow, humbling realization that "drawing some lines" is never just drawing some lines.
If you have ever told a client "the chart will take a day or two," you already know how this story ends.
The Illusion of Simple UI Work
Line graphs look deceptively straightforward. You have an x-axis, a y-axis, some data points, and lines connecting them. How hard can it be?
Very hard, as it turns out — and for reasons that only become visible once you are knee-deep in the implementation:
- Axis scaling. Deciding where tick marks fall, how many there should be, and how to handle non-round numbers cleanly is a small mathematical problem that quickly becomes a large formatting problem.
- Responsive layout. The chart needs to reflow when the container resizes. That means recalculating every coordinate on every resize event, debounced correctly.
- Label collision. When data points cluster together, labels overlap. Resolving this without making the chart look broken requires either a collision-detection pass or deliberate design trade-offs.
- Edge cases in the data. Null values, single-point series, negative numbers, very large ranges, very small ranges — each one breaks a naive implementation in a different way.
- Accessibility. Screen readers cannot read a canvas element. SVG with proper ARIA roles, title elements, and keyboard navigation adds a meaningful layer of work.
- Interaction. Hover tooltips, click events, zooming — none of this comes free.
Strip all of that away and yes, you can draw some lines in an afternoon. But a chart that is actually usable in a production interface? That is a different scope entirely.
Why Developers Keep Underestimating This
The core issue is effort invisibility. When you look at a finished chart in a polished product, you see the output, not the 47 micro-decisions baked into it. Your brain anchors on the visual simplicity and ignores the engineering surface area underneath.
This is the same cognitive trap that makes developers underestimate:
- Form validation (looks like a few
ifstatements, actually involves UX flows, async checks, and localization) - Date pickers (looks like a calendar, actually involves timezones, locale formatting, keyboard navigation, and mobile layout)
- Search bars (looks like an
<input>, actually involves debouncing, ranking, empty states, and accessibility)
Custom data visualization sits at the far end of this spectrum. It combines geometry, math, responsive design, accessibility, and data handling into a single component.
When a Library Is the Right Call
The honest engineering answer most of the time is: use a library.
Tools like D3.js, Chart.js, Recharts, or Apache ECharts exist precisely because this problem has been solved — painfully, repeatedly — by teams with the time to get every edge case right. Reaching for one of them is not laziness. It is recognizing that charting is a deep domain and your competitive advantage probably lies elsewhere.
A useful mental model: treat charting libraries the way you treat payment processors. You could implement card tokenization yourself. You should not. The same logic applies here.
That said, there are legitimate reasons to go custom:
- Your design system has constraints no off-the-shelf library can meet
- You are building a charting product itself, and the library becomes the product
- Performance requirements (millions of data points) push you toward WebGL rendering that existing libraries do not support well
- Licensing or bundle-size constraints rule out the available options
Outside these cases, a library plus careful theming will get you 95% of the way there in a fraction of the time.
What This Means for Estimation
If you are a product manager, founder, or engineering lead, the 50-hour line graph story carries a direct message about how to run estimation sessions.
Never estimate UI components by their visual complexity alone. A feature that looks like "just a chart" should be broken down into its actual engineering tasks:
[ ] Select and integrate charting library (or justify going custom)
[ ] Define data contract / API shape
[ ] Handle loading, empty, and error states
[ ] Implement responsive behavior
[ ] Add tooltips and interaction layer
[ ] Accessibility pass (ARIA, keyboard, color contrast)
[ ] Cross-browser and mobile QA
[ ] Edge case data testing (nulls, single points, large ranges)
That list, costed honestly, rarely comes in under a week for a production-quality component. Acknowledging that upfront saves painful scope conversations later.
The Broader Lesson About Invisible Complexity
Software is full of components where the visible surface and the engineering depth are wildly mismatched. Charts are a clean example because the gap is so legible — literally anyone can look at a line graph and think they understand what was built.
The developer who spent 50 hours on their graph did not waste 45 of them. They spent those hours on the things that make a chart trustworthy: correct scaling, graceful degradation, readable labels, interaction that does not break on edge cases. That work is invisible in the final product, which is exactly the point. Invisible quality is still quality.
Good software often looks effortless because the effort was front-loaded correctly.
Source: I spent 50 hours drawing a line graph — Doug MacDowell, via Hacker News: https://www.dougmacdowell.com/50-hours-to-draw-some-lines.html
Why this matters for your project: Whether you are building a SaaS dashboard, a mobile analytics screen, or an internal ops tool, data visualization is almost always on the roadmap. Getting the scope right from the start — choosing libraries deliberately, estimating interaction and accessibility work, and stress-testing with real messy data — is the difference between a chart that ships confidently and one that quietly embarrasses you in a client demo.




