Cube.js, el marco de Panel de código abierto: Ultimate Guide

Cube.js es un framework de código abierto para crear aplicaciones web analíticas. Se utiliza principalmente para crear herramientas internas de inteligencia empresarial o para agregar análisis orientados al cliente a una aplicación existente. En la mayoría de los casos, el primer paso para crear una aplicación de este tipo es un panel de análisis. Por lo general, comienza con:»agreguemos un panel de análisis a nuestro panel de administración.»Entonces, como siempre sucede en el desarrollo de software, las cosas se complican, se complican mucho más.

Cuando empezamos a trabajar en Cube.js, queríamos crear una herramienta, que fuera fácil de iniciar pero que escalara fácilmente en características, complejidad y volumen de datos. Cubo.js sienta una base sólida para su futuro sistema analítico, ya sea una aplicación independiente o integrada en la existente.

Puedes pensar en este tutorial como » Cubo.js 101.»Le guiaré a través de los pasos básicos para diseñar el primer panel desde la base de datos hasta las visualizaciones.

La demostración en vivo del panel final está disponible aquí. El código fuente completo está en Github.

Arquitectura

La mayoría de las aplicaciones web modernas se construyen como una aplicación de una sola página, donde el frontend está separado del backend. El backend también suele dividirse en varios servicios, siguiendo una arquitectura de microservicios.

Cubo.js adopta este enfoque. Convencionalmente se ejecuta Cube.motor js como servicio. Administra la conexión a su base de datos, incluida la cola de consultas, el almacenamiento en caché, la agregación previa y más. También expone una API para su aplicación frontend para crear paneles y otras funciones de análisis.

Backend

El análisis comienza con los datos y los datos residen en una base de datos. Eso es lo primero que necesitamos tener en su lugar. Lo más probable es que ya tenga una base de datos para su aplicación y, por lo general, está bien usarla para análisis. Las bases de datos populares modernas, como Postgres o MySQL, son adecuadas para una carga de trabajo analítica simple. Por simple, me refiero a un volumen de datos con menos de 1 mil millones de filas.

MongoDB también está bien, lo único que necesitará agregar es el conector MongoDB para BI. Permite ejecutar código SQL sobre los datos de MongoDB. Es gratuito y se puede descargar fácilmente desde el sitio web de MongoDB. Una cosa más a tener en cuenta es la replicación. Se considera una mala práctica ejecutar consultas de análisis en su base de datos de producción, principalmente debido a los problemas de rendimiento. Cubo.js puede reducir drásticamente la cantidad de carga de trabajo de una base de datos, pero aún así, recomendaría conectarse a la réplica.

Para resumir, si usa Postgres o MySQL, simplemente cree una réplica y estaremos listos. Si utiliza MongoDB, descargue MongoDB Connector for BI y cree una réplica.

Si no tiene datos para el panel, puede cargar nuestro conjunto de datos de Postgres de comercio electrónico de muestra.

$ rizo http://cube.dev/downloads/ecom-dump.sql > volcado ecom.sql
$ createdb ecom
$ psql --el nombre de base de datos ecom -f ecom-dump.sql

Ahora, como tenemos datos en la base de datos, estamos listos para crear el Cubo.servicio de motor js. Ejecute los siguientes comandos en su terminal:

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

Los comandos anteriores install Cube.js CLI y crear un nuevo servicio, configurado para funcionar con la base de datos Postgres.

Cubo.js utiliza variables de entorno para la configuración. Utiliza variables de entorno que comienzan con CUBEJS_. Para configurar la conexión a nuestra base de datos, necesitamos especificar el tipo y el nombre de la base de datos. En el Cubo.carpeta de proyecto js reemplace el contenido de .env por lo siguiente:

 
CUBEJS_API_SECRET = SECRET
CUBEJS_DB_TYPE = postgres
CUBEJS_DB_NAME = ecom

Cube.esquema de datos js

El siguiente paso es crear un cubo.esquema de datos js. Cubo.js utiliza el esquema de datos para generar un código SQL, que se ejecutará en su base de datos. El esquema de datos no sustituye a SQL. Está diseñado para hacer que SQL sea reutilizable y darle una estructura a la vez que conserva toda su potencia. Los elementos básicos del esquema de datos son measures y dimensions. La medida

