# MDA-таблица ## Основные положения `MDA-таблица` (Multi Dimension Analysis) - средство позволяющее реализовать список, управляемый пользователем с возможностью анализа данных и их группировки. Основной особенностью `MDA-таблиц` является работа с данным вне базы данных. При первом запросе данных, будет выполнен запрос к базе данных, далее если не изменялся порядок сортировки данных, то запросы к базе не выполняются. Для проектирования `MDA-таблицы` разработчик определяет запрос данных, и описывает колонки этого запроса, часть колонок могут быть `измерениями`, другие колонки - `показатели`. - `Измерения` - колонки, по которым данные группируются - `Показатели` - колонки, к которым применяются функции агрегации Пользователь имеет возможность управлять сортировкой данных, порядком вывода колонок, способом агрегации значений, выводить под-итоги. Сохранять эти настройки в виде приватных и публичных, назначать настройку по умолчанию. Построение и отображение данных делится на две части: - `Модель запроса` - описывает правила получения данных из `БД`, `измерения` и `показатели` - `Представление данных` - описывает правила сортировки, агрегации и порядок вывода данных на экран. ## Модель запроса Описывает правила получения данных, `измерения` и `показатели`. Класс `ru.bitec.app.btk.sel.mda.model.MdaModel`. Для построения модели создан `класс-builder` `ru.bitec.app.btk.sel.mda.model.MdaModelBuilder` ### Текст запроса `Текст запроса` - строка, в которой содержится текст `sql-запроса`. Этот запрос будет получать исходные данные из базы данных. Для использования `связанных переменных` используется синтаксис `AnormSql`. Пример связанной переменной: ``` select ... from ... where t.id = {id} ``` Для указания значений связанных переменных используется метод `on` класса `ru.bitec.app.btk.sel.mda.model.MdaModelBuilder` Полный пример использования запроса со `связанными переменными`: ```scala val model = MdaModelBuilder() .setQuery( () => s""" select ... from ... where t.id = {id} """ ) .on(() => Seq( "id" -> 100.nl )) .build() ``` ### Измерения Определяют поля по которым доступна группировка и сортировка Класс `ru.bitec.app.btk.sel.mda.model.Dimension` #### Значимое измерение Измерение, представляющее собой единичную колонку запроса Пример создания: ```scala val model = MdaModelBuilder() .addDimension(NumberColumn("nNum"), "Число") .addDimension(StringColumn("sString"), "Строка") .addDimension(DateColumn("dDate"), "Дата") ``` Первым параметром передается объект `колонка`, который описывает тип данных и имя колонки в запросе данных #### Ссылочное измерение Измерение, представляющее из себя 2 колонки запроса, одна из которых содержит `id` объекта, а вторая - `headline`. Используется если в качестве измерения используется какой- либо объект с прямой ссылочностью. В отображаемых данных колонка с `id` будет невидима. ```{note} Важно для ссылочных полей создавать такие измерения, т.к. они позволят фильтроваться в универсальном фильтре по такому измерению как по ссылочному ``` Пример создания: ```scala val model = MdaModelBuilder() .addRefDimension("idRefObject", "idRefObjectHl", "Ссылочный объект", "Some_RefClassName") ``` Параметры в порядке следования: - имя колонки с идентификатором - имя колонки с отображаемым значением - Отображаемое имя - Имя класса, на который ссылается измерение #### Измерение переменной ссылочности Измерение, представляющее из себя 2 колонки запроса, одна из которых содержит `gid` объекта, а вторая - `headline`. Используется если в качестве измерения используется какой- либо объект, на который ссылочность организована через `gid` В отображаемых данных колонка с `gid` будет невидима. ```{note} Важно для ссылочных полей создавать такие измерения, т.к. они позволят фильтроваться в универсальном фильтре по такому измерению как по ссылочному ``` Пример создания: ```scala val model = MdaModelBuilder() .addAnyRefDimension("gidRefObject", "gidRefObjectHl", "Ссылочный объект", List("Some_RefClassName1", "Some_RefClassName2")) ``` Параметры в порядке следования: - имя колонки с идентификатором - имя колонки с отображаемым значением - Отображаемое имя - Список классов, на который ссылается измерение ### Показатели Определяют поля по которым доступна агрегация значений Класс `ru.bitec.app.btk.sel.mda.model.Dimension` #### Простой показатель Показатель, представляющий собой единичную колонку запроса Пример создания: ```scala val model = MdaModelBuilder() .addMeasure(NumberColumn("nSum"), "Сумма") ``` Первым параметром передается объект `колонка`, который описывает тип данных и имя колонки в запросе данных #### Составной показатель Так же как и `простой показатель` представляет собой единичную колонку запроса, но имеет дополнительное `измерение`, в разрезе которого должна производиться агрегация. Например, сумма в договоре, где дополнительным измерением является валюта. Пример создания: ```scala val model = MdaModelBuilder() .addCompositeMeasure( NumberColumn("nSum"), Dimension(StringColumn("sMsr"), "Валюта"), "Сумма" ) ``` Параметры в порядке следования: - `колонка`, которая описывает тип данных и имя колонки в запросе данных - `измерение` - дополнительное измерение, в рамках которого требуется агрегация - отображаемое имя ### Колонки Модель обладает перечнем колонок, которые были использованы при создании `измерений` и `значений`. Класс `ru.bitec.app.btk.sel.mda.model.Column` Колонки определяют: - тип данных - имя колонки в запросе данных - тип редактора Типы колонок: - `NumberColumn`\ Числовая колонка - `BooleanColumn`\ Булева колонка. Наследник от числовой, с типом редактора `чекбокс` - `MoneyColumn`\ Денежная колонка. Наследник от числовой, с типом редактора `Денежный редактор` - `LongColumn`\ Целочисленная колонка - `StringColumn`\ Строковая колонка - `DateColumn`\ Колонка с типом `дата`, с типом редактора `редактор даты` - `DateTimeColumn`\ Колонка с типом `дата и время`. Наследник от `DateColumn`, с типом редактора `Редактор даты и времени` Стандартный тип редактора может быть переопределен, используя метод `setEditorType`, который принимает строку, имеющую формат настройки `динамического типа редактора`. Пример: ```scala NumberColumn("nNum").setEditorType("EditorType=etEdit") ``` ## Представление данных Отвечает за настройки отображения данных в `MDA-таблице`: - Порядок сортировки - Вывод промежуточных итогов - Агрегация значений показателей - Порядок вывода колонок на экран - Пользовательское переопределение наименования колонки - Изменение стилей строк итогов/подытогов - Размеры, видимость колонок - Параметры настройки Класс `ru.bitec.app.btk.sel.mda.view.MdaView`. Представлением управляет пользователь, используя пользовательский интерфейс настройки вывода колонок, а так же сохраняя и загружая настройки. ### Измерения Определяет настройки сортировки, группировки и вывода промежуточных итогов. ### Показатели Определяет показатели, по которым будет выполнена агрегация ### Атрибуты Определяет порядок вывода колонок на экран и их наименование ### Описание формируемых атрибутов выборки На каждый подобранный `атрибут представления` в выборке формируются следующие атрибуты: - `idValue[<имя колонки>]` - невидимый атрибут, будет содержать `id` для `ссылочных измерений` или `gid` для `измерений переменной ссылочности`. - `value[<имя колонки>]` - видимый атрибут, в котором будет отображаться значение, видимое пользователя. Для `ссылочных измерений` или `измерений переменной ссылочности` в этот атрибут выводится значение колонки, объявленной как `headline` - `sEditor[<имя колонки>]` - невидимый атрибут, управляющий типом редактора - `sStyle[<имя колонки>]` - невидимый атрибут, управляющий стилем раскраски ячейки. ## Подключение MDA-таблицы к прикладной выборке ### Реализация отображения сгруппированных данных Для подключения к прикладной выборке сервиса `MDA-таблиц` необходимо: 1. Унаследовать выборку от `ru.bitec.app.btk.sel.mda.Btk_MdaAbsAvi` 2. Создать отображение, если требуется 3. Унаследовать нужное отображение от отображения `Grid` 4. Определить модель запроса данных, переопределив метод `buildModel`, используя строителя модели `ru.bitec.app.btk.sel.mda.model.MdaModelBuilder` 5. Переопределить метод `getSourceDataRep`, который будет определять выборку для открытия исходных данных. ### Реализация отображения исходных данных Для реализации выборки, которая будет отображать `исходные данные` (данные которые вернул запрос из базы данных), необходимо: 1. Унаследовать выборку от `ru.bitec.app.btk.sel.mda.Btk_MdaAbsAvi` 2. Создать отображение, если требуется 3. Унаследовать нужное отображение от отображения `SourceDataGrid` ### Управление типом редактора Тип редактора для колонки определяется в момент описания `модели запроса данных`. Каждый тип колонки имеет свой тип редактора по умолчанию, для его переопределения можно воспользоваться методом `setEditorType` ### Интеграция с универсальным фильтром Универсальный фильтр анализирует `модель запроса данных` и на все `показатели` и `измерения` позволяет наложить условия фильтрации. Условие фильтрации будет наложено поверх результат запроса, описанного в `модели`. Правила формирования доступных для фильтрации атрибутов: - для `ссылочных измерений` создается ссылочный атрибут фильтрации - для `измерений переменной ссылочности` создается атрибут фильтрации переменой ссылочности - для всех остальных `измерений` и `показателей` создаются значимые атрибуты фильтрации в соответствие с типом данных ### Создание стандартного фильтра Стандартный фильтр создается по тем же правилам, что и для обычной выборки. ### Использование макросов Для использования макроса выборки в тексте запроса необходимо получить его текст, используя метод `selection.getMacro`, и добавить его в нужное место запроса. Пример: ```scala val model = MdaModelBuilder() .setQuery(() => s""" select ... from ... where ${selection.getMacro("SomeMacrosName")} """ ) ``` ## Описание основных методов - `extendDynMeta` - позволяет добавить в перечень атрибутов выборки свои атрибуты. - `extendDynRow` - позволяет установить дополнительные значения в формируемую строку выборки - `buildModel` - метод, который должен переопределить разработчик, для описания `модели данных` - `mdaModel` - возвращает `модель данных` - `mdaView` - возвращает `представление данных` - `needGenChooseCheckBox` - признак, что требуется формировать чекбоксы для выбора строк - `forSelectedRows` - позволяет обойти выбранные через чекбоксы строки. - `getSourceDataRep` - метод, который должен переопределить разработчик, для указания выборки, которая будет открыта из операции `Открыть исходные данные` - `filterRow` - позволяет отфильтровать записи - `refreshBySql` - метод, который принудительно делает перезапрос данных из базы данных, и обновляет выборку ## Описание основных операций - `openSourceData` - `Открыть исходные данные`\ Открывает выборку, указанную в методе `getSourceDataRep`, в которой будут отображены исходные данные для выбранных строк - `chooseAll` - `Выбрать все записи`\ Для всех записей проставляет чекбокс выбора - `clearAllChosen` `Снять выбор со всех записей`\ Для всех записей снимет чекбокс выбора - `chooseSelected` `Выбрать выделенные записи`\ Для всех выделенных записей проставляет чекбокс выбора - `clearSelected` `Снять выбор с выделенных записей`\ Для всех выделенных записей снимет чекбокс выбора ## Описание настройки атрибутов Настройка происходит через выборку `ru.bitec.app.btk.sel.mda.Btk_MdaViewEditorAvi#attrEditor`. Выборка ожидает в качестве параметра `mdaModel` в формате JSON и опционально прошлый `mdaView` для формирования нового `mdaView`. Возвращает JSON отредактированного `mdaView`. Для работы с созданием/сохранением/загрузки настроек выборка ожидает названия выборки и репрезентации и опционально id прошлой настройки. ![ViewEditor1](../img/mda/ViewEditor_1.PNG) На вкладке `Настройка сортировки и агрегации` можно настроить - Порядок и тип сортировки - Вывод промежуточных итогов - Тип агрегация значений показателей - Стили подытогов ![ViewEditor2](../img/mda/ViewEditor_2.PNG) На вкладке `Настройка выводимых столбцов` можно настроить - Порядок вывода колонок на экран - Пользовательское переопределение наименования колонки - Размеры, видимость колонок ![ViewEditor3](../img/mda/ViewEditor_3.PNG) На вкладке `Характеристики настройки` можно настроить - Изменение параметров настройки - Стили итогов