The lorem ipsum in development

We’ve all been guilty of this: showing a new UI mockup to the user with lorem ipsum or typing in fake data into forms for testing. That’s bad because fake data does not have the same characteristics of real data. Real data has specific lengths, formats and structure. Fake data is arbitrary. It is even more embarrassing if a lorem ipsum gets into production. But using fake data is not only a problem in the user interface.
Using fake data is also a problem in programming. We see it in names of classes: *Impl, *Manager or *Holder.
These names do not communicate well. Why not name classes with intent? Take a look at domain driven design and the ubiquitous language for a starter.
But also using only fake data in tests is bad. Yes you need to test the extreme cases but even here you need to inform your selection of data from the real world. Build in the constraints that the domain provides. Without the domain you build highly flexible software which is a nightmare to maintain. But also the test data should not be just arbitrary: you need the corner cases and to find them look again into the domain, the real world. To do this you need to gather real data from users, domain experts or existing systems and reports. Real data has constraints, constraints drive creativity and decisions. The problem with deferring the decisions too much is you maintain your flexibility until then. So make decisions but not from fake but real data.

Books and talks that shaped my mind as a developer

Over the years I’ve read many books and watched many talks but a few stand out (at least for me) that influenced me in my development career.

The inmates are running the asylum by Alan Cooper
This book opened my eyes that I approached software development completely from the wrong standpoint: the software should serve the user not vice versa.

Design Patterns by Erich Gamma et al
Oh others use the same patterns as me and what? you can even talk about it without explaining every detail…

Refactoring by Martin Fowler
This book taught me that you can change the structure and the design of the software without changing its function. Cool.

Inventing on Principle by Bret Victor
Seeing a new way of interacting with your software in development blew my mind. Think WYSIWYG on steroids.

Getting real by 37signals
Getting to the core of what is essential and what really needs to be done in software/product development is laid out here so clear and stripped down that it struck me.

Information visualization by Edward Tufte
Another book which reduces its topic (this time: presenting information) to the core and by this identifying so much unnecessary practice that it hurts.

Start with why by Simon Sinek
Purpose. Why do you develop software? Why do I arrange an UI or the architecture of an application? This is what design is about.

Only openings by Frank Chimero
Do I try to eliminate failures and therefore options or do I leave the possibility to the user to choose…

Web design is 95% typography by Oliver Reichenstein
Concentrate on the main part, the bigger part, the 95%. If you get them right the rest isn’t so important after all.

Discount usability by Jakob Nielsen
Do what you can do with what you have.

UX tips: charts

Continuing our series about UX tips for small areas we take a look at charts this time.

  • always label your axis – this one should be obvious the reader needs to know at what data he looks
  • use units – is this meter or yards, data can only be understood if the scale is clear
  • use distinctive colors – different data, different color, and don’t forget the color blind
  • use color with purpose – same data, same color, e.g. having different values of the same source should use the same color or tint of color
  • for bar charts always start at zero – the distortion often used for exaggerating differences is immense
  • leave out decoration – decoration distracts from the data
  • no 3d effect – data speaks for itself, please do not try to make it prettier
  • use them for lots of data – if you just have a few numbers a table of data might be more appropriate
  • use a title – what aspect or slice of data are you showing me, a summary helps to understand perspective and intention
  • use a big enough font – this and the appropriate contrast should be obvious for all UI work
  • label tick marks – use them at meaningful intervals, do not just slice the axis into equidistant intervals
  • include time – even if it isn’t a time series chart, tell the reader from when the data is
  • size 2d shapes by area – do not use diameter or radius for sizing 2d shapes (circles, bubbles…), unless you use bar charts (where the length is compared) the proportion gets way out of hand
  • use consistent rounding – first round your numbers and do this consistently
  • for comparisons use the same scale – do not distort your data by presenting it at different scale

What’s your super power?

