hero banner - visualizing your email inbox

How to create email interactive treemaps

5 min read
Tags:

Intro

This post will cover how to create email interactive treemaps using the Nylas Email API. We will look at what is a treemap, how to consider categorizing emails and building a treemap visualization of your email inbox. You can find all the code in this blog on our Nylas Samples repository. We recently discussed creating email interactive treemaps on our LiveStream Coding with Nylas:

Prerequisites

Environment

We will need to have Node.js setup to run the code. Go ahead and setup Node.js on your machine.

What are Treemaps?

A treemap is a visual representation of data in the form of rectangles:

example of a treemap
Example Treemap

Each rectangle represents specific pieces of data or collections of data that can represent treemaps themselves. In either case, the visualization is repetitive where each treemap can be a representation of more treemaps (treemaps on treemaps).

So by clicking on any specific rectangle will display more categories of data below. You can read more about Treemapping on Wikipedia. Similarly, if you think about Emails and their different purposes, we are going to group them to create email interactive treemaps.

Now we’ve gone over the basics of Treemaps.

Retrieving Emails using Nylas

Let’s retrieve emails using the Nylas Email API. So we are going to use Postman to retrieve emails using the Nylas Email API /messages endpoint and save the JSON response:

Saving Emails using Postman

Now we’ve retrieved emails using the Nylas Postman collection.

Exploring ways to Categorize Emails

Categorizing emails can be done in many ways. There can be different types of emails, let’s consider one approach to start. Here is is one approach for organizing emails:

Categorize Emails into Groups

So we will categorize emails as follows:

  • Internal
    • Status Updates (i.e. meeting updates, document shared)
    • Broadcasts (emails sent to a specific group)
    • Individuals
  • External Emails
    • Company or Tool
    • Individuals

In this section, we’ve explored how to categorize emails.

Create Email Interactive Treemaps

Let’s build out the functionality to create email interactive treemaps using the categorization we specified previously.

We are going to use FoamTree to create the interactive treemap. So here is a general code sample of what the JavaScript will look like to generate an treemap:

// example src/index.js

// add FoamTree via `npm i @carrotsearch/foamtree`
import { FoamTree } from "@carrotsearch/foamtree";

// data where each sub-category is represented by groups
const groups = {
  label: "top-level label",
  //total items in group
  weight: 100,
  groups: [
    label: "sub-category label"
    weight: 50
    groups: [
      //lower level category
    ]
  ],
}

new FoamTree({
  // html tag to attach treemap to
  id: "app",
  // data to generate treemap
  dataObject: groups,
  parentFillOpacity: 0.9,
  layout: "squarified"
});

Here is what the html file importing the JavaScript will look like:

<!DOCTYPE html>
<html>

<head>
  <title>Email Inbox Treemap</title>
  <meta charset="UTF-8" />
</head>

<body>
  <div id="app"></div>
  <script src="src/index.js"></script>
</body>

</html>

We can bundle the JavaScript using parcel, so here is what our package.json dependencies and scripts looks like:

{
  "name": "email-visualization-javascript",
  "version": "1.0.0",
  "description": "Email visualizations in JavaScript",
  "main": "index.html",
  "scripts": {
    "start": "parcel index.html --open",
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "@carrotsearch/foamtree": "^3.5.0",
    "node-gyp": "^9.3.0",
    "parcel-bundler": "^1.12.5"
  }
}

Let’s create the functionality to categorize emails in Node.js:

// src/categorization.js

// import emails as json
const emails = require('./response.json')

// create regex for different groups
const nylasEmailRegex = /\@nylas.com/;
const nylasBroadcastEmailRegex = /\[email protected]/;
const nylasStatusUpdateEmailRegex = /Updated|Invitation:|Accepted:|Document shared with you:|DevRel/;
const externalCompanyEmailRegex = /grammarly.com|atlassian.net|asana|docs.google.com|google.com|canva.com|zoom.us|/;

const emailGroups = {
  nylasBroadcastEmails: { count: 0, emails: {} },
  nylasStatusUpdateEmails: { count: 0, emails: {} },
  nylasEmails: { count: 0, emails: {} },
  companyEmails: { count: 0, emails: {} },
  unorganizedEmails: { count: 0, emails: {} }
}

