Cube.js, le framework de tableau de bord Open Source: Guide Ultime

Cube.js est un framework open source pour la création d’applications Web analytiques. Il est principalement utilisé pour créer des outils de business intelligence internes ou pour ajouter des analyses orientées client à une application existante. Dans la majorité des cas, la première étape de la création d’une telle application est un tableau de bord analytique. Cela commence généralement par — « ajoutons un tableau de bord analytique à notre panneau d’administration. »Ensuite, comme cela arrive toujours dans le développement de logiciels, les choses deviennent plus compliquées, beaucoup plus compliquées.

Quand nous avons commencé à travailler sur Cube.js, nous voulions créer un outil simple à démarrer mais évolutif en fonctionnalités, en complexité et en volume de données. Cube.js pose une base solide pour votre futur système analytique, qu’il s’agisse d’une application autonome ou intégrée à l’application existante.

Vous pouvez considérer ce tutoriel comme « Cube.js 101. »Je vais vous guider à travers les étapes de base de la conception du premier tableau de bord, de la base de données aux visualisations.

La démo en direct du tableau de bord final est disponible ici. Le code source complet est sur Github.

Architecture

La majorité des applications Web modernes sont construites comme une application d’une seule page, où le frontend est séparé du backend. Le backend est également généralement divisé en plusieurs services, suivant une architecture de microservice.

Cube.js adopte cette approche. Classiquement, vous exécutez Cube.js Backend en tant que service. Il gère la connexion à votre base de données, y compris la file d’attente des requêtes, la mise en cache, la pré-agrégation, etc. Il expose également une API pour votre application frontend pour créer des tableaux de bord et d’autres fonctionnalités d’analyse.

Backend

Analytics commence par les données et les données résident dans une base de données. C’est la première chose que nous devons mettre en place. Vous avez probablement déjà une base de données pour votre application et, généralement, elle est très bien à utiliser pour l’analyse. Les bases de données populaires modernes telles que Postgres ou MySQL sont bien adaptées à une charge de travail analytique simple. Par simple, j’entends un volume de données avec moins de 1 milliard de lignes.

MongoDB est également correct, la seule chose que vous devrez ajouter est le connecteur MongoDB pour BI. Il permet d’exécuter du code SQL au-dessus de vos données MongoDB. Il est gratuit et peut être facilement téléchargé depuis le site Web de MongoDB. Une autre chose à garder à l’esprit est la réplication. Il est considéré comme une mauvaise pratique d’exécuter des requêtes d’analyse sur votre base de données de production, principalement en raison des problèmes de performances. Cube.js peut réduire considérablement la charge de travail d’une base de données, mais je vous recommande néanmoins de vous connecter au réplica.

Pour résumer – Si vous utilisez Postgres ou MySQL, créez simplement une réplique et nous sommes prêts à partir. Si vous utilisez MongoDB — téléchargez MongoDB Connector for BI et créez une réplique.

Si vous n’avez pas de données pour le tableau de bord, vous pouvez charger notre exemple de jeu de données e-commerce Postgres.

$ curl http://cube.dev/downloads/ecom-dump.sql > ecom-dump.j'ai créé un fichier ecom-f-dump pour les fichiers sql
sqlcreatedb ecom
pspsqlnamedbname ecom-f ecom-dump.sql

Maintenant, comme nous avons des données dans la base de données, nous sommes prêts à créer le Cube.service Backend js. Exécutez les commandes suivantes dans votre terminal:

$ npm install-g cubejs-cli
createcubejs create dashboard-backend-d postgres

Les commandes ci-dessus installent le Cube.js CLI et créer un nouveau service, configuré pour fonctionner avec la base de données Postgres.

Cube.js utilise des variables d’environnement pour la configuration. Il utilise des variables d’environnement commençant par CUBEJS_. Pour configurer la connexion à notre base de données, nous devons spécifier le type et le nom de la base de données. Dans le Cube.dossier de projet js remplacez le contenu de .env par ce qui suit:

 
CUBEJS_API_SECRET =SECRET
CUBEJS_DB_TYPE =postgres
CUBEJS_DB_NAME=ecom

Cube.schéma de données js

L’étape suivante consiste à créer un Cube.schéma de données js. Cube.js utilise le schéma de données pour générer un code SQL, qui sera exécuté dans votre base de données. Le schéma de données ne remplace pas SQL. Il est conçu pour rendre SQL réutilisable et lui donner une structure tout en préservant toute sa puissance. Les éléments de base du schéma de données sont measures et dimensions.

La mesure est appelée données quantitatives, telles que le nombre d’unités vendues, le nombre de visites uniques, le profit, etc.La dimension

