Data Visualisation with D3.js

Meteor World Map

Represents meteor impact recordings across the globe, each hit represented as a point of varying size and colour, corresponding to its mass. Allows users to hover each point to view more information. Data is provided by a TOPOJSON API and is scalable in that the size variations are evened out by a logarithmic function.

USA Education Data Choropleth

A choropleth map of all counties in the US representing the portion of the population with a Bachelors degree or higher.

Product Category Tree Map

A tree map with variable inputs to display top sales in the categories of ‘Video Games’, ‘Movies’, and top funded Kickstarter campaigns.

GDP Interactive Bar Chart

A simple bar chart with a hover tooltip created to map US gross domestic product from a JSON API.

Scatter Plot Graph

An interactive, time-based scatter plot graph rendering static data for doping statistics for the Alpe d’Huez fastest race times, served from a static JSON file.

Climate Heat Map

A heat map showing earth surface climate temperature per month over several hundred years. Heat data is represented by colour and a sliding bar at the bottom. Data again server through a JSON API.

State Contiguity Force Directed Graph

A Force Directed Graph showing state contiguity for all countries in the world. Force directed graphs (FDG’s) represent data as nodes on a meshwork and give the user the ability to drag and hover individual nodes to see the country name.

Microservice & API Projects

Microservices

Timestamp

Converts between UNIX timestamps and readable date formats (American standard).

Image Search Abstractor

Queries an image database and returns the abstract data. Supports pagination and querying historical search data.

File Metadata

Reads a file and returns the size in bytes.

Request Header Parser

Returns basic data on the client’s user agent including IP, supported languages, and operating system.

Imperial Metric Converter

Converts between imperial and metric units via the URL query parameters giving a JSON response.

URL Shortener

Allows users to register a URL to a number, accessing the service URL with this number will redirect to the registered location.

API Based Applications

Exercise Logger

Lightweight service to log exercise sessions and query historical data. Supports interaction with a basic interface and a REST API.

Message Board

Allows for the creation of boards for specific topic, post threads on boards, and leave replies to posts.

Bug / Issue Tracker

An issue tracker API for the free code camp quality and security projects.

Personal Inventory

A book indexing library with comments and optional UI.

Stock Ticker

Queries stock levels and add allows users to ‘like’ a stock based on each device’s IP.

Games of Life

A story of repeating patterns of behaviour.

The Game of Life by the mathematician John Horton Conway in 1970 is a zero-player game based on replicating cellular autonoma. this post details three different versions I made and the reason why for each.

The Game of Life presents an N sized grid where each cell has two possible states, alive or empty (dead). With each game tick, the cell can change state or remain as it is based on the number of cells around it. A cell with too many neighbours will die of overpopulation, a cell with too few will die without ‘civilisation’ to sustain it. Cells with the right amount of neighbours will come alive and so on.

V1 – React.js

V2 – React-Redux

V3 – Three.js

In this way, the Game of Life, a Turing Complete model in which each generation is a direct result of the previous state, is the perfect challenge for a state-building exercise.

My first version took a number of weeks, built in React, it helped me learn fundamental algorithm concepts and state-management techniques which would come in useful later.

I revisited this project again years later, reproducing it in a couple of hours, determined to make a cleaner, more robust rendition. At the time I was working with WebGL and three.js, so went back one more time to create a 3D game inspired by the 2D Game of Life.

I’m going to take a ‘poking fun’ approach to talking about these, I believe a little bit of mocking you’re old work is good for illustrating how much has changed since then, and appreciating the quirks of the learning process.

Remember kidos, in learning, there’s no such thing as “bad code”, just code that hasn’t seen growth yet.

Version One: October 2017

This original game, submitted as part of the freeCodeCamp challenge, came straight after the Recipe List and came with a steep learning curve for me.

I knew that I needed a table-like layout for rows and columns, I was familiar with using array’s and .map() but was yet to learn that you could make arrays of JSX and just… dump them in where you need them. I thought there was something magical about an inline array.map. 🤷‍♀️ This lead to some interesting patterns such as creating an N-sized row or column with and N-sized array in state.

a react state initialisation with an array full of 0's
I don’t miss old react state initialisation

<Table /> acted as the game renderer and controller, a pattern which would stick in future projects. It’s state held a ticker which would advance by one with each generation. It rendered a table by looking over the arr state item above twice (you were locked into square layouts) and rendered <Cell /> components.

the cell function to check other cells
Thankfully I was saved any ‘out of bounds’ errors (in which a cell on the edge tries to check a non exisiting cell) due to the function checking if the key exited in an alive state, and then checking a second time if the key existed in a dead state. In both cases the query for, say “col–1-row-21” would be undefined but no further value checking would take place.

