Creating a progressive UI to simplify information architectures and enhance presentation
This article is a five-part series on creating interactive infographics with plain Javascript.
Previously we designed a two-way map locator to enhance user-navigation. In this article, we’ll continue to base our UI example on Google Cloud Platform (GCP) products to present content that has a sophisticated architecture.
Watch how we can make product information easy to use.
Video demo: how to simplify information architectures with a progressive UI design
Let’s design a UI to present multifaceted content.
There is an advantage in organising information as a hierarchy. You can categorise and step through topics to reveal meaningful relationships.
For example, on a knowledge portal, a zoologist may be interested in a topic concerning Jack Russells. She’s going along a specific information path:
Animals > Mammals > Carnivore > Canis > Dogs > Jack Russells
Suppose she’s also studying on Huskies, Hyenas, and Foxes. What is a good way to represent connected information vis-a-vis Jack Russells? How to provide contextual information without overwhelming the user with a data dump?
One approach is to break up data into small segments and reconnect them across multiple standalone pages. With every page load, users jump through new categories and webpages to find more details. However, it becomes harder to highlight contexture relationships. Too many page loads may also disorientate or frustrate users. The result is degraded user experience.
There’s got to be a better way to guide users towards their goals. One part of that equation is solved in our previous discussion. We can put an entire map, or animal kingdom, onto a canvas and still navigate gainfully.
We’re now left with the “Jack Russell” problem — the design challenge of getting the UI to display detailed content one level down without affecting information flow.
Think of extending an information pathway (of a node) as adding an HTML container. Like using post-it notes, we can “paste” these containers onto a browser window to reveal layered information. No page load is required. We’ve basically described an inline UI.
Now comes the exciting part. When a visitor “hop” from one node to another, these containers swaps in and out to show updated content. We’ll show users what’s going on by animating the UI.
Animated revealers for layered content
Users can now access detailed content without losing the big picture. Best yet, they are always on top of a consistent and persistent UI.
Tips: If you are writing a Single-Page-Application (SPA) such as React or Angular, create the best user experience by hydrating the routes dynamically. For example, when a user clicks on a backlink that takes her directly to the route animalchart.com/jack-russells, the SPA should pull the relevant data, auto-focus on the node, and fire off the animation without having the user to do anything.
Implementation is straightforward.
legend[]
array (from part-one discussion).Add a click
listener to the main while
loop (part-one discussion).
while (item[i]) {...itemElementName[i].addEventListener("click", showLayeredContent)}
click
listener to each node.click
will trigger a custom function showLayeredContent
.showLayeredContent
runs instructions to:
legend[]
.canvas
.function showLayeredContent(event) {
var div = document.createElement('div');
div.id = "some HTML" + deepContent;
_// add your CSS
// add your animation_
// attach the new container to the DOM
document.body.appendChild(div);
// ... add animation to show what's going on
anotherLayeredElement(_this_.id);
// ... more "post-it notes", if any
}
document.createElement(‘div’)
creates the “post-it note” container dynamically.div.id = “some HTML” + ‘deepContent’
populates the container.deepContent
contains the actual content. Use this.id
as the index key to retrieve records from the legend[]
datastore.document.body.appendChild(div)
appends the container to the DOM for rendering. document.body
is generic. Use canvas
or your own container element.anotherLayeredElement(this.id)
adds more containers. In our demo video, we used a total of 3 “sticky” containers.Tip 1: Dynamically generate the container element and its CSS so that we can quickly adapt the engine to other projects.
Tip 2: Remember to remove the old containers before swapping in new ones.
Position the first “sticky” container to the right as a full height element. It’s entrance is animated in a bottom-to-up motion.
var sticky01 = document.getElementById( myContainerID );
// Stage the container's pre-animation positionsticky01.style.bottom = "-100vh";sticky01.style.right = "0%";
// Attach CSS class to the RHS container.sticky01.classList.add("myCssClass");
// Once your container is ready, animate its entrance.sticky01.style.transform = "translateY(0px)";...
sticky01
references the first containerTip: Change _translateY_
to _translate3d_
to take advantage of hardware acceleration for improved performance.
layeredContainerRHS {position: fixed;overflow-y: scroll;top: 0;right: 0;width: 50vw;height: 100vh;zIndex: 9;transition: all 200ms cubic-bezier(0.165, 0.84, 0.44, 1);}
position: fixed
“sticks” the container onto the canvas
UI.overflow-y: scroll
makes it possible to display unlimited content via vertical scrolling.top: 0
sets the pre-entrance position of the container “below” the canvas.right: 0
, width: 50vw
and height: 100vh
styles the container to occupy the right side of the browser window.zIndex: 9
assigns the layering order.transition
creates the animation effect. cubic-bezier
produces a silky smooth motion.
Opening and closing “sticky” containers
So far we’ve created a full-height “sticky” container to display detailed information. Meanwhile, users can still browse other topics.
If you wish to tier information into more layers, simply add more containers. In our demo video, we’ve added two smaller containers to show summary information:
function middleSticky(ID) {...// "middle" sticky container (#02)div.style.left = "25vw";div.style.height = "44vh";div.style.width = "30vw";div.style.background = "#000";...middleSticky.style.transform = “translateY(0vh)”;...}
function leftSticky(ID) {...// "left-most" sticky container (#03)div.style.left = "0vw";div.style.height = "21vh";div.style.width = "25vw";div.style.background = "#e68717";...leftMostSticky.style.transform = “translateY(0vh)”;...}
translateY(0vh)
initiates the starting animation positions:Once the zoologist is done with any topics, the UI closes the sticky containers to maximise the main navigation UI. In reverse order, “Slide down” the sticky containers and remove it from the DOM behind the scene.
function closeStickyWindows(id){div.style.transform= "translateY(0vh)";setTimeout(() => {div.parentNode.removeChild(div);}, 500);}
500
e.g. (last animation starting at 300ms) + (200ms to complete the animation).div.parentNode.removeChild(div)
removes the DOM element (i.e. garbage collection). Use .remove()
if ES6 backward compatibility is not an issue.Users can browse content in a more granular manner.
In the final part of the series, we’ll talk about ideas that gives UIs a human touch.
Part-one sets the foundation for designing interactive infographics.
Part-two adds navigation features to browse content.
Part-three adds a dynamic mini-map to enhance navigation.
Part-four → You’re are here.
Part-five demonstrates why it is so easy to create UIs with a human touch.
If you enjoyed this story, you can find more at Pageii Studio.