Можно ли при создании собственных JS визуализаций пользоваться какими-то библиотеками, например react/angular/vue

Добрый день, подскажите пожалуйста, можно ли при создании собственных JS визуализаций пользоваться какими-то библиотеками, например react/angular/vue?
Можно ли настроить связь (кроссфильтрацию/передачу параметров) между разработанной визуализацией на JS и стандартными встроенными визуализациями и фильтрами?

Здравствуйте, есть несколько уровней кастомизации фронтенда:

1. Примитивное.

Вы просто используете доступные опции и найтройки стилей, формата внутри конкретных дешлетов.

2. Темы и их настройка.

По умолчанию в Luxms BI доступны темная и светлая темы. Тема есть ничто иное как JSON-объект из ключей, хранящих цвета, тени и всякие градиенты. Есть предустановленные ключи, которые использует основной фронтенд. Их можно переписать благодаря специальному файлу themes.json, который нужно будет загрузить в раздел resources специального датасета ds_res (он есть всегда по умолчанию). Те настройки, которые там будут мерджатся с основным набором настроек тем и поэтому можно менять только малый набор цветов, а не полный перечень. По итогу выставляется ряд css переменных, которые фронтенд цепляет и красит компоненты.
Выглядит это например так (когда нужно поменять два конкретных цвета шаблона)

{
  "light": {
    "color1": "red",
    "bg_default": "#f1f1f1"
  },
  "dark": {
    "color1": "blue",
    "bg_default": "#a1a1a1"
   }
} 

3. Разработка кастомных визуализаций или целых миниподразделов.

3.1 Кастомная визуализация на базе класса external (Тип визуализаций Внешний, если выбирать в панели редактирования).

Дешлет ждет от вас ссылку на html файл и если она есть - вставляет iframe, где рендерит этот файл с той структурой, что там есть. Теоретически вы можете просто указать там примитивную статическую страницу или вообще ссылку на внешний ресурс из интернета.
Но чтобы это был управляемый компонент - вам потребуется специальный файлик скриптов bixel.js (GitHub - rcslabs/bixel: BI eXternal ELement) - реализующий необходимую событийную систему для работы с данными из Luxms BI.
Поскольку это фрейм - вы можете написать базовый html, инстанс React, Vue или angular, но он будет связан с основным окном лишь опосредовано - через URL, событийную систему и доступный список observable сервисов фронтенда - их будет не так много из существующих.

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

3.2 Кастомная визуализация на базе класса **internal **(Тип визуализаций Внутренний, если выбирать в панели редактирования).

Вы создаёте реакт-компонент с указанием export default, ссылку на js файл в собранном виде которого можете указать в качестве файла-источника. Это уже нативный элемент платформы, которому доступны все методы и сервисы основного клиента. Для более удобной разработки кастомных компонентов у нас есть специальный проект на гитлабе luxmsbi-web-resources, который реализует удобную среду для развертывания локального сервера и массового управления всеми ресурсами всех датасетов.

В нем вы избавлены от необходимости билдить компоненты типа tsx, jsx и работаете с ними в “ленивом режиме”, правя код компонента, не заботясь о билдовании (это касается только реакт-компонентов). Ряд специальных команд отправит ваши компоненты типа MyComponent.tsx (который есть ребенок React.Component) в уже сбидженом виде (паре .js и .js.map) на сервер и за одно проверит изменения и отличия в том, что есть у вас на локали и тем, что лежит на сервере. Прелести git и все такое)
Этот проект так же можно использовать для компонентов типа external выше. Свой вебпак конфиг и свои компоненты, которые вы можете добавить в package.json. Но ожидать, что вы сможете написать вью-компонент и попытаться замаунтить его к дешборду не стоит. Только как обычный набор скриптов внутри external шаблона. Для реакта почти никаких ограничений нет, разве что вы будете вынуждены использовать структуру URL как она заявлена в основном клиенте, названия разделов и эндпойнтов поменять вы не сможете, но сможете перемещаться и выставлять параметры этого урла (или фильтров для кубов)

