使用 Cumul.io 和任何 Web 框架嵌入交互式分析组件

❥ 赞助商

在本文中,我们将解释如何使用 Cumul.io 将一个集成且交互式的数据可视化层构建到应用程序中。为此,我们构建了一个 演示应用程序,它可视化 Spotify 播放列表分析!我们使用 Cumul.io 作为我们的交互式仪表盘,因为它使集成变得超级简单,并提供允许仪表盘和应用程序之间交互的功能(例如 自定义事件)。该应用程序是一个简单的 JavaScript Web 应用程序,带有一个 Node.js 服务器,虽然您可以选择,如果您愿意,使用 AngularReactReact Native 来使用 Cumul.io 仪表盘。

在这里,我们构建了仪表盘,这些仪表盘显示来自 The Kaggle Spotify Dataset 1921–2020,160k+ 轨迹 的数据以及用户登录后通过 Spotify Web API 获取的数据。我们构建了仪表盘,以洞察播放列表和歌曲特征。我们添加了一些 Cumul.io 自定义事件,这些事件将允许任何访问这些仪表盘的最终用户从图表中选择歌曲并将其添加到他们自己的 Spotify 播放列表中。他们还可以选择一首歌曲以显示更多信息,并在应用程序中播放。完整应用程序的代码也在 一个公开的仓库 中公开提供。

以下是完整版本最终结果的偷窥

Cumul.io 自定义事件是什么以及它们的功能?

简而言之,Cumul.io 自定义事件是一种从仪表盘触发事件的方式,用于在集成仪表盘的应用程序中使用。您可以将自定义事件添加到仪表盘中的选定图表中,并让应用程序监听这些事件。

为什么? 这个工具的酷点在于它允许您在构建它的应用程序中重用来自分析仪表盘、BI 工具的数据。它使您能够根据数据定义操作,这些操作可以直接从集成的仪表盘中触发,同时保持仪表盘,分析层与应用程序完全分离的实体,可以与它分开管理。

它们包含什么: Cumul.io 自定义事件附加到图表而不是整个仪表盘。因此,事件具有的信息仅限于图表具有的信息。

简而言之,事件只是一个 JSON 对象。此对象将包含字段,例如触发它的仪表盘的 ID、事件的名称以及其他一些字段,具体取决于触发事件的图表类型。例如,如果事件是从散点图中触发的,您将收到x 轴y 轴值的点它被触发了。另一方面,如果它是从表格中触发的,您将收到例如值。查看来自不同图表的这些事件的外观示例

// '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"
 }
}
//'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"
  }
}

这种功能的可能性实际上是无限的。当然,根据您想做的事情,您可能需要编写几行代码,但它无疑是一个非常强大的工具!

仪表盘

我们实际上不会在这里介绍仪表盘创建过程,我们将在将其集成到应用程序后关注交互部分。本演练中集成的仪表盘已经创建,并且启用了自定义事件。当然,您可以创建自己的仪表盘并将其集成,而不是我们预先构建的仪表盘(您可以创建免费试用账户)。但在那之前,先了解一下 Cumul.io 仪表盘;

Cumul.io 提供了一种从平台内部或通过其 API 创建仪表盘的方式。无论哪种情况,仪表盘都将在平台内可用,与您要将其集成到的应用程序分离,因此可以完全独立维护。

在您的登录页面上,您将看到您的仪表盘,并可以创建一个新的仪表盘

您可以打开一个并拖放您想要的任何图表

您可以连接数据,然后将其拖放到这些图表中

并且,该数据可以是许多事物之一。例如,您可以连接到 Cumul.io 的预先存在的数据库,您使用的数据库仓库中的数据集,自定义构建的插件等。

启用自定义事件

我们已经在本演示中使用的仪表盘中的散点图表格中启用了这些自定义事件,我们将在下一部分中将其集成。如果您想完成此步骤,请随时创建自己的仪表盘!

首先,您需要将自定义事件添加到图表中。为此,首先选择您想要添加事件的仪表盘中的一个图表。在图表设置中,选择交互性并打开自定义事件

要添加事件,请单击编辑并定义其事件名称标签。事件名称是您的应用程序将接收到的,而标签是显示在仪表盘上的。在本例中,我们添加了 2 个事件;‘添加到播放列表’和‘歌曲信息’