est appelée données catégorielles, telles que l’état, le sexe, le nom du produit ou les unités de temps (par exemple, jour, semaine, mois).

Classiquement, les fichiers de schéma se trouvent dans le dossier schema. Voici un exemple de schéma, qui peut être utilisé pour décrire les données des utilisateurs.

 
cube('Utilisateurs', {
sql: 'SÉLECTIONNEZ * PARMI les utilisateurs`,
mesures: {
nombre: {
sql: 'id',
type: 'compte`
}
},
dimensions: {
ville: {
sql` 'ville',
type` 'chaîne`
},
signedUp: {
sql` 'created_at',
type: 'heure`
},
Nom de l'entreprise: {
sql` 'nom_entreprise',
type` 'chaîne`
}
}
});

Maintenant, avec le schéma ci-dessus en place, nous pouvons envoyer des requêtes au Cube.backend js sur les données des utilisateurs. Cube.les requêtes js sont des objets javascript simples. Habituellement, il a un ou plusieurs measures, dimensions et timeDimensions.

Si nous voulons répondre à la question « Où sont basés nos utilisateurs? »nous pouvons envoyer la requête suivante au Cube.js:

{
mesures: ,
dimensions:
}

Cube.js générera le SQL requis basé sur le schéma, l’exécutera et renverra le résultat.

Créons une requête légèrement plus compliquée. Nous pouvons ajouter un timeDimensions pour voir comment le ratio des différentes villes a changé chaque mois au cours de la dernière année. Pour ce faire, nous ajouterons une dimension temporelle signedUp, la regrouperons par mois et filtrerons uniquement les inscriptions de l’année dernière.

{
mesures:,
dimensions:,
Dimensions temporelles:
}]
}

Cube.js peut générer des schémas simples basés sur les tables de votre base de données. Générons les schémas dont nous avons besoin pour notre tableau de bord, puis démarrons un serveur de développement.

$ cubejs generate-t users, orders
n npm run dev

Vous pouvez inspecter les schémas générés et envoyer des requêtes de test en ouvrant un terrain de jeu de développement à http://localhost:4000.

Frontend

Nous allons créer notre frontend et notre tableau de bord avec React, en utilisant le Cube.client js React. Mais vous pouvez utiliser n’importe quel framework ou simplement javascript vanillé pour créer un frontend avec Cube.js. Ce tutoriel vous montre comment créer un tableau de bord en javascript pur.Nous allons tout configurer à l’aide de l’application Create React, qui est officiellement prise en charge par l’équipe React. Il regroupe toutes les dépendances de l’application React et facilite le démarrage d’un nouveau projet. Exécutez les commandes suivantes dans votre terminal:

$ npx create-react-app dashboard-frontend
cdcd dashboard-frontend
startnpm start

La dernière ligne démarre un serveur sur le port 3000 et ouvre votre navigateur Web à http://localhost:3000.

Nous allons construire notre interface utilisateur avec Reactstrap, qui est un wrapper React pour Bootstrap 4. Installez Reactstrap et Bootstrap à partir de NPM. Reactstrap n’inclut pas le CSS Bootstrap, il doit donc être installé séparément:

$ npm install reactstrap bootstrapsavesave

Import Bootstrap CSS dans le fichier src/index.js avant l’importation ./index.css:

importer 'bootstrap/dist/css/bootstrap.min.css';

Nous sommes maintenant prêts à utiliser les composants Reactstrap.

L’étape suivante consiste à installer Cube.client js pour récupérer les données du serveur et notre bibliothèque de visualisation pour les afficher. Pour ce tutoriel, nous allons utiliser les recharges. Cube.js est indépendant de la visualisation, ce qui signifie que vous pouvez utiliser n’importe quelle bibliothèque de votre choix. Nous utiliserons également le moment et le chiffre pour bien formater les dates et les nombres.

$ npm installsavesave @cubejs-client / core @cubejs-client / react recharge le chiffre du moment

Enfin, nous en avons fini avec les dépendances, alors allons-y et créons notre premier graphique.Remplacez le contenu de src/App.js par ce qui suit:

