Построение таблицы на основе датасета

Следуя данной инструкции, вы построите в Editor таблицу на основе датасета. Для удобства в качестве источника данных мы будем использовать подключение и датасет из развернутого демо-воркбука.

Перед началом работы

Чтобы начать работать с DataLens, воспользуйтесь инструкцией по развертыванию.

Разверните демо-воркбук

  1. Сохраните из DataLens Gallery работу с названием DataLens Demo Dashboard:

    1. В DataLens Gallery откройте карточку работы.
    2. Нажмите ИспользоватьСкачать. Воркбук будет скачан в виде файла в формате JSON.
    3. На странице коллекций и воркбуков нажмите СоздатьВоркбук.
    4. В открывшемся окне нажмите Выбрать файл и загрузите JSON-файл с конфигурацией демо-воркбука. При необходимости скорректируйте название и описание и нажмите Сохранить.
  2. Перейдите в созданный воркбук и на вкладке Датасеты найдите датасет с названием 00: Продажи.

  3. Скопируйте идентификатор датасета: рядом с ним нажмите на Копировать ID. Идентификатор будет скопирован в буфер обмена.

Создайте чарт в Editor

  1. В воркбуке в правом верхнем углу нажмите СоздатьЧарт в Editor. На открывшейся странице выберите тип визуализации Таблица.

  2. Свяжите чарт с датасетом: для этого перейдите на вкладку Meta и добавьте ID датасета в links:

    {
                "links": {
                    "salesDataset": "r7h********"
            	   }
            }
            

    Где:

    • r7h******** — идентификатор датасета, скопированный на предыдущем шаге.
    • salesDataset — произвольное имя-алиас, которое вы присваиваете датасету, с помощью которого запрашиваете данные для чарта из источника.

    Примечание

    Вкладка Meta нужна для описания служебной информации о списке связанных сущностей. Эта информация используется для определения, с какими подключениями и датасетами связан чарт, а также для диалога связанных объектов, при копировании воркбука и при публикации в Public.

  3. Получите данные из источника: для этого откройте вкладку Source и укажите:

    const {buildSource} = require('libs/dataset/v2');
            module.exports = {
                'salesSourceData': buildSource({
                    datasetId: Editor.getId('salesDataset'),
                    columns: ['Тип  оплаты', 'Год заявки', 'Месяц заявки', 'Продажа, ₽'],
                }),
            };
            

    salesSourceData — произвольное имя-алиас, которое вы присваиваете объекту с запрошенными данными чарта, которое используется для доступа на вкладке Prepare.

    В значении поля columns перечислены имена полей из датасета.

    Примечание

    В данном примере используется служебный модуль const {buildSource} = require('libs/dataset/v2'); для более удобной работы с датасетами.

  4. Очистите содержимое вкладок Params и Config: они содержат шаблон, не относящийся к нашему примеру.

  5. На вкладке Prepare сформируйте таблицу:

    Примечание

    В примере используется служебный модуль const Dataset = require('libs/dataset/v2') — для более удобной работы с датасетами. Метод Dataset.getDatasetRows() извлекает данные из источника, переданного в параметре datasetName, и предоставляет их в удобном компактном виде.

    Если необходимо, данные можно получить в полном виде самостоятельно с помощью метода Editor.getLoadedData().

    const Dataset = require('libs/dataset/v2');
            const loadedData = Editor.getLoadedData();
            
            // Получаем данные из датасета в удобном формате с помощью служебного модуля
            // datasetName — имя датасета на вкладке Sources
            const data = Dataset.getDatasetRows({datasetName: 'salesSourceData'});
            
            // Вспомогательная функция для группировки данных по заданному имени поля датасета 
            function groupBy(arr, field) {
                return arr.reduce((acc, item) => {
                    const key = item[field];
                    if (!acc[key]) {
                        acc[key] = [];
                    }
                    acc[key].push(item);
                    
                    return acc;
                }, {});
            }
            
            // Массив с уникальными значениями из поля "Год заявки", отсортированное по возрастанию чисел
            const years = Array.from(new Set(data.map(d => String(d['Год заявки'])))).sort();
            
            // Общие стили для ячеек-заголовков таблицы
            const headStyles = {background: 'var(--g-color-base-misc-light)', verticalAlign: 'middle'};
            
            // Конфигурация ячеек-заголовков таблицы
            const head = [
                {
                    name: 'Тип оплаты',
                    formattedName: Editor.generateHtml({
                        tag: 'span',
                        content: [
                            {tag: 'span', content: 'Тип оплаты'},
            				// всплывающая подсказка для заголовка ячейки
                            {
                                tag: 'dl-tooltip',
                                content: ' ℹ',
                                style: {
                                    display: 'inline-block',
                                    margin: '0px 0px 0px 4px',
                                    'line-height': '12px',
                                    'text-align': 'center',
                                    width: '16px',
                                    height: '16px',
                                    border: '1px solid #ccc',
                                    'border-radius': '50%',
                                },
                                attributes : {
                                    'data-tooltip-content': {
                                        tag: 'i',
                                        content: 'Tooltip content',
                                    },
                                },
                            }
                        ],
                    }),
                    css: headStyles,
                    pinned: true,
                },
                // Формируем колонки по полученному выше массиву со значениями из поля "Год заявки"
                ...years.map(year => ({
                    name: year,
                    css: headStyles,
                })),
                {
                    name: 'Продажи, все года',
                    css: headStyles,
                },
            ];
            
            // Вспомогательная функция для отрисовки линии чарта
            function createChart(chartData) {
                const chartWidth = 80;
                const chartHeight = 40;
            
                // Вычисляем минимальное и максимальное значение координат
                const minX = Math.min(...chartData.map(d => d.x));
                const maxX = Math.max(...chartData.map(d => d.x));
                const minY = Math.min(...chartData.map(d => d.y));
                const maxY = Math.max(...chartData.map(d => d.y));
            
                // Вычисляем координаты в зависимости от размеров контейнера чарта (chartWidth, chartHeight)
                const coords = chartData.sort((d1, d2) => d1.x - d2.x).map(d => ([
                    (d.x - minX) / (maxX - minX) * chartWidth, 
                    (d.y - minY) / (maxY - minY) * chartHeight,
                ]));
                // Создаем путь для svg-линии по сформированным выше координатам
                let d = "";
                coords.forEach((_, x) => {
                    d += d === "" ? "M" : " L";
                    d += `${coords[x][0]} ${coords[x][1]}`;
                });
                // Создаем svg с цветом линии var(--g-color-base-brand) и толщиной 2px
                return `
                    <svg width="${chartWidth}" height="${chartHeight}">
                        <path 
                            d="${d}" 
                            style="fill: none; stroke: var(--g-color-base-brand); stroke-width: 2;"
                        />
                    </svg>`;
            }
            
            const rows = [];
            
            // Вспомогательная функция форматирования чисел
            const formatSalesValue = new Intl.NumberFormat('ru-RU').format;
            const postfix = ', ₽';
            
            // Сгруппированные строки по полю "Тип оплаты"
            const groupedData = groupBy(data, 'Тип  оплаты');
            // Формируем и наполняем строки таблицы для каждого сгруппированного типа оплаты
            Object.entries(groupedData).forEach(([key, items]) => {
                // Сгруппированные строки по полю "Год заявки"
                const salesByYears = groupBy(items, 'Год заявки');
                // Вычисляем сумму по полю "Продажа, ₽" по всем годам 
                const totalSales = items.reduce((sum, d) => sum + d['Продажа, ₽'], 0);
                rows.push({
                    cells: [
                        {
                            value: key,
                        },
                        // Формируем колонки по подготовленным ранее значениям "Год заявки"
                        ...years.map(year => {
                            const salesByYear = salesByYears[year] ?? [];
                            const yearSales = salesByYear.map(d => ({
                                x: new Date(d['Месяц заявки']).getTime(), 
                                y: d['Продажа, ₽'],
                            }));
                            const maxSales = Math.max(...salesByYear.map(d => d['Продажа, ₽']));
                            const minSales = Math.min(...salesByYear.map(d => d['Продажа, ₽']));
            
                            return {
                                value: maxSales, 
                                formattedValue: Editor.generateHtml(`
                                    <div>
                                        ${createChart(yearSales)}
                                        <div style="margin-top: 8px;">Min: <b>${formatSalesValue(minSales)}${postfix}<b></div>
                                        <div>Max: <b>${formatSalesValue(maxSales)}${postfix}</b></div>
                                    </div>
                                `),   
                            };
                        }),
                        {
                            value: totalSales,
                            formattedValue: formatSalesValue(totalSales) + postfix,
                            css: {
                                verticalAlign: 'middle',
                                textAlign: 'center',
                                fontSize: '16px',
                            },
                        },
                    ],
                });
            });
            
            module.exports = {head, rows};
            
  6. Вверху чарта нажмите Выполнить. В области предпросмотра отобразится таблица с данными из датасета со сгруппированными строками по полю Тип оплаты и сгруппированными колонками по полю Год заявки с графиком по значениям продаж по месяцам:

    image.png

  7. Чтобы сохранить чарт, в правом верхнем углу нажмите Сохранить и введите название чарта.