Following the idea that “components should be self contained”, each <Cell /> had it’s own internal life state (nice)… and then on mount, writes this state to a ‘global’ object (i.e. outside the react tree) (not nice) with the following format string as a key: ‘”‘ + “col-” + this.props.colId + “-row-” + this.props.rowId + ‘”‘. 🤮 Don’t ask me why the quote marks are in double brackets because I cant remember.

Cells each had a method to look at adjacent cells in this global object and calculate their next state, which was hard coded because ofcourse.

The last anti pattern was that this function was called when the lifecycle method componentWillReceiveProps was called, i.e. when the ‘tick’ being passed down from the board went up.

Now this idea to tick a game forward in itself isn’t too bad, though it should have used componentShouldUpdate and checked that the new tick was changed. The issue here was that every cell, updating itself, was reading and writing from the same object. The cell does not know how much of the board is from the previous generation and how much form the last. Also, the fact that the globalObject existed outside the react app meant that it existed outside of the application lifecycle structure which could exacerbate this issue.

Remarkably though, it works most of the time.

Somehow, unless my machine is running slower than usuual, the cell updates sync in such a way that the game behaves as it should. the submission was accepted but this always bugged me, it haunted me, it’s remaking was inevitable.

Takeaways

A big thing I took away from this project that I hope could benifit others who may read this is that this potential cell de-sync issue was not enough to wreck the project. The code is duck-taped together in so many ways, its highly innefficient and jumbled but it works.

Often times I see people who achieve things and don’t allow themselves credit becuase they believe they somehow cheated or missed the point of the project. Its a part of imposter syndrome; they think that there is some sort of universally accepted correct structure that they were supposed to find but didn’t and are soon to be revealed as a fraud.

In my view this is how we get into innane discources such as “is HTML a programing language” or “this site design is invalid becuse you used a CSS framework”. In industry, clients generally don’t care whats gone on behind the scenes, they just care about the specification and the end result. To quote my favourite TV show, if you are asked to make somthing which behaves in a certain way then…

Coding isn’t the thing, its the thing that gets us to the thing.

The early prototype. https://codepen.io/Oddert/pen/OOLKzW?editors=0010
Final submitted version. https://codepen.io/Oddert/pen/POwgdP

Version Two: April 2019

It took longer than I thought for the urge to remake the game to finally take hold (other stuff took precedent).

This new game was built with create-react-app and included Redux. This time, the store had a two main keys board which contained data relating to the board display and control which controlled UI elements (in the end this was only used for the ‘paint’ mode, allowing users to write to the board).

The board was a two dimensional array with cell objects inside. Each cell object stored its x-y position and an ‘alive’ property. The reducer for this section only had two actions, one to manually change the state of a cell (for painting) and one which would loop over the whole board, calculate the new state for each cell, then write this new state to an entrely new board array, thus achieving feed-forward imutability.

The <Board /> class had two properties, one to generate rows by calling the next which would generate cells. <Cell /> classes still performed the check individually to see how they should render and would listen for mouse events to paint the board.

And that’s it, cells update when they need to, React takes care of that, the controller component dispatches to tick the game forward, and the files are simple and light apart from the enormous bundle size of create react app.

screenshot of version two
The quickly-finished version two with a clean edge less look.

There were still questions as to whether performing the board loop calculation within the reducer violated Redux’s pure function policy; that reducers should be pure functions and do little work. Despite this, the function would produce the same outcome every time and has no side affects so it is still pure in that sense.

Regardless, this was the remake that I had wanted to do since forever, and it only took a couple of hours, as opposed to approximately a week for the previous.

But I wasn’t finished.

Version Three: May 2019

Around this time I had been investigating WebGL and three.js for a potential project with Matter of Stuff, where I was an intern for my Diploma in Professional Studies (DPS).

See the Pen KYREdx by Robyn Veitch (@Oddert) on CodePen.

One of my little experiments involved creating a ‘voxel builder’, a simple grid space where you can place blocks in 3D.

I took the board state, extended it to a three dimensional array and wrote a function to map to the 3D grid space. I extracted the looping function and created a simple adaptation to run outside of React-Redux (which this project does not use). Lastly, I modified the rule set to return an alive cell if the number of neighbours was as follows: 5 <= num <= 9.

The result is this, a fully 3d rendition of the Game of Life. The rule set could use tweaking given that the cells tend to bubble outwards and oscillate around the edges. And of course you do not benefit from Redux’s immutable patterns.

Never the less I was pleased with the result which went on to influence a range of projects which took place thanks to Matter of Stuff.

PinApathy

A Pinterest.com clone built with React on an Express back-end. Authentication by Passport.js using both local and 3rd party oath2, Mongoose and MondoDB as the database, hosted on Mlab.

