My grandfather, James, was a meticulous recordkeeper. He kept handwritten journals detailing everything from his doctor visits to the daily fluctuations of stocks he owned. I only discovered this part of his life seven years after his death, when my family’s basement flooded on Christmas Eve in 2011 and we found his journals while cleaning up the damage. His records impressed me the most. He documented every trip he ever took, including dates, countries and cities visited, methods of , and he traveled with. In total, he left the United States 99 times, visited 80 countries, and spent 1,223 days at sea on 48 ships.

A section of the handwritten travel log kept by the author’s grandfather
A section of the travel log.

I was only twenty-four when he died, so I hadn’t yet realized that I’d inherited many of his record-keeping, journaling, and collecting habits. And I had never had the chance to ask him many questions about his travels (like why he went to Venezuela twelve times or what he was doing in Syria and Beirut in the 1950s). So, in an effort to discover more about him, I decided to make an infographic of his travel logs.

Today, we take for granted that we can check stocks on our phones or go online and view records from doctor visits. The kinds of repetitive tasks my grandfather did might seem excessive, especially to young web developers and designers who’ve never had to do them. But my grandfather had no recording method besides pencil and paper for most of his life, so this was a normal and especially vital part of his daily routine.

A photograph of a ship called SS Amor, taken by the author’s grandfather in the West Indies in 1939.
SS Amor in the West Indies. Taken by the author’s grandfather in 1939.
A photograph of the New York City skyline, taken by the author’s grandfather, probably in the 1930s.
New York City. Taken by the author’s grandfather, probably in the 1930s.

Whether you’re processing Sass, minifying, or using Autoprefixer, you’re using tools to perform mundane and repetitive tasks that people previously had to do by hand, albeit in a different medium.

But what do you do when you’re faced with a problem that can’t be solved with a plugin, like my grandfather’s travel ? If you’re a designer, what’s the best way to structure unconventional so you can just focus on designing?

My idea for the travel web app was to graph each country based on the number of my grandfather’s visits. As the country he visited the most (twenty-two times), Bermuda would have a graph bar stretching 100 percent across the screen, while a country he visited eleven times (St. Thomas, for example) would stretch roughly 50 percent across, the proportions adjusted slightly to fit the name and visits. I also wanted each graph bar to be the country’s main flag color.

The big issue to start was that some of the data was on paper and some was already transcribed into a text file. I could have written the HTML and CSS by hand, but I wanted to have the option to display the data in different ways. I needed a JSON file.

I tediously transcribed the remaining travel data into a tab-separated text file for the countries. I added the name, number of visits, and flag color:

...
honduras	    1    #0051ba
syria	1	#E20000
venezuela	    16    #fcd116
enewetak	2	rgb(0,56,147)
...

For the ships, I added the date and name:

...
1941    SS Granada
1944    USS Alimosa
1945    USS Alcoa Patriot
...

Manually creating a JSON file would have taken forever, so I used JavaScript to iterate through the text files and create two separate JSON files—one for countries and one for ships—which I would later merge.

First, I used Node readFileSync() and trim() to remove any quotation marks at the end of the file so as to avoid an empty object in the results:

const fs = require('fs');

let countriesData = fs.readFileSync('countries.txt', 'utf8')
	.trim();

This returned the contents of the countries.txt file and stored it in a variable called countriesData. At that point, I outputted the variable to the console, which showed that the data was lumped together into one giant string with a bunch of tabs (t) and newlines (n):

"angaurt2t#56a83cnantiguat5t#ce1126nargentinat2trgb(117,170,219)narubat10trgb(0,114,198)nbahamast3trgb(0,173,198)nbarbadost6trgb(255,198,30)nbermudat22trgb(0,40,104)nbonairet1trgb(37,40,135)nguyanat2trgb(0,158,73)nhondurast1trgb(0,81,186)nvirgin Islandst2trgb(0,40,104)nbrazilt3trgb(30,181,58)nburmat1trgb(254,203,0)ncanary Islandst1trgb(7,104,169)ncanal Zonet7trgb(11,14,98)ncarriacout1trgb(239,42,12)n ..."

