S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | |
7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 | 30 | 31 |
Migration Pain
I lost two days and a half days this week updating from version 3 of the d3 library to the current version 4. What started out as a smooth transition quickly veered off course thanks, in part, to (1) functions being renamed, (2) Functions keeping the same name, but doing something different, (3) the defaults changed, and (4) class names changed.
1.) Functions Renamed
Giving the D3 developers the benefit of the doubt, there are times when it makes sense to change a function name rather then deprecate the old name and keep it along for legacy reasons: the functionality changes. This is especially true when the functionality change is ever so slight. A developer using a library may not think to retest every corner case. Changing the function name creates a compilation error, which will force the developer to re-test their code.
After reading the documentation, and adjusting from names like d3.scale.linear to d3.scaleLinear I noticed something was still not right.
I went from pretty graphs like this with nice subdued gridlines, readable axes and axis legends:
To (in my opinion) rather hideous ones like this:
Of course there were no errors or warnings to help me get started figuring what went wrong.
2.) Functions with the same name and different functionality
The first thing I wanted back was the horizontal grid lines. The problem was subtle, so subtle that I only found
it by carefully analyzing several v4 examples. Where I had been creating the grid by adding additional tick lines using the argument yAxis.ticks() (as in .ticks(yAxis.ticks())) I now had to call yAxis.tickValues() (as in .ticks(yAxis.tickValues())).
I’m not sure whether the functionality of ticks() changed slightly, or it’s returning a slightly different object that can no longer work as an argument. At least it’s now working. In fairness, ticks() is a function call off of the scale object whose name did change, however a warning that the argument could no longer be used to set the tick values would have been greatly appreciated. That is not a change any developer would anticipate needing to make.
3.) The defaults changed
Notice the difference in axis font sizes & fonts? The difference in fonts actually accounts for the difference in size. Previously I hadn’t explicitly set either font size or style, so it defaulted to whatever the page was set to. The only reason I can think of to change the defaults is if you needs some guarantee on size value to keep elements from overlapping. It’s a stretch, but it’s also a minor fix.
4.) The class name changed
This is the most aggravating change because it’s also the least defensible. Notice how my tick lines went from light gray to black? I had specified the light gray in my (cascading style sheets) CSS, a styling markup language. In CSS you specify an element either by it’s id or by a class name. Each element can have a single id, but infinitely many classes. When the class name changed, my css rules were no longer applied. It would have made more sense to simply add a new class name to the object, not remove it.
Avoiding future pain
Not updating is simply not an issue, not for web applications. Bugs will be discovered, vulnerabilities too. I owe it to my users to remain up to date so they can continue to use my apps. Still, there are things I can do to lessen future pain. I moved my graph declarations to their own javascript file, effectively creating an interface layer between my apps and d3. Now at least all the pain will be contained to updating a single file.
Posted in Work Life
Leave a Reply