se conoce como datos cuantitativos, como el número de unidades vendidas, el número de visitas únicas, los beneficios, etc.

La dimensión se conoce como datos categóricos, como el estado, el género, el nombre del producto o las unidades de tiempo (por ejemplo, día, semana, mes).

Convencionalmente, los archivos de esquema se encuentran en la carpeta schema. Aquí hay un ejemplo del esquema, que se puede usar para describir los datos de los usuarios.

cubo(`Usuarios`, {
sql: `SELECT * FROM usuarios`,
medidas: {
count: {
sql: `id`,
tipo: "contar`
}
},
dimensiones: {
ciudad: {
sql: `la ciudad`,
tipo: `cadena`
},
signedUp: {
sql: `created_at`,
tipo: `el tiempo`
},
companyName: {
sql: `company_name`,
tipo: `cadena`
}
}
});

Ahora, con el esquema anterior, podemos enviar consultas al Cubo.motor js sobre los datos de los usuarios. Cubo.las consultas js son objetos javascript simples. Usualmente uno o más measures, dimensions, y timeDimensions.

Si queremos responder a la pregunta "¿Dónde están basados nuestros usuarios?"podemos enviar la siguiente consulta al Cubo.js:

{
medidas: ,
dimensiones:
}

Cubo.js generará el SQL requerido basado en el esquema, lo ejecutará y devolverá el resultado.

Vamos a crear una consulta un poco más complicada. Podemos agregar un timeDimensions para ver cómo la proporción de diferentes ciudades ha ido cambiando cada mes durante el último año. Para hacer esto, agregaremos una dimensión de tiempo signedUp, la agruparemos por mes y filtraremos solo los registros del año pasado.

{
medidas: ,
dimensiones: ,
timeDimensions:
}]
}

Cubo.js puede generar esquemas simples basados en las tablas de su base de datos. Generemos los esquemas que necesitamos para nuestro panel de control y luego iniciemos un servidor de desarrollo.

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

Puede inspeccionar los esquemas generados y enviar consultas de prueba abriendo un área de desarrollo en http://localhost:4000.

Frontend

Construiremos nuestro frontend y panel de control con React, usando el Cubo.cliente de js React. Pero puedes usar cualquier framework o simplemente javascript de vainilla para construir un frontend con Cube.js. Este tutorial le muestra cómo crear un panel de control en javascript puro.Configuraremos todo con la aplicación Create React, que es compatible oficialmente con el equipo de React. Empaqueta todas las dependencias de la aplicación React y hace que sea fácil comenzar con un nuevo proyecto. Ejecute los siguientes comandos en su terminal:

$ npx create-react-app dashboard-frontend
cd cd dashboard-frontend
start npm start

La última línea inicia un servidor en el puerto 3000 y abre su navegador web en http://localhost:3000.

Construiremos nuestra interfaz de usuario con Reactstrap, que es un envoltorio de React para Bootstrap 4. Instale Reactstrap y Bootstrap desde NPM. Reactstrap no incluye CSS de arranque, por lo que debe instalarse por separado:

$ npm install reactstrap bootstrap save guardar

Importar CSS de Bootstrap en el archivo src/index.js antes de importar ./index.css:

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

Ahora estamos listos para usar los componentes Reactstrap.

El siguiente paso es instalar Cube.cliente js para obtener los datos del servidor y nuestra biblioteca de visualización para mostrarlos. Para este tutorial, vamos a usar Recharts. Cubo.js es independiente de la visualización, lo que significa que puede usar cualquier biblioteca que desee. También usaremos el momento y los números para formatear bien las fechas y los números.

$ npm install save save @ cubejs-client / core @cubejs-client / react recharts número de momento

Finalmente, hemos terminado con las dependencias, así que sigamos adelante y creemos nuestro primer gráfico.Reemplace el contenido de src/App.js con el siguiente:

