Quantcast
Viewing all articles
Browse latest Browse all 13

How to Work with Complex JSON Data for Visualization with JavaScript

Welcome to the third installment in our series on Data Visualization with Progress KendoReact. We created a dynamic layout within our single-page React application using KendoReact’s layout functionality.Image may be NSFW.
Clik here to view.

Today we’ll be taking a step away from the view and working on, arguably, the most important part of our application: the data itself. KendoReact is quite intelligent at guessing how we want to display data. However, we still need to do some significant manipulation of our raw data to shape it into something that KendoReact’s data visualization components can use. Today our main focus will be on how to pull out information from JSON data based on business specifications. We’ll use building blocks like higher-order functions and mapping/reducing to accomplish this.

Here’s the general shape of the data that we’ll be teasing apart:

[
  {
    name: string representing region,
    restaurants: [
      {
        name: string representing individual store,
        ratings: [
          {
            date: string representing review sample time,
            values: {
              customer: string,
              staff_satisfaction: string,
              sales: string,
              cleanliness: string
            }
          },
          ...
        ]
      },
      ...
    ]
  },
  ...
] 

The JSON data above represents several regions of stores and the ratings that each store has received. I’ve written a set of utility functions for splitting this data apart and getting everything we need to visualize the data. Today I’ll mainly be talking about loading in the data. Then I’ll demonstrate one of the functions that’s being used throughout these data manipulations.

The first thing we have to do in our application to work with this data is actually import it. In a real-world application, that would likely mean fetching asynchronously from a backend or external source, but for now we’ll import the rating data statically. Let’s add these two lines to our App.js file. The first in the outer scope with the rest of our imports and the second within the definition of our App component:

import ratingsJSON from './data/pizza-store-data.json';
...
const [ratings] = useState([{ name: 'All Regions' }, ...ratingsJSON]); 

In the above example, we’re loading in the rating data via useState. Since we want the data to be our primary source of truth, we won’t destructure out the second mutative argument from useState‘s return value. If you’re confused about the useState call here, check out our previous installment that goes over using React Hooks to setup local application state.

A critical principle of ReactJS and many front-end frameworks is the idea that the view is simply a projection or representation of an application’s state. Any time the data changes, the view shows that new state faithfully.

As such, we’ll want to do any data operations separate from the view. Let’s make a directory in src/ called utils/ and include a file to do all of our data operations. I named mine dataSplitter.js.

Image may be NSFW.
Clik here to view.

For the remainder of this article I’m going to discuss one of the main building blocks that dataSplitter uses. All of the operations that I’m performing on this data are built from a few basic ideas and I’m hoping that if I describe this one example, you’ll be able to parse out many of the tools that I’m creating within dataSplitter.

Note: The rest of article assumes you have a pretty good understanding of JavaScript array map and reduce methods among others. If you need to brush up you knowledge of these concepts before continuing, I suggest this article that follows a similar philosophy for how I’ll be manipulating our ratings data.

Pluck

One extremely beneficial pattern for destructuring JSON data in JavaScript is commonly referred to as pluck. Pluck is a higher-order function that gets properties off of an object. You might be wondering: “Why can’t we just access object properties with dot notation?”. For one, this can be dangerous and cause a program to crash if you attempt to access a property that isn’t there. Destructuring objects can avoid this with defaulting, but the notation can be quite confusing and less transferrable between problems. A pluck pattern solves these problems and allows us to grab properties from deep within JSON data gracefully.

The beauty of pluck comes from the fact that it’s higher order. Say we have an array that looks like this:

const teletubbies = [
  { color: blue },
  { color: red },
  { color: green }
] 

If we want the color from every object in the array, we could do a map accessing each color with dot notation like this:

const colors = teletubbies.map((teletubby) => {
  return teletubby.color;
}); 

The above syntax returns to us an array of colors, one for each element, but it is cumbersome. And if we want to get a different property from each teletubby (I apologize for the weird example), we’ll have to write another similar map that destructures each Teletubby specifically. More complications arise if you want data at a different depth since you’ll need to concern yourself with defaulting and destructuring properly. Here’s how we can do the same thing with pluck:

const colors = teletubbies.map(pluck('color')); 

It gives us a simple API that says something like “for every x, I want its y property”. It scales wonderfully and is a more generic tool for destructuring, rather than a specific destructuring application for one problem.

Here’s my implementation of the pluck function used throughout this app:

const pluck = (...keys) => (data) => {
  return keys.reduce((subData, key) => {
    return subData === undefined ? subData : subData[key];
  }, data);
}; 

The rest operator for ...keys allows us to retrieve properties at arbitrary depth within an object. It also means that if we get undefined at any point in the chain, we bubble that undefined value back out to the result without throwing an error. So for example, we can say something like pluck('nest', 'egg', 'bird', 'feather', 'flea' ), which will return us a function that gets items from objects like this:

{
  nest: {
    egg: {
      bird: {
        feather: {
          flea: { ... }
        }
      }
    }
  }
} 

And will simply return undefined if we give it something like this:

{
  nest: { 
    foo: 100 
  }
} 

The post How to Work with Complex JSON Data for Visualization with JavaScript appeared first on Digital Primates.


Viewing all articles
Browse latest Browse all 13

Trending Articles