Перечень шагов для выполнения
Сначала загрузите код D3, откройте его в блокноте (notepad++) и попробуйте перевести его в расширение Qlik. Это может разозлить вас, так как это не сработает.
Поэтому я решил сделать свое расширение по частям, чтобы постепенно переварить все и узнать, что делает каждый бит и как он взаимодействует с Qlik.
Таким образом, вот перечень шагов, которым нужно следовать (в зависимости от ваших существующих знаний):
- Пройдите курс по коду Javascript: JavaScript | Codecademy
- Получите знания по css из w3schools. Учебник по JavaScript.
- Поработайте с превосходными примерами от barryharmsen по учебникам Расширение QlikView, документация и примеры – исправление Qlik! Исправление Qlik!
- Научитесь любить шаблон расширения от bmz на шаблонах расширения объектов
- Внесите мои настройки в шаблон расширения (см. Прилагаемый файл)
- Сойдите с ума от D3
Когда вы проработаете шаги 1-3 и переварите шаг 4, тогда наступит момент, где это руководство пойдет легко.
Предварительное чтение шаблона расширения Script.js
Прежде чем мы что-нибудь попробуем, давайте рассмотрим этот шаблон расширения. Если вы посмотрите на код bat, то вас могут напугать % £ $, но на самом деле Брайан хорошо это объясняет, а я расширил это объяснение ниже небольшими изменениями, там, где я думаю, что необходимо небольшое объяснение.
ОК, поэтому, предположим, что у вас открыт файл Script.js, давайте посмотрим.
Требуемое имя, путь и файлы
Первые две строки просто установили некоторые простые переменные имени и пути расширения
varextensionName = «_Adams Template File»;
//remember to also update this in definition.xml
varextensionPath=Qva.Remote+»?public=only&name=Extensions/» + extensionName +»/»;
Я немного изменил шаблон, поэтому вам нужно только ввести имя добавочного номера в одном месте, как вы увидите в моих комментариях, потому что я потратил часы на поиск простого решения (которое я пропустил во время создания).
Это также означает, что, когда мы добавляем расширение, нам больше не нужно вводить имя.
Следующий шаг — загрузить дополнительные файлы JavaScript, которые вы можете захотеть, и снова я изменил это, так как мне не нравилось вложение функций, я думаю, что это просто читается немного проще:
functionextensionInit() {
var jsfiles = [];
//load jquery if required
if (typeof jQuery == ‘undefined’) {
push(extensionPath + «jquery.js»);
}
//Pushing any other js files
push(extensionPath + «d3.v3.min.js»);
//jsfiles.push(extensionPath + «additionalfileshere.js»);
//now load these and call next function
LoadScript(jsfiles, extensionDone);
} //end extension_Init
Поэтому вместо того, чтобы вставлять функции Qva.LoadScript, мы просто посылаем нужные файлы в массив, а затем вызываем его.
Разъяснение кода:
Просто объявите функцию, а затем установите переменную ([] означает пустой массив), чтобы удерживать имена скриптов:
functionextensionInit() {
var jsfiles = [];
Это стандартный код, чтобы проверить, загружен ли jQuery или нет, и если нет, то он загружает это как первые элементы в наш массив.
if(typeof jQuery == ‘undefined’) {
push(extensionPath + «jquery.js»);
}
Затем мы можем просто повторить push-строку для любых других файлов, которые мы хотим загрузить. В этом случае мы хотим загрузить сценарий d3.
push(extensionPath + «d3.v3.min.js»);
Наконец, мы просто скажем qlikview загрузить файлы, а затем вызвать следующую функцию для запуска, которая является функцией расширения.
LoadScript(jsfiles, extensionDone);
} //end extension_Init
Затем большой кусок смущающего кода
Игнорируйте его! Я выяснил, что в основном требуется включить в расширении событие щелчка. Я просто взял его, как написано, и оставил без изменений.
if(Qva.Mgr.mySelect == undefined) {
Mgr.mySelect = function(owner, elem, name, prefix) {
if (!Qva.MgrSplit(this, name, prefix)) return;
AddManager(this);
this.Element = elem;
this.ByValue = true;
binderid = owner.binderid;
Name = this.Name;
onchange = Qva.Mgr.mySelect.OnChange;
onclick = Qva.CancelBubble;
}
Mgr.mySelect.OnChange = function() {
var binder = Qva.GetBinder(this.binderid);
if (!binder.Enabled) return;
if (this.selectedIndex < 0) return;
var opt = this.options[this.selectedIndex];
Set(this.Name, ‘text’, opt.value, true);
}
Mgr.mySelect.prototype.Paint = function(mode, node) {
this.Touched = true;
var element = this.Element;
var currentValue = node.getAttribute(«value»);
if (currentValue == null) currentValue = «»;
var optlen = element.options.length;
disabled = mode != ‘e’;
//element.value = currentValue;
for (var ix = 0; ix < optlen; ++ix) {
if (element.options[ix].value === currentValue) {
selectedIndex = ix;
}
}
style.display = Qva.MgrGetDisplayFromMode(this, mode);
}
}
Загрузка кода расширения
Здесь загружается основной код, здесь выполняется только одно небольшое изменение, и мы должны использовать переменную имени расширения, которую мы задали в качестве первой строки, вместо того, чтобы повторять ее (исключение ошибки)
AddExtension(extensionName , function(){
Теперь некоторая отладка
Мне очень понравился этот фрагмент кода, спасибо dgudkov обзор BI: Создание расширений в QlikView: некоторые подсказки и советы
Firebug – один из лучших инструментов для отладки, доступен как дополнение Firefox, но с этим небольшим кодом вы можете запустить его в любом браузере, просто нажмите F12, когда вы будете в документе на точке доступа.
Однако он также присутствует в приложении Qlikview. Хотя он не может читать файлы сценариев, чтобы помочь в отладке (Javascript не может загружать локальные файлы), он отображает консоль, которая действительно полезна, поскольку вы можете передавать сообщения console.log() для проверки.
Эту небольшую настройку использует Дмитрий и снова для простоты можно запустить функцию extensionInit внутри нее, поскольку это – функция, от которой все работает.
LoadScript(‘https://getfirebug.com/firebug-lite.js’, function()
extensionInit();
});
Например, я хотел дважды проверить значения в массиве, поэтому использовал следующий код (вы также можете использовать window.alert и т. д.):
log(«your max value is «+d3.max(dataset));
log(«The array values are:»);
for(var b=0; b< dataset.length; b++){
log(dataset[b]);
}
Вот, все готово для вашего приложения:
Шаг1 — Создание базовой диаграммы D3
Итак, давайте построим диаграмму!
Я предполагаю, что вы используете мой шаблон и меняете имя и код между большими маркерами, чтобы показать вам, где разместить свой код. Я также предполагаю, что вы прошли примеры в QlikFix и понимаете, как загружать и запускать расширения и т. д.
Настроить
- Запустите template.qar (вы знаете, что это всего лишь zip с расширением, переименованным в .qar?), чтобы экспортировать его в свою папку расширения, а затем просто создайте копию папки. Давайте назовем его как «01 Базовая диаграмма», но на самом деле вы можете назвать это так, как хотите.
- Откройте XML-определение и создайте ему это описание, затем удалите любой код, который нам не нужен в этом случае. Вы можете просто прокомментировать строки, которые нам не нужны, в этом случае почти все.
<?xmlversion=»1.0″ encoding=»utf-8″?>
<ExtensionObjectLabel=»01 A Basic Chart» Description=»First Chart Extension» PageHeight=»50000″>
<!—<Dimension Label=»Dimension 1″ Initial=»Path» TargetName=»Dimension Name» />—>
<!—<Dimension Label=»Dimension 2″ Initial=»Measure» TargetName=»Dimension Name» />—>
<!—<Measurement Label=»Measure 1″ Initial=»Sum(Measure)»/>—>
<!—Text Label=»Text Box 1″ Type=»text» Expression=»TITLE»/>—>
<!—Text Label=»Checkbox 1″ Type=»checkbox» Initial=»» />—>
<!—Text Label=»selectBox 1″ Type=»select» Select=»select1,select2,select3″
SelectLabel=»selectL1,selectL2,selectL3″ Expression=»selectL3″/>—>
<Initiate Name=»Chart.Title» value=»01 A Basic Chart» />
<Initiate Name=»Caption.Text» Value=»01 A Basic Chart» />
</ExtensionObject>
- Откройте script.js и измените переменную имени вверху.
Быстрый старт
Так выглядит настройка, поэтому давайте наконец начнем с действительно простой диаграммы, которая просто отображает некоторые статические цифры.
Вот код, который мы написали для создания диаграммы, вы можете просто скопировать и вставить это, если хотите, и мы рассмотрим его более подробно ниже.
- Скопируйте и вставьте весь этот код в раздел в шаблоне script.js
Element.innerHTML= ‘<svg class=»chart»></svg>’;
var data = [4, 8, 15, 16, 23, 42];
var width = 420,
barHeight = 20;
var x = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0, width]);
var chart = d3.select(«.chart»)
.attr(«width», width)
.attr(«height», barHeight * data.length);
var bar = chart.selectAll(«g»)
.data(data)
.enter().append(«g»)
.attr(«transform», function(d, i) { return «translate(0,» + i * barHeight + «)»; });
append(«rect»)
.attr(«width», x)
.attr(«height», barHeight-1);
append(«text»)
.attr(«x», function(d) { return x(d); })
.attr(«y»,(barHeight-1) / 2)
.attr(«dy», «.35em»)
.text(function(d) { return d; });
И это все, если вы открываете новый Qvw, включаете веб-представление и добавляете свой объект расширения, у вас должна быть простая диаграмма
Подробный код
Поэтому, чтобы разбить код на более управляемые куски (и помните, что я не проходил предварительного обучения JavaScript здесь, поэтому мои объяснения могут быть базовыми)
Основная настройка
Здесь мы просто скажем, что добавляем svg с классом диаграммы:
Element.innerHTML= ‘<svg class=»chart»></svg>’;
Здесь мы просто добавляем некоторые действительно базовые данные в массив под названием «данные»,
vardata = [4, 8, 15, 16, 23, 42];
Затем просто устанавливаем несколько элементов отображения, поэтому ширина диаграммы и высота столбцов
var width = 420,
barHeight = 20;
Настройте наш диапазон данных
Теперь мы можем получить удовольствие от работы с D3, и первое, что нужно сделать для этого, — отмасштабировать нашу диаграмму. В D3 есть очень умный способ взять «область» и масштабировать её до «диапазона», и я рекомендую прочитать это: d3: масштабы и цвет. | Джером Кукер
Все, что мы здесь делаем, говорит D3, что мы собираемся сделать линейное масштабирование, а затем как мы хотим преобразовать нашу область (в данном случае нашу переменную данных) в диапазон (размер диаграммы). С гистограммой, скорее всего, мы захотим начать масштаб в 0, чтобы мы могли жестко закодировать это, а внешний предел – это максимум нашего набора данных, для которого мы можем использовать удобную функцию d3.max. Затем мы просто скажем «диапазон», который мы хотим сопоставить, в этом случае жестко закодированный в 0, а внешний предел – это ширина нашей диаграммы.
varx = d3.scale.linear()
.domain([0, d3.max(data)])
.range([0, width]);
Добавить диаграмму
Следующим шагом будет добавление нашего объекта диаграммы, что делается очень простым кодом, который не нуждается в каких-либо объяснениях, и единственное, что нужно отметить, это то, что «диаграмма» — это класс, который мы назвали в нашем svg html в первой строке.
varchart = d3.select(«.chart»)
.attr(«width», width)
.attr(«height», barHeight * data.length);
Настройка столбцов
Следующим шагом будет создание данных о столбцах, которые составляют диаграмму. При работе с D3 вы часто будете видеть ссылку «g», но на самом деле это svg-код, и для его понимания, а также понимания того, почему мы используем «transform», можно прочесть этот материал : https://www.dashingd3js.com/svg-group-element-and-d3js
В основном здесь говорится о следующем:
- Объявить переменную панель и сделать её нашей группой данных
- Для каждого элемента данных добавить панель в группу
- Установить для свойства «location» значение 0 (слева), а затем индексное число * высоту столбца вниз (слева вверху)
Таким образом, это в основном показывает нам, где по оси x начнутся столбцы (0), а затем где они начнутся на оси y (в зависимости от номера строки)
varbar = chart.selectAll(«g»)
.data(data)
.enter().append(«g»)
.attr(«transform», function(d, i) { return «translate(0,» + i * barHeight + «)»; });
Вы можете прочесть больше о функции (d, i) в документации d3 api, но в общем: «Если значение является константой, тогда всем элементам присваивается одинаковое значение атрибута, в противном случае, если значение является функцией, то функция оценивается для каждого выбранного элемента (по порядку), передается текущая точка d и текущий индекс i, причем этот контекст является текущим элементом DOM ».
Рисуем прямоугольники
Здесь нам просто нужно сделать данные видимыми! Мы делаем это, создавая панель с использованием прямоугольника. Опять же этот код довольно прямолинейный, просто создаём прямоугольник с шириной, эквивалентной нашей переменной x (которая является «диапазоном», который мы создали из нашей «области») и придаем ему фиксированную высоту, как мы устанавливали ранее, но вычтем единицу от высоты, которая дает нам расстояние между столбцами.
append(«rect»)
.attr(«width», x)
.attr(«height», barHeight-1);
Добавить текст на столбцы
Последний шаг – добавить наш текст для отображения значения, этот код выглядит немного более сложным, но на самом деле он тоже очень прямолинейный. Опять же, мы просто добавляем что-то к нашим объектам столбца, в этом случае – некоторый текст. Затем мы просто устанавливаем атрибуты текста:
- Добавить наш текст в столбец
- Присвоить ему координату x, в этом случае мы хотим сместить ее до конца строки, поэтому нам нужно вернуть длину данных (x), которые мы установили ранее.
- Присвоить ему координату y, которая в этом случае является высотой столбца, а наш разделитель – двумя, что является центром столбца
- Затем мы хотим удостовериться, что элемент остается центрированным независимо от того, какой размер шрифта мы используем, а также убедитесь, что если мы применяем любое вращение, оно вращается вокруг центра текста, а не снизу, поэтому чтобы сделать это мы используем атрибут svg dy (просто согласитесь, что это работает!)
- Наконец, нам нужно прописать наш текст, что в данном случае является просто нашим значением данных
append(«text»)
.attr(«x», function(d) { return x(d) ; })
.attr(«y»,(barHeight-1) / 2)
.attr(«dy», «.35em»)
.text(function(d) { return d; });
Подведем итоги
Таким образом, вы можете видеть, что на самом деле в Qlikview довольно просто добавить диаграмму. Однако в этом случае все, что мы делаем, это используем Qlikview в качестве «браузера» для отображения нашей диаграммы.
Общие ошибки
Я видел это, как правило, забывая изменить имя шаблона
Ссылки
- Шаблон расширения Qlikview от bmz на Object Extension Templates
- Расширенные учебники от barryharmsen на QlikView Extension tutorials, documentation and examples — The Qlik Fix! The Qlik Fix!
- Расширенные советы и подсказки от dgudkov BI Review: Building extensions in QlikView: some hints & tips
- Notepad++ https://notepad-plus-plus.org/download/v6.9.2.html
- Форматирование D3 http://www.jeromecukier.net/blog/2011/08/11/d3-scales-and-color/
- http://www.d3noob.org/2012/12/setting-scales-domains-and-ranges-in.html
- Небольшая заметка по G в svg http://tutorials.jenkov.com/svg/g-element.html and SVG Group Element and D3.js | DashingD3js.com
- Базовая диаграмма D3 https://bost.ocks.org/mike/bar/
- Qlikview SDK QlikView Version 11 SDK | Qlik Community
- Базовый столбец D3 от ajlandry GitHub — wallyflops/d3Graph: Trying to get d3.js working in a QV extension (any graph can be added on later, in theory)
- Документация по API для D3 d3/API.md at master · d3/d3 · GitHub
- Учебный центр по технологиям анализа данных и BI: расписание/запись на учебные курсы, тестирование разработчиков — https://education.biconsult.ru/
- Присоединяйтесь к QUBIC – сообщество профессионалов в области BI! Наши страницы в соц.сетях – расписание учебных курсов, бесплатные учебные материалы, анонсы мероприятий: https://vk.com/club165575964 и https://www.facebook.com/qubicspb
- Неофициальный форум разработчиков QlikView & Qlik Sense Russian forum
- Канал на Youtube – много обучающих видео и записи вебинаров
- Готовые решения “Конструктор финансовой отчетности” и “Анализ продаж”