Software makers and users often have conflicting goals - with the makers winning. Yet they all too often shoot themselves in the foot by distrusting the users - their customers. Or worse, maltreating them. It is time to get angry about bad and malicious software design. This Blog calls software designers on the carpet - giving them credit and shame where they deserve it.
One of my favorite not-well-known features of Mac is that standard emacs CTRL keyboard shortcuts are available system wide to move the cursor and do basic editing WITHOUT moving ones hands from the home position. This is incredibly valuable to touch typists (such as myself). This works in all Apple products (TextEdit, Terminal, Pages, Web browsers, etc.)
But it doesn't work in Microsoft Word for Mac. Fortunately, Word for Mac offers a built-in tool for customizing the keyboard that easily lets you add this feature back in. Just follow this simple recipe:
Select the menu Tools->Customize Keyboard…
In Categories, select All Commands
Then for each of the following, click in Press new keyboard shortcut and enter the keyboard shortcut, and select the command from the "Commands" window and press Assign.
The key idea of the visualization is to provide a rich, interactive overview that gives clear access to my life's publications without requiring any training. In order to reach this goal, I simplified - offering only the essential features that lets people filter based on the three fundamental characteristics:
People - my co-authors
Time - when I published
Publications - what I published, including hand-picked keywords
I chose a bubble plot for my co-authors that displays people larger depending on the number of papers I co-authored with them. People are colored based on their basic category (Faculty, Student, Industry or Researcher). People's names are truncated (and sized) depending on available space - but show the full name (and number of co-authored publications) as a tooltip.
All visual elements are selectable and filter based on the thing that was clicked (person, person type, category - and even individual papers, represented by orange dots in the timeline). It is also possible to perform meta data text search. To support all of this interaction without making it overly complex, I chose a simplistic design that doesn't support history or queries any more complex than simple conjunctions. To start over, press the "Reset" button.
The implementation is entirely custom. I built a Python/Django back end with a custom database that enables me to have entities for each author (avoiding typos, different names, etc.), venue and even keyword. Plus, there is an administrative interface for updating content, so I don't have to muck with HTML and ftp anymore on a day to day basis. The database goes further to support the main page as well with news and project updates.
The visualization uses the standard D3 bubble plot and a custom timeline. The timeline includes range sliders on top to enable filtering of dates as well as keywords. Each publication is represented by an orange dot. Clicking on a dot shows the first page of the paper (created using imagemagick) to extract the image of the page from the .pdf file. I've also made PDFs all papers directly accessible.
Also, there is a simple API that you can use to access the database in a RESTful format should you want to access my publications for some reason.
I don't know if I should be proud that I accomplished something, or horrified at how long it took and how complex modern interactive web programming is today (or perhaps how atrophied my programming brain has become). In any case, I wanted 100% control over the interaction, and I finally got what I wanted - but it was hard. I could have done this in Java or in iOS much, much, much faster (well, at least if I had a graph layout algorithm handy).
Anyway, here is a high-level summary of what I learned:
Interactive Graphics Layer: HTML5 "canvas" v. "svg". First exploration was to analyze canvas (pixel-based write-only renderer) v. SVG (DOM-based, animatable, eventable vector graphics). SVG is much closer to my beloved Pad++ & Piccolo days of yore - and scalable and interactive is what I need. So, SVG it is.
D3: Advanced. Written by the brilliant and experienced Mike Bostock. High level, focused on data bound visualizations. A slight impedance mismatch for what I am looking for - but in the end, the clear winner (more below)
Raphael: Low-level and multi-platform compatible. Meaning it supports the least common denominator of features across all browsers (including IE's VML). This means no groups and no classes. No groups means it is very difficult to hang data off a collection of items in the DOM - and so you are obligated to create a shadow data structure in the app. No classes means no easy styling, and no generic event handlers.
JQuery SVG Plugin: This is actually about the feature set I was initially looking for, but the tool just isn't sophisticated enough. The architecture isn't clean enough, the docs and examples aren't sufficient, and I didn't have confidence that this project has legs. Close though - and with some TLC, it could become great.
The basic data binding model (w/ "enter" and "exit" mechanisms for more and fewer bound data items) just takes a while to wrap your head around. The docs here are good - just new to me.
The relationship between D3 selection and underlying objects took a while to get a handle on. When you get a selection, are those DOM objects, and if not, what are they? This should be spelled out really clearly in the docs.
Guidance on use with JQuery. Turns out this wasn't hard, but I (like just about everyone I know) rely on JQuery - so what are the catches? When is it a good idea to use D3 v. JQuery binding? Are they interchangable? Can you even use JQuery to select SVG DOM elements? A section on this in the docs would be really helpful.
Events bound to selections are *statically* bound. This is the same as JQuery, and I should have known better - but it really threw me for a loop. This means that when you bind an event to a class name, and then change the class name - the event handler doesn't get unbound. You have to manually unbind and then bind new event handlers.
Knowing what is a DOM attribute and what is a CSS style is confusing. A summary table of supported SVG objects, attributes and styles would be really helpful.
I kept on wanting to write event handlers that worked on only some elements of a selection, but couldn't figure out how. For example, I would have a bunch of active nodes, and want to act on all of them except the one the mouse was over. With 20 years of iterative programming in my brain, I spent an inordinate amount of time before I realized that in this new world of selection-based programming, the right approach was to change "class" tags on the elements so just the things I wanted had the right class names - and then select on that class.
Finally, the D3 API docs are pretty good, but badly need complete examples. Many have no examples, and hunting through the demos to see how something is actually used is very time consuming. And where there are examples, they are usually abstracted. That is fine for conceptual understanding, but I kept wishing they were linked to full, simple standalone examples. For example, I spent 3 hours getting the syntax of a path right - and then figured out later I could have just created a line. Sigh...
Well, there's more - but that's a start. Modern web graphics technology is amazing. I'm heading out of the country for a few weeks, but when I return, I expect to be able to start building cool stuff!