How to Make Your Dashboard & App Interact With Custom Events

The time has come to share a demo on Custom Events on Cumul.io. A great feature you can use to make your creativity shine and bring dashboards to life. By the end of this blogpost, you’ll be able to create your own custom events, and use them in your application.

For the purpose of this walkthrough, we’ve created a fun demo using the Spotify Web API. Here, we use our dashboard as an insight into playlist and song characteristics. We’ve added some custom events that will allow any end user visiting our dashboards to select songs from a chart and add them to one of their own Spotify playlists. They can also select a song to display more info on them, and play them from within the application. You can try all of this out here! And the code is also publicly available in an open repository.

Here’s a sneak peak into what the end result for the full version looks like:

You can add a song to one of your playlists.

You can display further song info and play the song from the dashboard.

You can display a playlist insights dashboard on one of your own playlist.

What are Custom Events and Their Capabilities?

Simply put, custom events are a way to trigger an event from your dashboard, to be used in your own application. You can add custom events into selected charts in your dashboard, and have your application listen for these events. Once the event is triggered and your application is notified of this, you will have access to info such as the ID of the dashboard the event was triggered from, the name of the event and the values of the point in the chart it was triggered from. Now, you are free to implement any custom functionality you may want.

Why?

The power of this tool is in how it allows you to reuse data from your dashboards within your application. It gives you the freedom to define actions based on data, that can be triggered straight from within an integrated dashboard. A simple example might be a chart about employees/colleagues, and an event that you define that means when you click on a data point representing a person, you switch tabs to see that person’s profile. Or, you may want to have a few options: to see their profile, or to send them an email for example.

What It Contains

An important thing to note is that custom events are attached to charts rather than dashboards as a whole. So the information an event has is limited to the information a chart has. In other words, the data that an event has is limited to the data made available to the chart.

An event is simply put a JSON object. This object will contain fields such as the ID of the dashboard that triggered it, the name of the event and a number of other fields depending on the type of chart that the event was triggered from. For example, if the event was triggered from a scatter plot, you will receive the x-axis and y-axis values of the point it was triggered from. On the other hand, if it were triggered from a table, you would receive column values for example. See examples of what these events will look like from different charts:

//'Song Info' custom event from a point in a scatter plot
{
 "type":"customEvent",
 "dashboard":"xxxx",
 "name":"xxxx",
 "object":"xxxx",
 "data":{
   "language":"en",
   "x-axis":{"id":0.601,"value":"0.601","label":"Danceability"},
   "y-axis":{"id":0.532,"value":"0.532","label":"Energy"},
   "name":{"id":"xxxx","value":"xxx","label":"Name"},
   "event":"song_info"
  }
}

//'Add to Playlist' custom event from a row in a table
{
 "type":"customEvent",
 "dashboard":"xxxx",
 "name":"xxxx",
 "object":"xxxx",
 "data":{
   "language":"en",
   "columns":[
     {"id":"Ensueno","value":"Ensueno","label":"Name"}, 
     {"id":"Vibrasphere","value":"Vibrasphere","label":"Artist"}, 
     {"value":0.406,"formattedValue":"0.41","label":"Danceability"}, 
     {"value":0.495,"formattedValue":"0.49","label":"Energy"}, 
     {"value":180.05,"formattedValue":"180.05","label":"Tempo (bpm)"}, 
     {"value":0.568,"formattedValue":"0.5680","label":"Accousticness"}, 
     {"id":"2007-01-01T00:00:00.000Z","value":"2007","label":"Release Date (Yr)"},
   ],
   "event":"add_to_playlist"
 }
}

The possibilities with this functionality are virtually limitless. Granted, depending on what you want to do, you may have to write a couple more lines of code, but it is unarguably quite a powerful tool!

The Demo (Summary)

We’ve chosen to build a demo that uses the Spotify Web API. The idea is to build a dashboard that’s integrated into a simple web application, which can be used to add songs to your own Spotify playlists. We have a dashboard that displays playlist analytics, such as the energy, acousticness, danceability of its songs (all metrics accessible via the Spotify Web API). Custom events, in turn, create the appropriate API calls to Spotify from within the application.