这就是您在图表级别设置仪表盘以触发事件所需的全部设置。在离开编辑器之前,您需要您的仪表盘 ID 才能稍后集成仪表盘。您可以在仪表盘的设置选项卡中找到它。其余的工作将在应用程序级别完成。在这里,我们将定义当我们收到任何这些事件时我们实际上想要做什么

要点

  1. 事件在图表级别上工作,并将包括图表信息范围内的信息
  2. 要添加事件,请转到您想要添加事件的图表的图表设置
  3. 定义事件的名称和标签。就完成了!
  4. (不要忘记记下仪表盘 ID 以进行集成)

在您自己的平台中使用自定义事件

现在您已经将一些事件添加到仪表盘中,下一步是使用它们。这里的关键点是,一旦您在仪表盘中单击事件,集成仪表盘的应用程序就会收到事件。 Integration API 提供了一个函数来监听这些事件,然后您就可以定义如何处理它们。有关 API 和 SDK 代码示例的更多信息,您还可以查看相关的开发者文档

对于本节,我们还提供了一个开放的 GitHub 仓库(与 主应用程序的仓库 分开),您可以将其用作添加自定义事件的入门项目。

cumulio-spotify-datatalks 仓库的结构使得您可以检出名为skeleton的提交以从头开始。所有后续提交都将代表我们在此处执行的步骤。它是完整应用程序的精简版本,重点关注演示自定义事件的应用程序的主要部分。我将跳过一些步骤,例如 Spotify API 调用(在 src/spotify.js 中),以便将本教程限制在‘添加和使用自定义事件’主题上。

后续步骤的实用信息

让我们看看我们的案例中发生了什么。我们创建了两个事件:add_to_playlistsong_info。我们希望仪表板的访问者能够将歌曲添加到他们自己的 Spotify 帐户中选择的播放列表中。为此,我们采取以下步骤

  1. 将仪表板与您的应用程序集成
  2. 监听传入事件

将仪表板与您的应用程序集成

首先,我们需要将仪表板添加到我们的应用程序中。这里我们使用 Cumul.io Spotify 播放列表仪表板 作为主仪表板,以及 歌曲信息仪表板 作为深入仪表板(这意味着我们在主仪表板中创建一个新仪表板,当我们触发事件时会弹出)。如果您查看名为skeleton 的提交并运行 npm run start,应用程序目前应该只打开一个空的“Cumul.io Favorites”选项卡,在右上角有一个登录按钮。有关如何在本地运行项目的说明,请转到本文底部

要集成仪表板,我们需要使用 Cumulio.addDashboard() 函数。此函数期望一个包含仪表板选项的对象。以下是我们添加仪表板的操作

src/app.js 中,我们创建一个对象来存储主仪表板和显示歌曲信息的深入仪表板的仪表板 ID,以及一个 dashboardOptions 对象

// 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'
  }
};

我们创建一个 loadDashboard() 函数,该函数调用 Cumulio.addDashboard()。此函数可以选择接收一个容器并在将仪表板添加到应用程序之前修改 dashboardOptions 对象。

// 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);
};

最后,我们使用此函数在加载 Cumul.io Favorites 选项卡时添加我们的播放列表仪表板

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

此时,我们已经集成了播放列表仪表板,当我们在Energy/Danceability by Song 散点图中点击一个点时,我们会获得两个选项,它们是我们之前添加的自定义事件。但是,我们还没有对它们做任何事情。

监听传入事件

现在我们已经集成了仪表板,我们可以告诉我们的应用程序在收到事件时做一些事情。这里有两个包含“添加到播放列表”和“歌曲信息”事件的图表

首先,我们需要设置代码以监听传入事件。为此,我们需要使用 Cumulio.onCustomEvent() 函数。在这里,我们选择将此函数包装在一个 listenToEvents() 函数中,该函数可以在我们加载 Cumul.io Favorites 选项卡时调用。然后我们使用 if 语句来检查我们收到的事件

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

这是事情取决于您的需求和创造力的点。例如,您只需将一行打印到控制台,或设计自己的行为围绕您从事件中接收的数据。或者,您还可以使用我们创建的一些辅助函数来显示一个播放列表选择器以将歌曲添加到播放列表中,并集成歌曲信息仪表板。这就是我们所做的;

