<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Qlik Sense Extension Nebula.js React - Qlik Sense - Обучение, учебник, онлайн курс</title>
	<atom:link href="https://qliksense.ivan-shamaev.ru/tag/qlik-sense-extension-nebula-js-react/feed/" rel="self" type="application/rss+xml" />
	<link>https://qliksense.ivan-shamaev.ru/tag/qlik-sense-extension-nebula-js-react/</link>
	<description>Qlik Sense на русском языке. Пошаговые уроки для изучения Клик Сенс</description>
	<lastBuildDate>Sat, 12 Feb 2022 07:47:24 +0000</lastBuildDate>
	<language>ru-RU</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.1</generator>

<image>
	<url>https://qliksense.ivan-shamaev.ru/wp-content/uploads/2018/07/QlikSense_ICON2-150x150.png</url>
	<title>Qlik Sense Extension Nebula.js React - Qlik Sense - Обучение, учебник, онлайн курс</title>
	<link>https://qliksense.ivan-shamaev.ru/tag/qlik-sense-extension-nebula-js-react/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Как создать Qlik Sense Extension с помощью Nebula.js и React</title>
		<link>https://qliksense.ivan-shamaev.ru/build-a-qlik-sense-extension-with-nebula-js-react/</link>
					<comments>https://qliksense.ivan-shamaev.ru/build-a-qlik-sense-extension-with-nebula-js-react/#respond</comments>
		
		<dc:creator><![CDATA[qliksense-expert]]></dc:creator>
		<pubDate>Sat, 12 Feb 2022 06:22:49 +0000</pubDate>
				<category><![CDATA[Уровень 2]]></category>
		<category><![CDATA[Nebula.js React]]></category>
		<category><![CDATA[Qlik Sense Extension Nebula.js React]]></category>
		<category><![CDATA[Qlik Sense Extension with Nebula.js + React]]></category>
		<guid isPermaLink="false">https://qliksense.ivan-shamaev.ru/?p=2708</guid>

					<description><![CDATA[<p>Обзор В этой серии руководств мы собираемся создать расширение Qlik Sense с использованием Nebula.js и React, используя Recharts библиотеки построения диаграмм React. Recharts — это компонуемая библиотека диаграмм компонентов React, созданная на основе D3. Вы можете найти домашнюю страницу библиотеки здесь . В частности, мы собираемся создать расширение диаграммы с областями на основе некоторых<a class="moretag" href="https://qliksense.ivan-shamaev.ru/build-a-qlik-sense-extension-with-nebula-js-react/"> Читать дальше&#8230;</a></p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/build-a-qlik-sense-extension-with-nebula-js-react/">Как создать Qlik Sense Extension с помощью Nebula.js и React</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Обзор</h1>
<p><span>В этой серии руководств мы собираемся создать расширение Qlik Sense с использованием Nebula.js и React, используя Recharts библиотеки построения диаграмм React. Recharts — это компонуемая библиотека диаграмм компонентов React, созданная на основе D3. Вы можете найти домашнюю страницу библиотеки </span><a class="au kj" href="https://recharts.org/en-US" rel="noopener ugc nofollow" target="_blank"><span>здесь</span></a><span> .</span></p>
<p><span>В частности, мы собираемся создать расширение диаграммы с областями на основе некоторых данных о COVID-19. Я знаю, что это не супер оригинально, но он научит вас основам создания расширений в Nebula и React.</span></p>
<h1>Что вы узнаете</h1>
<ul>
<li><span>Как начать создавать расширения Qlik Sense с помощью Nebula.js и React</span></li>
<li><span>Основы хуков React</span></li>
<li><span>Библиотека графиков Recharts</span></li>
</ul>
<h1><span>Что вам нужно</span></h1>
<ul>
<li><span>Qlik Sense Desktop или Qlik Sense Business Cloud</span></li>
<li><span>Node и NPM, установленные на вашем компьютере, и редактор кода</span></li>
<li><span>Доступ к нашему стартовому проекту Nebula React доступен здесь: </span><a class="au kj" href="https://github.com/datalitlearning/nebula-react-starter" rel="noopener ugc nofollow" target="_blank"><span>https://github.com/datalitlearning/nebula-react-starter .</span></a></li>
</ul>
<h1>Проект github Nebula — React</h1>
<p><span>Загрузите стартовый проект Nebula — React с Github и запустите пользовательский интерфейс Nebula.js.</span></p>
<p><span>Мы создали стартовый проект, чтобы избежать головной боли при настройке. Это тесно связано с примером React на странице github Nebula.js. Чтобы начать работу с ним, перейдите к: <a href="https://github.com/datalitlearning/nebula-react-starter" target="_blank" rel="noopener">https://github.com/datalitlearning/nebula-react-starter</a></span></p>
<p><span>и либо клонируйте репо, либо загрузите. </span><span>Затем откройте папку с выбранным вами редактором кода и в терминале перейдите в корень вашего проекта и запустите…</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">npm i
npm run start</pre>
<p><span>Это запустит пользовательский интерфейс, в котором вы можете ввести свои учетные данные сайта Qlik Sense и подключиться к своему сайту. Он должен выглядеть примерно так, как показано ниже:</span></p>
<p>Подключение к вашему сайту Qlik Sense с помощью Nebula.js</p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_1.png"><img fetchpriority="high" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_1.png" alt="" width="1400" height="592" class="aligncenter size-full wp-image-2711" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_1.png 1400w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_1-300x127.png 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_1-1024x433.png 1024w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_1-768x325.png 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></a></p>
<p><span>Если у вас возникли проблемы с подключением к вашему сайту, щелкните знак вопроса, чтобы получить помощь (рядом с пунктом «Подключиться </span><strong class="jn hr"><span>к</span></strong><span> движку» в пользовательском интерфейсе), вам необходимо передать URL-адрес Websocket для подключения к вашему сайту Qlik.</span></p>
<p><span>После этого выберите приложение, и запустится среда разработки Nebula.js! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></span></p>
<blockquote><p><span>Обратите внимание, что в этом руководстве мы будем использовать данные COVD </span><span>-19. Я предварительно загрузил эти данные в qvf-файл, который можно найти в репозитории руководства на GitHub.</span></p></blockquote>
<p><span>Теперь ваша среда разработки nebula должна работать на </span><a class="au kj" href="http://localhost:8000/" rel="noopener ugc nofollow" target="_blank"><span>http://localhost:8000</span></a><span> и, по сути, представляет собой упрощенный пользовательский интерфейс Qlik, который вы можете использовать для разработки своего расширения. При первом запуске вы получите бесконечно работающий счетчик, который выглядит примерно так:</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_2.png"><img decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_2.png" alt="" width="1400" height="570" class="aligncenter size-full wp-image-2712" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_2.png 1400w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_2-300x122.png 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_2-1024x417.png 1024w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_2-768x313.png 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></a></p>
<p><span>Не идеально. Nebula.js ищет ваше скомпилированное расширение, но пока ничего не может найти. Давайте исправим это, открыв </span><strong class="jn hr"><span>новое</span></strong><span> окно терминала и перейдя в корень вашего проекта туманности…</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">cd nebula-react-starter</pre>
<p>далее запускаем сборку</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">npm run build</pre>
<p><span>Ура, теперь мы должны увидеть наше расширение в пользовательском интерфейсе Nebula.js…</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_3.png"><img decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_3.png" alt="" width="1400" height="610" class="aligncenter size-full wp-image-2713" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_3.png 1400w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_3-300x131.png 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_3-1024x446.png 1024w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_3-768x335.png 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></a></p>
<p><span>Теперь мы запускаем наш сервер разработки ( </span><em class="mm"><span>через npm run start</span></em><span> ) и перекомпилируем наше расширение при внесении изменений ( </span><em class="mm"><span>через npm run build</span></em><span> ).</span></p>
<p><span>Вы также заметите, что у нас есть новая папка </span><strong class="jn hr"><em class="mm"><span>dist</span></em></strong><span> в наших файлах проекта, она содержит наш скомпилированный код расширения, который подбирает nebula.</span></p>
<h1><span>Проверка файлов проекта</span></h1>
<p><span>Прежде чем мы углубимся в программирование, давайте просмотрим файлы проекта, чтобы у вас было понимание кода:</span></p>
<p><strong class="jn hr"><span>data.js:</span></strong><span> содержит цель данных. Цель данных — это способ определить, где находятся динамические HyperCubeDef в свойствах универсального объекта. Для каждого целевого объекта данных вы можете указать дополнительные сведения, такие как максимальное/минимальное количество измерений и показателей.</span></p>
<p><strong class="jn hr"><span>extDefinition.js</span></strong><span> : он будет содержать определение нашей панели свойств, но пока должен быть пустым объектом.</span></p>
<p><strong class="jn hr"><span>object-properties.js</span></strong><span> : свойства нашего расширения, включая выборку данных HyperCube и те, которые мы хотим изменить с помощью нашей панели свойств.</span></p>
<p><strong class="jn hr"><span>root.jsx</span></strong><span> : это точка входа в реакцию. Мы экспортируем функцию </span><strong class="jn hr"><em class="mm"><span>рендеринга</span></em><span> </span></strong><span>, которая содержит метод рендеринга React DOM. Он отображает JSX в </span><strong class="jn hr"><em class="mm"><span>переменную элемента</span></em></strong><span> , которая передается в функцию при вызове в index.js.</span></p>
<p><strong class="jn hr"><span>index.js</span></strong><span> : здесь отображается наше расширение. Чтобы отобразить что-то, что вам нужно для доступа к элементу DOM, которому назначена визуализация, вы можете сделать это, импортировав </span><code class="ms mt mu mv ma b">useElement</code><span>функцию. Это то, что мы передали нашему методу рендеринга ReactDOM, чтобы отобразить наш JSX в нашем расширении.</span></p>
<h1><span>Начало работы с Recharts</span></h1>
<p><span>Я бы порекомендовал вам прочитать руководство по началу работы с Rechart, </span><a class="au kj" href="https://recharts.org/en-US/guide/getting-started" rel="noopener ugc nofollow" target="_blank"><span>прежде</span></a><span> чем мы начнем, чтобы у вас было некоторое представление о библиотеке.</span></p>
<p><span>Мы начнем с установки библиотеки и импорта компонентов в наш проект.</span></p>
<p><span>В терминальном режиме</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">npm install recharts --save</pre>
<p><span>Затем создайте новый файл с именем </span><strong class="jn hr"><span>App.jsx</span></strong><span> в папке </span><strong class="jn hr"><span>src . </span></strong><span>В этом компоненте мы импортируем и визуализируем диаграмму областей Recharts, используя некоторые фиктивные данные. Нам также нужно импортировать и отображать </span><strong class="jn hr"><span>App.jsx</span></strong><span> в нашем файле </span><strong class="jn hr"><span>root.jsx</span></strong><span> .<br />
</span></p>
<p><span style="color: #ff6600;"><strong>App.jsx</strong></span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import React from 'react';
import { XAxis, YAxis, AreaChart, Area } from 'recharts';

const App = () =&gt; {

  const data = [
    {
      name: 'Page A', uv: 4000, pv: 2400, amt: 2400,
    },
    {
      name: 'Page B', uv: 3000, pv: 1398, amt: 2210,
    },
    {
      name: 'Page C', uv: 2000, pv: 9800, amt: 2290,
    },
    {
      name: 'Page D', uv: 2780, pv: 3908, amt: 2000,
    },
    {
      name: 'Page E', uv: 1890, pv: 4800, amt: 2181,
    },
    {
      name: 'Page F', uv: 2390, pv: 3800, amt: 2500,
    },
    {
      name: 'Page G', uv: 3490, pv: 4300, amt: 2100,
    },
  ];

  return (
    &lt;AreaChart 
      width={500}
      height={400}
      data={data}
    &gt;
      &lt;XAxis dataKey="name" /&gt;
      &lt;YAxis /&gt;
      &lt;Area type="monotone" dataKey="uv" stackId="1" stroke="#8884d8" fill="#8884d8" /&gt;
      &lt;Area type="monotone" dataKey="pv" stackId="1" stroke="#82ca9d" fill="#82ca9d" /&gt;
      &lt;Area type="monotone" dataKey="amt" stackId="1" stroke="#ffc658" fill="#ffc658" /&gt;
    &lt;/AreaChart&gt;
  );
};

export default App;</pre>
<p><span style="color: #ff6600;"><strong>root.jsx</strong></span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import ReactDOM from 'react-dom';
import React from 'react';
import App from './App'

export function render(element) {
  ReactDOM.render(&lt;App /&gt;, element);
}

export function teardown(element) {
  ReactDOM.unmountComponentAtNode(element);
}</pre>
<p><span>Теперь вы должны увидеть диаграмму, отображаемую в нашем пользовательском интерфейсе Nebula. Давайте уделим минуту, чтобы просмотреть код в </span><strong class="jn hr"><span>App.jsx</span></strong><span> и понять следующие шаги для нашего расширения.</span></p>
<p><span>Обратите внимание, переменная данных, которую мы передаем в нашу диаграмму с областями, представляет собой массив объектов. Это отличается от структуры наших данных HyperCube, поэтому нам нужно будет манипулировать данными из нашего HyperCube, прежде чем передавать их в нашу диаграмму позже в этом руководстве.</span></p>
<p><span>Также обратите внимание, как мы отображаем данные на нашей диаграмме. Мы создаем отдельные компоненты </span><strong class="jn hr"><span>Area</span></strong><span> для каждой области рендеринга. Мы хотим, чтобы наше расширение поддерживало несколько мер, поэтому нам нужно будет создать ряд этих компонентов области в зависимости от количества мер, созданных в нашем расширении.</span></p>
<h1><span>Использование данных из нашего HyperCube</span></h1>
<p><span>Теперь мы возьмем данные из нашего гиперкуба и вставим их в нашу диаграмму. Для этого мы будем использовать пользовательские хуки Nebula для получения данных из нашего движка.</span></p>
<blockquote><p><strong><span>Пользовательские хуки</span></strong><span> — это механизм повторного использования логики с отслеживанием состояния.</span></p></blockquote>
<p><span>В </span><strong><span>index.js</span></strong><span> мы уже используем два таких хука: </span><strong><span>useElement</span></strong><span> (который получает HTMLElement, в который визуализируется эта визуализация) и </span><strong class="jn hr"><span>useLayout</span></strong><span> (который получает макет универсального объекта, связанного с этой визуализацией).</span></p>
<p><span>Гиперкуб Qlik находится в макете универсального объекта, поэтому давайте сохраним его в переменной с именем </span><strong><span>hc:</span></strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">const hc = layout.qHyperCube</pre>
<p><span>Теперь ваш </span><strong><span>index.js</span></strong><span> должен выглядеть так, как показано ниже. Вы также можете консольно войти в </span><strong><span>hc</span></strong><span> и посмотреть на объект в консоли. Обратите внимание, что когда вы добавляете в расширение </span><strong class="jn hr"><span>измерения</span></strong><span> и </span><strong class="jn hr"><span>меры</span></strong><span> , данные в </span><strong class="jn hr"><span>hc.qDataPages[0].qMatrix</span></strong><span> обновляются.</span></p>
<p><span style="color: #ff6600;"><strong>index.js</strong></span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useElement, useLayout, useEffect } from '@nebula.js/stardust';
import properties from './object-properties';
import data from './data';
import { render } from './root';

export default function supernova() {
  return {
    qae: {
      properties,
      data,
    },
    component() {
      const el = useElement();
      const layout = useLayout();
      const hc = layout.qHyperCube;

      useEffect(() =&gt; {
        // do some heavy update
      }, [layout]);

      render(el, hc, { layout });
    },
  };
}</pre>
<p><span>Если мы посмотрим на данные </span><strong class="jn hr"><span>HyperCube</span></strong><span> более подробно, то увидим, что он возвращает массив массивов, который содержит объект для каждого измерения/меры, которые мы добавляем в наш </span><strong class="jn hr"><span>HyperCube</span></strong><span> . Нам нужно преобразовать это в структуру данных, которую ожидает Recharts, чтобы заполнить диаграмму.</span></p>
<p><span>Как видно из примера данных выше, нам нужно создать массив объектов, где каждый объект содержит наши данные в парах ключ-значение. Прежде чем мы продолжим и сделаем это, давайте рассмотрим хуки React.</span></p>
<h1><span>Объясняя Nebula / React Hooks</span></h1>
<p><span>Прежде чем мы перейдем к коду, я хочу объяснить использование хуков в проектах Nebula и React. Хуки были представлены в React 16.8 и позволяют нам использовать состояние и другие функции React в функциональных компонентах.</span></p>
<p><span>Хуки имеют ряд преимуществ, включая упрощение повторного использования логики с сохранением состояния между компонентами и упрощение нашего кода React (нам больше не нужно использовать компоненты класса!)</span></p>
<p><span>Библиотека Nebula.js создала реализацию в стиле хуков для реализации повторно используемой логики.</span></p>
<blockquote><p><span>В то время как реализация Nebula полностью настраиваема с помощью пользовательских хуков, концепция и правила очень похожи, настолько, что вы можете прочитать </span><a class="au kj" href="https://reactjs.org/docs/hooks-intro.html" rel="noopener ugc nofollow" target="_blank"><span>документацию по хукам React</span></a><span> , чтобы понять, как использовать собственные хуки stardust.</span></p></blockquote>
<p><span>На самом деле, Nebula.js поставляется со своими собственными хуками </span><code class="ms mt mu mv ma b">useState</code><span>&amp; </span><code class="ms mt mu mv ma b">useEffect</code><span>, которые выполняют те же функции, что и собственные хуки React. Все пользовательские хуки в библиотеке Nebula можно найти </span><a class="au kj" href="https://qlik.dev/apis/javascript/nebulajs-stardust" rel="noopener ugc nofollow" target="_blank"><span>здесь</span></a><span> (с префиксом </span><strong class="jn hr"><span>use</span></strong><span> ).</span></p>
<h1><span>Вернемся к нашему коду..</span></h1>
<p><span>Чтобы манипулировать нашими данными из HyperCube, нам нужно использовать </span><code class="ms mt mu mv ma b">useEffect</code><span>хук Nebula.js.</span></p>
<blockquote><p><span>Переданная функция </span><code>useEffect</code><span>будет запущена после того, как рендеринг будет зафиксирован на экране.</span></p>
<p><span>По умолчанию эффекты запускаются после каждого завершенного рендеринга, но вы можете активировать их </span><a href="https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect" rel="noopener ugc nofollow" target="_blank"><span>только при изменении определенных значений</span></a><span> .</span></p></blockquote>
<p><span>В этом случае мы будем запускать функцию, которая перебирает наш HyperCube и реструктурирует данные.</span></p>
<p><strong class="jn hr"><span>Для начала мы собираемся принудительно выбрать одно измерение и две меры в нашем расширении</span></strong><span> . На данный момент это упростит код, и мы вернемся к этому в следующем руководстве.</span></p>
<p><span>Мы можем установить это в нашем файле </span><strong class="jn hr"><span>data.js</span></strong><span> , который теперь должен выглядеть следующим образом:</span></p>
<p><span style="color: #ff6600;"><strong>data.js</strong></span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">export default {
  targets: [{
    path: '/qHyperCubeDef',
    dimensions: {
      min: 1,
      max: 1,
    },
    measures: {
      min: 2,
      max: 2,
    },
  }]
};</pre>
<p><span>Мы также собираемся добавить следующий код в раздел </span><strong class="jn hr"><span>компонентов нашей функции </span></strong><span></span><strong class="jn hr"><span>supernova</span></strong><span> в нашем файле </span><strong class="jn hr"><span>index.js</span></strong><span> .</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">// state to store our data used in our chart
const [seriesData, setSeriesData] = useState([]);

