Рубрики
Без рубрики

Речь таблица данных ⚛ с помощью материала и искра радости 😛

Если вы хотите визуализировать большие объемы равномерных данных, диаграммы не работают хорошо, потому что они влияют на … Tagged с JavaScript, React, MaterialUI, учебник.

Если вы хотите визуализировать большие объемы равномерных данных, диаграммы не работают хорошо, потому что они эффективно скрывают информацию об отдельных элементах данных. Тем не менее, это тот случай, когда таблицы данных пригодятся! 😇

В этом уроке мы узнаем, как отобразить огромные нагрузки данных в таблице данных, которая построена с нуля в React. Мы рассмотрим, как извлекать данные из базы данных через API и визуализировать их в таблице данных с важными функциями, такими как фильтрация, сортировка и т. Д.

Мы будем использовать Материал UI Потому что это самая популярная структура пользовательского интерфейса для React. Создан с вдохновением от Google Дизайн материала , он предоставляет много компонентов, которые мы можем использовать для получения красивого пользовательского интерфейса.

Вот наш план на сегодня!

  • Подготовьте данные В базе данных – много данных!
  • Запустить API работать с этими данными, быстро и легко
  • Создайте приложение с реагированием и материальным пользовательским интерфейсом
  • Создайте базовую таблицу данных
  • Расширить таблицу данных с различными функциями, шаг за шагом

Звучит хорошо? Пойдем!

Прежде чем погрузиться в взломать, посмотрите на скриншот таблицы данных, которую мы собираемся создать. Также проверьте Полный исходный код Доступно на GitHub.

Полагаем, мы будем использовать один из самых популярных хранилищ данных SQL – Postgresql база данных. Пожалуйста, убедитесь, что у вас установлен PostgreSQL. (В противном случае это может перестать быть таким популярным однажды 😛.)

Теперь мы можем скачать и импортировать тщательно подготовленный пример набора данных электронной коммерции для PostgreSQL. Набор данных связан с воображаемой компанией электронной коммерции, которая хочет отслеживать свои заказы и статусы:

$ curl  > ecom-dump.sql
$ createdb ecom
$ psql --dbname ecom -f ecom-dump.sql

Итак, база данных готова! Давайте продолжим …

Мы собираемся использовать Cube.js для нашего API. Cube.js-это аналитическая платформа API с открытым исходным кодом, которая помогает создавать API для запасов данных SQL и создавать аналитические приложения. Он удаляет всю сундуку построения слоя API, генерируя SQL и запрашивая базу данных. Он также предоставляет множество функций производственного класса, таких как многоуровневое кэширование для оптимальной производительности, многоцелевое, безопасность и многое другое.

Итак, давайте запустим API в дополнение к нашей базе данных с Cube.js в нескольких простых шагах.

Во-первых, нам нужно установить утилиту командной строки cube.js (CLI). Для удобства давайте установим его на глобальном масштабе на нашу машину.

$ npm install -g cubejs -cli

Затем, с установленным CLI, мы можем создать базовый бэкэнд, выполнив одну команду. Cube.js поддерживает Все популярные базы данных , поэтому мы можем предварительно сконфигурировать бэкэнд для работы с PostgreSQL:

$ cubejs create <имя проекта> -d <Тип базы данных>

Чтобы создать бэкэнд, мы выполняем эту команду:

$ cubejs создает React-Data-Table -d постгрес

Теперь нам нужно соединять это в базу данных. Для этого мы предоставляем несколько вариантов через .env Файл в корне папки проекта cube.js ( react-data-table ):

CUBEJS_DB_NAME=ecom
CUBEJS_DB_TYPE=postgres
CUBEJS_API_SECRET=secret

Теперь мы можем запустить бэкэнд!

В режиме разработки бэкэнд также будет запускать детскую площадку Cube.js. Это действительно круто. 🤘 Cube.js Playground СЕРИБАНСКОЕ ВРЕМЯ веб-приложения, которое помогает создать схему данных, проверить запросы и генерировать шаблон DACT DASHBOARD. Запустите следующую команду в папке проекта cube.js:

$ node index.js

Далее, Open http://localhost: 4000 в вашем браузере.

Мы будем использовать детскую площадку Cube.js для создания схемы данных. По сути, это код JavaScript, который декларативно описывает данные, определяет аналитические объекты, такие как меры и измерения, и отображает их на запросы SQL. Вот пример схемы, которая может быть использована для описания данных продуктов.