import React, {Component} from "react";
import {
BarChart,
Bar,
XAxis,
YAxis,
Info-bulle,
ResponsiveContainer
} de "recharges";
import cubejs from "@cubejs-client/core";
import moment from "moment";
import { QueryRenderer } from "@cubejs-client/react";
const cubejsApi = cubejs(process.env.REACT_APP_CUBEJS_TOKEN, {
apiUrl: process.env.REACT_APP_API_URL
});
const dateFormatter = item => moment(item).format("MMM YY");
class App extends Component {
render() {
return (
<QueryRenderer
query={{
measures: ,
timeDimensions:,
granularité: "mois"
}
]
}}
cubejsApi ={cubejsApi}
render = {({Jeu de résultats }) => {
si (!ResultSet) {
retour " Chargement...";
}
retour (
< ResponsiveContainer width = hauteur "100%"={300}>
< Données de diagramme à barres = { Jeu de résultats.chartPivot()}>
< XAxis dataKey = "x" tickFormatter = {dateFormatter} />
< YAxis />
< Info-bulle labelFormatter = {dateFormatter} />
< Barre de données = "Commandes.compte "fill=" rgba(106, 110, 229)" />
</ BarChart>
</ Réceptionneur>
);
}}
/>
);
}
}
exporter l'application par défaut;

Vous pouvez consulter cet exemple dans le CodeSandbox ci-dessous.

Examinons plus en détail la façon dont nous chargeons les données et dessinons le graphique.

Tout d’abord, nous initialisons le Cube.client API js:

const cubejsApi = cubejs(processus.env.REACT_APP_CUBEJS_TOKEN, {
apiUrl: processus.env.REACT_APP_API_URL
});

Créer un.fichier env avec les informations d’identification suivantes. Dans l’environnement de développement, Cube.js n’impose pas l’utilisation du jeton pour autoriser les requêtes, vous pouvez donc utiliser n’importe quelle chaîne pour votre jeton ici. Vous pouvez en savoir plus sur l’utilisation et la génération de jetons dans l’environnement de production ici dans la documentation.

 
REACT_APP_CUBEJS_TOKEN = VOTRE JETON
REACT_APP_API_URL = http://localhost:4000/cubejs-api/v1

Ensuite, nous utilisons le Cube QueryRenderer.composant js React pour charger les données des commandes.

< QueryRenderer
query = {{
mesures:,
Dimensions temporelles:,
granularité: " mois"
}
]
}}
cubejsApi ={cubejsApi}
render = {({Jeu de résultats }) => {
// Résultat de rendu
}}
/>

QueryRenderer effectue une requête API vers le Cube.js backend et utilise la technique des accessoires de rendu pour vous permettre de rendre le résultat comme vous le souhaitez. Nous avons déjà couvert le format de requête ci—dessus, mais au cas où vous souhaiteriez l’actualiser, voici la référence complète du format de requête.

Le paramètre render de QueryRenderer est une fonction du type ({error, resultSet, isLoading}) => React.Node. La sortie de cette fonction sera rendue par le QueryRenderer. A resultSet est un objet contenant des données obtenues à partir de la requête. Si cet objet n’est pas défini, cela signifie que les données sont toujours récupérées.

resultSet fournit plusieurs méthodes de manipulation des données, mais dans notre cas, nous n’avons besoin que de la méthode chartPivot, qui renvoie les données dans un format attendu par les Recharges.

Nous allons tracer les données des commandes sous forme de graphique à barres dans un conteneur réactif.

 
si (!ResultSet) {
retour " Chargement...";
}
retour (
< ResponsiveContainer width = hauteur "100%"={300}>
< Données de diagramme à barres = { Jeu de résultats.chartPivot()}>
< XAxis dataKey = "x" tickFormatter = {dateFormatter} />
< YAxis />
< Info-bulle labelFormatter = {dateFormatter} />
< Barre de données = "Commandes.compte "fill=" rgba(106, 110, 229)" />
</ BarChart>
</ Réceptionneur>
);

Création d’un tableau de bord

Nous avons appris à construire un seul graphique avec Cube.js et Recharges, et nous sommes maintenant prêts à commencer à construire l’ensemble du tableau de bord. Il existe quelques bonnes pratiques concernant la conception de la mise en page du tableau de bord. La pratique courante consiste à placer les métriques les plus importantes et de haut niveau en haut sous forme de graphiques à valeur unique, parfois appelés KPI, puis à répertorier les ventilations pertinentes de ces métriques.

Voici la capture d’écran de notre tableau de bord final avec des KPI en haut suivis de graphiques à barres et à courbes.

Tout d’abord, refactorisons notre graphique et extrayons le code commun en un composant <Chart /> réutilisable. Créer un fichier src/Chart.js le contenu suivant:

import React de "react";
import {Card, CardTitle, CardBody, CardText} de "reactstrap";
import {QueryRenderer} de "@cubejs-client/react";
const Chart = ({ cubejsApi, title, query, render }) => (
<Card>
<CardBody>
<CardTitle tag="h5">{title}</CardTitle>
<CardText>
<QueryRenderer
query={query}
cubejsApi={cubejsApi}
render={({ resultSet }) => {
if (!resultSet) {
return <div className="loader" />;
}
return render(resultSet);
}}
/>
</ Texte de carte>
</ Corps de carte>
</ Carte>
);
exporter le graphique par défaut;