//state to store our dimension name
const [dimKey, setDimKey] = useState([]);

//state to store our measure names
const [measKeys, setMeasKeys] = useState([]);

//Array that we will populate with restructured data
const series = [];</pre>
<p><span>Мы создаем 3 набора начального состояния для хранения:</span></p>
<ul>
<li><span>Реструктурированные данные, которые мы передадим на нашу диаграмму</span></li>
<li><span>Массив, содержащий имя нашего измерения</span></li>
<li><span>Массив, содержащий имена наших мер</span></li>
</ul>
<p><span>На данный момент мы будем хранить имена наших измерений и показателей в виде массива, чтобы его было легче расширить, когда мы разрешим больше показателей.</span></p>
<p><span>Далее, в нашем </span><code class="ms mt mu mv ma b"></code><em class="mm">useEffect</em><span>, мы сопоставим наши данные HyperCube и создадим новый массив объектов. Обратите внимание, что в приведенном ниже коде мы сопоставляем </span><strong class="jn hr"><span>hcData</span></strong><span> и помещаем объекты в массив с именем </span><strong class="jn hr"><span>series</span></strong><span> , который содержит данные измерений и измерений в парах ключ-значение.</span></p>
<p><span>Затем мы помещаем эти данные вместе с именами измерений и показателей в состояние (строки 41–43 ниже). Наконец, мы добавляем эти данные в наш метод рендеринга и в </span><strong class="jn hr"><span>root.jsx</span></strong><span> передаем их в наш компонент приложения.</span></p>
<p><strong>index.js</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useElement, useLayout, useEffect, useState } from '@nebula.js/stardust';
import properties from './object-properties';
import data from './data';
import { render } from './root';