4. Полная или частичная отдача фронтенд части клиенту.

Требует лицензии и договоренностей с клиентом.
Вам отдается один или несколько структурных компонентов в виде файлов, доступных для изменений в проекте luxmsbi-web-resources. Вы можете реализовать уже там собственную логику взаимодействия и внешнего вида всех участвующих компонентов и в разумных пределах менять даже структуру URL. Но это так же будет означать, что ответственность за логику и работу таких компонентов и последствий несет уже ваша команда разработки. Консультации и помощь в том, как организовать разработку в таких рамках мы конечно же готовы вам предоставить.

P.S. Под полной отдачей фронтенда клиента имеется ввиду, что вы можете получить рутовые компоненты фронтенда, кои можете менять как угодно, но не получаете сам доступ к основному проекту** luxmsbi-web-client**.
Проще говоря, вы говорите нам: хотим полностью поменять вот эти несколько разделов фронтенд -части Luxms BI. Мы отдаем вам клиента с подготовленным шаблоном, на базе которого вы и разворачиваете разработку всех кастомных визуализаций

А можете подробнее рассказать про пункт Кастомная визуализация на базе класса internal, и прислать пример такого “ленивого” react компонента?
Насколько я понимаю это самый гибкий функционал влияния на стандартную тему и стандартные дэши. Интересует какие возможности влияния на другие компоненты есть у таких internal компонентов, например можно ли их скрывать по условию, организовывать табы на одном дашборде, можно ли подменять json конфиг других дашей?

У нас ведется обучение коллег-разработчиков у клиента и уже там подробно все объясняется
Можем тезисно ответить на ваши вопросы:

1.

Такой компонент с точки зрения разработчика есть файл MyComponent.tsx (jsx не важно)
Приведем пример такого компонента в виде классового реакт компонента (можно и функционального, там изменения минимальны)

import React from "react";
import './MyComponent.scss';
interface IMyComponent {
  width: number;
  height: number;
  wtf?: string;
}
export default class MyComponent extends React.Component<IMyComponent> {
   public constructor(props) {
     super(props);
     this.state = {
      // тут состояние
     };
  }
// иные функции и классические обработчики жизненного цикла реакт компонента
  public render() {
   return (<div className="myClass">Hello world!</div>)
 }
}

2.

Менять конфиг дешлета - плохая практика. Дешлет меняется только в момент разработки или обновления кода его компонента (и то если это нужно), но не в лайв режиме.
Для реализации реакции одного дешлета на другой есть observable сервисы, которые есть как коробочные (классический пример - сервис фильтров, на котором работает управляющий деш и реализующий реакцию на фильтрацию всех дешлетов-подписчиков). Но прелесть в том, что вы сами можете создавать такие сервисы. Как типа Singleton так и Фабрику (или иной шаблон проектирования при умении). Создали такой сервис наследника специального класса BaseService, который этот Observable и реализует (подключаете его из экспортируемого пакета bi-internal при кастомной разработке) и он, допустим, запрашивает разово данные с сервера из одного или нескольких кубов, попутно фильтруя их изначально или через собственные же вами написанные методы и формирует свою модель, на изменение которой может подписаться ваш кастомный компонент. Вы прокидываете callback для такого сервиса, в котором реализуется зависимая от тех самых изменений модели логика рендера вашего компонента. например если это модель фильтр-сервиса - то вы получаете актуальный объект фильтров, который просто используете для перезапроса данных для отображения в вашем текущем компоненте. Таким образом ваш компонент становится простым View-компонентов, в котором может почти не быть логики, а только отображение.

3.

Табы можно организовать разными способами - один из которых - сделать дешлет (!), в котором разместить реакт-компонент с этими табами и написать обработчик клика для каждого таба, осуществляющего установку в сервис урла приложения значения нужных вам GET параметров например. И да, можно у этого дешлета отключить бордер и тень, чтобы он выглядел как часть основного шаблона.
Размер такого дешлета может быть крошечным - достаточным, чтобы эти табы отобразить и все. Тут просто нужно поиграться с блоком frame внутри конфига дешлетов, чтобы настроить грид более детально, нежели простой драгндроп