将歌曲添加到播放列表

这里,我们将使用 src/ui.js 中的 addToPlaylistSelector() 函数。此函数期望一个歌曲名称和 ID,并将显示一个包含登录用户所有可用播放列表的窗口。然后它将发布一个 Spotify API 请求以将歌曲添加到选定的播放列表中。由于 Spotify Web API 需要歌曲的 ID 才能添加它,因此我们在散点图中创建了一个派生的 Name & ID 字段。

我们在 add_to_playlist 上收到的示例事件将包括散点图的以下内容

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

以及表格的这些列

"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"}
]

我们通过 getSong() 函数从事件中提取歌曲的名称和 ID,然后调用 ui.addToPlaylistSelector() 函数

/*********** 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
    }
  });
};

现在,“添加到播放列表”事件将显示一个窗口,其中包含登录用户可以将歌曲添加到其中的可用播放列表

显示更多歌曲信息

我们想要做的最后一件事是,让“歌曲信息”事件在点击时显示另一个仪表板。它将显示有关所选歌曲的更多信息,并包括播放歌曲的选项。这也是我们开始使用 API 的更多复杂用例的步骤,这些用例可能需要一些背景知识。具体来说,我们使用了 可参数化过滤器。其思想是在仪表板中创建一个参数,其值可以在创建授权令牌时定义。我们在创建授权令牌时将参数包含为元数据

对于此步骤,我们创建了一个 songId 参数,该参数用于歌曲信息仪表板上的过滤器

然后,我们创建一个 getDashboardAuthorizationToken() 函数。此函数期望元数据,然后将其发布到我们服务器中 server/server.js/authorization 端点

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.' };
  }
};

最后,我们在触发 song_info 事件时使用加载 songInfo 仪表板。为此,我们使用歌曲 ID 创建一个新的授权令牌

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);
};

我们对 loadDashboard() 函数进行了一些修改,以便使用新令牌

const loadDashboard = (id, container, key, token) =u003e {n  dashboardOptions.dashboardId = id;n  dashboardOptions.container = container || '#dashboard-container';  nn  if (key u0026u0026 token) {n    dashboardOptions.key = key;n    dashboardOptions.token = token;n  }nn  Cumulio.addDashboard(dashboardOptions);n};

然后调用 ui.displaySongInfo()。最终结果如下所示

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);
    }
  });
};

!我们完成了!在这个演示中,我们使用了许多辅助函数,我没有详细介绍,但您可以随意克隆演示存储库并尝试使用它们。您甚至可以忽略它们并围绕自定义事件构建自己的功能。

结论

对于任何打算在其应用程序中集成数据可视化和分析层的人来说,Cumul.io 提供了一种非常简单的实现方法,正如我在本演示中所演示的。仪表板仍然是应用程序的独立实体,可以单独进行管理。如果您在业务环境中进行集成分析,并且不希望开发人员不断返回并修改仪表板,那么这将是一个很大的优势。

另一方面,您可以从仪表板触发并监听其宿主应用程序中的事件,这使您可以根据这些独立仪表板中的信息定义实现。这可以是任何事情,从我们的案例中的播放歌曲到触发发送特定电子邮件。从某种意义上说,世界是你的牡蛎,你决定如何处理来自分析层的数据。换句话说,您可以重复使用仪表板中的数据,它不必仅仅保留在仪表板和分析世界中 🙂

运行此项目的步骤

在您开始之前

  1. 使用 npm install 克隆 cumulio-spotify-datatalks 存储库
  2. 在根目录中创建一个 .env 文件,并从您的 Cumul.ioSpotify 开发者平台 帐户中添加以下内容
  3. 来自 Cumul.io:CUMULIO_API_KEY=xxx CUMULIO_API_TOKEN=xxx
  4. 来自 Spotify:SPOTIFY_CLIENT_ID=xxx SPOTIFY_CLIENT_SECRET=xxx ACCESS_TOKEN=xxx REFRESH_TOKEN=xxxnpm run start
  5. 在您的浏览器中,转到 https://:3000/ 并登录您的 Spotify 帐户 🥳