export default function supernova() {
  return {
    qae: {
      properties,
      data,
    },
    component() {

      const el = useElement();
      const layout = useLayout();
      
      const [seriesData, setSeriesData] = useState([]);
      const [dimKey, setDimKey] = useState([]);
      const [measKeys, setMeasKeys] = useState([]);
      const hc = layout.qHyperCube;
      const series = [];

      useEffect(() =&gt; {

        const hcData =  hc.qDataPages[0].qMatrix;

        if (hcData.length === 0) return;

        const dim1 = hc.qDimensionInfo[0].qFallbackTitle;
        const meas1 = hc.qMeasureInfo[0].qFallbackTitle;
        const meas2 = hc.qMeasureInfo[1].qFallbackTitle;

        hcData.map(e =&gt; (
          series.push({
            [dim1]: e[0].qText,
            [meas1]: e[1].qText,
            [meas2]: e[2].qText,
          })
        ));

        setDimKey([dim1]);
        setMeasKeys([meas1, meas2]);
        setSeriesData(series);
      }, [layout]);

      render(el, seriesData, dimKey, measKeys, { layout });
    },
  };
}</pre>
<p><span style="color: #ff6600;"><strong>root.jsx</strong></span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import ReactDOM from 'react-dom';
import React from 'react';
import App from './App'