cube(`Products`, {
  sql: `SELECT * FROM public.products`,

  measures: {
    count: {
      type: `count`
    }
  },

  dimensions: {
    name: {
      sql: `name`,
      type: `string`
    },

    id: {
      sql: `id`,
      type: `number`,
      primaryKey: true,
      shown: true
    },

    description: {
      sql: `description`,
      type: `string`
    },

    createdAt: {
      sql: `created_at`,
      type: `time`
    }
  }
});

Cube.js может генерировать простую схему данных на основе таблиц базы данных. Если в вашей базе данных уже есть нетривиальный набор таблиц, рассмотрите возможность использования генерации схемы данных, потому что он может сэкономить много времени.

Итак, давайте перейдем к вкладке схемы Cube.js Playground, выберите public Группа в представлении дерева, выберите line_items , заказы , Продукты и Пользователи Таблицы и нажмите «Создать схему. ” В результате у нас будет 4 сгенерированных файла в схема Папка – ровно один файл схемы на таблицу.

После того, как схема генерируется, мы можем запросить данные через детскую площадку Cube.js. Для этого перейдите на вкладку «Build» и выберите некоторые меры и измерения из схемы. Похоже, магия, не так ли?

Вкладка «Build» – это место, где вы можете создавать образцы диаграмм, используя различные библиотеки визуализации и проверять все аспекты того, как была создана эта диаграмма, начиная с сгенерированного SQL вплоть до кода JavaScript для отображения диаграммы. Вы также можете осмотреть запрос Cube.js, закодированный с JSON, который отправляется в Backend Cube.js.

Хорошо, мы все готовы. API готов, теперь давайте …

Большие новости! 😛

Игровая площадка Cube.js может генерировать шаблон для любой выбранной фронтальной структуры и библиотеки диаграммы для вас. Чтобы создать шаблон для нашего приложения, перейдите к «приложению Dashboard» и используйте эти параметры:

  • Структура: Реагировать
  • Основной шаблон: Реагировать материал ui static
  • Библиотека диаграммы: Chart.js

Поздравляю! Теперь у нас есть приборная панель Папка в нашем проекте. Эта папка содержит весь код фронта, который мы собираемся расширить.

Прежде чем мы продолжим, давайте сделаем наиболее важное изменение – покажите в названии, что мы создаем таблицу данных. 😝

Для этого, Chnage Несколько строк в public/index.html Файл Dashboard-App следующее:

// ...

-    React App
+    React Data Table
+       
// ...

Кроме того, давайте установим несколько зависимостей от Dashboard-App Это облегчит нашу задачу создания таблицы данных:

$ npm install --save react-perfect-scrollbar @material-ui/pickers

Итак, теперь мы готовы …

Здорово иметь много данных в таблице, верно? Итак, давайте возьмем их через API.

Для этого мы собираемся определить ряд новых метрик: количество предметов в заказе (его размер), цена заказа и полное имя пользователя. С cube.js это супер-легкое:

Во -первых, давайте добавим полное имя в схему «Пользователи» в Schema/users.js файл. Чтобы создать полное имя, мы объединяем имя и фамилию, используя функцию SQL Конг :

