Bug Squashing, Refactoring, and Plea for an Interactive Equation Graph

Little Big Things

Lately I’ve been running a second Disk Clock set to calendar. This, however, has exposed a couple of hidden bugs. The regular clock disks I use update when I show dashboard. But with the disks set to longer term disks – week, moon, year – it didn’t update until the mouse passed over it. Perhaps I messed something up while adjusting the update rates a while back?

Actually, it just never gets started. With faster disks, a regular update comes along and sets things in motion. Since this won’t always happen, I had to trigger the time event early on dashboard show. En route, I found some old (and now missing!) constants that hadn’t been converted to time expressions.

Flickering Firefox

Firefox has peculiarity that the hidden input element will sometimes flash a highlight box when updating. While working on the update issue, I noticed this flickering rapidly while cursor was sitting still. And then it disappeared. Later it showed up again. It was only occurring over the text box. This box is re-created from freshly minted HTML on updates. Perhaps due to the above fix, the creation of new elements was triggering the mouseover event – which triggered a refresh of the text box and started the cycle all over again. I’m now caching the HTML and not updating the box if there is no change.

Patches on Hold

The large disk update almost certainly applies to DC-stable. The circular update may have. I’ve patched the stable branch, and will package up 1.0.4 at the end of the week, after having giving it some more shake-down time. It’s in bitbucket (stable branch) if you can’t wait.

If It Quacks Like a Class

Meanwhile, I’ve started looking on refactoring and modularizing the code. I’ve started switching back to a more idiomatic Javascript classish style where it make sense. i.e., disks all derive from from a single prototype, so I might as well make Disk the constructor and Disk.prototype the master.

Highlights and Lowlights

The main thing I’ve been focusing on is the overlay and highlights. I noticed some common code for canvas context setup between the main and overlay layers, so I factored that out. It left a whole mess of setup in the overlay layer, mostly concerned with decoding the pointer position. At the end, the overlay draw method called the text box update directly, using some of the values derived at the top.

I wanted to disentangle these parts, but it’s proved tricky. It didn’t help that the ways I was handling the information transfer from pointer to overlay to drawing where rather convoluted. After lots of back and forth changes, I’ve it mostly reduced out, and the text update call pulled out of the draw.

Part of the solution was turning the highlight, formally a property bag holding the disk and polar pointer location, into full fledged object. It’s been a series of tough decisions – the highlight and the disk seem to be fighting each other over all the information. I could have the highlight calculate everything, but some of the data belongs to the disk, and I’d have to pass the highlight into some of the disk methods. I’ve currently got it down to where minimal information, calculated in the highlight, has to be passed into disk methods.

Marked Cache

One of the monolithic functions I’ve been trying to chop up is the marker drawing routine. It’s slowly grown up over the course of the programs evolution to support a myriad of features: scaling markers so they are visible at various sizes, not drawing them when things get too crowded, lambda coloration, and more. Initially, I pulled all the data out to a cache array of properties. Different methods filled in each section of the properties, and then the drawing routine just had to iterate the properties.

The second solution takes advantage of prototypical inheritance. From a basic marker descend the four sub-classes (root, major, median, minor). From these are created all the individual marks with their own size and position. When a size change occurs, I just have to update the prototype markers. When the drawing routine iterates over the individual marks, they will pull the appropriate size information from their prototype.

Divide and Conquer

Next up, I chopped the animate method in half, separating most of the first-time code from the update code. The next target is the position update, a 40 line maze of conditionals. I started caching some of the size-dependent information so I wouldn’t need local variables to track it, and then discovered a bit of a bug from my animation-skip fix.

Frozen In Time

That solution was to calculate the standard delay time in terms of pixels of perimeter, and use that as a basis for determining when a big change had occurred. Unfortunately, I also use that delay function to determine the animation rate; this gets processed once while determining which disks to draw, a moment when many of them will be the wrong size – even zero.

Chopped and Routed

I did get updatePosition refactored. A few things get recalculated. I could probably work out the delay time problems, however I’m still very uneasy with the delay and skip calculations. The comparison of modified times feels an awful lot like I’m running two things through same-but-different equations in order to compare them. More fundamentally, the transformations have grown conceptually complicated, and I’d really like to clarify things for greater maintainability.

This Must Exist?

What I want in interactive graph of the system of equations where I can edit the inputs, and watch the values flow through the intermediate variables to outputs. I could work it up in a spreadsheet if I just wanted the numbers, but $B$2 is a terrible way to refer to variables, and it wouldn’t give me an immediate representation of the relationships. I could write a program to do the math with variables, but it’s neither interactive or visual. I could draw the diagram or use GraphViz, but that’s not interactive and wouldn’t calculate examples. Unfortunately, combining math or equation with graph or network gets gets a rather lot of noise the search results.

Posted Thursday, February 5th, 2009 under Devlog.

Comments are closed.