Another thing we do is to integrate yet another dashboard within the application that displays further information on the song that was clicked. This is an example of a drill through dashboard. It zooms into a certain part of a chart to display a dashboard with more detail on that point.

Adding Custom Events on Cumul.io

Note: We have already added the custom events to the dashboard used in this demo. If you want to go through this step, feel free to create your own dashboards too!

First thing you need to do will be to add custom events to a chart. To do this, first select a chart in your dashboard you’d like to add an event to. In the chart settings, select Interactivity and turn Custom Events on:

To add an event, click edit and define its Event Name and Label. Event Name is what your application will receive and Label is the one that will show up on your dashboard. In our case, we’ve added 2 events; ‘Add to Playlist’ and ‘Song Info’:

This is all the setup you need for your dashboard to trigger an event on a chart level. Before you leave the editor, you will need your dashboard ID to integrate the dashboard later. You can find this in the Settings tab of your dashboard. The rest of the work remains on application level. This will be where we define what we actually want to do once we receive any of these events.

Take Away Points

  1. Events work on a chart level and will include information within the limits of the information on the chart
  2. To add an event, go to the chart settings on the chart you want to add them to
  3. Define name and label of event. And you’re done!
  4. (Don’t forget to take note of the dashboard ID for integration)

Using Custom Events in Your own Platform

Now that you’ve added some events to the dashboard, the next step is to use them. The key point here is that, once you click an event in your dashboard, your application that integrates the dashboard receives an event. Our Integration API provides a function to listen to these events, and then it’s up to you to define what you do with them. For more information on the API and code examples for your SDK, you can also check out the relevant developer docs.

For this section, we’re also providing an open GitHub repository (separate to the repository for the main application) that you can use as a starting project to add custom events to.

The cumulio-spotify-datatalks repository is structured so that you can checkout on the commit called skeleton to start from the beginning. All the following commits will represent a step we go through here. It’s a boiled down version of the full application, focusing on the main parts of the app that demonstrates Custom Events. I’ll be skipping some steps such as the Spotify API calls which are in src/spotify.js, so as to limit this tutorial to the theme of ‘adding and using custom events’. To run this project with all of its capabilities, you can register an application on the Spotify Developer Dashboard and go to Instructions to locally run the project.

Useful Info for Following Steps

Let’s have a look at what happens in our case. We had created 2 events; ‘add_to_playlist’ and ‘song_info’. We want visitors of our dashboard to be able to add a song to their own playlist of choice in their own Spotify account. In order to do so, we take the following steps:

  1. Integrate the dashboard in your app
  2. Listen to incoming events

Integrate the Dashboard in Your App

First, we need to add a dashboard to our application. Here we use the Cumul.io Spotify Playlist dashboard as the main dashboard and the Song Info dashboard as the drill through dashboard. If you have checked out on the commit called skeleton and npm run start, the application should currently just open up an empty ‘Cumul.io Favorites’ tab, with a Login button at the top right. For instructions on how to locally run the project, go here:

To integrate a dashboard, we will need to use the Cumulio.addDashboard() function. This function expects an object with dashboard options. Here’s what we do to add the dashboard:

In src/app.js, we create an object that stores the dashboard IDs for the main dashboard and the drill through dashboard that displays song info alongside a dashboardOptions object:

//create dashboards object with the dashboard ids and dashboardOptions object

//!!!change these IDs if you want to use your own dashboards!!!
const dashboards = {
  playlist: 'f3555bce-a874-4924-8d08-136169855807', 
  songInfo: 'e92c869c-2a94-406f-b18f-d691fd627d34',
};

const dashboardOptions = {
  dashboardId: dashboards.playlist,
  container: '#dashboard-container',
  loader: {
    background: '#111b31',
    spinnerColor: '#f44069',
    spinnerBackground: '#0d1425',
    fontColor: '#ffffff'
  }
};