cube(`Users`, {
  sql: `SELECT * FROM public.users`,

// ...

  dimensions: {    

// ...

    id: {
+      shown: true,
      sql: `id`,
      type: `number`,
      primaryKey: true
    },

    firstName: {
      sql: `first_name`,
      type: `string`
    },

    lastName: {
      sql: `last_name`,
      type: `string`
    },

+    fullName: {
+      sql: `CONCAT(${firstName}, ' ', ${lastName})`,
+      type: `string`
+    },

// ...

Затем давайте добавим другие меры в схему «заказы» в схема/orders.js файл.

Для этих мер мы собираемся использовать Подпрограмма Особенность cube.js. Вы можете использовать размеры подказлов для эталонных мер от других кубиков внутри измерения. Вот как определить такие измерения:

cube(`Orders`, {
  sql: `SELECT * FROM public.orders`,

  dimensions: {

// ...

    id: {
+      shown: true,
      sql: `id`,
      type: `number`,
      primaryKey: true
    },

    createdAt: {
      sql: `created_at`,
      type: `time`
    },

+    size: {
+      sql: `${LineItems.count}`,
+      subQuery: true,
+      type: 'number'
+    },
+
+    price: {
+      sql: `${LineItems.price}`,
+      subQuery: true,
+      type: 'number'
+    },

    completedAt: {
      sql: `completed_at`,
      type: `time`
    }
  }
});

Мы почти там! Итак, чтобы отобразить таблицу данных, давайте заменим src/pages/dashboardpage.js Файл со следующим содержанием:

import React from "react";
import { makeStyles } from "@material-ui/styles";

import Table from "../components/Table.js";

const useStyles = makeStyles(theme => ({
  root: { padding: 15 },
  content: { marginTop: 15 },
}));

const Dashboard = () => {
  const classes = useStyles();

  const query = {
    timeDimensions: [
      {
        dimension: 'Orders.createdAt',
        granularity: 'day'
      }
    ],
    dimensions: [
      'Users.id',
      'Orders.id',
      'Orders.size',
      'Users.fullName',
      'Users.city',
      'Orders.price',
      'Orders.status',
      'Orders.createdAt',
    ]
  };

  return (
    
); }; export default Dashboard;

Обратите внимание, что теперь этот файл содержит запрос cube.js, который довольно эксплуатационный: мы просто просим API вернуть несколько измерений, и он делает это.

Изменения в Панель инструментов минимальны, однако, вся магия рендеринга таблицы данных происходит внутри <Таблица/> Компонент и изменения в результате запроса отражены в таблице.

Давайте создадим это <Таблица/> компонент в src/components/table.js Файл со следующим содержанием:

import React, { useState } from "react";
import clsx from "clsx";
import PropTypes from "prop-types";
import moment from "moment";
import PerfectScrollbar from "react-perfect-scrollbar";
import { makeStyles } from "@material-ui/styles";
import Typography from "@material-ui/core/Typography";
import { useCubeQuery } from "@cubejs-client/react";
import CircularProgress from "@material-ui/core/CircularProgress";
import {
  Card,
  CardActions,
  CardContent,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
  TablePagination
} from "@material-ui/core";

const useStyles = makeStyles(theme => ({
  root: {
    padding: 0
  },
  content: {
    padding: 0
  },
  inner: {
    minWidth: 1050
  },
  nameContainer: {
    display: "flex",
    alignItems: "baseline"
  },
  status: {
    marginRight: 15
  },
  actions: {
    justifyContent: "flex-end"
  },
}));

const TableComponent = props => {

  const { className, query, cubejsApi, ...rest } = props;

  const classes = useStyles();

  const [rowsPerPage, setRowsPerPage] = useState(10);
  const [page, setPage] = useState(0);

  const tableHeaders = [
    { text: "Full Name", value: "Users.fullName" },
    { text: "User city", value: "Users.city" },
    { text: "Order price", value: "Orders.price" },
    { text: "Status", value: "Orders.status" },
    { text: "Created at", value: "Orders.createdAt" }
  ];
  const { resultSet, error, isLoading } = useCubeQuery(query, { cubejsApi });
  if (isLoading) {
    return 
; } if (error) { return
{error.toString()}
; } if (resultSet) { let orders = resultSet.tablePivot(); const handlePageChange = (event, page) => { setPage(page); }; const handleRowsPerPageChange = event => { setRowsPerPage(event.target.value); }; return (
{tableHeaders.map((item) => ( {item.text} ))} {orders.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage).map(obj => ( {obj["Orders.id"]} {obj["Orders.size"]} {obj["Users.fullName"]} {obj["Users.city"]} {"$ " + obj["Orders.price"]} {obj["Orders.status"]} {moment(obj["Orders.createdAt"]).format("DD/MM/YYYY")} ))}
); } else { return null } }; TableComponent.propTypes = { className: PropTypes.string, query: PropTypes.object.isRequired }; export default TableComponent;

Окончательно! Вот таблица данных, которой мы ждали:

Выглядит великолепно, да?

Обратите внимание, что на самом деле это не так просто! 😜 У вас есть встроенная страница, которая позволяет отображать и ориентироваться в огромных количествах данных.

Тем не менее, это выглядит серым и мрачным. Итак, давайте добавим цвет и расширим стол с …

Пользовательский формат ячейки

В таблице содержится статусы заказов, которые отображаются как текст на этом этапе. Давайте заменим их на пользовательский компонент!

Идея состоит в том, чтобы визуализировать статус порядка с красочной точкой. Для этого мы создадим пользовательский составная часть. Давайте создадим этот компонент в src/components/statusbullet.js Файл со следующим содержанием:

import React from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';
import { makeStyles } from '@material-ui/styles';

const useStyles = makeStyles(theme => ({
  root: {
    display: 'inline-block',
    borderRadius: '50%',
    flexGrow: 0,
    flexShrink: 0
  },
  sm: {
    height: 15,
    width: 15
  },
  md: {
    height: 15,
    width: 15
  },
  lg: {
    height: 15,
    width: 15
  },
  neutral: { backgroundColor: '#fff' },
  primary: { backgroundColor: '#ccc' },
  info: { backgroundColor: '#3cc' },
  warning: { backgroundColor: '#cc3' },
  danger: { backgroundColor: '#c33' },
  success: { backgroundColor: '#3c3' }
}));

const StatusBullet = props => {
  const { className, size, color, ...rest } = props;

  const classes = useStyles();

  return (
    
  );
};

StatusBullet.propTypes = {
  className: PropTypes.string,
  color: PropTypes.oneOf([
    'neutral',
    'primary',
    'info',
    'success',
    'warning',
    'danger'
  ]),
  size: PropTypes.oneOf(['sm', 'md', 'lg'])
};

StatusBullet.defaultProps = {
  size: 'md',
  color: 'default'
};

export default StatusBullet;

Чтобы заставить его работать, нам нужно применить некоторые минимальные изменения в таблице данных. Давайте изменим src/components/table.js следующее:

// ...

} from "@material-ui/core";

import StatusBullet from "./StatusBullet";

const statusColors = {
  completed: "success",
  processing: "info",
  shipped: "danger"
};

const useStyles = makeStyles(theme => ({

// ...


+  
  {obj["Orders.status"]}


// ...

Ницца! 🎉 Теперь у нас есть таблица, которая отображает информацию обо всех заказах и имеет несколько красочных прикосновений:

Фильтрация данных

Тем не менее, трудно изучить эти заказы, используя только предоставленные элементы управления. Чтобы исправить это, мы добавим комплексную панель инструментов с фильтрами и сделаем нашу таблицу интерактивной.

Во -первых, давайте добавим несколько зависимостей. Запустите команду в Dashboard-App папка:

npm install --save @date-io/date-fns@1.x date-fns @date-io/moment@1.x moment

Затем создайте <Инструменты/> компонент в src/components/toolbar.js Файл со следующим содержанием:

import "date-fns";
import React from "react";
import PropTypes from "prop-types";
import { makeStyles } from "@material-ui/styles";
import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import Tab from "@material-ui/core/Tab";
import Tabs from "@material-ui/core/Tabs";
import withStyles from "@material-ui/core/styles/withStyles";

const AntTabs = withStyles({
  indicator: {},
})(Tabs);
const AntTab = withStyles((theme) => ({
  root: {
    textTransform: 'none',
    minWidth: 25,
    fontSize: 12,
    fontWeight: theme.typography.fontWeightRegular,
    marginRight: 0,
    opacity: 0.6,
    '&:hover': {
      opacity: 1,
    },
    '&$selected': {
      fontWeight: theme.typography.fontWeightMedium,
      outline: 'none',
    },
    '&:focus': {
      outline: 'none',
    },
  },
  selected: {},
}))((props) => );
const useStyles = makeStyles(theme => ({
  root: {},
  row: {
    marginTop: 15
  },
  spacer: {
    flexGrow: 1
  },
  importButton: {
    marginRight: 15
  },
  exportButton: {
    marginRight: 15
  },
  searchInput: {
    marginRight: 15
  },
  formControl: {
    margin: 25,
    fullWidth: true,
    display: "flex",
    wrap: "nowrap"
  },
  date: {
    marginTop: 3
  },
  range: {
    marginTop: 13
  }
}));

const Toolbar = props => {
  const { className,
    statusFilter,
    setStatusFilter,
    tabs,
    ...rest } = props;
  const [tabValue, setTabValue] = React.useState(statusFilter);

  const classes = useStyles();

  const handleChangeTab = (e, value) => {
    setTabValue(value);
    setStatusFilter(value);
  };

  return (
    
{handleChangeTab(e,value)}} aria-label="ant example"> {tabs.map((item) => ())}
); }; Toolbar.propTypes = { className: PropTypes.string }; export default Toolbar;

Давайте изменим src/pages/dashboardpage файл:

import React from "react";
import { makeStyles } from "@material-ui/styles";

+ import Toolbar from "../components/Toolbar.js";
import Table from "../components/Table.js";

const useStyles = makeStyles(theme => ({
  root: {
    padding: 15
  },
  content: {
    marginTop: 15
  },
}));

const DashboardPage = () => {
  const classes = useStyles();
+  const tabs = ['All', 'Shipped', 'Processing', 'Completed'];
+  const [statusFilter, setStatusFilter] = React.useState(0);

  const query = {
    "timeDimensions": [
      {
        "dimension": "Orders.createdAt",
        "granularity": "day"
      }
    ],
    "dimensions": [
      "Users.id",
      "Orders.id",
      "Orders.size",
      "Users.fullName",
      "Users.city",
      "Orders.price",
      "Orders.status",
      "Orders.createdAt"
    ],
+    "filters": [
+      {
+        "dimension": "Orders.status",
+        "operator": tabs[statusFilter] !== 'All' ? "equals" : "set",
+        "values": [
+          `${tabs[statusFilter].toLowerCase()}`
+        ]
+      }
+    ]
  };

  return (
    
+
); }; export default DashboardPage;

Идеальный! 🎉 Теперь таблица данных имеет фильтр, который переключается между различными типами заказов:

Тем не менее, заказы имеют другие параметры, такие как цена и даты. Давайте создадим фильтры для этих параметров. Для этого измените src/components/toolbar.js файл:

import "date-fns";
import React from "react";
import PropTypes from "prop-types";
import clsx from "clsx";
import { makeStyles } from "@material-ui/styles";
import Grid from "@material-ui/core/Grid";
import Typography from "@material-ui/core/Typography";
import Tab from "@material-ui/core/Tab";
import Tabs from "@material-ui/core/Tabs";
import withStyles from "@material-ui/core/styles/withStyles";
+ import DateFnsUtils from "@date-io/date-fns";
+ import {
+   MuiPickersUtilsProvider,
+   KeyboardDatePicker
+ } from "@material-ui/pickers";
+ import Slider from "@material-ui/core/Slider";

// ...

const Toolbar = props => {
  const { className,
+   startDate,
+   setStartDate,
+   finishDate,
+   setFinishDate,
+   priceFilter,
+   setPriceFilter,
    statusFilter,
    setStatusFilter,
    tabs,
    ...rest } = props;
  const [tabValue, setTabValue] = React.useState(statusFilter);
+ const [rangeValue, rangeSetValue] = React.useState(priceFilter);

  const classes = useStyles();

  const handleChangeTab = (e, value) => {
    setTabValue(value);
    setStatusFilter(value);
  };
+  const handleDateChange = (date) => {
+    setStartDate(date);
+  };
+  const handleDateChangeFinish = (date) => {
+    setFinishDate(date);
+  };
+ const handleChangeRange = (event, newValue) => {
+   rangeSetValue(newValue);
+ };
+ const setRangeFilter = (event, newValue) => {
+   setPriceFilter(newValue);
+ };

  return (
    
{handleChangeTab(e,value)}} aria-label="ant example"> {tabs.map((item) => ())}
+ + + + Start Date} + format="MM/dd/yyyy" + value={startDate} + onChange={handleDateChange} + KeyboardButtonProps={{ + "aria-label": "change date" + }} + /> + + + + + + + Finish Date} + format="MM/dd/yyyy" + value={finishDate} + onChange={handleDateChangeFinish} + KeyboardButtonProps={{ + "aria-label": "change date" + }} + /> + + + + + + Order price range + + +
); }; Toolbar.propTypes = { className: PropTypes.string }; export default Toolbar;

