Cube.js to framework open source do tworzenia analitycznych aplikacji internetowych. Jest on używany przede wszystkim do budowania wewnętrznych narzędzi Business intelligence lub do dodawania analiz zorientowanych na klienta do istniejącej aplikacji. W większości przypadków pierwszym krokiem budowy takiej aplikacji jest panel analityczny. Zwykle zaczyna się od—”dodajmy panel analityczny do naszego panelu administracyjnego.”Potem, jak to zawsze bywa w rozwoju oprogramowania, sprawy stają się bardziej skomplikowane, znacznie bardziej skomplikowane.
kiedy zaczęliśmy pracować nad Cube.js, chcieliśmy zbudować narzędzie, które jest proste do uruchomienia, ale łatwo skaluje się pod względem funkcji, złożoności i objętości danych. Cube.js kładzie solidny fundament pod przyszły system analityczny, niezależnie od tego, czy jest to samodzielna aplikacja, czy wbudowana w istniejącą.
możesz myśleć o tym samouczku jako ” Cube.js 101.”Przeprowadzę Cię przez podstawowe kroki projektowania pierwszego Pulpitu nawigacyjnego od bazy danych po wizualizacje.
demo końcowego Pulpitu Nawigacyjnego jest dostępne tutaj. Pełny kod źródłowy znajduje się na Githubie.
Architektura
większość nowoczesnych aplikacji internetowych jest zbudowana jako aplikacja jednostronicowa, w której nakładka jest oddzielona od zaplecza. Backend również zazwyczaj jest podzielony na wiele usług, zgodnie z architekturą mikroserwisu.
Kostka.js przyjmuje to podejście. Konwencjonalnie prowadzisz Cube.Backend js jako usługa. Zarządza połączeniem z bazą danych, w tym kolejką zapytań, buforowaniem, wstępną agregacją i innymi. Udostępnia również interfejs API dla aplikacji frontend do tworzenia pulpitów nawigacyjnych i innych funkcji analitycznych.
Backend
Analiza rozpoczyna się od danych i danych znajdujących się w bazie danych. To jest pierwsza rzecz, którą musimy mieć na miejscu. Najprawdopodobniej masz już bazę danych dla swojej aplikacji i zwykle dobrze jest używać jej do analizy. Nowoczesne popularne bazy danych, takie jak Postgres lub MySQL, doskonale nadają się do prostego obciążenia analitycznego. Mówiąc prościej, mam na myśli wolumen danych z mniej niż miliardem wierszy.
MongoDB jest również w porządku, jedyną rzeczą, którą musisz dodać, jest MongoDB Connector for BI. Umożliwia wykonywanie kodu SQL na danych MongoDB. Jest bezpłatny i można go łatwo pobrać ze strony MongoDB. Należy pamiętać o replikacji. Za złą praktykę uważa się uruchamianie zapytań analitycznych w bazach danych produkcyjnych głównie z powodu problemów z wydajnością. Cube.js może znacznie zmniejszyć obciążenie bazy danych, ale mimo to polecam połączenie z repliką.
podsumowując – jeśli używasz Postgres lub MySQL, po prostu utwórz replikę i jesteśmy gotowi. Jeśli używasz MongoDB-Pobierz MongoDB Connector for BI i stwórz replikę.
jeśli nie masz żadnych danych do Pulpitu nawigacyjnego, możesz załadować nasz przykładowy zestaw danych e-commerce Postgres.
$ curl http://cube.dev/downloads/ecom-dump.sql > Ecom-dump.sql$ createdb ecom$ psql --dbname ecom-f Ecom-dump.sql
teraz, ponieważ mamy dane w bazie danych, jesteśmy gotowi do utworzenia kostki.usługa zaplecza js. Uruchom następujące polecenia w terminalu:
$ npm install-g cubejs-cli$ cubejs create dashboard-backend-d postgres
powyższe polecenia install Cube.js CLI i utworzyć nową usługę, skonfigurowaną do pracy z bazą danych Postgres.
Kostka.js używa zmiennych środowiskowych do konfiguracji. Używa zmiennych środowiskowych zaczynających się od CUBEJS_
. Aby skonfigurować połączenie z naszą bazą danych, musimy określić typ i nazwę bazy danych. W kostce.folder projektu js zamień zawartość .env
na następującą:
CUBEJS_API_SECRET=SECRETcubejs_db_type=postgresCUBEJS_DB_NAME = ecom
Cube.js data Schema
następnym krokiem jest utworzenie sześcianu.schemat danych js. Cube.js używa schematu danych do generowania kodu SQL, który zostanie wykonany w Twojej bazie danych. Schemat danych nie jest zamiennikiem SQL. Został zaprojektowany tak, aby SQL był wielokrotnego użytku i nadawał mu strukturę, zachowując całą jego moc. Podstawowe elementy schematu danych to measures
i dimensions
.
środek jest określany jako dane ilościowe, takie jak liczba sprzedanych jednostek, liczba unikalnych wizyt, zysk i tak dalej.
wymiar jest określany jako dane kategoryczne, takie jak stan, płeć, Nazwa Produktu lub jednostki czasu (np. dzień, tydzień, miesiąc).
tradycyjnie pliki schematu znajdują się w folderze schema
. Oto przykład schematu, który może być użyty do opisania danych użytkowników.
cube ('Users`, {sql:' SELECT * FROM users`,miary: {count: {sql: "id",type": "count`}},wymiary: {miasto: {sql: `city`,typ: `string`},signedUp: {SQL: `created_at`,type:' time`},nazwa firmy: {sql: 'Nazwa firmy`,type:' string`}}});
teraz, z powyższym schematem na miejscu, możemy wysyłać zapytania Do Kostki.zaplecze js dotyczące danych użytkowników. Cube.zapytania js są zwykłymi obiektami javascript. Zwykle ma jeden lub więcej measures
, dimensions
i timeDimensions
.
jeśli chcemy odpowiedzieć na pytanie „Gdzie są nasi użytkownicy?”możemy wysłać następujące zapytanie do sześcianu.js:
{wymiary:,wymiary:}
Cube.js wygeneruje wymagany SQL na podstawie schematu, wykona go i odeśle wynik z powrotem.
stwórzmy nieco bardziej skomplikowane zapytanie. Możemy dodać timeDimensions
, aby zobaczyć, jak stosunek różnych miast zmieniał się co miesiąc w ciągu ostatniego roku. Aby to zrobić, dodamy wymiar czasu signedUp
, pogrupujemy go według miesięcy i filtrujemy tylko zeszłoroczne rejestracje.
{wymiary:,wymiary:,wymiary czasowe:}]}
Cube.js może generować proste schematy na podstawie tabel bazy danych. Wygenerujmy Schematy potrzebne do naszego pulpitu nawigacyjnego, a następnie uruchom serwer dev.
$ cubejs generate-t users, orders$ npm run dev
możesz sprawdzać wygenerowane schematy i wysyłać zapytania testowe, otwierając plac zabaw dla programistów pod adresem http://localhost:4000.
Frontend
zbudujemy nasz frontend i dashboard z Reactem, używając kostki.js React client. Ale możesz użyć dowolnego frameworka lub po prostu vanilla javascript, aby zbudować frontend z Cube.js. Ten samouczek pokazuje, jak zbudować pulpit nawigacyjny w czystym javascript.Wszystko skonfigurujemy za pomocą aplikacji Create React, która jest oficjalnie wspierana przez zespół Reactowy. Pakuje wszystkie zależności aplikacji Reactowej i ułatwia rozpoczęcie pracy z nowym projektem. Uruchom następujące polecenia w terminalu:
$ NPX create-react-app dashboard-frontend$ cd dashboard-frontend$ npm start
ostatnia linia uruchamia serwer na porcie 3000 i otwiera przeglądarkę pod adresem http://localhost:3000.
zbudujemy nasz interfejs użytkownika z Reactstrap, który jest opakowaniem Reactowym dla Bootstrap 4. Zainstaluj Reactstrap i Bootstrap z NPM. Reactstrap nie zawiera Bootstrap CSS, więc musi być zainstalowany osobno:
$ npm install reactstrap bootstrap -- save
Importuj Bootstrap CSS do pliku src/index.js
przed zaimportowaniem ./index.css
:
import ' bootstrap / dist / css / Bootstrap./ min.css';
teraz jesteśmy gotowi do użycia komponentów Reactstrap.
następnym krokiem jest instalacja Cube.klient js do pobrania danych z serwera i naszej biblioteki wizualizacji, aby je wyświetlić. W tym samouczku użyjemy doładowań. Cube.js jest agnostykiem wizualizacji, co oznacza, że możesz użyć dowolnej biblioteki. Wykorzystamy również moment i cyfrę, aby ładnie sformatować daty i liczby.
$ npm install -- save @cubejs-client/core @cubejs-client / react recharts moment numeral
wreszcie skończyliśmy z zależnościami, więc zróbmy nasz pierwszy wykres.Zamień zawartość src/App.js
na następującą:
Importuj {BarChart,Bar,XAxis,YAxis,Tooltip,ResponsiveContainer> z "doładowań";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 (<QueryRendererquery={{measures: ,timeDimensions:,granularity: "month"}]}}cubejsApi={cubejsApi}render = {({ resultSet }) => {jeśli (!resultSet) {return " Loading...";}return (<ResponsiveContainer width = "100%" height={300}><BarChart data = {resultSet.chartPivot()}><XAxis dataKey= " x "tickFormatter = {dateFormatter} /><YAxis /><Tooltip labelFormatter = {dateFormatter} /><Bar dataKey=" Orders.count "fill=" rgba(106, 110, 229)" /></BarChart></ResponsiveContainer>);}}/>);}}Eksportuj domyślną aplikację;
możesz sprawdzić ten przykład w CodeSandbox poniżej.
przyjrzyjmy się głębiej jak ładujemy Dane i rysujemy Wykres.
najpierw inicjalizujemy kostkę.klient API js:
const cubejsApi = cubejs (proces.env.REACT_APP_CUBEJS_TOKEN, {apiUrl: proces.env.REACT_APP_API_URL});
Utwórzplik env z następującymi poświadczeniami. W środowisku programistycznym Cube.js nie wymusza użycia tokenu do autoryzowania zapytań, więc możesz użyć dowolnego ciągu znaków dla swojego tokena tutaj. Więcej informacji na temat używania i generowania tokenów w środowisku produkcyjnym można znaleźć w dokumentach.
REACT_APP_CUBEJS_TOKEN=YOUR-TOKENREACT_APP_API_URL=http://localhost:4000/cubejs-api/v1
następnie używamy kostki QueryRenderer.komponent js React do Ładowania Danych zamówień.
<QueryRendererquery={{miary: ,timeDimensions:,: "miesiąc"}]}}cubejsApi={cubejsApi}render = {({ resultSet }) => {// Renderuj wynik}}/>
QueryRenderer wykonuje żądanie API do kostki.backend js i używa techniki render props, aby umożliwić renderowanie wyniku w dowolny sposób. Omówiliśmy już powyższy format zapytania, ale jeśli chcesz odświeżyć-oto pełny odnośnik do formatu zapytania.
render
parametr QueryRenderer jest funkcją typu ({error, resultSet, isLoading}) => React.Node
. Wynik tej funkcji będzie renderowany przez QueryRenderer. resultSet
jest obiektem zawierającym dane uzyskane z zapytania. Jeżeli obiekt ten nie jest zdefiniowany, to znaczy, że dane są w dalszym ciągu pobierane.
resultSet
udostępnia wiele metod manipulacji danymi, ale w naszym przypadku potrzebujemy tylko metody chartPivot
, która zwraca dane w formacie oczekiwanym przez Recharts.
wykreślamy dane zamówień jako wykres słupkowy wewnątrz responsywnego kontenera.
if (!resultSet) {return " Loading...";}return (<ResponsiveContainer width = "100%" height={300}><BarChart data = {resultSet.chartPivot()}><XAxis dataKey= " x "tickFormatter = {dateFormatter} /><YAxis /><Tooltip labelFormatter = {dateFormatter} /><Bar dataKey=" Orders.count "fill=" rgba(106, 110, 229)" /></BarChart></ResponsiveContainer>);
budowanie Pulpitu Nawigacyjnego
nauczyliśmy się budować pojedynczy Wykres za pomocą kostki.js i Recharts, a teraz jesteśmy gotowi do rozpoczęcia budowy całego pulpitu nawigacyjnego. Istnieje kilka najlepszych praktyk dotyczących projektowania układu Pulpitu nawigacyjnego. Powszechną praktyką jest umieszczanie najważniejszych i wysokopoziomowych wskaźników na szczycie jako pojedynczych Wykresów wartości, czasami nazywanych KPI, a następnie lista odpowiednich podziałów tych wskaźników.
oto zrzut ekranu naszego końcowego Pulpitu nawigacyjnego z wskaźnikami KPI na górze, a następnie wykresami słupkowymi i liniowymi.
najpierw refaktorujmy nasz wykres i wyodrębnijmy wspólny kod do komponentu <Chart />
wielokrotnego użytku. Utwórz plik src/Chart.js
o następującej zawartości:
Importuj Reacta z "react";Importuj { Card, CardTitle, CardBody, CardText } z "reactstrap";Importuj {QueryRenderer } z "@cubejs-client / react";const Chart = ({ cubejsApi, title, query, render }) => (<Card><CardBody><CardTitle tag="h5">{title}</CardTitle><CardText><QueryRendererquery={query}cubejsApi={cubejsApi}render={({ resultSet }) => {if (!resultSet) {return <div className="loader" />;}return render(resultSet);}}/></CardText></CardBody></Karta>);Eksportuj domyślny Wykres;
następnie użyjmy tego komponentu do utworzenia Pulpitu nawigacyjnego. Zamień zawartość src/App.js
na następującą:
Importuj React, {Component } z "react";Importuj { Container, Row, Col } z "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).format("0,0");const dateFormatter = item = > moment(item).format ("MMM YY");const renderSingleValue = (resultSet, key) => (<H1 height = {300}> {numberFormatter (resultSet.chartPivot ())}</H1>);class App extends Component {render () {return (<płyn pojemnikowy><wiersz><pułkownik sm="4"><WykrescubejsApi={cubejsApi}title=" Total Users "query={{measures: }}render ={resultSet = > renderSingleValue(resultSet, " Users.liczyć")}/></pułkownik><pułkownik sm="4"><WykrescubejsApi = {cubejsApi}title="Total Orders"query={{ measures: }}render={resultSet => renderSingleValue(resultSet, "Orders.liczyć")}/></pułkownik><pułkownik sm="4"><WykrescubejsApi={cubejsApi}title="zamówienia wysyłane"query={{miary:,filtry:}]}}render={resultSet = > renderSingleValue(resultSet, "Orders.liczyć")}/></pułkownik></wiersz><br /><br /><wiersz><pułkownik sm="6"><WykrescubejsApi={cubejsApi}title="Nowi użytkownicy w czasie"query={{miary: ,timeDimensions:,: "miesiąc"}]}}render={resultSet => (<ResponsiveContainer width = "100%" height={300}><AreaChart data = {resultSet.chartPivot()}><XAxis dataKey=" category "tickFormatter = {dateFormatter} /><YAxis tickFormatter={numberFormatter} /><Tooltip labelFormatter = {dateFormatter} /><Areatype = "monotone"dataKey= " Users.count"name="Users"stroke="RGB(106, 110, 229)"fill="rgba(106, 110, 229, .16)"/></AreaChart></ResponsiveContainer>)}/></pułkownik><pułkownik sm="6"><WykrescubejsApi={cubejsApi}title="zamówienia według statusu w czasie"zapytanie={{miary: ,wymiary: ,wymiary czasowe:,ziarnistość: "miesiąc"}]}}render={resultSet => {return (<ResponsiveContainer width = "100%" height={300}><BarChart data = {resultSet.chartPivot()}><XAxis tickFormatter={dateFormatter} dataKey= "x" /><YAxis tickFormatter={numberFormatter} /><BarstackId = " a "dataKey= " wysyłka, zamówienia.count"name="Shipped"fill="#7DB3FF"/><BarstackId="a"dataKey="przetwarzanie, zamówienia.count"name="Processing"fill = "# 49457B"/><BarstackId = " a "dataKey= " zrealizowane, zamówienia.count"name="Completed"fill=" # FF7C78"/><Legenda /><Tooltip /></BarChart></ResponsiveContainer>);}}/></pułkownik></wiersz></kontener>);}}Eksportuj domyślną aplikację;
to wystarczy, aby zbudować nasz pierwszy pulpit nawigacyjny. Spróbuj w codesanbox poniżej.
kolejne kroki
zbudowaliśmy prosty panel proof of concept z Cube.js. Możesz sprawdzić demo na żywo tutaj. Pełny kod źródłowy jest dostępny na Githubie.
aby dowiedzieć się więcej o Cube.wdrożenie zaplecza js, możesz zapoznać się z dokumentacją wdrożenia. Ponadto, tutaj można znaleźć więcej samouczków na różne tematy.
i dołącz do naszej społeczności Slack! Jest to świetne miejsce, aby uzyskać pomoc i być na bieżąco z nowymi wydaniami.