I believe that every software developer (even every human) has a super power. One (or more) strength which helps his team, his company, his work to be better. It might be hidden or contained but it is there.
One way to find it is to ask your colleagues. Another to identify your contributions in your last projects or to look at what kind of work brings you joy, makes you feel like a fish in the water.
Let me give you an example. My power is to tackle complexity, reduce it to the essence and bring clarity to people. When I see a complex (or complected) network of interchanging applications doing things twice or even thrice, not talking to another, misunderstanding one might feel overwhelmed. I feel the need to dig in and bring out the most important part, the critical path, the essence. This isn’t restricted to software, this could be a group of people as well. I like to understand systems what makes them work and what hinders them. What is wasted and where do we have to make more effort.
Ask yourself: where I am good at? Where do I see things others don’t? Where do I accept the challenge? When do I strive? There might be your super power…

UX tips: Forms

User experience is a vast field which can be overwhelming at start. To make it easier for others I want to break it down to specific areas.
The start makes a rather narrow field of software: forms.

Forms are ubiquitous: almost every software user interface has them. Most of them are too big and overwhelm the user. But in complex software you cannot “just” leave out some inputs to make a small form. Here are some tips to improve your next form:

  • use a grid – your labels and inputs (and indeed every UI element) should be layouted on a grid, the goal is to improve scanability and readability and to reduce visual clutter
  • align all labels in the same way – this one should be obvious, but often it is missed, it doesn’t matter if the labels are left or above the input, all should be aligned in the same way
  • use labels – another obvious one but often labels are omitted to make the UI look cleaner, but if the user cannot see from looking at your interface where he inputs his username or password something went really wrong
  • put fields in chunks – if the form gets too big (and most of them do), use blocks with whitespace around them to chunk fields, how do find out the groups for the chunking? You should know the domain and you can always ask the user
  • use specialized inputs – if only a date can be entered use a calendar widget, if you need a color use a palette input, the goal is to reduce errors made by the user, which also reduces his frustrations
  • provide format helps – if you cannot provide a specialized input, provide format helps, describe how the input should be formatted and what formats are accepted, again to reduce errors
  • order the fields – ask the user and a domain expert what the mental model of the fields is, what order should the inputs be made, what is optional, what is important
  • distinct the mandatory from the optional – nothing is more frustrating than to fill out a form, click submit and get told 10 times which fields are missing
  • use different sizes – if the input is just a one digit number the input should be sized to indicate this, if you want 3 lines of text, use three rows, the goal is to visually communicate what kind of input is expected, but remember: please align them properly

I hope these tips help you to make better forms and make your users less frustrated.

JavaScript for Java developers (revised, partly)

Almost 5 years ago I wrote a piece about the specialities of the JavaScript language for developers knowing Java. A lot has happened since then. The old (EcmaScript Standard Version 5) way is still working but some of the rough edges has been eased out.

I want to concentrate on two areas: (variable) declaration and their scope and object/class creation.

Declaration

Now JavaScript has new ways to declare variables. The old var still works and declares a variable with a function scope:

function f() {
  var a = 2;
  var b = 1;
  if (a > b) {
    var a = 5;
    alert(a); // 5
  }
  alert(a); // 5
}

But since ES6 (also known as ES 2015) you can use let to declare a variable with block scope.

function f() {
  let a = 2;
  let b = 1;
  if (a > b) {
    let a = 5;
    alert(a); // 5!
  }
  alert(a); // 2!
}

You can also use const to create a constant, but must assign it in the same line.

  const i = 5;
  i = 3; // TypeError: Assignment to constant variable
  const b; // SyntaxError: Missing initializer in const declaration

It is not the same as final which you can declare and initialize in different lines:

final int i = 5;
i = 3; // error!
final b; // that's ok
b = 3;
b = 4; // error

Also beware that const declares a constant, not necessarily an immutable object:

  const a = [5, 3];
  a[0] = 3; // ok!

Object creation

Now this is the part where the JavaScript syntax changed a lot. The old functional way is still working but now you can declare a class in a more Java-ish way:

class Person {
  constructor(name) {
    this.name = name;
  }
}

You can also use a var:

var Person = class {
  constructor(name) {
    this.name = name;
  }
};

Methods can be declared as well:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  fullName() { // getter!
    return this.firstName + ' ' + this.lastName;
  }
}

var p = new Person('John', ''Doe);
alert(p.fullName());