Ensuite, utilisons ce composant pour créer le tableau de bord. Remplacez le contenu de src/App.js par ce qui suit:

import React, {Component} from "react";
import {Container, Row, Col} from "reactstrap";
import {
AreaChart,
Area,
XAxis,
YAxis,
Tooltip,
ResponsiveContainer,
Legend,
BarChart,
Bar
} from "recharts";
import moment from "moment";
import numeral from "numeral";
import cubejs from "@cubejs-client/core";
import Chart from "./Chart.js";
const cubejsApi = cubejs(process.env.REACT_APP_CUBEJS_TOKEN, {
apiUrl: process.env.REACT_APP_API_URL
});
const numberFormatter=item= > chiffre (item).format("0,0");
const dateFormatter=item=> moment (item).format ("MMM AA");
const renderSingleValue =(Jeu de résultats, clé) => (
< h1 height = {300} > { numberFormatter(ResultSet.chartPivot()) } </h1>
);
l'application de classe étend le composant {
render() {
return (
< Liquide de récipient>
< Rangée>
< Col sm="4">
< Graphique
cubejsApi={cubejsApi}
title="Nombre total d'utilisateurs"
query={{measures:}}
render={ResultSet=> renderSingleValue(ResultSet, "Utilisateurs.compter")}
/>
</ Col>
< Col sm="4">
< Graphique
cubejsApi={cubejsApi}
title="Total des commandes"
query={{measures:}}
render={ResultSet=> renderSingleValue(ResultSet, "Commandes.compter")}
/>
</ Col>
< Col sm="4">
< Graphique
cubejsApi={cubejsApi}
title="Commandes expédiées"
query={{
mesures:,
filtres:
}
]
}}
render = {ResultSet=> renderSingleValue(ResultSet, "Commandes.compter")}
/>
</ Col>
</ Rangée>
< br />
< br />
< Rangée>
< Col sm="6">
< Graphique
cubejsApi={cubejsApi}
title="Nouveaux utilisateurs Au fil du temps"
query={{
mesures:,
timeDimensions:,
granularité: " mois"
}
]
}}
render = { Jeu de résultats => (
< ResponsiveContainer width = hauteur "100%"={300}>
< Données AreaChart = { Jeu de résultats.chartPivot()}>
< XAxis dataKey ="category" tickFormatter = {dateFormatter} />
< YAxis tickFormatter = {numberFormatter} />
< Info-bulle labelFormatter = {dateFormatter} />
< Zone
type="monotone"
dataKey="Utilisateurs.count"
name="Utilisateurs"
stroke="rvb(106, 110, 229)"
fill="rgba(106, 110, 229, .16)"
/>
</ AreaChart>
</ Réceptionneur>
)}
/>
</ Col>
< Col sm="6">
< Graphique
cubejsApi ={cubejsApi}
title="Commandes par statut au fil du temps"
query= {{
mesures:,
dimensions:,
timeDimensions:,
granularité: " mois"
}
]
}}
render = { Jeu de résultats => {
retour (
< ResponsiveContainer width = hauteur "100%"={300}>
< Données de diagramme à barres = { Jeu de résultats.chartPivot()}>
< XAxis tickFormatter = {dateFormatter} dataKey="x" />
< YAxis tickFormatter = {numberFormatter} />
< Barre
stackId="a"
dataKey="expédié, commandes.compte"
name="Expédié"
fill="#7DB3FF"
/>
< Barre
stackId="a"
dataKey="traitement, commandes.count"
name="Traitement"
fill="#49457B"
/>
< Barre
stackId="a"
dataKey="terminé, Commandes.compte"
name="Terminé"
fill="#FF7C78"
/>
< Légende />
< Info-bulle />
</ BarChart>
</ Réceptionneur>
);
}}
/>
</ Col>
</ Rangée>
</ Conteneur>
);
}
}
exporter l'application par défaut;

C’est suffisant pour construire notre premier tableau de bord. Essayez-le dans la boîte de codes ci-dessous.

Prochaines étapes

Nous avons construit un tableau de bord simple de preuve de concept avec Cube.js. Vous pouvez consulter la démo en direct ici. Le code source complet est disponible sur Github.

Pour en savoir plus sur Cube.déploiement backend js, vous pouvez vous référer à la documentation de déploiement. En outre, vous trouverez ici plus de tutoriels sur une variété de sujets.

Et rejoignez notre communauté Slack ! C’est un endroit idéal pour obtenir de l’aide et rester à jour avec les nouvelles versions.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.