Ещё несколько уточняющих вопросов:

  1. А у стандартных дешей есть такие-то зависимости от урла? или данные в них управляются только фильтрами (управляющий деш)? то есть на стандартные деши кроме как фильтров и частично lpe ни как больше не повлиять? (чтобы знать какие люфты есть в стандартных вещах)
  2. Можно ли в конфиге даша, в ключе option использовать lpe условия? и вообще в каких местах даша можно использовать lpe? (по документации есть пример только в style)
  3. К вашему ответу по поводу организации Табов, получается, что такое можно сделать только полностью на кастомных дашах? а если в дашборде будут стандартные даши, то они будут сквозные?
  4. Вы упомянули ключ frame, а можно подробнее про этот ключ, так как в документации есть только про упоминание о его существовании, но нет ни слова что это и с для чего он используется

1.

Вообще в SPA все зависит от урла) он является основным источником информации для приложения - какой раздел отобразить - какие фильтры применить. Потому ответ на ваш вопрос по умолчанию “да, конечно”.
Например, по умолчанию фильтры на кубы хранятся в скрытом ключе модели UrlState (так зовется тот самый url observable сервис, singleton, на который “молится” весь веб-клиент), который зовется _koobFilters: {…} и только когда вы выбираете какой-то фильтр в управляющем деше или выставляете его программно в кастомном - то информация об этом хранится в этом ключе, но вы ее явно в урле не увидите. Хотя на дешлетах это отобразится. При перезагрузке страницы фильтры исчезают. Однако, добавив в урл параметры типа f.age=12,45 - ds вы получите дополнительный фильтр по умолчанию на дешлеты (даже на управляющий деш, вообще говоря) который будет работать и после перезагрузки страницы (подходит, когда вы указали ряд фильтров и хотите поделиться с кем-то ссылкой на итоговый дешборд, не используя для этого выгрузку в презентации и т.д.)

2.

Нет, options всегда только массив строковых идентификаторов настроек.
lpe вы используете, когда создаете межу (measure, факт) составного типа (результат нескольких операций над дименшнами, когда готовой аггрегационной функции нет).
Вы также используете его в блоке style, для того чтобы выставлять css свойства на основе выражений для значений межи. С недавних пор и дименшна и межи.
Плюс по факту вы пишете lpe, когда устанавливаете фильтр на дименшн. Выглядит по-разному, возможно, но сервер и клиент в указанных случаях использует одинаковый парсинг LISP alike выражения

3.

Да, можно сделать переиспользуемый компонент, который будет слушать например урл, который будет хранить нужный вам параметр (если его уже нет по умолчанию, например идентификатор дешборда dboard). Можно сделать подобное и на стандартных дешлетах, у которых прописать свойство

onClick: {
    navigate: {
/* здесь список ключей, которые вы хотите поменять в урле (понимай "модели url-observable-сервиса")
*/
// например
 dboard: 1 
// перейдет при клике на дешборд c id = 1 
// текущего датасета
     }
}

Либо вы можете сделать дешлет, занимающий все доступное пространство дешборда, где будет использоваться компонент обертка, состоящая например из компонента-хидера, футера и изменяющегося от параметров из урла компонента-контроллера, загружающего другие визуализации (у нас для этого есть сервис, загружающий компоненты и такой компонент можно будет замаунтить в контейнер в компоненте-обертке выше)
Сквозные элементы типа табов к сожалению не предусмотрены по умолчанию - это следствие того, что дешборды вообще говоря не зависимы друг от друга как структурные единицы. Они связаны опосредовано, через фильтры кубов и сервис урла.
К тому же как показала практика - даже такой просто элемент как табы каждый хочет по-своему со своей логикой - и мы отказались от этого из коробки - добавляем лишь по требованию клиента и согласованию функционала.