We create a loadDashboard() function that calls Cumulio.addDashboard(). This function optionally receives a container and modifies the dashboardOptions object before adding dashboard to the application.

//create a loadDashboard() function that expects a dashboard ID and container

const loadDashboard = (id, container) => {
  dashboardOptions.dashboardId = id;
  dashboardOptions.container = container || '#dashboard-container';  
  Cumulio.addDashboard(dashboardOptions);
};

Finally, we use this function to add our playlist dashboard when we load the Cumul.io Favorites tab:

export const openPageCumulioFavorites = async () => {
  ui.openPage('Cumul.io playlist visualized', 'cumulio-playlist-viz');
  /**************** INTEGRATE DASHBOARD ****************/
  loadDashboard(dashboards.playlist);
};

At this point, we’ve integrated the playlist dashboard and when we click on a point in the Energy/Danceability by Song scatter plot, we get 2 options with the custom events we added earlier. However, we’re not doing anything with them yet.

Listen to Incoming Events

Now that we’ve integrated the dashboard, we can tell our app to do stuff when it receives an event. The two charts that have ‘Add to Playlist’ and ‘Song Info’ events here are:

The Energy/Danceability by Song Scatter Plot

The Data Table

First, we need to set up our code to listen to incoming events. To do so, we need to use the Cumulio.onCustomEvent() function. Here, we chose to wrap this function in a listenToEvents() function that can be called when we load the Cumul.io Favorites tab. We then use if statements to check what event we’ve received:

const listenToEvents = () => {
  Cumulio.onCustomEvent((event) => {
    if (event.data.event === 'add_to_playlist'){
      //DO SOMETHING
    }
    else if (event.data.event === 'song_info'){
      //DO SOMETHING
    }
  });
};

This is the point after which things are up to your needs and creativity. For example, you could simply print a line out to your console, or design your own behaviour around the data you receive from the event. Or, you could also use some of the helper functions we’ve created that will display a playlist selector to add a song to a playlist, and integrate the Song Info dashboard. This is how we did it;

Add Song to Playlist

Here, we will make use of the addToPlaylistSelector() function in src/ui.js. This function expects a Song Name and ID, and will display a window with all the available playlists of the logged in user. It will then post a Spotify API request to add the song to the selected playlist. As the Spotify Web API requires the ID of a song to be able to add it, we’ve created a derived Name & ID field to be used in the scatter plot.

An example event we receive on ‘add_to_playlist’ will include the following for the scatter plot:

"name":{"id":"So Far To Go&id=3R8CATui5dGU42Ddbc2ixE","value":"So Far To Go&id=3R8CATui5dGU42Ddbc2ixE","label":"Name & ID"}

And these columns for the table:

"columns":[
 {"id":"Weapon Of Choice (feat. Bootsy Collins) - Remastered Version","value":"Weapon Of Choice (feat. Bootsy Collins) - Remastered Version","label":"Name"},
 {"id":"Fatboy Slim","value":"Fatboy Slim","label":"Artist"},  
....
 {"id":"3qs3aHNUcqFGv7jMYJJCYa","value":"3qs3aHNUcqFGv7jMYJJCYa","label":"ID"}
]

We extract the Name and ID of the song from the event via the getSong() function, then call the ui.addToPlaylistSelector() function:

/*********** LISTEN TO CUSTOM EVENTS AND ADD EXTRAS ************/
const getSong = (event) => {
  let songName;
  let songArtist;
  let songId;
  if (event.data.columns === undefined) {
    songName = event.data.name.id.split('&id=')[0];
    songId = event.data.name.id.split('&id=')[1];
  }
  else {
    songName = event.data.columns[0].value;
    songArtist = event.data.columns[1].value;
    songId = event.data.columns[event.data.columns.length - 1].value;
  }
  return {id: songId, name: songName, artist: songArtist};
};