You can also use property getters to sugarcode the access code:

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  get fullName() { // getter!
    return this.firstName + ' ' + this.lastName;
  }
}
var p = new Person('John', ''Doe);
alert(p.fullName); // <-- just called like a property, not a method

Static methods are also streamlined:

class Factory {
  static antiqueStyleNames(firstName, birthplace) {
    return new Person(firstName, 'of ' + birthplace);
  }
}

Inheritance, although still prototypical, can be done with extends:

class A extends B {
  constructor(a) {
    super();
  }

  m() {
    super.n();
  }
}

JavaScript only supports single inheritance but mixins are now possible:

var mixin = Base => class extends Base {
  a() {return 1; }
};

class B {}

class A extends mixin(B) {}

alert(new A().a()); // 1!

There are many more things in modern JavaScript like arrow functions, spread and rest operators and many more. JavaScript is evolving (Java also) so even if you are mainly located in the Javaland, it pays off to take a look at JavaScript from time to time.

Some tricks for working with SVG in JavaScript

Scalable vector graphics (SVG) is a part of the document object model (DOM) and thus can be modified just like any other DOM node from JavaScript. But SVG has some pitfalls like having its own coordinate system and different style attributes which can be a headache. What follows is a non comprehensive list of hints and tricks which I found helpful while working with SVG.

Coordinate system

From screen coordinates to SVG

function screenToSVG(svg, x, y) { // svg is the svg DOM node
  var pt = svg.createSVGPoint();
  pt.x = x;
  pt.y = y;
  var cursorPt = pt.matrixTransform(svg.getScreenCTM().inverse());
  return {x: Math.floor(cursorPt.x), y: Math.floor(cursorPt.y)}
}

From SVG coordinates to screen

function svgToScreen(element) {
  var rect = element.getBoundingClientRect();
  return {x: rect.left, y: rect.top, width: rect.width, height: rect.height};
}

Zooming and panning

Getting the view box

function viewBox(svg) {
    var box = svg.getAttribute('viewBox');
    return {x: parseInt(box.split(' ')[0], 10), y: parseInt(box.split(' ')[1], 10), width: parseInt(box.split(' ')[2], 10), height: parseInt(box.split(' ')[3], 10)};
};

Zooming using the view box

function zoom(svg, initialBox, factor) {
  svg.setAttribute('viewBox', initialBox.x + ' ' + initialBox.y + ' ' + initialBox.width / factor + ' ' + initialBox.height / factor);
}

function zoomFactor(svg) {
  var height = parseInt(svg.getAttribute('height').substring(0, svg.getAttribute('height').length - 2), 10);
  return 1.0 * viewBox(svg).height / height;
}

Panning (with zoom factor support)

function pan(svg, panX, panY) {
  var pos = viewBox(svg);
  var factor = zoomFactor(svg);
  svg.setAttribute('viewBox', (pos.x - factor * panX) + ' ' + (pos.y - factor * panY) + ' ' + pos.width + ' ' + pos.height);
}

Misc

Embedding HTML

function svgEmbedHTML(width, height, html) {
    var svg = document.createElementNS("http://www.w3.org/2000/svg", "foreignObject");
    svg.setAttribute('width', '' + width);
    svg.setAttribute('height', '' + height);
    var body = document.createElementNS('http://www.w3.org/1999/xhtml', 'body');
    body.style.background = 'none';
    svg.appendChild(body);
    body.appendChild(html);
    return svg;
}

Making an invisible rectangular click/touch area

function addTouchBackground(svgRoot) {
    var rect = svgRect(0, 0, '100%', '100%');
    rect.style.fillOpacity = 0.01;
    root.appendChild(rect);
}

Using groups as layers

This one needs an explanation. The render order of the svg children depends on the order in the DOM: the last one in the DOM is rendered last and thus shows above all others. If you want to have certain elements below or above others I found it helpful to use groups in svg and add to them.

function svgGroup(id) {
    var group = document.createElementNS('http://www.w3.org/2000/svg', 'g');
    if (id) {
        group.setAttribute('id', id);
    }
    return group;
}

// and later on:
document.getElementById(id).appendChild(yourElement);