importación de Reaccionar, { Componente } de "reaccionar";
importar {
BarChart,
Bar
x-eje,
Eje,
Descripción,
ResponsiveContainer
} de "recharts";
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: ,
granularidad: "mes"
}
]
}}
cubejsApi={cubejsApi}
render={({ conjunto de resultados }) => {
si (!ResultSet) {
return " Loading...";
}
volver (
<ResponsiveContainer width="100%" height={300}>
<BarChart datos={conjunto de resultados.chartPivot()}>
<x-eje dataKey="x" tickFormatter={dateFormatter} />
<Eje />
<Descripción labelFormatter={dateFormatter} />
<Barra de dataKey="las Órdenes.el recuento de" fill="rgba(106, 110, 229)" />
</BarChart>
</ResponsiveContainer>
);
}}
/>
);
}
}
exportación por defecto de la Aplicación;

Usted puede comprobar fuera de este ejemplo en la CodeSandbox a continuación.

Veamos más a fondo cómo cargamos los datos y dibujamos el gráfico.

Primero, inicializamos el Cubo.cliente API de js:

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

Crear un .archivo env con las siguientes credenciales. En el entorno de desarrollo, Cube.js no impone el uso del token para autorizar consultas, por lo que puede usar cualquier cadena para su token aquí. Puede obtener más información sobre el uso y la generación de tokens en el entorno de producción aquí en los documentos.

 
REACT_APP_CUBEJS_TOKEN=YOUR-TOKEN
REACT_APP_API_URL=http://localhost:4000 / cubejs-api / v1

A continuación, estamos utilizando el cubo QueryRenderer.Componente js React para cargar datos de pedidos.

<QueryRenderer
query={{
medidas: ,
timeDimensions: ,
granularidad: "el mes de la"
}
]
}}
cubejsApi={cubejsApi}
render={({ conjunto de resultados }) => {
// resultado del Render
}}
/>

QueryRenderer realiza una solicitud a la API para el Cubo.motor js y utiliza la técnica de accesorios de renderizado para permitirle renderizar el resultado como desee. Ya hemos cubierto el formato de consulta anterior, pero en caso de que desee actualizar, aquí está la referencia completa del formato de consulta.

El parámetro render de QueryRenderer es una función del tipo ({error, resultSet, isLoading}) => React.Node. La salida de esta función será renderizada por el QueryRenderer. A resultSet es un objeto que contiene datos obtenidos de la consulta. Si este objeto no está definido, significa que los datos todavía se están obteniendo.

resultSet proporciona múltiples métodos para la manipulación de datos, pero en nuestro caso, solo necesitamos el método chartPivot, que devuelve los datos en un formato esperado por Recharts.

Trazaremos los datos de pedidos como un gráfico de barras dentro de un contenedor receptivo.

 
if (!ResultSet) {
return " Loading...";
}
volver (
<ResponsiveContainer width="100%" height={300}>
<BarChart datos={conjunto de resultados.chartPivot()}>
<x-eje dataKey="x" tickFormatter={dateFormatter} />
<Eje />
<Descripción labelFormatter={dateFormatter} />
<Barra de dataKey="las Órdenes.el recuento de" fill="rgba(106, 110, 229)" />
</BarChart>
</ResponsiveContainer>
);

Creación de un panel de control

Aprendimos a crear un gráfico único con Cube.js y Recharts, y ahora estamos listos para comenzar a construir todo el tablero. Hay algunas prácticas recomendadas con respecto al diseño del diseño del tablero de instrumentos. La práctica común es poner las métricas más importantes y de alto nivel en la parte superior como gráficos de valor único, a veces llamados KPI, y luego enumerar los desgloses relevantes de esas métricas.

Aquí está la captura de pantalla de nuestro panel final con KPI en la parte superior seguido de gráficos de barras y líneas.

Primero, refactoricemos nuestro gráfico y extraigamos el código común en un componente <Chart /> reutilizable. Crear un archivo src/Chart.js el siguiente contenido:

importar React desde "react";
importar { Card, CardTitle, CardBody, CardText } desde "reactstrap";
importar { QueryRenderer } desde "@ 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);
}}
/>
</CardText>
</CardBody>
</Tarjeta de>
);
la exportación de Gráfico predeterminado;