Чтобы эти фильтры работали, нам нужно подключить их к родительскому компоненту: добавить состояние, изменить наш запрос и добавить новые реквизиты в <Инструменты/> составная часть. Кроме того, мы добавим сортировку в таблицу данных. Итак, измените src/pages/dashboardpage.js Файл как это:

// ...

const DashboardPage = () => {
  const classes = useStyles();
  const tabs = ['All', 'Shipped', 'Processing', 'Completed'];
  const [statusFilter, setStatusFilter] = React.useState(0);
+ const [startDate, setStartDate] = React.useState(new Date("2019-01-01T00:00:00"));
+ const [finishDate, setFinishDate] = React.useState(new Date("2022-01-01T00:00:00"));
+ const [priceFilter, setPriceFilter] = React.useState([0, 200]);
+ const [sorting, setSorting] = React.useState(['Orders.createdAt', 'desc']);

  const query = {
    timeDimensions: [
      {
        "dimension": "Orders.createdAt",
+    "dateRange": [startDate, finishDate],
        "granularity": "day"
      }
    ],
+    order: {
+      [`${sorting[0]}`]: sorting[1]
+    },
    "dimensions": [
      "Users.id",
      "Orders.id",
      "Orders.size",
      "Users.fullName",
      "Users.city",
      "Orders.price",
      "Orders.status",
      "Orders.createdAt"
    ],
    "filters": [
      {
        "dimension": "Orders.status",
        "operator": tabs[statusFilter] !== 'All' ? "equals" : "set",
        "values": [
          `${tabs[statusFilter].toLowerCase()}`
        ]
      },
+     {
+        "dimension": "Orders.price",
+        "operator": "gt",
+        "values": [
+         `${priceFilter[0]}`
+       ]
+     },
+     {
+       "dimension": "Orders.price",
+       "operator": "lt",
+       "values": [
+         `${priceFilter[1]}`
+       ]
+     },
    ]
  };

  return (
    
); }; export default DataTablePage;

