Intersystems DeepSee. Простая и быстрая визуализация данных
DeepSee являет собой OLAP кубы которые «смотрят» на выбранную таблицу выбранной области, такие кубы можно фильтровать по всем полям исходной таблицы, что позволяет просматривать данные с любой точки. Например, одной из поставленных задач был вывод информации о родившихся, DeepSee позволил на основе кубов создать таблицы отображающие сколько детей родилось за последний год, разделить их в группы по полу, весу, длине тела, возрасту матерей и месту рождения. Так же для каждого параметра можно задать условия DrillDown — проваливания в параметр, так вместо года мы можем посмотреть сколько всего родилось в конкретный месяц, день, час.
Звучит неплохо, верно? Так оно и есть!
Однако, как и всегда в любой бочке мёда найдется своя ложка дёгтя, в случае с DeepSee это дизайн в котором подаются данные:
В таком виде показывать аналитику кому-либо не стоит, нас или примут за жутких консерваторов или за людей, не имеющих вкуса.
К счастью я нашел спасение, на просторах github, полностью открытый продукт под названием DeepSeeWeb (DSW) — это сайт созданный с использованием jQuery и AngularJS. И если чистый DeepSee работает внутри СУБД, т.е. что бы на него попасть, необходимо зайти на портал управления Caché, то DeepSeeWeb работает как простой клиент к серверу используя REST запросы, которые описаны в устанавливаемом в Caché пакете MDX2JSON, но ничто не запрещает нам писать свои запросы, для этого главное освоить «местный» язык — Caché ObjectScript (COS). Каждый запрос представляет из себя:
«Объявление» в установленном по умолчанию классе-обработчике (класс файл с кодом в COS), например REST.cls. В этом классе создается следующая секция XDATA:
XData UrlMap
{
И в ней мы можем определять реакцию сервера на запросы клиента, каждый запрос объявляется следующим образом:
где Url это собственно имя запроса, http://<наш сервер>/<имя приложения>/Url
в Url так же можно передавать аргументы arg1, arg2… тогда запрос приобретет вид
http://<наш сервер>/<имя приложения>/Url/arg1/arg2
далее указывается метод запроса (POST, GET, DELETE and etc.), и завершает все Call — функция, которая собственно и будет обрабатывать наш запрос.
Многих должно быть заинтересовало, что за такое <имя приложения> мы встраиваем в наш запрос. Для того чтобы иметь доступ к REST функциям, необходимо в СУБД создать Веб-приложение
Здесь мы должны задать ему то самое имя, по которому сервер поймет, что именно мы от него хотим и определить класс-обработчик для REST запросов.
Но, пожалуй, хватит теории, подробней к этому вопросу можно будет вернуться в следующий раз. А учитывая что в ру-пространстве информации про DeepSee крайне мало, следующий раз непременно будет.
Продолжим про DeepSeeWeb.
Давайте рассмотрим его по шагам.
Главное меню:
Сайт подгрузил все ранее созданные в DeepSee (старом дизайне) дашборды и вывел нам их в стиле Metro, сохранив исходную структуру, что было в папках, там и осталось. От внимательных глаз не ускользнет иконка гаечного ключа внизу экрана, это переход в режим настройки внешнего вида плиток меню.
Можно изменить цвет, иконку, заголовок и цвет текста. Однако, самым интересным является возможность вывода на плитку данных одного из графиков, что находится на выбранном дашборде.
Познакомившись с меню, давайте двигаться дальше и перейдем внутрь дашборда.
Каждый виджет старого дизайна имеет свой аналог в новом, связь осуществляется за счет типа виджета, при запросе списка всех виджетов клиент получает их название, тип и запрос для получения данных, затем сопоставляет существующие на клиенте типы с полученными и отображает их. Сами виджеты «рисуются» с помощью библиотеки Highcharts, это очень мощный инструмент для визуализации данных, для разработки он предоставляет десятки разнообразных chart«ов — графиков, линейных, столбчатых, круговых, временных линий, а так же множество методов для их кастомизации, у этой библиотеки просто огромное API позволяющее вытворять с графиками всё, что душе угодно.
И вот как только вы познакомитесь с Highcharts, вы непременно пожелаете увидеть какие-нибудь чарты (chart) на своих дашбордах, и… Познаете разочарование, как когда-то его познал я, по умолчанию DeepSeeWeb имеет в своем распоряжении лишь часть графиков из большой библиотеки! Но мы ведь работаем с JavaScript, а значит для нас нет ничего невозможного! И правда, разработчики ожидали, что кому-нибудь да приспичит добавить что-то новое. И реализовали возможность добавления, даже сделали красивую форму для этого:
Это простой JSON редактор, в котором необходимо объявить массив widgets и в нем каждый новый объект будет описывать отдельный виджет:
url: путь до js файла описывающего виджет
Этот файл представляет из себя angular фабрику (factory)
function PieChart(Utils) {
function CustomWidget($scope) {
……
}
}
angular.module('widgets')
.factory('PieChart', ['Utils', PieChartFact]);
class: имя фабрики в указанном файле
name: имя виджета, который мы описываем
type: тип виджета, chart указывает что новый виджет будет отображать график из библиотеки Highcharts, так же существуют типы «pivot», «text», «map» — таблица, текст и карта.
Теперь вернемся к свойству name, откуда собственно брать имя нового виджета, ведь чтобы что-то описывать, надо это создать. Создание новых виджетов оказалось для меня самой сложной задачей, а было все очень просто, достаточно просто внимательно прочитать README.
Итак, чтобы создать новый виджет необходимо создать новый класс в Cache, я делал это студии, которая входит в комплект Cache.
ВСЁ! Создаем новый файл, пишем в нем:
Class <Название виджета> Extends %DeepSee.Component.Portlet.abstractPortlet
{
}
И готово, новый виджет создан. Для его отображения на дашборде необходимо его туда положить, перейдем в портал управления старым DeepSee и добавим виджет и если ранее мы выбирали из того что уже было
То теперь мы выбираем из категории портлет созданный нами виджет:
Здесь список всех созданных мной виджетов.
Неописанный в настройках пользовательский виджет выглядит именно так, он сообщает что не знает такой виджет и что делать с ним не имеет понятия.
Теперь мы с вами знаем как добавлять собственные виджеты и давайте попробуем. Сперва добавим новый виджет из библиотеки Highcharts.
Например, такой, отображающий сколько посещений у нас на сайте было в разрезе каждого часа.
Согласно Highcharts такие графики называются spiderWeb. Создадим файл SpiderWeb.js и напишем туда:
function SpiderWebFact(BaseChart, Utils) {
function SpiderWebChart($scope) {
//Говорим виджету что бы он тянул scope из базового для всех
//highcharts-виджетов класса
BaseChart.apply(this, [$scope]);
var _this = this;
//указываем тип графика может быть bar, column, line, area, pie
this.setType('line',true);
//получаем данные с сервера
this.requestData();
//Описываем настройки виджета именно для SpiderWeb
var ex = {
options: {
plotOptions: {
series: {
//не пропускать на графике места в которых график равен 0, что бы не было //разрывов
connectNulls: true
}
},
//описываем что выводить в всплывающем окне при наведении на маркер графика
tooltip: {
shared: true,
useHTML: true,
formatter: function () {
var t = this;
/* jshint ignore:end */
var a= ""+t.x+":00";
var all = 0;
for(var i =0;i'+_this.toTitleCase(t.points[i].series.name)+': ' + '' + val + " ";
}
if(t.points.length>1)
a+= "Всего: "+all.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ")+"
";
return a;
}
}
},
yAxis: {
//основная директива SpiderWeb, именно она делает его таким, каков он есть
gridLineInterpolation: 'polygon',
lineWidth: 0,
min: 0
},
xAxis: {
//указываем что на конец каждого измерения необходимо добавить 00, потому что
//с сервера время приходит в формате 01,02,03 …
labels: {
formatter: function () {
return this.value + ':00';
}
}
}
};
//передаем только что объявленные настройки в список всех настроек виджета
Utils.merge($scope.chartConfig, ex);
}
return SpiderWeb;
}
//объявляем фабрику
angular.module('widgets')
.factory('SpiderWebChart', ['BaseChart', 'Utils', SpiderWebFact]);
Теперь создадим класс в Cache, и дабы не путаться назовем его тоже SpiderWeb.
Class User.SpiderWeb Extends %DeepSee.Component.Portlet.abstractPortlet
{
}
User здесь это название папки в которой будет лежать файл, папка может быть любой. Далее добавим новый виджет в настройки, как мы помним, у нас там уже есть один виджет из примера выше, поэтому сейчас настройки приобретут следующий вид:
{
"widgets": [
{
"url": "src/factories/pieChart.js",
"class": "PieChart",
"name": "user.piewithvalues",
"type": "chart"
},
{
"url": "src/factories/ SpiderWeb.js",
"class": " SpiderWeb Chart",
"name": "user.spiderweb",
"type": "chart"
}
Теперь добавив этот виджет в старом портале мы увидим его и на новом именно в том виде как и хотели.
Статья получилась жутко затянутой надеюсь информация будет полезна, и в следующий раз можно будет приступить к добавлению виджета не имеющего ничего общего с библиотекой Highcharts, это будет намного интересней, и вы увидите какие возможности перед вами может открыть DeepSee при правильном использовании.
А открытость DeepSeeWeb позволяет сообществу участвовать в разработке проекта, что позволит ему вбирать лучшие идеи. Хотя я за 3 месяца работы, сделал лишь один pull-request, вот такой я жадина!
Для разжигания интереса вот вам скрин, что у меня получилось в качестве первой версии своей работы по BI системе DeepSee.
Из новых интересных возможностей — фильтр по дате (правый угол) и текстовый виджет.
P.S. Простите за отсутствие данных, мы еще не решили что показывать, а что скрывать, поэтому прячем все.
→ Ссылка на DeepSeeWeb