07-bixel-internals
Введение
Внешний визель
понимается как фрейм, который встраивается в LuxmsBI
в качестве дэшлета и отображает данные
LuxmsBI
обеспечивает эту возможность путем отправки данных и служебных
сообщений этому фрейму при его загрузке, и при изменении выбора в
панелях.
Внешний визель
в качестве cлоя асбтракции подключает библиотеку bixel
,
которая скрывает детали взаимодействия с LuxmsBI
LuxmsBI
отвечает за:
- Создание/удаление/отображение в нужном месте элемента IFRAME
- Загрузку страницы по указанному в конфиге URL
- Загрузку данных по указанным в конфиге дэшлета осям
- Отправку данных и служебных сообщений фрейму
Внешний визель
(+ bixel
) отвечают за:
- Собственную загрузку
- Получение, обработку и корректные ответы на сообщения от
LuxmsBI
- Отображение данных
- Отображение информационных сообщений (идет загрузка, ошибка, нет данных)
Концепция
Внешний визель
и LuxmsBI
обмениваются строковыми сообщениями в формате JSON
В качестве транспорта используется метод window.postMessage
Внешний визель
отправляет сообщения вwindow.parent
LuxmsBI
отправляет сообщения вiframe.contentWindow
Транспорт подлежит расширению для возможности встраивания в LuxmsBI iPad
Каждая сторона соблюдает протокол обмена, отправляет корректные сообщения и ответы
Формат любого сообщения:
interface IMessage {
type: string; // тип сообщения
uid: number; // уникальный идентификатор (инкремент)
payload: {...} // данные, разные для разных типов
}
Принимающая сторона должна проверить тип сообщения (message.type
):
- Если
message.type
оканчивается на_OK
- сообщение является ответом об успехе операции по команде с тем жеuid
- Если
message.type
оканчивается на_FAILED
- сообщение является ответом об ошибке операции по команде с тем жеuid
- В противном случае сообщение является командой, которую необходимо обработать и
дать ответ - сообщение с типом<тип сообщения>_OK
либо<тип сообщения>_FAILED
Соглашения по формату сообщений
type
type
является строкой, в uppercase, разделенная символом подчеркивания
Если type
оканчивается на _OK
или _FAILED
то сообщение является ответом.
INIT
- команда инициализацииINIT_OK
- успешный ответ на команду инициализацииNO_DATA
- Сообщение об отсутствии данныхSOME_UNKNOWN_MESSAGE
- неизвестный тип сообщенияSOME_UNKNOWN_MESSAGE_FAILED
- ответ об ошибке при обработке такого неизвестного типа сообщения
uid
uid
является уникальным идентификатором сообщения от одной стороны.
Он обязательно совпадает у сообщения и ответа (но у них отличается тип: у ответа тип
оканчивается на _OK
или _FAILED
)
payload
JSON специальной формы для разных типов сообщений
В случае сообщения-ответа, если принимающая сторона не знает, что отправить в качестве payload, рекомендуется отправить payload из запроса.
Схема взаимодействия
Сначала
внешний визель
отправляет сообщение INIT, там самым сигнализируя о
том, что он вообще адекватный (а не просто для красоты), в нем загружена
библиотекаbixel
и он готов получать данные и слушать их изменения. В сообщении
отправляются способности визеля к отображению многомерных структур.внешний визель
может нарисовать декоративные элементы, свидетельствующие
о загрузке.LuxmsBI
отправляет ответINIT_OK
свидетельствующие о том, что фрейм вставлен
не куда-то, а в приложениеLuxmsBI
LuxmsBI
отправляет сообщениеLOADING
, и начинает загрузку данныхвнешний визель
может нарисовать декоративные элементы, свидетельствующие
о загрузке, а также нарисовать осиLuxmsBI
отправляет сообщениеLOAD
, говорящее о том, что данные загруженывнешний визель
нарисует данные, или будет их обрабатыватьЕсли данных в таблице data не оказалось, то
LuxmsBI
отправляет сообщениеNO_DATA
Если пользователь выбирает другие метрики/локации/периоды, то
LuxmsBI
аналогично отправляет сообщениеLOADING
, и, по загрузке,LOAD
илиNO_DATA
Если пользователь убирает выбор с метрик/локаций/периодов, то
LuxmsBI
сразу отправляет сообщениеNO_DATA
(сообщенияLOADING
не будет)Если пользователь щелкает по точке, и есть необходимость показать меню,
внешний визель
отправляет сообщениеCLICK_DATA_POINT
с координатами точки (как MLP координатами, так и
относительными экранными координатами места щелчка)
Формат сообщений
IAxes
общая структура, описывающая конфигурацию осей. Присутствует в разных ответах
interface IAxes {
metrics: IMetric[];
locations: ILocation[];
periods: IPeriod[];
units: IUnit[];
axesOrder: [string, string, string];
}
interface IMetric {
id: string; //
color: string;
bgColor: string;
title: string;
unit_id: string;
}
interface ILocation {
id: string;
color: string;
bgColor: string;
title: string;
}
interface IPeriod {
id: string;
color: string;
bgColor: string;
title: string;
period_type: number;
}
interface IUnit {
id: string;
value_prefix: string;
value_suffix: string;
title: string;
tinyTitle: string;
}
Все title
, color
, bgColor
должны быть вычислены LuxmsBI
по конфигу дэшлета
и иными эвристическими уловками.
axesOrder
- массив из трех строк, указывающий порядок. Каждый элемент является
строкой 'metrics'
, 'locations'
или 'periods'
. Первой идет строка, соответствующая оси x
, второй y
, третьей z
INIT
Отправляет bixel
payload имеет тип
interface IInitMessagePayload {
xsCount? : number;
ysCount? : number;
zsCount? : number;
metricsCount? : number;
locationsCount? : number;
periodsCount? : number;
}
Все поля необязательны, с их помощью визель сообщает о своих способностях
отображать многомерные структуры данных
Если соответствующее поле не указано, или равно null
, то подразумевается, визель
в состоянии отобразить любое количество значений соответствующей оси.
LOADING
Отправляет LuxmsBI
payload имеет тип
interface ILoadingMessagePayload {
axes : IAxes
}
Внешний визель
получив такое сообщение может нарисовать бегунов загрузки,
а также предварительно нарисовать оси и подписи.
NO_DATA
Отправляет LuxmsBI
payload имеет тип
interface INoDataMessagePayload {
axes : IAxes;
}
Внешний визель
получив такое сообщение может нарисовать сообщение об
отсутствии данных.
Такое сообщение можно получить двумя способами:
- В таблице data нет ни одного числа для осей - в этом случает следует ожидать, что ранее было отправлено сообщение
LOADING
с таким же полемaxes
- Ничего не выбрано в панелях, а дэшлет зависит от них - тогда предварительного
сообщенияLOADING
не должно было быть.
LOAD
Отправляет LuxmsBI
payload имеет тип
interface ILoadMessagePayload {
axes : IAxes,
data: {
metric_id: string;
loc_id: string;
period_id: string;
val: string | number;
}[];
}
Сигнализирует об успешной загрузке данных. Внешний визель
может нарисовать
график, или включить ободряющую музыку, или проанализировать полученные данные и
действовать согласно запрограмированному поведению.
CLICK_DATA_POINT
Отправляет внешний визель
при щелчке по точке
payload имеет тип
interface IClickDataPointMessagePayload {
metric_id: string;
loc_id: string;
period_id: string;
event: {
pageX: number,
pageY: number,
}
}
*_OK
Ответ, сигнализирующий об успехе обработки сообщения.
При получении такого сообщения стоит обрадоваться и продолжать работать дальше, по
спроектированному сценарию.
payload в большинстве случаев будет таким же, какой был в первоначальном сообщении
*_FAILED
Ответ, сигнализирующий об ошибке обработки сообщения
payload имеет тип
interface IFailedMessagePayload {
message : string;
}
Любая из сторон может проигнорировать это сообщение, или прекратить работу, или
сломаться, или вывести это сообщение на экран.