Фантастический! 🎉 Мы добавили несколько полезных фильтров. Действительно, вы можете добавить еще больше фильтров с пользовательской логикой. Смотрите Документация Для параметров формата фильтра.

И есть еще одна вещь! Мы добавили сортировку реквизита на панель инструментов, но мы также должны передать их в <Таблица/> составная часть. Чтобы исправить это, давайте изменим src/components/table.js файл:

// ...

+ import KeyboardArrowUpIcon from "@material-ui/icons/KeyboardArrowUp";
+ import KeyboardArrowDownIcon from "@material-ui/icons/KeyboardArrowDown";
import { useCubeQuery } from "@cubejs-client/react";
import CircularProgress from "@material-ui/core/CircularProgress";

// ...

const useStyles = makeStyles(theme => ({
  // ...
  actions: {
    justifyContent: "flex-end"
  },
+ tableRow: {
+   padding: '0 5px',
+   cursor: "pointer",
+   '.MuiTableRow-root.MuiTableRow-hover&:hover': {
+   }
+ },
+ hoverable: {
+   "&:hover": {
+     cursor: `pointer`
+   }
+ },
+ arrow: {
+   fontSize: 10,
+   position: "absolute"
+ }
}));

const statusColors = {
  completed: "success",
  processing: "info",
  shipped: "danger"
};