export function render(element, seriesData, dimKey, measKeys) {
  ReactDOM.render(&lt;App data={seriesData} dimKey={dimKey} measKeys={measKeys} /&gt;, element);
}

export function teardown(element) {
  ReactDOM.unmountComponentAtNode(element);
}</pre>
<p><span>Итак, теперь у нас есть все данные, которые нам нужны в </span><strong class="jn hr"><span>App.jsx</span></strong><span> . Теперь мы можем передать это в нашу диаграмму. Если вы помните ранее в этом руководстве, мы заметили, что нам нужно визуализировать компонент </span><strong class="jn hr"><span>AreaChart</span></strong><span> для каждой визуализируемой линии/области. Для этого нам нужно сопоставить наши ключи измерений.</span></p>
<p><span>Мы также создали массив цветов для окрашивания наших компонентов Area.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import React from 'react';
import { XAxis, YAxis, AreaChart, Area } from 'recharts';

const App = ({ data, dimKey, measKeys }) =&gt; {

  const colors = ["#8884d8", "#82ca9d"]

  return (
    &lt;AreaChart 
      width={500}
      height={400}
      data={data}
    &gt;
      &lt;XAxis dataKey={dimKey[0]} /&gt;
      &lt;YAxis /&gt;
      {measKeys.map((m, i) =&gt; (
        &lt;Area type="monotone" dataKey={m} stackId="1" stroke={colors[i]} fill={colors[i]} /&gt;
      ))}
    &lt;/AreaChart&gt;
  );
};

