Written by Jonnie Hallman
Back in December, I went down the long list of to-dos for Cushion and thought I’d tackle one I’ve wanted for a while now—project blocks. I wrote about this before and laughably estimated a few days to finish it. Any dev knows estimates are meaningless and any guess would require multiplying the original estimate several times.
So here we are. It’s January and Cushion doesn’t have project blocks yet. I’m about halfway there because a few days in, I realized if I wanted to do this right, I would need to rewrite the schedule timeline. I originally wrote it for the budget, then made it work for scheduling, redesigned it a few times, added a few more elements, and rigged it to somehow work with invoices. I was left with a monster that looked nice, but felt like a long-running Jenga game.
After hours of just staring at the screen, internally debating with myself, I knew rewriting the timeline was the only way. I started thinking about what the timeline even represented, now that I was months along with the beta. Does the name still make sense? Up until now, I considered anything in the top-half of Cushion to be “the timeline”—even the budget bar was a timeline to me, despite its lack of time.
This wasn’t right. I took a step back and pretended for a moment that I haven’t been working on Cushion for almost a year now. I looked at the scheduling timeline and pieced it apart. What were its components, if one were to separate it into reusable parts? It has “ticks”, or axes, at the top and bottom, but so does the budget bar. So, then the ticks shouldn’t be considered part of the timeline. I would need to step back even further.
Remove the ticks, remove the container, and you have the timeline on its own. And, the budget bar without the ticks and container is just the bar. Both of these are just visuals that could stand on their own, but are even more useful when adding the grounding and labeling of the container and ticks. It’s almost like a graph... Wait, it is a graph! A graph has axes and visuals—so do the schedule timeline and budget bar. I can’t believe I didn’t see it this way at first, but once I did, everything came together.
Instead of giving meaning to everything in the timeline, like outlined dots for estimated dates and solid dots for actual dates, I would remove the context completely and treat it like a real graph. These dots are just dots with an x-position—nothing more. An outlined dot is a “weak” dot; a solid dot is a “strong” dot. The lines that were once named after their data, like duration, delay, drag, etc., are now just lines with an x-position and a length. The arrows that once represented the current date of an active project now have no idea they represent anything—they’re just arrows.
The more I abstracted the timeline, the easier it became to write both the logic and the styling. Previously, I had tons of CSS classes, like
.remaining-duration-line—many of which shared the same qualities, like both delayed projects and early invoices being a light line. Now I didn’t need to be that descriptive. As a result, the style code was reduced to a fraction of what is was before.
Instead of bundling all the logic within the timeline, I pulled it all out and left the timeline with one job—draw. I would no longer feed it projects and invoices. I would just send it points. Then, outside the timeline, the real logic would live in factories and generate the points for the timeline. The timeline now has absolutely no concept of anything besides drawing shapes between two points and I can easily swap out the data I send it between clients, projects, and invoices.
I know abstraction is programming 101, but when you start a project and rapidly develop it as the idea grows, it’s hard to predict where the project is going. It’s even harder to take time to step back and reassess everything. I got to the point where the only way to proceed without a constant headache would be to rewrite the timeline.
Looking back, as soon as I decided I would need a second timeline for invoices, I should’ve stopped and realized I shouldn’t try to make the timeline do everything. It became too much and resulted in me unexpectedly losing a couple weeks of forward progress. On the bright side, I now have a solid system in place for future “graphs”. Schedule timelines and budget bars are just the beginning.