const TableComponent = props => {
-  const { className, query, cubejsApi, ...rest } = props;
+  const { className, sorting, setSorting, query, cubejsApi, ...rest } = props;

// ...

  if (resultSet) {

//...

+     const handleSetSorting = str => {
+       setSorting([str, sorting[1] === "desc" ? "asc" : "desc"]);
+     };

    return (
                            // ...

                
                  
                    {tableHeaders.map((item) => (
                       {
+                                 handleSetSorting(`${item.value}`);
+                                 }}
                      >
                        {item.text}
+                        
+                          {(sorting[0] === item.value) ? (sorting[1] === "desc" ?  :
+                            ) : null}
+                        
                      
                    ))}
                  
                
                         // ...

Замечательно! 🎉 Теперь у нас есть таблица данных, которая полностью поддерживает фильтрацию и сортировку:

И это все! 😇 Поздравляем с завершением этого учебника! 🎉

Также проверьте Полный исходный код Доступно на GitHub.

Теперь вы должны иметь возможность создавать пользовательские таблицы данных, работающие на Cube.js с помощью пользовательского интерфейса React и Material, чтобы отображать буквально любые объемы данных в ваших приложениях.

Не стесняйтесь исследовать Другие примеры из того, что можно сделать с помощью cube.js, таких как Руководство по мониторингу в реальном времени и Руководство с открытым исходным кодом веб -аналитической платформы Анкет

Оригинал: “https://dev.to/cubejs/react-data-table-with-material-ui-and-a-spark-of-joy-50o1”