pins in masonry style layout
The react-masonry package works to animate items efficiently into place in a way that is not possible with just css

The app replicates Pinterest’s masonry layout using react-masonry, allowing cards to create that cobblestone look, slotting into one another. Pins can be re-pined by new users, added to boards and have likes and comments posted.

The front-end was built using React-Router for pagination and to split the various aspects of functionality.

an individual pin in full-screen
An open pin with it’s source link credited and some comments underneath

The name was a joking placeholder on the observation that Pinterest’s once usable format was heavily modified and moved from it’s original format in the name of increased advertising and ‘engagement’. “Interest” meaning more click through’s instead of meaningful curation is replaced with “Apathy”.

user homepage
A user’s home page showing their boards and the three most recent pins

Zeiss Zugriff

The Zugriff (German word for bridge) is a conceptual product imagining if the opto-electronics Goliath Carl Zeiss AG moved into the field of portable audio.

a collage of ziess products
A moodboard of various Zeiss products / promotional imagery.

Carl Zeiss AG has been a sector leader for over 100 years, manufacturing lenses, optical products and specialising in the manufacture of micro-electronics (by way of their optics). A large and sterile brand, their ‘image’ is quite hard to place, certainly they wish to put forward an image of loyalty, stability and enabling but how much of that actually shines through their work?

early hinge development sketches
Zeiss leads absolutely in the sectors in which they operate, they set the standards and often have a unique presence despite attempts at copying. It was important that this speaker embody that distinction.

I decided that in the highly unlikely case that Zeiss broke form their optics-only model, such a speaker would want to embody the values of versatility, perhaps linking to their large sports-optics range. It should embody a ‘quirky’ high technology functionality and should embody the stability, balance and engineering associated with other Zeiss products.

blue foam scale model
The final block model put across the physical feel of the device despite not having a ‘proper’ hinge.

The final designed carried through a mirrored 360 hinge mechanism to allow differing modes of sound output (direction vs ambient). The unit is highly durable, made of an experimental fibre mesh aluminium and designed to compliment Zeiss’s sports optics range.

features of the product annotated
An annotated render from my presentation showing key points of functionality.
conceptual renders of the model showing different use cases
A final render series showing the device in a range of intended locations.

In reflection I found this project very challenging, after all Zeiss isn’t what I’d call a flexible brand. I enjoyed the chance to broaden my scope on branding and to consider the semiotic meanings and associations embodied by brands beyond simple aesthetic surface-level messaging.

Margate

The Margate Art tour is a conceptual piece of service design to link cultural hubs along the Kent coast.

Intended to strengthen the growing artistic trend, it is hoped to provide economic opportunity and regeneration.

The Margate Experience Project was a broad speculative piece, focusing on the design process as applied to a real world context.

Unit four of the course is the last unit in stage one and focuses on applying the design process to a real world context by asking us to consider the situation of Margate and how it, through design, could be improved.

The brief for this project was much more open than anything considered previously and offered a great scope for creativity, experimentation and consideration of wider socio-political factors.

margate image from beech
A symbol for modern Margate; the closed Dreamland centre overshadowed by an unmaterialised modernist vision, surrounded by scaffolding.

I was very excited for this project, not only was it the first structured project of my return to the course but it was a chance to act on the idea of using design to effect positive change in a real-life context, to break away from the established idea of physical, consumer-based product design.

In addition, I personally had a bit of a head start in that I had visited Margate before and given some amount of thought to the basic premise of this project.

margate in-person research
Day one of our group trip to Margate conducting research. Even Arlington can look good with strategic lens flares.

Research formed the backbone of this project to arguably a larger degree than some other past projects. This involved interviews, primary and secondary research, the creation of a ‘cultural map’ in groups, a three-day site visit and personal observations and anecdotes.

final presentation board
First Final Presentation Board
second final presentation board
Second Final Presentation Board

My design solution was a conceptual ferry service operating an ‘Art Tour’ around Margate, connecting visitors to key areas of cultural and artistic significance around the east coast.

The core of this idea is to place Margate at the centre of a broader artistic context and culture.

Margate has a rising art scene as personified by the greatly successful Turner Contemporary gallery but is somewhat stunted by its remote location and lack of other attractions. By offering figurative and literal links to other such locations, a coherent experience can be created centred around Margate with connections to London and Dover to entice tourists.

Reflecting back on the project I would have liked to delve deeper into specific aspects of the design like what the onboard commentary would have consisted of, more detail put into the design of the vessels and in general, added more user touch points to make the idea more unique.

In addition I think the project could have benefited from more primary research mid-way through but overall it was a greatly interesting brief to tackle.