4.

Ключ frame это автоматически заполняемый объект верхнего уровня у объекта конфигурации дешлета. Является неким свидетельством того, что в десктопном режиме дешлеты на дешборде представляют собой абсолютно спозиционированные элементы, с динамически расчитываемыми ширинами, высотами и оступами от края пространства, зарезервированного под дешлеты. Т.е справа от панели навигации (где доступные датасеты и дешборды текущего датасета) и сразу под хидером дешборда (если в урл добавить параметр displayMode=dashboard, то левая панель и хидер пропадут, оставляя все пространство только под дешлеты текущего дешборда (очень удобно, если вы хотите встроить дешборд во фрейм и поместить внутрь какого-либо интернет-ресурса извне, например в лендинге или ином демонстрационном ресурсе или же показывать на большом экране))
Проще говоря, дешлет - это адаптивное выдолбленное оконце на стене, через которое видно визуализацию (мы зовем такой класс Визелем). Да, я мастер аллегорий)
По умолчанию заполняется автоматически при драг-н-дропе и создании сетки дешлетов в режиме редактирования дешборда.
Выглядит такой объект примерно так:

{
  x: 0,
  y: 1,
  w: 5,
  h: 2
}

Где пара x,y - координаты точки отсчета размеров дешлета. Точка 0, 0 в таких координатах - это левый верхний угол у рабочего пространства для дешборда. w,h - от width и height соответственно - условные размеры дешлета.
Числа, что здесь указаны - условные единицы, которые при аккуратном использовании могут помочь вам настроить самые разные виды сеток дешлетов на дешборде. Значения могут быть и нецелыми - это значит, что вы настроены серьезно и с вами лучше не шутить) А вообще эти числа для всего массива дешлетов формируют динамический размер сетки дешлетов. Если вы хотите получить дырку в дешборде в произвольном месте - запросто. Просто подберите размеры и отступы так, чтобы этого добиться) Или наоборот - прилепить один к другому - то же самое. Первичные значения обычно строятся автоматически, да, но потом вы можете ручками поменять их на те, что вам больше подходят.

Насколько я понимаю, для визуализации графиков вы используете библиотеку https://www.highcharts.com/demo , вопросы

  1. А вы её полностью поддерживаете? или есть какие-то исключения?
  2. Можно ли полностью смотреть их документацию по графикам?
  3. Конфиг даша полностью пробрасывается в библиотеку или ключи фильтруются?

И ещё такой вопрос
4. а есть ли штатные средства визуальной группировки дашей / дашбордов? или максимум, что есть, это группы дашбордов в датасете?

По-умолчанию мы используем open-source библиотеку Apache ECharts (Apache ECharts).

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

По вопросам:

1.

Мы поддерживаем основной модуль библиотеки Highcharts, остальные модули необходимо подключать самостоятельно в коде кастомных дешлетов.

2. Да, конечно.

3.

Вопрос не совсем корректный, потому что конфиг дешлета и итоговый конфиг для библиотеки HC - это начальная и конечная точки. Между ними достаточно много дополнительной логики, аналог которой мы можете реализовать в коде своего кастомного дешлета.

4.

У нас есть визуализация типа board, которой нет в списке доступных типов визуализаций по умолчанию, но вы можете указать такой тип явно в конфиге дешлета. Его роль заключается в том, чтобы объединить несколько конфигов дешлета в рамках одного родительского дешлета (иными словами, на месте одного дешлета вы сразу можете увидеть несколько визуализаций, каждая из которых может жить своей жизнью) (вам просто нужно будет указать дополнительный ключ children в виде массива конфигов внутренних дешлетов которые по виду совпадают с родительским, нужно лишь не забыть для каждого прописать обязательно поле view_class, где указать строкой тип визуализации, например (line, column, bar и т.д.)). Но для группировки дешбордов кроме групп дешбордов пока нет иных способов.

В планах по развитию платформы есть пункт про реализацию конструктора табов как для дешбордов, так и дешлетов.