Содержание урока по Qlik Sense
Создание расширенного расширения визуализации с использованием Qlik Nebula.js и D3.js
В моем последнем посте я рассказал о надежных возможностях API-интерфейсов Qlik Sense (QS) для создания готовых визуальных метафор и способах их интеграции в экосистему Qlik. Естественным выбором для разработчиков при создании расширений QS на протяжении многих лет был Extension API , в основном использующий ванильный JavaScript, jQuery и AngularJS.
API расширений состоит из методов и свойств, используемых для создания пользовательских расширений визуализации.
Введите… Решение Qlik Sense с открытым исходным кодом — Nebula.js !
Nebula.js — это набор библиотек и API-интерфейсов JavaScript, не зависящих от продукта и платформы, которые помогают разработчикам интегрировать визуализации и гибридные приложения поверх Qlik Associative Engine в QS Desktop, QS Enterprise для Windows и SaaS-редакции Qlik Sense. Это руководство специально относится к выпуску QS SaaS. Nebula.js предлагает разработчикам альтернативу API возможностей, которые исторически использовались для создания гибридных приложений. В этом руководстве основное внимание будет уделено разработке новой визуализации на основе пользовательского сценария с использованием Nebula.js и сторонней библиотеки визуализации D3.js. Наша цель — понять, как мы можем использовать Nebula.js для создания объекта расширения QS и реализации готовых возможностей визуализации в рамках SaaS .Платформа. В этом руководстве не делается акцент на части программирования D3.js, но обсуждается мотивация визуализации.
Сценарий пользователя. У организации, использующей Qlik Sense, есть новое требование по разработке визуального представления для понимания многомерного многомерного набора данных для своей организации. Их набор данных состоит из числовых значений, и они хотят сравнить несколько объектов вместе, чтобы проанализировать отношения между ними. Основываясь на этих требованиях, их инженер по визуализации данных представляет им «график с параллельными координатами».
Итак, что такое график с параллельными координатами?
Графики с параллельными координатами (PCP) доказали свою эффективность при эффективной визуализации многомерных наборов данных высокой размерности. В параллельных координатах каждый объект представлен в виде вертикальных полос, а значения нанесены на график в виде серии линий, соединенных по каждой оси. Их преимущество в том, что вертикальные полосы (функции) могут иметь собственный масштаб, поскольку каждая функция работает с разными единицами измерения. PCP дает представление о конкретных скрытых закономерностях в данных, таких как сходства, кластеры и т. д., и позволяет проводить более простой сравнительный анализ.
Основываясь на требованиях, давайте начнем с создания расширения QS с помощью Nebula.js .
Предпосылки :
- Node.js (версия 10 или новее)
- Терминал (например, Git Bash в Windows или Terminal в Mac)
- IDE на ваш выбор, например, VS Code.
- Существующая веб-интеграция или возможность ее создания в вашем арендаторе (особенно это относится к выпуску QS SaaS).
- Приложение Qlik Sense с данными.
Шаг 1: Используйте интерфейс командной строки nebula.js для импорта необходимых пакетов. Команда помещает проект в папку /hello со следующей структурой:
- /src
- index.js — основная точка входа этой визуализации
- object-properties.js — свойства объекта, хранящиеся в приложении.
- data.js — конфигурация данных
- /test – Интеграционные тесты
- package.json
Команда:
npx @nebula.js/cli create hello --picasso none
Шаг 2: Запустите сервер разработки, выполнив:
cd hello npm run start
Команда запускает локальный сервер разработки и открывает http://localhost:8080 в вашем браузере. Преимущество наличия сервера разработки с Nebula.js заключается в том, что он предоставляет интерактивный способ тестирования и редактирования вашего расширения без необходимости итеративного развертывания в QS каждый раз, когда вносится новое изменение.
Шаг 3: Настройте структуру данных.
Визуализации в QS основаны на определении гиперкуба (qHyperCubeDef). Следовательно, любой новый визуальный объект, который мы хотим добавить в экосистему QS, должен иметь определенную структуру данных. В Nebula.js у нас есть файл object-properties.js, который позволяет определить структуру нашего объекта.
const properties = { showTitles: true, qHyperCubeDef: { qInitialDataFetch: [{ qWidth: 30, qHeight: 200 }], } }
Нам также необходимо установить цель данных в файле data.js, чтобы мы ссылались на правильное определение гиперкуба (важно отметить, если у вас есть несколько объектов qHyperCubeDef).
export default { targets: [ { path:'/qHyperCubeDef', } ], };
Шаг 4: Разработка расширения визуализации с использованием Nebula.js и D3.js.
Специальный код QS Nebula.js:
Теперь, когда у нас все готово, мы начинаем разработку нашего расширения с пользовательским объектом визуализации, используя файл index.js из нашего проекта.
Обратите внимание, что Nebula.js и его основной пакет @nebula.js/stardust построены на концепции настраиваемых хуков . Это может показаться знакомым людям, работающим с React.js . Хуки — это концепция, которая делает упор на повторно используемые составные функции, а не на классические объектно-ориентированные классы и наследование. Основные хуки, от которых мы зависим при разработке нашего объекта расширения, описаны ниже:
Метод, который помогает нам визуализировать наш объект визуализации, — это функция component(). Функция component() выполняется каждый раз, когда что-то, связанное с рендерингом объекта, изменяется, например, тема, модель данных, выборка данных, состояние компонента и т. д. Эту функцию можно сравнить с функцией paint() в Extension API.
Чтобы отобразить наши данные, нам сначала нужно получить доступ к макету через хук useLayout, а затем использовать его в сочетании с хуком useEffect. qDataPages [0].qMatrix гиперкуба содержит все данные (измерения и меры), используемые в среде QS, и нам нужно будет передать эти данные в нашу визуализацию на основе D3.js.
component() { const element = useElement(); const layout = useLayout(); useEffect(() => { var qMatrix = layout.qHyperCube.qDataPages[0].qMatrix; } }
Чтобы увидеть значения данных и понять структуру qHyperCube , всегда полезно выполнить console.log(layout) . Фрагмент показывает значения, характерные для нашего варианта использования. Каждый раз, когда к нашему объекту расширения добавляется новое измерение или мера, qDataPages[0].qMatrix обновляется этими значениями .
Затем необходимые значения измерения для нашей диаграммы извлекаются из гиперкуба с использованием свойства qText из qDataPages[0].qMatrix, как показано ниже.
var data = qMatrix.map(function (d) { return { PetalLength: d[0].qText, PetalWidth: d[1].qText, SepalLength: d[2].qText, SepalWidth: d[3].qText, Species: d[4].qText, }; });
Наш следующий шаг — определить ширину и высоту объекта визуализации и зафиксировать его идентификатор . Мы будем использовать этот идентификатор для привязки его к нашему объекту элемента из хука useLayout, как показано ниже:
var width = 1000; var height = 400; var id = "container_" + layout.qInfo.qId; const elem_new = `<div id=${id}></div>`; element.innerHTML = elem_new;
Наконец, мы вызываем функцию D3.js из хука useEffect.
viz(data, width, height, id);
Специальный код D3.js:
Функция viz() содержит весь наш код D3.js, который позволяет нам рисовать график в параллельных координатах. Во-первых, нам нужно добавить SVG к <div> , содержащему идентификатор нашего объекта QS, как показано ниже.
var svg = d3 .select("#" + id) .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr( "transform", "translate(" + margin.left + "," + margin.top + ")" );
Затем мы получаем все измерения, кроме Species , для построения наших осей x и y.
var dimensions = Object.keys(data[0]).filter(function (d) { return d != "Species"; }); var y = {}; for (var i in dimensions) { var name_new = dimensions[i]; y[name_new] = d3.scaleLinear().domain([0, 8]).range([height, 0]); } var x = d3.scalePoint().range([0, width]).domain(dimensions);
Чтобы нарисовать линии для нашего графика с параллельными координатами, нам нужно построить функцию пути , которая будет брать строку из нашего qHyperCube и возвращать координаты x и y линии.
function path(d) { return d3.line()( dimensions.map(function (p) { return [x(p), y[p](d[p])]; }) ); }
И, наконец, мы связываем все с нашим SVG, как показано ниже:
svg .selectAll("myPath") .data(data) .enter() .append("path") .attr("class", function (d) { return "line " + d.Species; }) .attr("d", path) .style("fill", "none") .style("stroke", function (d) { return color(d.Species); }) .style("opacity", 0.5);
Шаг 5: Развертывание расширения.
Чтобы создать наш проект, мы используем приведенную ниже команду, чтобы сгенерировать все файлы, доступные для чтения QS, и поместить их в папку /hello-ext. Затем эту папку можно сжать (.zip) и загрузить в раздел расширений консоли SaaS для использования в среде QS.
npm run sense
Dashboard:
Если вы только начинаете работать с Nebula.js, https://qlik.dev — отличное место для ознакомления с основами и подробного изучения связанных функций.
Исходный код этого проекта доступен по адресу: https://github.com/dipankarqlik/Nebula