const listenToEvents = () => {
  Cumulio.onCustomEvent(async (event) => {
    const song = getSong(event);
    console.log(JSON.stringify(event));
    if (event.data.event === 'add_to_playlist'){
      await ui.addToPlaylistSelector(song.name, song.id);
    }
    else if (event.data.event === 'song_info'){
      //DO SOMETHING
    }
  });
};

Now, the ‘Add to Playlist’ event will display a window with the available playlists that a logged in user can add the song to:

Display More Song Info

The final thing we want to do is to make the ‘Song Info’ event display another dashboard when clicked. It will display further information on the selected song, and include an option to play the song. For this step, we make use of Parameterizable Filters. The idea is to create a parameter on your dashboard, for which the value can be defined while creating an authorization token. We include the parameter as metadata while creating an authorization token.

For this step, we have created a songId parameter that is used in a filter on the Song Info dashboard:

Then, we create a getDashboardAuthorizationToken() function. This expects metadata which it then posts to the /authorization endpoint of our server in server/server.js :

const getDashboardAuthorizationToken = async (metadata) => {
  try {
    const body = {};
    if (metadata && typeof metadata === 'object') {
      Object.keys(metadata).forEach(key => {
        body[key] = metadata[key];
      });
    }

    /*
      Make the call to the backend API, using the platform user access credentials in the header
      to retrieve a dashboard authorization token for this user
    */
    const response = await fetch('/authorization', {
      method: 'post',
      body: JSON.stringify(body),
      headers: { 'Content-Type': 'application/json' }
    });

    // Fetch the JSON result with the Cumul.io Authorization key & token
    const responseData = await response.json();
    return responseData;
  }
  catch (e) {
    return { error: 'Could not retrieve dashboard authorization token.' };
  }
};

Finally, we use the load the songInfo dashboard when the ‘song_info’ event is triggered. In order to do this, we create a new authorization token using the song ID:

const token = await getDashboardAuthorizationToken({ songId: [song.id] });

We make some modifications to the loadDashbord() function so as to use the new token:

const loadDashboard = (id, container, key, token) => {
  dashboardOptions.dashboardId = id;
  dashboardOptions.container = container || '#dashboard-container';  

  if (key && token) {
    dashboardOptions.key = key;
    dashboardOptions.token = token;
  }

  Cumulio.addDashboard(dashboardOptions);
};

Then call the ui.displaySongInfo(). The final result looks as follows:

const listenToEvents = () => {
  Cumulio.onCustomEvent(async (event) => {
    const song = getSong(event);
    if (event.data.event === 'add_to_playlist'){
      await ui.addToPlaylistSelector(song.name, song.id);
    }
    else if (event.data.event === 'song_info'){
      const token = await getDashboardAuthorizationToken({ songId: [song.id] });
      loadDashboard(dashboards.songInfo, '#song-info-dashboard', token.id, token.token);
      await ui.displaySongInfo(song);
    }
  });
};

And voila! We are done! In this demo we used a lot of helper functions I haven’t gone through in detail, but you are free clone the demo repository and play around with them. You can even disregard them and build your own functionality around the custom events.

Instructions to Locally Run Project

Before you start:

  1. Clone the cumulio-spotify-datatalks repository
  2. npm install
  3. Create a .env file in the root directory and add the following from your Cumul.io and Spotify Developer accounts:
    From Cumul.io:
    CUMULIO_API_KEY=xxx
    CUMULIO_API_TOKEN=xxx
    From Spotify:
    SPOTIFY_CLIENT_ID=xxx
    SPOTIFY_CLIENT_SECRET=xxx
    ACCESS_TOKEN=xxx
    REFRESH_TOKEN=xxxnpm run start
  4. On your browser, go to http://localhost:3000/ and login to your Spotify account 🥳

Resources

The CuMusicalio App
Academy article on Custom Events
Webinar on Custom Events
Academy article on Parameterizable Filters
Qick Start for the Spotify Web API

Add a Comment

Your email address will not be published. Required fields are marked *