Next, I split the string at the line breaks (n):

const fs = require('fs');

let countriesData = fs.readFileSync('countries.txt', 'utf8')
.trim()
.split('n');

After split(), in the console, the countries’ data lived in an array:

[
  "angaurt2t#56a83c",
  "antiguat5t#ce1126",
  "argentinat2trgb(117,170,219)",
  "arubat10trgb(0,114,198)",
  "bahamast3trgb(0,173,198)",
  "barbadost6trgb(255,198,30)",
  "bermudat22trgb(0,40,104)",
  ...
]	

I wanted to split each item of country data at the tabs, separating the name, number of visits, and color. To do this, I used map(), which iterates and runs a function on each item, returning something new. In this case, it split the string at each tab it found and returned a new array:

const fs = require('fs');

let countriesData = fs.readFileSync('countries.txt', 'utf8')
	.trim()
	.split('n')
	.map(item => item.split('t'));

After I used map(), countriesData was an array of arrays with each country and its data split into separate items:

[
  [
    "angaur",
    "2",
    "#56a83c"
  ],
  [
    "antigua",
    "5",
    "#ce1126"
  ],
  [
    "argentina",
    "2",
    "rgb(117,170,219)"
  ],
  [
    "aruba",
    "10",
    "rgb(0,114,198)"
  ],
  [
    "bahamas",
    "3",
    "rgb(0,173,198)"
  ],
  ...
]

To create the final output for each country, I used reduce(), which uses an accumulator and a function to create something new, whether that’s an object, a value, or an array. Accumulator is a fancy way of referring to the end product, which in our case is an object ({}).

const fs = require('fs');

let countriesData = fs.readFileSync('countries.txt', 'utf8')
	.trim()
	.split('n')
	.map(item => item.split('t'))
	.reduce((countries, item) => {
		return countries;
	}, {countries: []});

I knew I wanted {countries: []} to contain the data. So instead of creating it on the first pass and testing whether it existed on each iteration, I added {countries: []} to the resulting object. That way, it existed before I started iterating.

This process returned an empty object because I hadn’t told reduce() what to do with each array of data.

To fix this, I used reduce() to push and add a new object for each country with the name (item[0]), visits (item[1]), and color (item[2]) into the end result object. Finally, I used a capitalization function on each name value to ensure formatting would be consistent.

const fs = require('fs');

const cap = (s) => {
  return s.charAt(0).toUpperCase() + s.slice(1);
};

let countriesData = fs.readFileSync('countries.txt', 'utf8')
	.trim()
	.split('n')
	.map(item => item.split('t'))
	.reduce((countries, item) => {
		countries["countries"].push({
			name: cap(item[0]),
      			visits: item[1],
      			color: item[2]
		});
		return countries;
	}, {countries: []});

I used the same method for the ships.txt file and merged the two using Object.assign, a method that takes two objects and creates a new one.

let result = Object.assign({}, countriesData, shipsData);

I could have created a function that took a text file and an object, or created a form-to-JSON tool, but these seemed like overkill for this project, and I had already transcribed some of the data into separate files before even conceiving of the infographic idea. The final JSON result can be found on CodePen.

I used the JSON data to create the infographic bars, defining the layout for each one with CSS Grid and dynamic styles for width and color. Check out the final product at ninetyninetimes.com. I think my grandfather would have enjoyed seeing his handwritten logs transformed into a visual format that showcases the breadth of his travels.

He passed away in 2005, but I remember showing him my Blackberry and explaining the internet to him, showing him how he could look at pictures from around the and read articles. He took a sip of his martini and sort of waved his hand at the screen. I think he preferred handwritten notes and life outside of the internet, something many of us can appreciate. After sifting through all his travel logs, I more clearly understood the importance he placed on having different experiences, meeting new people, and fearlessly exploring the . To him, his travels were more than just dates on a page. Now they’re more than that for me, too.

The author wishes to thank Mattias Petter Johansson, whose video series, “Fun Fun Function,” inspired some of the thinking in this article.





Source link

LEAVE A REPLY

Please enter your comment!
Please enter your name here