const { 
 nylasBroadcastEmails, 
 nylasStatusUpdateEmails, 
 nylasEmails, 
 companyEmails, 
 unorganizedEmails 
} = emailGroups;

let totalEmailCount = 0;

// collect emails into an array including sender and subject
const emailArray = emails.map(({ from, subject }) => {
  const sender = from[0].email;

  totalEmailCount++
  return ({
    sender,
    subject
  })
});

const updateSenderCount = (sender, group) => {
 if(!nylasBroadcastEmails.emails[sender]) {
  nylasBroadcastEmails.emails[sender] = 1;
 } else {
  nylasBroadcastEmails.emails[sender]++;
 }
}

// populate email groups
emailArray.map(({sender, subject}) => {
  if(nylasBroadcastEmailRegex.test(sender)) {
    nylasBroadcastEmails.count++
    updateSenderCount(sender, nylasBroadcastEmails.emails)
    return;
  }

  if(nylasStatusUpdateEmailRegex.test(subject)) {
    nylasStatusUpdateEmails.count++;
    updateSenderCount(sender, nylasStatusUpdateEmails.emails)
    return;
  }

  if(nylasEmailRegex.test(sender)) {
    nylasEmails.count++;
    updateSenderCount(sender, nylasEmails.emails)
    return;
  }

  if(externalCompanyEmailRegex.test(sender)) {
    companyEmails.count++;
    updateSenderCount(sender, companyEmails.emails);
    return;
  }

  unorganizedEmails.count++;
  updateSenderCount(sender, unorganizedEmails.emails);
});

const createGroup = (label, weight, emails) => ({
  label,
  weight,
  groups: Object.keys(emails).map(email => ({
    label: `${email} - ${emails[email]}`,
    weight: emails[email],
    groups: []
  }))
})

const nylasEmailsCount =  nylasBroadcastEmails.count + nylasStatusUpdateEmails.count + nylasEmails.count;
const externalEmailsCount = companyEmails.count + unorganizedEmails.count;

// generate groups to display using formtree
const groups = {
  label: "",
  weight: totalEmailCount,
  groups: [
    {
      label: `@nylas emails ${nylasEmailsCount}`,
      weight: nylasEmailsCount,
      groups: [
        createGroup(
          `team messages - ${nylasBroadcastEmails.count}`, 
          nylasBroadcastEmails.count, 
          nylasBroadcastEmails.emails
        ),
        createGroup(
          `status updates - ${nylasStatusUpdateEmails.count}`, 
          nylasStatusUpdateEmails.count, 
          nylasStatusUpdateEmails.emails
        ),
        createGroup(
          `team messages - ${nylasEmails.count}`, 
          nylasEmails.count, 
          nylasEmails.emails
        ),
      ]
    },
    {
      label: `@external emails ${externalEmailsCount}`,
      weight: externalEmailsCount,
      groups: [
        createGroup(
          `company/tools - ${companyEmails.count}`, 
          companyEmails.count, 
          companyEmails.emails
        ),
        createGroup(
          `unorganized - ${unorganizedEmails.count}`, 
          unorganizedEmails.count, 
          unorganizedEmails.emails
        ),
      ]
    }
  ]
}

export default groups

Be sure to update the src/index.js to import the groups created in the src/categorization.js file.

Running the command npm start will load our email treemap in the browser at http://localhost:1234/:

Email Interactive Treemap

Now we’ve created a visualization of emails using an interactive treemap.

Build Time!

In this blog post, we explored how to create email interactive treemaps. Continue building with Nylas and learn more by visiting the documentation on the Nylas Email API. Sign up here if you need to create a Nylas account for free!

Related resources

How to create an appointment scheduler in your React app

Learn how to create an appointment scheduler in your React app using Nylas Scheduler. Streamline bookings and UX with step-by-step guidance.

Beyond APIs: Designing elegant, smart Web Components

Dive into the world of smart Web Components for advanced API integration solutions. Design elegant, customizable elements to elevate user experiences.

How to integrate a React calendar component to streamline scheduling

Elevate your app’s scheduling with a React calendar component and seamlessly integrate with Nylas for efficient calendar management.