Расширение Qlik Sense: встроенное средство выбора диапазона дат
Если вы хотите иметь «Средство выбора диапазона дат» в своем отчете Qlik Sense, почти всегда рекомендуется использовать расширение qlik-date-picker
, которое было добавлено в qlik-dashboard-bundle
.
Однако в определенных ситуациях это расширение не работает в соответствии с требованиями клиентов. Например, клиент хочет иметь Qlik Sense Mashup, в котором средство выбора диапазона дат является одним из основных фильтров на странице, поэтому оно всегда должно быть видно. В частности, вместо того, чтобы позволять пользователям многократно нажимать кнопку для отображения календарного представления (предположим, что цель отчета - часто проверять показатели с разными диапазонами дат), он должен отображаться в строке, что он всегда присутствует для выбора другой даты. диапазоны.
К сожалению, это практически невозможно с текущим qlik-date-picker
в комплекте. Фактически, это модифицированная версия популярной библиотеки JavaScript daterangepicker.js
. Я посетил его репозиторий на GitHub. Многие разработчики просили добавить функции встроенного отображения в средства отслеживания проблем, но похоже, что автор не совсем заинтересован в этом.
Поэтому мне нужно «взломать» включенную библиотеку JS, чтобы внести такие изменения. После нескольких раундов я обнаружил, что этого делать не стоит по нескольким причинам:
- Файл JS, включенный в это расширение Qlik Sense, полностью адаптирован для использования Qlik Sense, и вся структура была изменена и полностью отличается от исходной библиотеки JS.
- Файл JS был уменьшен, что затрудняет его изменение из-за плохой читаемости.
- Библиотека никогда не предназначалась для отображения встроенного календаря. Так что это не проблема, которую можно решить несколькими строками кода.
- События
show
иhide
были тщательно настроены, что потенциально может вызвать проблемы, даже если оно будет изменено для отображения в строке. Например, если средство выбора используется в представлении модели или во всплывающем представлении на веб-странице, вложенные функции обратного вызова действительно сложно отлаживать и обслуживать.
Исходя из всех вышеперечисленных требований и существующих ограничений, я решил разработать автономное расширение Qlik Sense для реализации этой функции. назовем это qlik-date-picker-inline
.
Создать расширение Qlik Sense
Перейдите на dev-hub
рабочего стола или сервера Qlik Sense, щелкните «Редактор расширений» в левой навигационной панели или «Создать новое расширение» в главном окне.
Введите имя расширения и выберите «Базовый шаблон визуализации». Затем нажмите «Создать и отредактировать».
Вы можете использовать любые инструменты IDE, которые предпочитаете, или просто использовать веб-редактор в dev-hub. Лично я предпочитаю код Microsoft VS. Итак, я открою папку расширения из моего кода VS.
Однако важно иметь в виду, что добавление ссылочного файла (JS, CSS и т. Д.) Непосредственно с помощью инструментов IDE или копирование / перемещение в папку расширения НЕ будет работать! Когда мы добавляем необходимые зависимости, такие как файл JS библиотеки, мы должны создать файл в Qlik Sense Extension Editor, а затем скопировать вставку кода в созданный файл.
Здесь мы выбрали библиотеку под названием Lightpick, в которую нужно включить 3 файла. Файл JS, файл CSS и собственная зависимость moment.js. На снимке экрана ниже показан пример добавления lightpicker.js, и процедуры точно такие же для двух других файлов.
Чтобы исходный код библиотеки можно было скопировать и вставить, перейдите в исходный репозиторий GitHub.
Принятие библиотеки JS с помощью Qlik Sense
Qlik Sense использует модули define
и require
для включения зависимостей. Нам нужно добавить правильный путь к библиотеке, а иногда даже изменить саму библиотеку, если ей нужна собственная зависимость. В нашем случае ему действительно нужен moment.js, поэтому нам нужно его изменить.
Во-первых, перейдем к qlik-date-picker-inline.js
, чтобы добавить файлы библиотеки.
define( [ "qlik", "./lightpick", "./moment", "css!./lightpick.css"], function (qlik, Lightpick, moment) { ...
Обратите внимание, что нам нужно игнорировать .js
расширения при их включении с помощью define
. Кроме того, мы используем префикс css!
, чтобы сообщить Qlik Sense, что это файл CSS, а не файл JS.
Затем перейдем к lightpick.js
, чтобы изменить ссылку на зависимость.
Первоначально заводская функция выглядит так
(function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Make globaly available as well define(['moment'], function (moment) { return factory(moment); }); } ...
define(['moment']...
не будет работать в Qlik Sense. Давайте изменим его на define(['./moment']
, что является относительным путем. Итак, если вы предпочитаете создать папку lib
в своем расширении, вы также можете изменить относительный путь на ./lib/moment
. Но здесь я просто положу его в корневую папку.
Протестируйте встроенное средство выбора диапазона дат
Автор этой библиотеки lightpick подготовил неплохую документацию по использованию этой библиотеки. Пожалуйста, обратитесь к этому репозиторию GitHub с множеством демонстраций.
Перейдем к qlik-date-picker-inline.js
и поместим следующий код в paint
функцию.
paint: function ($element) {
console.log('in paint')
//add your rendering code here
$element.html( '<input type="hidden" id="datepicker"/>' );
var picker = new Lightpick({
inline: true,
singleDate: false,
numberOfMonths: 2,
field: document.getElementById('datepicker'),
onSel
ect: function(start, end){}
});
//needed for export
return qlik.Promise.resolve();
}
Здесь нам нужен тег input
для работы lightpick
. Однако на самом деле мы не хотим, чтобы Qlik Sense отображал этот ввод. Итак, мы можем установить type
на hidden
.
Кроме того, мы хотим установить inline
в true
, чтобы отображать средство выбора в строке, а также singleDate
, установленное в false
, чтобы убедиться, что он выбирает диапазон, а не одну дату. список настраиваемых элементов можно найти в README репозитория GitHub.
Давайте добавим расширение в панель управления Qlik Sense.
Оно работает!
Добавить поле даты в виджет расширения
Чтобы средство выбора даты действительно работало с Qlik Sense, нам нужно добавить поле ввода, чтобы пользователи могли заполнить измерение даты.
В блоке return
функции расширения нам нужно сначала определить initialProperties
. Здесь мы просто определяем qListObjectDef
с qInitialDateFetch
, потому что нам нужно только одно поле. Кроме того, мы задаем высоту 1e4
для списка, который буквально позволяет около 110 лет с последовательными днями в измерении даты.
initialProperties: { version: 1.0, qListObjectDef: { qInitialDataFetch: [{ qWidth: 1, qHeight: 1e4 }] } },
Затем мы определяем, что items object
in definition object
содержит только одно поле ввода для поля даты. definition object
in Qlik Sense Extension можно использовать для определения accordion
меню с правой стороны.
definition: { type: "items", component: "accordion", items: { dimension: { type: "items", label: "Date Field", ref: "qListObjectDef", min: 1, max: 1, items: { dimension: { type: "string", expression: "optional", expressionType: "dimension", ref: "qListObjectDef.qDef.qFieldDefs.0", label: "Input Date Field" } } }, appearance: { uses: "settings" } } },
После этого мы сможем ввести поле даты расширения.
Если хотите, теперь вы можете попробовать вывести объект layout
, чтобы увидеть выбранные даты.
paint: function ($element, layout) { console.log(layout) ....
Внедрить функцию выбора даты
Теперь нам нужно сообщить Qlik Sense, что пользователь выбрал диапазон дат, когда диапазон дат фактически выбран в средстве выбора. В определении Lightpick
нам нужно реализовать объект onSelect
.
var self = this var allDates = layout.qListObject.qDataPages[0].qMatrix onSelect: function(start, end){ if (start && end) { // Convert start & end moment to date string var startDateString = start.format('D/M/YYYY') var endDateString = end.format('D/M/YYYY') // Populate all the dates in between of the range toBeSelected = [] allDates.forEach(qDate => { if (checkDateInBetween(moment(qDate[0].qText, 'D/M/YYYY'), startDateString, endDateString)) { toBeSelected.push(qDate[0].qElemNumber) } }); console.log(toBeSelected) // Select the dates if (toBeSelected.length > 0) { self.backendApi.selectValues(0, toBeSelected, false) } } }
Здесь мы сначала получаем все даты из объекта layout
. Затем зациклируйте все даты, чтобы проверить, попадают ли они в выбранный диапазон. Если да, вставьте его в массивtoBeSelected
.
Теперь, если мы выберем диапазон 1/1/2014
- 12/1/2014
, API бэкэнд Qlik должен быть обновлен, и мы сможем увидеть выбор на панели выбора.
Реализуйте «setDateRange» на основе существующего выбора.
Теперь у нас все еще есть проблема. После того, как мы выбрали диапазон дат, он не сохраняется в средстве выбора. Кроме того, если у нас уже есть диапазон дат, выбранный в Qlik Sense, это не отразится на средстве выбора. Это связано с тем, что Qlik Sense будет обновлять расширение после каждого изменения пользователем. Итак, нам нужно позволить расширению определять, есть ли выбранный диапазон, и программно устанавливать его в сборщике.
// Get current selection if there are any var selectedDates = [] allDates.forEach(qDate => { if (qDate[0].qState == "S") { selectedDates.push(moment(qDate[0].qText, "D/M/YYYY")) } }); if (selectedDates.length > 0) { selectedDates = selectedDates.sort((a,b) => a-b) minSelectDate = selectedDates[0] maxSelectDate = selectedDates[selectedDates.length - 1] picker.setDateRange(minSelectDate, maxSelectDate, true) picker.gotoDate(maxSelectDate.subtract(1, 'month')) }
Здесь важно установить 3-й параметр setDateRange
на false
. Это предотвращает запуск функции setDateRange
события onSelect
. Если мы этого не сделаем, setDateRange
вызовет событие onSelect
средства выбора, в котором есть backendApi.selectValues()
, и это приведет к обновлению всего расширения и повторному вызову setDateRange
.
Кроме того, не забудьте вызвать функцию gotoDate
в конце, чтобы убедиться, что средство выбора интерактивно перейдет к выбранной дате. Это очень важно, если у вас есть другие виджеты, которые могут выбирать даты.
OK! Теперь мы сделали это Qlik Sense Extension. Фрагменты кода, вероятно, сложно связать вместе, чтобы получить полную картину. Но не волнуйтесь, вы можете найти полный исходный код в моем репозитории на GitHub:
Если вы считаете, что мои статьи полезны, рассмотрите возможность присоединения к Medium Membership, чтобы поддержать меня и тысячи других авторов! (Щелкните ссылку выше)
Ресурсы:
Lightpick: https://wakirin.github.io/Lightpick/
Moment.js: https://momentjs.com
Документация для разработчиков Qlik Sense: https://help.qlik.com/en-US/sense-developer/April2019
Репозиторий GitHub: https://github.com/qiuyujx/qlik-date-picker-inline