Siguiente, vamos a utilizar este componente para crear el tablero de instrumentos. Sustitúyase el contenido de src/App.js por el siguiente:

importar React, {Componente } desde "react";
importar { Contenedor, Fila, Col } desde "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 = > numeral (item).formato("0,0");
const DateFormatter = item = > momento (item).formato ("MMM AA");
const renderSingleValue = (Conjunto de resultados, clave) => (
<h1 height = {300}> {NumberFormatter (Conjunto de resultados.chartPivot ())}< / h1>
);
clase de Aplicación se extiende Componente {
render() {
volver (
<Recipiente de líquido>
<Fila>
<Col sm="4">
<Gráfico
cubejsApi={cubejsApi}
title="Total de Usuarios"
query={{ medidas: }}
render={conjunto de resultados => renderSingleValue(conjunto de resultados, "a los Usuarios.contar")}
/>
</Col>
<Col sm="4">
<Gráfico
cubejsApi={cubejsApi}
title="Total de Pedidos"
query={{ medidas: }}
render={conjunto de resultados => renderSingleValue(conjunto de resultados, "las Órdenes.contar")}
/>
</Col>
<Col sm="4">
<Gráfico
cubejsApi={cubejsApi}
title="los Pedidos Enviados"
query={{
medidas: ,
filtros:
}
]
}}
render={ResultSet = > renderinglevalue (ResultSet, " Orders.contar")}
/>
</Col>
</Fila>
<br />
<br />
<Fila>
<Col sm="6">
<Gráfico
cubejsApi={cubejsApi}
title="los Nuevos Usuarios a lo Largo del Tiempo"
query={{
medidas: ,
timeDimensions: ,
granularidad: "el mes de la"
}
]
}}
render={conjunto de resultados => (
<ResponsiveContainer width="100%" height={300}>
<AreaChart datos={conjunto de resultados.chartPivot()}>
<x-eje dataKey="categoría" tickFormatter={dateFormatter} />
<Eje tickFormatter={numberFormatter} />
<Descripción labelFormatter={dateFormatter} />
<Área de
type="monotono"
dataKey="Usuarios.la cuenta"
nombre="Usuarios"
stroke="rgb(106, 110, 229)"
fill="rgba(106, 110, 229, .16)"
/>
</AreaChart>
</ResponsiveContainer>
)}
/>
</Col>
<Col sm="6">
<Gráfico
cubejsApi={cubejsApi}
title="Pedidos por el Estado a lo Largo del tiempo"
query={{
medidas: ,
dimensiones: ,
timeDimensions: ,
granularidad: "el mes de la"
}
]
}}
render={conjunto de resultados => {
volver (
<ResponsiveContainer width="100%" height={300}>
<BarChart datos={conjunto de resultados.chartPivot()}>
<x-eje tickFormatter={dateFormatter} dataKey="x" />
<Eje tickFormatter={numberFormatter} />
<Bar
stackId="a"
dataKey="enviado, Pedidos.la cuenta"
nombre="Enviado"
fill="#7DB3FF"
/>
<Bar
stackId="a"
dataKey="procesamiento de Pedidos.la cuenta"
nombre="Procesamiento"
fill="#49457B"
/>
<Bar
stackId="a"
dataKey="finalizado, los Pedidos.la cuenta"
nombre="Completado"
fill="#FF7C78"
/>
<la Leyenda />
<Descripción />
</BarChart>
</ResponsiveContainer>
);
}}
/>
</Col>
</Fila>
</Contenedor>
);
}
}
exportación por defecto de la Aplicación;

Que es suficiente para construir nuestro primer tablero de instrumentos. Pruébalo en el CodeSanbox de abajo.

Próximos pasos

Hemos creado un panel de prueba de concepto simple con Cube.js. Puede consultar la demostración en vivo aquí. El código fuente completo está disponible en Github.

Para obtener más información sobre Cube.implementación de backend de js, puede consultar la documentación de implementación. Además, aquí puede encontrar más tutoriales sobre una variedad de temas.

¡Y únete a nuestra Comunidad de Slack! Es un gran lugar para obtener ayuda y mantenerse al día con los nuevos lanzamientos.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.