export default App;</pre>
<p><span>Теперь ваше расширение должно выглядеть примерно так, как показано ниже.</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_4.png"><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_4.png" alt="" width="1400" height="592" class="aligncenter size-full wp-image-2714" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_4.png 1400w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_4-300x127.png 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_4-1024x433.png 1024w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_4-768x325.png 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></a></p>
<h1><span>Делаем нашу диаграмму отзывчивой</span></h1>
<p><span>Мы закончим написание кода в части 1 этого руководства, сделав нашу диаграмму адаптивной. К счастью, у Recharts есть хороший и простой пример этого на своем сайте, который можно найти </span><a class="au kj" href="https://recharts.org/en-US/examples/AreaResponsiveContainer" rel="noopener ugc nofollow" target="_blank"><span>здесь</span></a><span> .</span></p>
<p><span>Они предоставляют компонент </span><strong class="jn hr"><span>ResonsiveContainer</span></strong><span> , который мы можем обернуть вокруг нашей диаграммы, чтобы она расширялась до размера своего родительского контейнера. Мы можем импортировать и использовать это в </span><strong class="jn hr"><span>App.jsx</span></strong><span> , как показано ниже.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import React from 'react';
import { XAxis, YAxis, AreaChart, Area, ResponsiveContainer } from 'recharts';

const App = ({ data, dimKey, measKeys }) =&gt; {

  const colors = ["#8884d8", "#82ca9d"]

  return (
    &lt;div style={{ width: '100%', height: '100%' }}&gt;
      &lt;ResponsiveContainer&gt;
        &lt;AreaChart 
          width={500}
          height={400}
          data={data}
        &gt;
          &lt;XAxis dataKey={dimKey[0]} /&gt;
          &lt;YAxis /&gt;
          {measKeys.map((m, i) =&gt; (
            &lt;Area type="monotone" dataKey={m} stackId="1" stroke={colors[i]} fill={colors[i]} /&gt;
          ))}
        &lt;/AreaChart&gt;
      &lt;/ResponsiveContainer&gt;
    &lt;/div&gt;
  );
};

export default App;</pre>
<h1><span>Тестирование расширения в Qlik Sense</span></h1>
<p><span>Наконец, мы быстро импортируем наше расширение в Qlik Sense и убедимся, что все работает должным образом.</span></p>
<p><span>Запустите приведенную ниже команду в своем терминале</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">npm run sense</pre>
<p><span>Это поместит наше расширение в новую папку в нашем репозитории. Затем мы можем заархивировать это и импортировать на наш сайт Qlik Sense.</span></p>
<p><span>И вот, у нас есть рабочее расширение, созданное с использованием Nebula.js и React!</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_5.png"><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_5.png" alt="" width="1400" height="766" class="aligncenter size-full wp-image-2715" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_5.png 1400w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_5-300x164.png 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_5-1024x560.png 1024w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2022/02/build_qlik_sense_extension_with_nebula_js_react_5-768x420.png 768w" sizes="(max-width: 1400px) 100vw, 1400px" /></a></p>
<h1>Использованные материалы при создании статьи</h1>
<ul>
<li><a href="https://medium.com/data-lit/lets-build-a-qlik-sense-extension-with-nebula-js-react-part-1-2-44909ab15a47" target="_blank" rel="noopener">https://medium.com/data-lit/lets-build-a-qlik-sense-extension-with-nebula-js-react-part-1-2-44909ab15a47</a></li>
</ul>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/build-a-qlik-sense-extension-with-nebula-js-react/">Как создать Qlik Sense Extension с помощью Nebula.js и React</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qliksense.ivan-shamaev.ru/build-a-qlik-sense-extension-with-nebula-js-react/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
