<?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 api - Qlik Sense - Обучение, учебник, онлайн курс</title>
	<atom:link href="https://qliksense.ivan-shamaev.ru/tag/qlik-sense-api/feed/" rel="self" type="application/rss+xml" />
	<link>https://qliksense.ivan-shamaev.ru/tag/qlik-sense-api/</link>
	<description>Qlik Sense на русском языке. Пошаговые уроки для изучения Клик Сенс</description>
	<lastBuildDate>Mon, 14 Feb 2022 07:46:22 +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 api - Qlik Sense - Обучение, учебник, онлайн курс</title>
	<link>https://qliksense.ivan-shamaev.ru/tag/qlik-sense-api/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Обзор функций Javascript в редакторе Qlik Sense Extensions</title>
		<link>https://qliksense.ivan-shamaev.ru/overview-javascript-functions-extensions/</link>
					<comments>https://qliksense.ivan-shamaev.ru/overview-javascript-functions-extensions/#respond</comments>
		
		<dc:creator><![CDATA[qliksense-expert]]></dc:creator>
		<pubDate>Sat, 09 Jan 2021 20:22:39 +0000</pubDate>
				<category><![CDATA[Уровень 2]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[javascript qlik sense]]></category>
		<category><![CDATA[qlik sense api]]></category>
		<category><![CDATA[Qlik Sense Extension]]></category>
		<category><![CDATA[Qlik Sense Extensions]]></category>
		<guid isPermaLink="false">https://qliksense.ivan-shamaev.ru/?p=2488</guid>

					<description><![CDATA[<p>== A == arguments &#8211; alert &#8211; показывает сообщение и ждёт, пока пользователь нажмёт кнопку «ОК» atob &#8211; Функция декодирует строку данных , которые были закодированы с помощью Base64 кодирования. var decodedData = scope.atob(encodedData); angular &#8211; addEventListener &#8211; способ назначения обработчиков на события с привязкой к элементу. Синтаксис: element.addEventListener(event, handler[, options]); event &#8211; Имя<a class="moretag" href="https://qliksense.ivan-shamaev.ru/overview-javascript-functions-extensions/"> Читать дальше&#8230;</a></p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/overview-javascript-functions-extensions/">Обзор функций Javascript в редакторе Qlik Sense Extensions</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>== A ==</h2>
<ul>
<li><strong>arguments</strong> &#8211;</li>
<li><strong>alert </strong>&#8211; <span>показывает сообщение и ждёт, пока пользователь нажмёт кнопку «ОК»</span></li>
<li><strong>atob </strong>&#8211; <span>Функция декодирует строку данных , которые были закодированы с помощью </span><a href="https://developer.mozilla.org/en-US/docs/Glossary/Base64"><span>Base64</span></a><span> кодирования.</span>
<ul>
<li>
<pre class="brush: js notranslate"><code><span class="token keyword">var</span> decodedData <span class="token operator">=</span> scope<span class="token punctuation">.</span><span class="token function">atob</span><span class="token punctuation">(</span>encodedData<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
</li>
</ul>
</li>
<li><strong>angular </strong>&#8211;</li>
<li><strong>addEventListener </strong>&#8211; способ назначения обработчиков на события с привязкой к элементу. Синтаксис:
<ul>
<li><code>element.addEventListener(event, handler[, options]);</code>
<ul>
<li><code>event</code> &#8211; Имя события, например<span> </span><code>"click"</code></li>
<li><code>handler</code> &#8211; Ссылка на функцию-обработчик</li>
<li><code>options</code> &#8211; Дополнительный объект со свойствами: <code>once</code><span>, <code>capture</code>, <code>passive</code>.</span></li>
</ul>
</li>
<li><span>Метод </span><code>addEventListener</code><span> позволяет добавлять несколько обработчиков на одно событие одного элемента</span>
<ul>
<li>
<pre class="EnlighterJSRAW" data-enlighter-language="js">function handler1() {
  alert('Спасибо!');
};

function handler2() {
  alert('Спасибо ещё раз!');
}

elem.onclick = () =&gt; alert("Привет");
elem.addEventListener("click", handler1); // Спасибо!
elem.addEventListener("click", handler2); // Спасибо ещё раз!</pre>
<p><strong></strong></li>
</ul>
</li>
</ul>
</li>
<li><strong>app </strong>&#8211;</li>
</ul>
<h2>== B ==</h2>
<ul>
<li><strong>blur </strong>&#8211;</li>
<li><strong>btoa </strong>&#8211; <span>Метод создает </span><a href="https://developer.mozilla.org/en-US/docs/Glossary/Base64"><span>Base64</span></a><span> закодированную ASCII строку из </span><a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMString/Binary"><span>двоичной строки</span></a> / Binary<span> (то есть </span><code>String</code> <span>объект , в котором каждый символ в строке рассматриваются как байты двоичных данных). Вы можете использовать этот метод для кодирования данных, которые в противном случае могут вызвать проблемы со связью, передать их, а затем использовать метод <code>atob()</code> для повторного декодирования данных.</span>
<ul>
<li>
<pre class="brush: js notranslate"><code><span class="token keyword">var</span> encodedData <span class="token operator">=</span> scope<span class="token punctuation">.</span><span class="token function">btoa</span><span class="token punctuation">(</span>stringToEncode<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
</li>
</ul>
</li>
<li><strong>break </strong>&#8211;</li>
<li><strong>backendApi </strong>&#8211;</li>
</ul>
<h2>== C ==</h2>
<ul>
<li><strong>customElements </strong>&#8211;</li>
<li><strong>closed </strong>&#8211;</li>
<li><strong>clientInformation </strong>&#8211;</li>
<li><strong>crypto </strong>&#8211;</li>
<li><strong>cancelAnimationFrame </strong>&#8211;</li>
<li><strong>cancelIdleCallback </strong>&#8211;</li>
<li><strong>captureEvents </strong>&#8211;</li>
<li><strong>clearInterval </strong>&#8211; <span>отменяет синхронизированное, повторяющееся действие, которое было ранее установлено вызовом </span><code>setInterval()</code><span>.</span></li>
<li><strong>clearTimeout </strong>&#8211; <span>отменяет тайм &#8211; аут ранее установленного вызовом метода </span><code>setTimeout()</code><span>.</span></li>
<li><strong>close </strong>&#8211;</li>
<li><strong>confirm </strong>&#8211; <span>отображает диалоговое окно, которое содержит две кнопки (OK и Cancel), а так же опциональное (необязательное) текстовое сообщение.</span>
<ul>
<li><code>result = confirm(message);</code>
<ul>
<li><code>message</code><span> </span>опциональная (необязательная) строка, которая будет отображена в диалоговом окне.</li>
<li><code>result</code><span> </span>булево значение, указывающее на нажатую кнопку OK или Cancel (<code>true</code> означает OK).</li>
</ul>
</li>
</ul>
</li>
<li><strong>createImageBitmap</strong> &#8211; <span>Метод создает bitmap из источника, при необходимости можно использовать только часть источника. Метод существует в глобальной области как в окнах, так и в рабочих процессах. Он принимает множество различных источников изображений и возвращает </span><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" data-flaw-src="{{domxref(&quot;Promise&quot;)}}"><code>Promise</code></a>, <span>которое <strong>resolve</strong> в </span><a href="https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap"><code>ImageBitmap</code></a><span>.</span></li>
<li><strong>chrome </strong>&#8211;</li>
<li><strong>caches </strong>&#8211;</li>
<li><strong>case </strong>&#8211;</li>
<li><strong>catch </strong>&#8211;</li>
<li><strong>continue </strong>&#8211;</li>
</ul>
<h2>== D ==</h2>
<ul>
<li><strong>dimensionInfo </strong>&#8211;</li>
<li><strong>document </strong>&#8211;</li>
<li><strong>devicePixelRatio </strong>&#8211;</li>
<li><strong>defaultStatus </strong>&#8211;</li>
<li><strong>dragomanClosure </strong>&#8211;</li>
<li><strong>define </strong>&#8211;</li>
<li><strong>debounceTimer </strong>&#8211;</li>
<li><strong>dispatchEvent </strong>&#8211;</li>
<li><strong>debugger </strong>&#8211;</li>
<li><strong>default </strong>&#8211;</li>
<li><strong>delete </strong>&#8211;</li>
<li><strong>do </strong>&#8211;</li>
</ul>
<h2>== E ==</h2>
<ul>
<li><strong>external </strong>&#8211;</li>
<li><strong>engineModuleGlobal </strong>&#8211;</li>
<li><strong>else </strong>&#8211;</li>
</ul>
<h2>== F ==</h2>
<ul>
<li><strong>frames </strong>&#8211;</li>
<li><strong>frameElement </strong>&#8211;</li>
<li><strong>fetch </strong>&#8211; <span class="seoSummary"><span>Метод </span><code>WindowOrWorkerGlobalScope</code> <span>Mixin начинается процесс извлечения ресурса из сети, возвращая обещание , которое выполняется , как только отклик доступен. </span></span><span>Обещание преобразуется в </span><code>Response</code> <span>объект, представляющий ответ на ваш запрос. Обещание </span><em><span>не</span></em><span> отклоняется при ошибках HTTP &#8211; оно отклоняется только при ошибках сети. Вы должны использовать </span><code>then</code> <span>обработчики для проверки ошибок HTTP.</span></li>
<li><strong>find </strong>&#8211;</li>
<li><strong>focus </strong>&#8211;</li>
<li><strong>false </strong>&#8211;</li>
<li><strong>finally </strong>&#8211;</li>
<li><strong>for </strong>&#8211;</li>
<li><strong>function </strong>&#8211;</li>
</ul>
<h2>== G ==</h2>
<ul>
<li><strong>getComputedStyle </strong>&#8211;</li>
<li><strong>getSelection </strong>&#8211;</li>
</ul>
<h2>== H ==</h2>
<ul>
<li><strong>html </strong>&#8211;</li>
<li><strong>history </strong>&#8211;</li>
</ul>
<h2>== I ==</h2>
<ul>
<li><strong>innerWidth </strong>&#8211;</li>
<li><strong>innerHeight </strong>&#8211;</li>
<li><strong>isSecureContext </strong>&#8211;</li>
<li><strong>indexedDB </strong>&#8211;</li>
<li><strong>if </strong>&#8211;</li>
<li><strong>in </strong>&#8211;</li>
<li><strong>instanceof </strong>&#8211;</li>
</ul>
<h2>== L ==</h2>
<ul>
<li><strong>location </strong>&#8211;</li>
<li><strong>locationbar </strong>&#8211;</li>
<li><strong>length </strong>&#8211;</li>
<li><strong>localStorage </strong>&#8211;</li>
<li><strong>layout </strong>&#8211;</li>
</ul>
<h2>== M ==</h2>
<ul>
<li><strong>menubar </strong>&#8211;</li>
<li><strong>matchMedia </strong>&#8211;</li>
<li><strong>moveBy </strong>&#8211;</li>
<li><strong>moveTo </strong>&#8211;</li>
</ul>
<h2>== O ==</h2>
<ul>
<li><strong>opener </strong>&#8211; Свойство <b>opener</b> возвращает ссылку на окно, которое открыло текущее. Когда Вы открываете новое окно с помощью open() Вы можете воспользоваться этим свойством, чтобы взаимодействовать с родительским окном из нового окна.
<ul>
<li>
<pre class="EnlighterJSRAW" data-enlighter-language="js">//Создадим новое окно win 
win = window.open();
//Выведем в новое окно текст
win.document.write("Текст нового окна");
//Теперь выведем текст в родительское окно с помощью свойства opener
win.opener.document.write("Текст родительского окна");</pre>
<p>&nbsp;</li>
</ul>
</li>
<li><strong>origin </strong>&#8211;</li>
<li><strong>outerWidth </strong>&#8211;</li>
<li><strong>outerHeight </strong>&#8211;</li>
<li><strong>onsearch </strong>&#8211;</li>
<li><strong>onappinstalled </strong>&#8211;</li>
<li><strong>onbeforeinstallprompt </strong>&#8211;</li>
<li><strong>onabort </strong>&#8211;</li>
<li><strong>onblur </strong>&#8211;</li>
<li><strong>oncancel </strong>&#8211;</li>
<li><strong>oncanplay</strong> &#8211;</li>
<li><strong>oncanplaythrough </strong>&#8211;</li>
<li><strong>onchange </strong>&#8211;</li>
<li><strong>onclick </strong>&#8211;</li>
<li><strong>onclose </strong>&#8211;</li>
<li><strong>oncontextmenu </strong>&#8211;</li>
<li><strong>oncuechange </strong>&#8211;</li>
<li><strong>ondblclick </strong>&#8211;</li>
<li><strong>ondrag </strong>&#8211;</li>
<li><strong>ondragend </strong>&#8211;</li>
<li><strong>ondragenter </strong>&#8211;</li>
<li><strong>ondragleave </strong>&#8211;</li>
<li><strong>ondragover </strong>&#8211;</li>
<li><strong>ondragstart </strong>&#8211;</li>
<li><strong>ondrop</strong> &#8211;</li>
<li><strong>ondurationchange </strong>&#8211;</li>
<li><strong>onemptied </strong>&#8211;</li>
<li><strong>onended </strong>&#8211;</li>
<li><strong>onerror </strong>&#8211;</li>
<li><strong>onfocus </strong>&#8211;</li>
<li><strong>onformdata </strong>&#8211;</li>
<li><strong>oninput </strong>&#8211;</li>
<li><strong>oninvalid </strong>&#8211;</li>
<li><strong>onkeydown </strong>&#8211;</li>
<li><strong>onkeypress </strong>&#8211;</li>
<li><strong>onkeyup </strong>&#8211;</li>
<li><strong>onload </strong>&#8211;</li>
<li><strong>onloadeddata </strong>&#8211;</li>
<li><strong>onloadedmetadata </strong>&#8211;</li>
<li><strong>onloadstart </strong>&#8211;</li>
<li><strong>onmousedown </strong>&#8211;</li>
<li><strong>onmouseenter </strong>&#8211;</li>
<li><strong>onmouseleave </strong>&#8211;</li>
<li><strong>onmousemove </strong>&#8211;</li>
<li><strong>onmouseout </strong>&#8211;</li>
<li><strong>onmouseover </strong>&#8211;</li>
<li><strong>onmouseup </strong>&#8211;</li>
<li><strong>onmousewheel </strong>&#8211;</li>
<li><strong>onpause </strong>&#8211;</li>
<li><strong>onplay </strong>&#8211;</li>
<li><strong>onplaying </strong>&#8211;</li>
<li><strong>onprogress </strong>&#8211;</li>
<li><strong>onratechange </strong>&#8211;</li>
<li><strong>onreset </strong>&#8211;</li>
<li><strong>onresize </strong>&#8211;</li>
<li><strong>onscroll </strong>&#8211;</li>
<li><strong>onseeked </strong>&#8211;</li>
<li><strong>onseeking </strong>&#8211;</li>
<li><strong>onselect </strong>&#8211;</li>
<li><strong>onstalled </strong>&#8211;</li>
<li><strong>onsubmit </strong>&#8211;</li>
<li><strong>onsuspend </strong>&#8211;</li>
<li><strong>ontimeupdate </strong>&#8211;</li>
<li><strong>ontoggle </strong>&#8211;</li>
<li><strong>onvolumechange </strong>&#8211;</li>
<li><strong>onwaiting </strong>&#8211;</li>
<li><strong>onwebkitanimationend </strong>&#8211;</li>
<li><strong>onwebkitanimationiteration </strong>&#8211;</li>
<li><strong>onwebkitanimationstart </strong>&#8211;</li>
<li><strong>onwebkitanimationend </strong>&#8211;</li>
<li><strong>onwheel </strong>&#8211;</li>
<li><strong>onauxclick </strong>&#8211;</li>
<li><strong>ongotpointercapture </strong>&#8211;</li>
<li><strong>onlostpointercapture </strong>&#8211;</li>
<li><strong>onpointerdown </strong>&#8211;</li>
<li><strong>onpointermove </strong>&#8211;</li>
<li><strong>onpointerup </strong>&#8211;</li>
<li><strong>onpointercancel </strong>&#8211;</li>
<li><strong>onpointerover </strong>&#8211;</li>
<li><strong>onpointerout </strong>&#8211;</li>
<li><strong>onpointerenter </strong>&#8211;</li>
<li><strong>onpointerleave </strong>&#8211;</li>
<li><strong>onselectstart </strong>&#8211;</li>
<li><strong>onselectionchange </strong>&#8211;</li>
<li><strong>onanimationend </strong>&#8211;</li>
<li><strong>onanimationiteration </strong>&#8211;</li>
<li><strong>onanimationstart </strong>&#8211;</li>
<li><strong>ontransitionend </strong>&#8211;</li>
<li><strong>onafterprint </strong>&#8211;</li>
<li><strong>onbeforeprint </strong>&#8211;</li>
<li><strong>onbeforeunload </strong>&#8211;</li>
<li><strong>onhashchange </strong>&#8211;</li>
<li><strong>onlanguagechange </strong>&#8211;</li>
<li><strong>onmessage </strong>&#8211;</li>
<li><strong>onmessageerror </strong>&#8211;</li>
<li><strong>onoffline </strong>&#8211;</li>
<li><strong>ononline </strong>&#8211;</li>
<li><strong>onpagehide </strong>&#8211;</li>
<li><strong>onpageshow </strong>&#8211;</li>
<li><strong>onpopstate </strong>&#8211;</li>
<li><strong>onrejectionhandled </strong>&#8211;</li>
<li><strong>onstorage </strong>&#8211;</li>
<li><strong>onunhandledrejection </strong>&#8211;</li>
<li><strong>onunload </strong>&#8211;</li>
<li><strong>open </strong>&#8211;</li>
<li><strong>ondevicemotion </strong>&#8211;</li>
<li><strong>ondeviceorientation </strong>&#8211;</li>
<li><strong>ondeviceorientationabsolute </strong>&#8211;</li>
<li><strong>onpointerrawupdate </strong>&#8211;</li>
<li><strong>openDatabase </strong>&#8211;</li>
</ul>
<h2>== P ==</h2>
<ul>
<li><strong>personalbar </strong>&#8211;</li>
<li><strong>parent </strong>&#8211;</li>
<li><strong>pageXOffset </strong>&#8211;</li>
<li><strong>pageYOffset </strong>&#8211;</li>
<li><strong>performance </strong>&#8211;</li>
<li><strong>postMessage </strong>&#8211;</li>
<li><strong>print </strong>&#8211;</li>
<li><strong>prompt </strong>&#8211; отображает диалоговое окно с необязательным запросом на ввод текста<span>: <code>result <span class="token operator">=</span> <span class="token function">prompt</span><span class="token punctuation">(</span>title<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token keyword">default</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></span>
<ul>
<li><span>Этот код отобразит модальное окно с текстом, полем для ввода текста и кнопками OK/Отмена.</span>
<ul>
<li><code>result</code> — это строка, содержащая текст, поступивший от пользователя или null.</li>
<li><code>title</code> &#8211; Текст для отображения в окне.</li>
<li><code>default</code> &#8211; Необязательный второй параметр, который устанавливает начальное значение в поле для текста в окне.</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>== Q ==</h2>
<ul>
<li><strong>queueMicrotask </strong>&#8211; <span class="seoSummary"><span>Метод, который подвергается воздействие на </span><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window"><code>Window</code></a> <span>или </span><a href="https://developer.mozilla.org/en-US/docs/Web/API/Worker"><code>Worker</code></a> <span>интерфейсе, в очередь microtask , которая будет выполнено в безопасное время до контроля возвращения в цикл обработки событий браузера. </span></span><span><strong>Микрозадача</strong> &#8211; это короткая функция, которая будет выполняться после того, как текущая задача завершит свою работу, и когда нет другого кода, ожидающего запуска, до того, как управление контекстом выполнения будет возвращено в цикл событий браузера. Это позволяет вашему коду выполняться без вмешательства в любой другой ожидающий выполнения код с потенциально более высоким приоритетом, но до того, как браузер восстановит контроль над контекстом выполнения, что может зависеть от работы, которую вам нужно выполнить.</span>
<ul>
<li>
<pre class="brush: js notranslate"><code>scope<span class="token punctuation">.</span><span class="token function">queueMicrotask</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
</li>
</ul>
</li>
<li><strong>qJsonp </strong>&#8211;</li>
<li><strong>qvangularGlobal </strong>&#8211;</li>
<li><strong>qListObject </strong>&#8211; <span>является базовым списком и подходит, если вы хотите создать список всех значений из поля. Объект списка &#8211; это визуализация, содержащая одно измерение. При получении макета объекта списка ( <code><span class="syntax">qListObjectDef</span></code> ) <span class="syntax">отображаются</span> все значения. Если выбор применяется к объекту списка, выбранные значения отображаются вместе с исключенными и дополнительными значениями.</span>
<ul>
<li><strong><span class="autonumber">Пример:</span> горизонтальный </strong><span class="syntax"><span><strong>список</strong> <code>initialProperties</code></span></span></li>
<li>
<pre class="EnlighterJSRAW" data-enlighter-language="js">initialProperties : {  
            version : 1.0,  
            qListObjectDef : {  
                qShowAlternatives : true,  
                qFrequencyMode : "V",  
                qSortCriterias : {  
                    qSortByState : 1  
                },  
                qInitialDataFetch : [{  
                    qWidth : 2,  
                    qHeight : 50  
                }]  
            },  
            fixed: true,  
            width: 25,  
            percent: true,  
            selectionMode: "CONFIRM"  
}</pre>
<p>&nbsp;</li>
</ul>
</li>
<li><strong>qHyperCube </strong>&#8211;</li>
<li><strong>qlik </strong>&#8211;</li>
</ul>
<h2>== R ==</h2>
<ul>
<li><strong>rows </strong>&#8211;</li>
<li><strong>releaseEvents </strong>&#8211;</li>
<li><strong>requestAnimationFrame </strong>&#8211;</li>
<li><strong>requestIdleCallback </strong>&#8211;</li>
<li><strong>resizeBy </strong>&#8211;</li>
<li><strong>resizeTo </strong>&#8211;</li>
<li><strong>regeneratorRuntime </strong>&#8211;</li>
<li><strong>require </strong>&#8211;</li>
<li><strong>requirejs </strong>&#8211;</li>
<li><strong>removeEventListener </strong>&#8211;</li>
<li><strong>return </strong>&#8211;</li>
<li><strong>reply </strong>&#8211;</li>
</ul>
<h2>== S ==</h2>
<ul>
<li><strong>self </strong>&#8211;</li>
<li><strong>scrollbars </strong>&#8211;</li>
<li><strong>statusbar </strong>&#8211;</li>
<li><strong>status </strong>&#8211;</li>
<li><strong>screen </strong>&#8211;</li>
<li><strong>scrollX </strong>&#8211;</li>
<li><strong>scrollY </strong>&#8211;</li>
<li><strong>screenX </strong>&#8211;</li>
<li><strong>screenY </strong>&#8211;</li>
<li><strong>screenLeft </strong>&#8211;</li>
<li><strong>screenTop </strong>&#8211;</li>
<li><strong>styleMedia </strong>&#8211;</li>
<li><strong>sessionStorage </strong>&#8211;</li>
<li><strong>scroll </strong>&#8211;</li>
<li><strong>scrollBy </strong>&#8211;</li>
<li><strong>scrollTo </strong>&#8211;</li>
<li><strong>setInterval </strong>&#8211; <span class="seoSummary"><span>Метод, предложенный на </span><a href="https://developer.mozilla.org/en-US/docs/Web/API/Window"><code>Window</code></a> <span>и </span><a href="https://developer.mozilla.org/en-US/docs/Web/API/Worker"><code>Worker</code></a> <span>интерфейсах, неоднократно вызывает функцию или выполняет фрагмент кода, с фиксированной задержкой по времени между каждым вызовом. </span></span><span>Он возвращает идентификатор интервала, который однозначно определяет интервал, поэтому вы можете удалить его позже, позвонив </span><code>clearInterval()</code><span>. Этот метод определяется </span><a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope"><code>WindowOrWorkerGlobalScope</code></a> <span>миксином.</span>
<ul>
<li>
<pre class="brush: js notranslate"><code><span class="token keyword">var</span> intervalID <span class="token operator">=</span> scope<span class="token punctuation">.</span><span class="token function">setInterval</span><span class="token punctuation">(</span>func<span class="token punctuation">,</span> <span class="token punctuation">[</span>delay<span class="token punctuation">,</span> arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
</li>
</ul>
</li>
<li><strong>setTimeout </strong>&#8211; <span>Метод </span><code>WindowOrWorkerGlobalScope</code> <span>Mixin (и преемника </span><code>Window.setTimeout()</code><span>) устанавливает таймер , который выполняет функцию или указанный фрагмент кода один раз, когда таймер истекает.</span>
<ul>
<li>
<pre class="brush: js notranslate"><code><span class="token keyword">var</span> timeoutID <span class="token operator">=</span> scope<span class="token punctuation">.</span><span class="token function">setTimeout</span><span class="token punctuation">(</span><span class="token keyword">function</span><span class="token punctuation">[</span><span class="token punctuation">,</span> delay<span class="token punctuation">,</span> arg1<span class="token punctuation">,</span> arg2<span class="token punctuation">,</span> <span class="token operator">...</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
</li>
</ul>
</li>
<li><strong>stop </strong>&#8211;</li>
<li><strong>showDirectory </strong>&#8211;</li>
<li><strong>showOpenFilePicker </strong>&#8211;</li>
<li><strong>showSaveFilePicker </strong>&#8211;</li>
<li><strong>speechSynthesis </strong>&#8211;</li>
<li><strong>switch </strong>&#8211;</li>
</ul>
<h2>== T ==</h2>
<ul>
<li><strong>this </strong>&#8211;</li>
<li><strong>toolbar </strong>&#8211;</li>
<li><strong>top </strong>&#8211;</li>
<li><strong>trustedTypes </strong>&#8211;</li>
<li><strong>throw </strong>&#8211;</li>
<li><strong>true </strong>&#8211;</li>
<li><strong>try </strong>&#8211;</li>
<li><strong>typeof </strong>&#8211;</li>
</ul>
<h2>== V ==</h2>
<ul>
<li><strong>visualViewport </strong>&#8211;</li>
<li><strong>var </strong>&#8211;</li>
<li><strong>void </strong>&#8211;</li>
</ul>
<h2>== W ==</h2>
<ul>
<li><strong>window </strong>&#8211;</li>
<li><strong>webkitStorageInfo </strong>&#8211;</li>
<li><strong>webkitCancelAnimationFrame </strong>&#8211;</li>
<li><strong>webkitRequestAnimationFrame </strong>&#8211;</li>
<li><strong>webkitRequestFileSystem </strong>&#8211;</li>
<li><strong>webkitResolveLocalFileSystemURL </strong>&#8211;</li>
<li><strong>webpackJsonpsensei_codearea </strong>&#8211;</li>
<li><strong>while </strong>&#8211;</li>
<li><strong>with </strong>&#8211;</li>
</ul>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/overview-javascript-functions-extensions/">Обзор функций Javascript в редакторе Qlik Sense Extensions</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qliksense.ivan-shamaev.ru/overview-javascript-functions-extensions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>nebula.js &#8211; Qlik Sense API Javascript библиотека. Примеры</title>
		<link>https://qliksense.ivan-shamaev.ru/nebula-js-qlik-sense-api-javascript-library-examples/</link>
					<comments>https://qliksense.ivan-shamaev.ru/nebula-js-qlik-sense-api-javascript-library-examples/#respond</comments>
		
		<dc:creator><![CDATA[qliksense-expert]]></dc:creator>
		<pubDate>Wed, 25 Nov 2020 20:03:24 +0000</pubDate>
				<category><![CDATA[Уровень 2]]></category>
		<category><![CDATA[mashup]]></category>
		<category><![CDATA[nebula.js]]></category>
		<category><![CDATA[qlik api]]></category>
		<category><![CDATA[qlik sense]]></category>
		<category><![CDATA[qlik sense api]]></category>
		<category><![CDATA[Qlik Sense Mashup]]></category>
		<category><![CDATA[qliksense]]></category>
		<guid isPermaLink="false">https://qliksense.ivan-shamaev.ru/?p=2440</guid>

					<description><![CDATA[<p>Введение в nebula.js nebula.js представляет собой набор библиотек JavaScript, визуализаций и интерфейсов командной строки, которые помогают разработчикам создавать и интегрировать визуализации поверх ассоциативного движка Qlik. Коллекция организована в @nebula.jsрамках области в виде пакетов npm. Основной пакет @nebula.js/stardustсодержит API-интерфейсы для интеграции существующих визуализаций с гибридными приложениями, а также API-интерфейсы для создания пользовательских визуализаций. EMBEDDING VISUALIZATIONS.<a class="moretag" href="https://qliksense.ivan-shamaev.ru/nebula-js-qlik-sense-api-javascript-library-examples/"> Читать дальше&#8230;</a></p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/nebula-js-qlik-sense-api-javascript-library-examples/">nebula.js &#8211; Qlik Sense API Javascript библиотека. Примеры</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1 id="introduction-to-nebulajs"><span>Введение в nebula.js</span></h1>
<p><code class="language-text">nebula.js</code><span> представляет собой набор библиотек JavaScript, визуализаций и интерфейсов командной строки, которые помогают разработчикам создавать и интегрировать визуализации поверх ассоциативного движка Qlik.</span></p>
<p><span>Коллекция организована в </span><code class="language-text">@nebula.js</code><span>рамках области в виде пакетов npm. Основной пакет </span><code class="language-text">@nebula.js/stardust</code><span>содержит API-интерфейсы для интеграции существующих визуализаций с гибридными приложениями, а также API-интерфейсы для создания пользовательских визуализаций.</span></p>
<h1><strong>EMBEDDING VISUALIZATIONS. ВСТРАИВАНИЕ ВИЗУАЛИЗАЦИЙ</strong></h1>
<h2>Configuration. Конфигурация</h2>
<p><span>Когда вы создаете веб-сайт, будь то сайт всей компании или небольшой личный проект, у вас, скорее всего, есть свои собственные рекомендации по дизайну, шаблоны и требования UX, и вы захотите применить эти рекомендации к тому, что вы с ним интегрируете; диаграммы должны использовать ваши цветовые схемы, шрифты, языковой стандарт и уважать любые ограничения, которые могут быть у вас на интерактивность. Вы также можете контролировать, как загружаются диаграммы и темы, в зависимости от того, подключено ли ваше решение к сети или нет.</span></p>
<p><span>Вы можете управлять большинством из них через </span><code class="language-text">Configuration</code><span>объект.</span></p>
<h3 id="temporary-config">В<span>ременный конфиг</span></h3>
<p><span></span><code class="language-text">Configuration</code><span>Объект является необязательным аргументом , который вы можете предоставить при инстанцировании </span><code class="language-text">embed</code><span>экземпляра:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">import { embed } from '@nebula.js/stardust';

const n = embed(enigmaApp, {
  context: {
    theme: 'dark',
  },
  types: [
    /* types */
  ],
});

n.render(/* chart 1*/);
n.render(/* chart 2*/);</pre>
<h3 id="reusable-config"><span>Многоразовая конфигурация</span></h3>
<p><span>Если вы работаете с несколькими приложениями или хотите иметь несколько разных конфигураций, вам может быть проще сначала создать конфигурации, а затем повторно использовать их.</span></p>
<p><span>Создайте файл, </span><code class="language-text">baseConfig</code><span>который выполняет тяжелую работу по регистрации типов и тем:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">const baseConfig = embed.createConfiguration({
  types: [
    /* register type once*/
  ],
  themes: [
    /* register themes once*/
  ],
});</pre>
<p><span>Создайте другую конфигурацию, которая наследуется от </span><code class="language-text">baseConfig</code><span>, примените </span><code class="language-text">'dark'</code><span>тему и установите ограничение, запрещающее выбор:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">const noSelectionDark = baseConfig.createConfiguration({
  context: {
    theme: 'dark',
    constraints: { select: true },
  },
});

// render chart with dark theme with no selections allowed
noSelectionDark(enigmaApp).render(/*chart config*/);
noSelectionDark(anotherEnigmaApp).render(/*chart config*/);</pre>
<p><span>Вы также можете напрямую привязать конфигурацию к приложению:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">const swedishPink = baseConfig(enigmaApp, {
  context: {
    theme: 'pinkish',
    language: 'sv-SE',
  },
});

swedishPink.render(/* chart config */);</pre>
<h3 id="registering-types"><span>Регистрация типов</span></h3>
<p><span>Перед визуализацией визуализации ее модуль необходимо загрузить и зарегистрировать. Вы можете загрузить необходимые модули из npm:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">$npm install @nebula.js/sn-bar-chart @nebula.js/sn-pie-chart</pre>
<p><span>А потом зарегистрируйте каждого </span><code class="language-text">type</code><span>индивидуально:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import barchart from '@nebula.js/sn-bar-chart';
import piechart from '@nebula.js/sn-pie-chart';

embed.createConfiguration({
  types: [
    {
      name: 'bar',
      load: () =&gt; Promise.resolve(barchart),
    },
    {
      name: 'pie',
      load: () =&gt; Promise.resolve(piechart),
    },
  ],
});</pre>
<h3 id="loading-on-the-fly"><span>Загрузка на лету</span></h3>
<p><span>Если вы точно не знаете, какие типы вам нужны, и не хотите устанавливать все, чтобы уменьшить размер вашего пакета, вы можете загрузить визуализации во время выполнения, используя облегченный загрузчик определений асинхронных модулей, например </span><a href="https://github.com/d3/d3-require"><span>d3-require</span></a><span> .</span></p>
<p><span>Начнем с установки модуля:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">npm install d3-require</pre>
<p><span>а затем настройте его для загрузки модулей из CDN, например </span><code class="language-text">https://unpkg.com</code><span>, а также укажите псевдоним для использования локальной версии </span><code class="language-text">@nebula.js/stardust</code><span>:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">import { requireFrom } from 'd3-require';
import * as stardust from '@nebula.js/stardust';

const loadSnType = requireFrom((name) =&gt; `https://unpkg.com/@nebula.js/sn-${name}-chart`).alias({
  '@nebula.js/stardust': stardust,
});</pre>
<p><span>Затем вы можете настроить все типы, которые вы ожидаете использовать:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">const types = ['bar', 'line', 'pie', 'sankey'].map((t) =&gt; ({
  type: t,
  load: () =&gt; loadSnType(t),
}));
const baseConfig = stardust.embed.createConfiguration({ types });</pre>
<p><span>Тип загружается с удаленного URL-адреса при первом отображении:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">baseConfig(enigmaApp).render({
  type: 'bar',
  fields: ['Product', '=sum(Sales)'],
});</pre>
<h3 id="context"><span>Контекст</span></h3>
<p><span>При настройке конфигурации вы можете применить, </span><code class="language-text">context</code><span>который контролирует язык, тему и ограничения в каждой визуализации, которую вы визуализируете:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">embed.createConfiguration({
  context: {},
});</pre>
<h4 id="constraints"><span>Ограничения</span></h4>
<p><span>Ограничения позволяют указать визуализации на отключение определенных типов взаимодействий и поведения.</span></p>
<p><span>Вы можете применить три различных ограничения:</span></p>
<ul>
<li><code class="language-text">passive</code><span>: отключить такие взаимодействия, как всплывающие подсказки.</span></li>
<li><code class="language-text">active</code><span>: отключение взаимодействий, влияющих на состояние визуального представления, таких как масштабирование, прокрутка и т. д.</span></li>
<li><code class="language-text">select</code><span>: выключить выделение.</span></li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  context: {
    constraints: {
      active: true,
      passive: true,
      select: true,
    },
  },
};</pre>
<p><code class="language-text">stardust</code><span> никоим образом не навязывает эти ограничения, вместо этого разработчик визуализации должен соблюдать и реализовывать их.</span></p>
<h4 id="language"><span>Язык</span></h4>
<p><code class="language-text">stardust</code><span> поддерживает 15 языков:</span></p>
<ul>
<li><code class="language-text">'en-US'</code><span> &#8211; Американский английский</span></li>
<li><code class="language-text">'sv-SE'</code><span> &#8211; шведский</span></li>
<li><code class="language-text">'it-IT'</code><span> &#8211; итальянский</span></li>
<li><code class="language-text">'zh-CN'</code><span> &#8211; Упрощенный китайский</span></li>
<li><code class="language-text">'zh-TW'</code><span> &#8211; Традиционный китайский</span></li>
<li><code class="language-text">'ko-KR'</code><span> &#8211; Корейский язык</span></li>
<li><code class="language-text">'de-DE'</code><span> &#8211; Немецкий</span></li>
<li><code class="language-text">'es-ES'</code><span> &#8211; Испанский</span></li>
<li><code class="language-text">'pt-BR'</code><span> &#8211; Бразильский португальский</span></li>
<li><code class="language-text">'ja-JP'</code><span> &#8211; Японский</span></li>
<li><code class="language-text">'fr-FR'</code><span> &#8211; Французкий язык</span></li>
<li><code class="language-text">'nl-NL'</code><span> &#8211; Голландский</span></li>
<li><code class="language-text">'tr-TR'</code><span> &#8211; Турецкий</span></li>
<li><code class="language-text">'pl-PL'</code><span> &#8211; польский</span></li>
<li><code class="language-text">'ru-RU'</code><span> &#8211; Русский</span></li>
</ul>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  context: {
    language: 'sv-SE',
  },
};</pre>
<h4 id="theme"><span>Тема</span></h4>
<p><span>Из коробки доступны две основные темы: </span><code class="language-text">'light'</code><span>и </span><code class="language-text">'dark'</code><span>.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">{
  context: {
    theme: 'dark',
  }
};</pre>
<p><span>Светлая тема</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_light_nebulajs.png"><img fetchpriority="high" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_light_nebulajs.png" alt="" width="524" height="436" class="aligncenter size-full wp-image-2442" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_light_nebulajs.png 524w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_light_nebulajs-300x250.png 300w" sizes="(max-width: 524px) 100vw, 524px" /></a></p>
<p><span>Темная тема</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_dark_nebulajs.png"><img decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_dark_nebulajs.png" alt="" width="523" height="434" class="aligncenter size-full wp-image-2443" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_dark_nebulajs.png 523w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_dark_nebulajs-300x249.png 300w" sizes="(max-width: 523px) 100vw, 523px" /><span></span></a></p>
<p><span>Вы также можете зарегистрировать собственные темы и применить одну из них в контексте:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  themes: [{
    id: 'pinkish',
    load: () =&gt; Promise.resolve({
      palettes: {
        data: [{
          scale: [
            '#fac6e5',
            '#ff95d6',
            '#e76eb1',
            '#b44772',
          ],
        }]
      }
    })
  }],
  context: {
    theme: 'pinkish'
  }
};</pre>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_pinkish_nebula.png"><img decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_pinkish_nebula.png" alt="" width="500" height="359" class="aligncenter size-full wp-image-2445" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_pinkish_nebula.png 500w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/theme_pinkish_nebula-300x215.png 300w" sizes="(max-width: 500px) 100vw, 500px" /></a></p>
<h2>Embedding visualizations. Встраивание визуализаций</h2>
<h3 data-testid="docs-header"><span>Встраивание визуализаций</span></h3>
<p><span>Вы можете встроить визуализацию двумя способами:</span></p>
<ol>
<li><span>На лету</span></li>
<li><span>Из существующего объекта</span></li>
</ol>
<p><span>Рендеринг выполняется с использованием </span><code class="language-text">render()</code><span>метода экземпляра, возвращаемого </span><code class="language-text">embed</code><span>функцией, который, как минимум, требует того, в который </span><code class="language-text">HTMLElement</code><span>вы хотите выполнить рендеринг:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { embed } from '@nebula.js/stardust';

const n = embed(enigmaApp);
n.render({
  element,
  // rest of the config
});</pre>
<h3 id="render-on-the-fly"><span>Рендеринг на лету</span></h3>
<p><span>При рендеринге визуализации на лету вам необходимо указать, что </span><code class="language-text">type</code><span> вы хотите визуализировать:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">n.render({
  element,
  type: 'barchart',
});</pre>
<p><span>Некоторые визуализации предъявляют минимальные требования к различным свойствам и / или данным, которые необходимо отображать, и в этом случае вы можете увидеть что-то вроде этого:</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/supernova_incomplete_nebulajs.png"><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/supernova_incomplete_nebulajs.png" alt="" width="747" height="489" class="aligncenter size-full wp-image-2447" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/supernova_incomplete_nebulajs.png 747w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/supernova_incomplete_nebulajs-300x196.png 300w" sizes="(max-width: 747px) 100vw, 747px" /></a></p>
<p><span>Чтобы предоставить визуализацию исходные данные, добавьте в </span><code class="language-text">fields</code><span>свойство измерения и меры данных :</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">n.render({
  element,
  type: 'barchart',
  fields: ['Region', '=sum(Sales)'],
});</pre>
<p><span>Вы также можете изменить начальные свойства:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">n.render({
  element,
  type: 'barchart',
  fields: ['Product', '=sum(Sales)'],
  properties: {
    title: 'Sales by region',
  },
});</pre>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/barchart_nebula.png"><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/barchart_nebula.png" alt="" width="773" height="529" class="aligncenter size-full wp-image-2448" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/barchart_nebula.png 773w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/barchart_nebula-300x205.png 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/barchart_nebula-768x526.png 768w" sizes="(max-width: 773px) 100vw, 773px" /></a></p>
<h2 id="render-from-existing-objects"><span>Рендеринг из существующих объектов</span></h2>
<p><span>Если вы уже создали общий объект в своем приложении и хотите его отобразить, вы можете сделать это, предоставив объекту </span><code class="language-text">id</code><span>:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">n.render({
  element,
  id: '&lt;ObjectID&gt;',
});</pre>
<h2>Current app selections. Выборки текущего приложения</h2>
<p><span>Важной частью Qlik является фильтрация данных с помощью выборок. Большинство диаграмм поддерживают выбор в данных, которые они отображают, которые затем отфильтровывают данные и влияют на другие диаграммы, подключенные к той же модели данных.</span></p>
<h3 id="current-app-selections-bar"><span>Панель выбора текущего приложения</span></h3>
<p><span>На панели выбора текущего приложения отображаются активные в данный момент выборки в указанном приложении. Для рендеринга этого бара вам сначала понадобится </span><code class="language-text">HTMLElement</code><span>:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">&lt;div class="curr-selections"&gt;&lt;/div&gt;</pre>
<p><span>Затем вы можете </span><code class="language-text">mount</code><span>выбрать пользовательский интерфейс в этом элементе:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">const n = embed(enigmaApp);

(await n.selections()).mount(document.querySelector('.curr-selections'));</pre>
<p><span>Без каких-либо выделений должно получиться так:</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/nebulajs_selectbar.png"><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/nebulajs_selectbar.png" alt="" width="790" height="57" class="aligncenter size-full wp-image-2449" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/nebulajs_selectbar.png 790w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/nebulajs_selectbar-300x22.png 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/nebulajs_selectbar-768x55.png 768w" sizes="(max-width: 790px) 100vw, 790px" /></a></p>
<p><span>Когда вы начинаете применять выборки в различных диаграммах, пользовательский интерфейс обновляется, чтобы отразить текущее состояние:</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/selections_update.gif"><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/selections_update.gif" alt="" width="792" height="520" class="aligncenter size-full wp-image-2450" /></a></p>
<h3 id="multiple-bars"><span>Несколько баров</span></h3>
<p><span>Если вы подключены к нескольким приложениям, вы можете отобразить текущий выбор в каждом из них, установив панель в разные элементы:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">(await embed(enigmaApp).selections()).mount(document.querySelector('.curr-selections'));

(await embed(anotherApp, { context: { theme: 'dark' } }).selections()).mount(
  document.querySelector('.another-curr-selections')
);</pre>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/selections_multiple_barchart_nebulajs.gif"><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/selections_multiple_barchart_nebulajs.gif" alt="" width="1020" height="428" class="aligncenter size-full wp-image-2451" /></a></p>
<h1>DEVELOPING VISUALIZATIONS. РАЗРАБОТКА ВИЗУАЛИЗАЦИЙ</h1>
<h2>Visualization. Визуализация</h2>
<h3 id="whats-a-visualization"><span>Что такое визуализация</span></h3>
<p><span>Визуализация в контексте этого API представляет собой визуальный вывод некоторых базовых данных, хранящихся в ассоциативной модели данных Qlik. Это может быть почти все, что вы хотите, и оно традиционно разработано для отображения данных в форме диаграммы, таблицы, kpi и т. Д.</span></p>
<p><strong>Визуализация состоит из двух основных частей: </strong></p>
<ul>
<li><span>backend <em>Generic Object</em></span><span>, который описывает </span><em><span>свойства</span></em><span> этого визуализация и сохраняется в модели данных, </span></li>
<li><span>и внешний интерфейс визуальной части, которая производит рендеринг <em>layout</em>  </span><span>из <em>Generic Object</em></span><span>.</span></li>
</ul>
<h4 id="definition"><span>Определение</span></h4>
<p><span>Минимальная визуализация, которая не содержит никаких данных и ничего не отображает, выглядит так:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">export default function () {
  return {
    qae: {
      /* */
    },
    component() {},
  };
}</pre>
<p><span>Здесь </span><code class="language-text">component()</code><span>вы визуализируете визуальную часть, а </span><code class="language-text">qae</code><span>здесь вы определяете свойства и данные, обрабатываемые ассоциативным механизмом Qlik (QAE).</span></p>
<h2>Rendering. Рендеринг</h2>
<p><span>В </span><code class="language-text">component</code><span>части определения происходит весь рендеринг, это просто функция, которая ничего не возвращает:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">export default function () {
  return {
    component() {
      // rendering logic goes here
    },
  };
}</pre>
<p><span>Чтобы отрендерить что-то, что вам нужно для доступа к элементу DOM, которому назначена визуализация, вы можете сделать это, импортировав </span><code class="language-text">useElement</code><span> функцию:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useElement } from '@nebula.js/stardust';</pre>
<p><span>Эта функция возвращает простой HTMLElement, который является вашей точкой входа в визуальный мир:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">component() {
  const element = useElement();
  element.innerHTML = 'Hello!';
}</pre>
<p><code class="language-text">useElement</code><span>&#8211; это одна из многих функций, которые удовлетворяют наиболее распространенные требования при разработке визуализации, они позволяют </span><em><span>подключаться</span></em><span> к ресурсам, предоставляемым обеими </span><code class="language-text">stardust</code><span>сторонами и ассоциативным движком Qlik.</span></p>
<h3 id="hooks">Hooks</h3>
<p><span>Если вы работали с </span><a href="https://reactjs.org/"><span>React,</span></a><span> вы могли узнать это как </span><em><span>хуки</span></em><span> . Хуки &#8211; это концепция, в которой упор делается на многократно используемые составные функции, а не на классические объектно-ориентированные классы и наследование. Хотя реализация полностью настраивается с использованием настраиваемых хуков, концепция и правила очень похожи, настолько, что вы можете прочитать </span><a href="https://reactjs.org/docs/hooks-intro.html"><span>документацию</span></a><span> по <a href="https://reactjs.org/docs/hooks-intro.html">крючкам React,</a> чтобы понять, как использовать собственные хуки stardust.</span></p>
<h4 id="useelement">useElement</h4>
<p><span>Вы уже видели </span><code class="language-text">useElement</code><span>крючок, его единственная цель &#8211; предоставить HTMLElement, к которому вы должны прикрепить свои собственные элементы, чтобы сделать ваш контент видимым, в следующем примере для элемента </span><code class="language-text">innerHTML</code><span>установлено значение </span><code class="language-text">Hello!</code><span>:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">component() {
  // get the element
  const element = useElement();
  // set element content
  element.innerHTML = 'Hello!';
}</pre>
<p><span>Однако статическая строка не даст многого, в большинстве случаев вы обновляете контент на основе ввода данных, состояния компонентов и взаимодействия с пользователем.</span></p>
<p><span></span><code class="language-text">component()</code><span>Функция выполняется каждый раз , когда что &#8211; то , что может быть связано с вашими изменениями рендеринга; тема, модель данных, выбор данных, состояние компонента и т. д. Таким образом, добавление и удаление прослушивателей событий, обновление узлов DOM и выборка данных не идеальны и могут быть довольно тяжелыми для производительности, если делать это каждый раз при </span><code class="language-text">component()</code><span>запуске. Вместо этого вы должны выполнять пакетные обновления с </span><code class="language-text">useEffect</code><span>.</span></p>
<h4 id="useeffect"><span>useEffect</span></h4>
<p><code class="language-text">useEffect</code><span>&#8211; это ловушка, которая принимает функцию обратного вызова, которая запускается только при изменении указанного вами значения. Это позволяет не только выполнять пакетные обновления, но и реализовывать собственную форму управления жизненным циклом в вашем компоненте.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useEffect } from '@nebula.js/stardust';
// ...
component() {
  const element = useElement();

  useEffect(() =&gt; {
    // run only once when the component is created
    console.log('created');
  }, []);
}</pre>
<p><span>Добавление слушателей событий к элементу обычно выполняется только при запуске компонента, а затем удаляется при его уничтожении:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">component() {
  const element = useElement();

  useEffect(() =&gt; {
    const listener = () =&gt; {
      console.log('clicked');
    };

    element.addEventListener('click', listener);

    return () =&gt; {
      // clean-up
      element.removeEventListener('click', listener);
    };
  }, [element]);
}</pre>
<p><span>В предыдущем примере </span><code class="language-text">element</code><span>в качестве второго аргумента предоставляется наблюдаемое значение, поэтому эффект запускается только при </span><code class="language-text">element</code><span>изменении. Однако, поскольку </span><code class="language-text">element</code><span>никогда не изменяется для одного и того же компонента, обратный вызов запускается только один раз при создании компонента. Таким образом </span><code class="language-text">listener</code><span>, экземпляр может быть создан только один раз, и </span><code class="language-text">click</code><span>добавляется только один прослушиватель событий. Обратный вызов также возвращает функцию в конце, это функция очистки, которая выполняется при изменении любого из наблюдаемых значений или при уничтожении компонента. Здесь вы должны очистить все добавленные побочные эффекты, в этом случае прослушиватель событий удаляется, чтобы избежать утечки памяти.</span></p>
<h4 id="usestate"><span>useState</span></h4>
<p><span>Поскольку </span><code class="language-text">component()</code><span>это функция, а не экземпляр класса или объекта, вы не можете использовать его </span><code class="language-text">this</code><span>для хранения значений экземпляра, как в противном случае. Способ хранения состояния </span><code class="language-text">useState</code><span>:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useState } from '@nebula.js/stardust';

export default function () {
  return {
    component() {
      const [count, setCount] = useState(0);
    },
  };
}</pre>
<p><code class="language-text">useState</code><span>возвращает кортеж, в котором первый элемент совпадает с начальным значением, указанным в качестве аргумента </span><code class="language-text">useState</code><span>, а второй элемент является функцией установки, с помощью которой вы можете изменить значение.</span></p>
<p><span>В следующем примере </span><code class="language-text">count</code><span>увеличивается на 1, когда пользователь нажимает </span><code class="language-text">element</code><span>:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">component() {
  const element = useElement();
  const [count, setCount] = useState(0);

  useEffect(() =&gt; {
    const listener = () =&gt; {
      setCount(count + 1);
    };

    element.addEventListener('click', listener);

    return () =&gt; {
      element.removeEventListener('click', listener);
    };
  }, [element]);
}</pre>
<p><span>Чтобы отобразить обновленное значение, вы можете добавить другое, </span><code class="language-text">useEffect</code><span>которое будет запускаться при </span><code class="language-text">count</code><span>изменении:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">const [count, setCount] = useState(0);
useEffect(() =&gt; {
  element.innerHTML = `Count: ${count}`;
}, [count]);</pre>
<h2>Configuring data. Конфигурирование данных</h2>
<p><span>В </span><code class="language-text">qae</code><span>разделе определения вы определяете свойства универсального объекта и форму данных, которые вы ожидаете использовать.</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  "qae": {
    "properties": {}
  }
}</pre>
<h3 id="generic-object"><span>Общий объект</span></h3>
<p><span>Каждая визуализация связана со всей моделью данных и ассоциативным механизмом Qlik через </span><em><span>универсальный объект</span></em><span> . Это объект JSON, содержащий </span><em><span>свойства, в</span></em><span> результате которых создается </span><em><span>макет</span></em><span> , описывающий состояние внутренней части визуализации.</span></p>
<p><span>Каждый раз, когда кто-то хочет визуализировать вашу визуализацию, в модели данных создается экземпляр универсального объекта. Если у создателя есть необходимые разрешения, он может сохранить и сохранить этот объект в своей модели данных.</span></p>
<h3 id="properties"><span>Свойства</span></h3>
<p><span>Какие свойства вы устанавливаете, полностью зависит от вас, однако это должен быть действительный объект JSON. Большинство свойств &#8211; это просто настройки, которые вы, возможно, захотите сохранить с течением времени. Если вы разрабатываете гистограмму, вы можете сохранить настройку, которая указывает, следует ли ее складывать или какой цвет должны иметь столбцы:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  "isStacked": true,
  "barColor": "red"
}</pre>
<p><span>Эти свойства </span><em><span>статичны</span></em><span> , то, что входит, выходит точно так же. Истинная сила универсального объекта &#8211; это </span><em><span>динамические</span></em><span> свойства, которые вы можете установить, что позволяет вам использовать ассоциативный механизм Qlik и получать доступ к данным внутри него.</span></p>
<p><span>Динамические свойства имеют особую структуру, которая позволяет серверной части различать динамические и статические свойства. У них также есть соглашение об именах: все они начинаются с </span><code class="language-text">q</code><span>буквы, за которой следует заглавная буква, что позволяет людям и машинам легко различать два типа свойств.</span></p>
<p><span>Существует множество различных </span><a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas"><span>предопределенных</span></a><span> динамических свойств для различных целей, например, вы можете использовать </span><a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas%2Fentries%2FValueExpression"><span>ValueExpression</span></a><span> для выполнения простых вычислений:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  "simpleMath": {
    "qValueExpression": {
      "qExpr": "1+1"
    }
  }
}</pre>
<h4 id="layout">Layout (Макет/Слой)</h4>
<p><span><em>layout </em>из Generic Object является результатом статических и динамических свойств. layout предыдущих свойств выглядит следующим образом:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  "isStacked": true,
  "barColor": "red",
  "simpleMath": 2
}</pre>
<p><span>Обратите внимание, что статические свойства остаются точно такими же, в то время как динамическое свойство </span><code class=" language-text">simpleMath</code><span>теперь содержит вычисленный результат ValueExpression.</span></p>
<p><span>Большинство динамических свойств имеют определение ввода и соответствующий вывод макета; а </span><a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas%2Fentries%2FListObjectDef"><span>ListObjectDef</span></a><span> приводит к </span><a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas%2Fentries%2FListObject"><span>ListObject</span></a><span> , а </span><a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas%2Fentries%2FSelectionObjectDef"><span>SelectionObjectDef</span></a><span> результаты в </span><a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas%2Fentries%2FSelectionObject"><span>SelectionObject</span></a><span> , и так далее.</span></p>
<h3 id="data"><span>Данные</span></h3>
<p><span>Наиболее часто используемым определением свойства является </span><a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas%2Fentries%2FHyperCubeDef"><span>HyperCubeDef</span></a><span> , это динамическое свойство, которое предоставляет вам данные из внутренней модели данных. Вы можете разместить это в корне объекта свойств или на более глубоком уровне, и у вас может быть столько, сколько вам нужно:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  "qHyperCubeDef": {},
  "anotherOne": {
    "qHyperCubeDef": {},
    "andAThird": {
      "qHyperCubeDef": {}
    }
  }
}</pre>
<p><span>Основными входными данными HyperCubeDef являются </span><em><span>измерения</span></em><span> и </span><em><span>меры</span></em><span> :</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  "qHyperCubeDef": {
    "qDimensions": [{ "qLibraryId": "hdg534" }],
    "qMeasures": [{ "qLibraryId": "gt5dgd" }]
  }
}</pre>
<p><span>В этом случае измерения и меры жестко запрограммированы на предопределенное значение, которое может существовать в определенной модели данных, что редко бывает тем, что вам нужно. Если вы разрабатываете диаграмму для использования другими с какой-либо моделью данных, которая вам нужна, чтобы можно было добавлять их динамически, вы можете сделать это, указав </span><em><span>целевые объекты данных</span></em><span> .</span></p>
<h4 id="data-targets"><span>Цели данных</span></h4>
<p><span>Целевой объект данных &#8211; это способ определить, где расположены динамические HyperCubeDef в свойствах универсального объекта. Хотя вы </span><code class=" language-text">stardust</code><span>можете просматривать свойства и находить все их использования </span><code class=" language-text">qHyperCubeDef</code><span>, вы можете не захотеть, чтобы все они были динамическими, или вы можете сгенерировать их только для внутреннего использования.</span></p>
<p><span>Вы указываете целевые объекты данных с помощью </span><code class=" language-text">data.targets</code><span>ключа </span><code class=" language-text">qae</code><span>, каждая цель должна иметь </span><code class=" language-text">path</code><span>ключ, который указывает путь JSON к HyperCubeDef из корня объекта свойств:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">qae: {
  properties: {
    qHyperCubeDef: {},
    my: {
      nested: {
        qHyperCubeDef: {}
      },
    }
  },
  data: {
    targets: [
      { path: '/qHyperCubeDef' },
      { path: '/my/nested/qHyperCubeDef' },
    ];
  }
}</pre>
<p><span>Вы можете для каждого целевого объекта данных указать дополнительные сведения, такие как максимальное / минимальное количество измерений и мер, и внести изменения при их добавлении.</span></p>
<p><span>Это полезно, когда вы знаете ограничения того, что может отображать диаграмма. Например, круговая диаграмма в основном используется, когда у нее есть ровно одно измерение и одна мера, но вы также можете реализовать поддержку второй меры. Это также избавляет вас от некоторой логики кода, поскольку </span><code class=" language-text">stardust</code><span>не пытается отобразить диаграмму, ограничения которой не были выполнены, а вместо этого показывает, что некоторые поля отсутствуют.</span></p>
<h4 id="field-limitations">Field limitations. <span>Ограничения поля</span></h4>
<p><span>Чтобы указать ограничения для измерений или показателей, добавьте каждый соответствующий тип поля как объект как часть целевого объекта данных:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">targets: [
  {
    path: '/qHyperCubeDef',
    dimensions: {
      min: 1,
      max: 1,
    },
    measures: {
      min: 1,
      max: 2,
    },
  },
];</pre>
<h3 id="field-modifications">Field modifications</h3>
<p><span>Вы также можете изменить добавленное или удаленное поле непосредственно перед тем, как изменение будет применено и отправлено на серверную часть, это полезно для таких вещей, как настройка сортировки при добавлении измерения или добавление дополнительных свойств, которые, как вы знаете, всегда необходимы.</span></p>
<p><span>Если вы, например, хотите убедиться, что нулевые значения подавляются, поскольку это не то, что вы можете визуализировать или представить в хорошем виде, вы можете установить, </span><code class=" language-text">qNullSuppression: true</code><span>когда добавляется измерение:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">dimensions: {
  added(dimension) {
    dimension.qNullSuppression = true;
  }
}</pre>
<h2>Consuming data. Потребление данных</h2>
<h3 id="access-layout">Access layout</h3>
<p><span>Вы можете получить доступ к <em>layout</em> Generic Object</span><span> через набор предопределенных hooks.</span></p>
<h4 id="uselayout">useLayout</h4>
<p><code class="language-text">useLayout</code><span> возвращает </span>evaluated layout свойств Generic Object:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useLayout } from '@nebula.js/stardust';

export default function () {
  return {
    qae: {
      properties: {
        qHyperCubeDef: {},
        simpleMath: {
          qValueExpression: {
            qExpr: '1+1',
          },
        },
      },
    },
    component() {
      const layout = useLayout();
      console.log(layout); // { qHyperCube: {/* HyperCube Layout */}, simpleMath: 2 }
    },
  };
}</pre>
<p><span>Вы должны </span><code class="language-text">useEffect</code><span>при наблюдении изменений на </span><code class="language-text">layout</code><span>:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">const layout = useLayout();

useEffect(() =&gt; {
  // do some heavy update
}, [layout]);</pre>
<h4 id="useapplayout">useAppLayout</h4>
<p><code class="language-text">useAppLayout</code><span>возвращает </span><a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas%2Fentries%2FNxAppLayout"><span>NxAppLayout,</span></a><span> к <a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas%2Fentries%2FNxAppLayout">которому</a> вы в данный момент подключены:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useAppLayout } from '@nebula.js/stardust';

export default function () {
  return {
    component() {
      const appLayout = useAppLayout();
      console.log(appLayout); // { qTitle: 'App title', qLocaleInfo: {/* */ } }
    },
  };
}</pre>
<p><span>Наиболее распространенный вариант использования макета приложения &#8211; это доступ, </span><code class="language-text">qLocaleInfo</code><span>который содержит сведения о локали, выбранные владельцем приложения и должен использоваться для форматирования чисел.</span></p>
<h3 id="models">Models. <span>Модели</span></h3>
<p><span>Помимо макетов приложения и универсального объекта, у вас есть полный доступ к API, созданным с помощью </span><code class="language-text">enigma.js</code><span>. Эти API-интерфейсы генерируются из схемы JSON-RPC и раскрывают всю мощь Associate Engine Qlik.</span></p>
<h4 id="usemodel"><span>useModel</span></h4>
<p><code class="language-text">useModel</code><span>возвращает сгенерированный API </span><a href="https://qlik.dev/apis/json-rpc/qix/genericobject#%23%2Fentries%2FGenericObject"><span>Generic Object</span></a><span> :</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useModel } from '@nebula.js/stardust';

export default function () {
  return {
    component() {
      const model = useModel();
      model.getInfo().then((info) =&gt; {
        console.log(info);
      });
    },
  };
}</pre>
<p><span>Общие операции в этом API:</span></p>
<ul>
<li><span>делать выбор с помощью </span><code class="language-text">beginSelections</code><span>,  </span><code class="language-text">selectHyperCubeValues</code> и <code class="language-text">endSelections</code></li>
<li><span>получить больше данных с </span><code class="language-text">getHyperCubeData</code></li>
</ul>
<h4 id="useapp"><span>useApp</span></h4>
<p><code class="language-text">useApp</code><span>возвращает сгенерированный API <a href="https://qlik.dev/apis/json-rpc/qix/doc#%23%2Fentries%2FDoc">Doc</a>:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useApp } from '@nebula.js/stardust';

export default function () {
  return {
    component() {
      const app = useApp();
      app.clearAll();
    },
  };
}</pre>
<p><span>Общие операции в этом API:</span></p>
<ul>
<li><span>изменять стек выбора с </span><code class="language-text">clearAll</code><span>,  </span><code class="language-text">back</code><span>,</span><code class="language-text">forward</code></li>
<li><span>создавать и применять закладки с помощью </span><code class="language-text">createBookmark</code> и <code class="language-text">applyBookmark</code></li>
</ul>
<h3 id="useglobal"><span>useGlobal</span></h3>
<p><code class="language-text">useGlobal</code><span>возвращает сгенерированный API </span><a href="https://qlik.dev/apis/json-rpc/qix/global#%23%2Fentries%2FGlobal"><span>Global</span></a><span> :</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useGlobal } from '@nebula.js/stardust';

export default function () {
  return {
    component() {
      const g = useGlobal();
      g.engineVersion().then((v) =&gt; {
        console.log(v);
      });
    },
  };
}</pre>
<p><span>Общие операции в этом API:</span></p>
<ul>
<li><span>получить список приложений с </span><code class="language-text">getDocList</code></li>
</ul>
<h2>HyperCube introduction. Введение в HyperCube</h2>
<p><span>Это </span><code class="language-text">HyperCubeDef</code><span>фундаментальная структура, которую вы настраиваете, прежде чем вам будет предоставлен результат в виде файла </span><code class="language-text">HyperCube</code><span>. Не позволяйте имени пугать вас, хотя оно содержит множество свойств и может быть настроено разными способами, в своей основной форме оно напоминает простую таблицу со строками и столбцами.</span></p>
<h3 id="hypercubedef-configuration"><span>Конфигурация HyperCubeDef</span></h3>
<p><span>Не все свойства одинаково важны, и есть несколько ключевых, о которых нужно помнить при настройке </span><code class="language-text">HyperCubeDef</code><span>.</span></p>
<h4 id="qmode"><span>qMode</span></h4>
<p><span>Хотя вам может не потребоваться </span><code class="language-text">qMode</code><span>явно устанавливать, поскольку по умолчанию используется простейший режим </span><code class="language-text">'S'</code><span>, важно знать, какое влияние он оказывает на структуру данных.</span></p>
<p><code class="language-text">qMode: 'P'</code><span>, или </span><em><span>режим</span></em><span> сводной таблицы, дает вам структуру, подходящую для представления сводных таблиц с группами как в вертикальном, так и в горизонтальном направлениях, а также группы для всех показателей.</span></p>
<p><code class="language-text">qMode: 'T'</code><span>, или </span><em><span>древовидный режим</span></em><span> , дает вам структуру, напоминающую дерево и подходящую для визуализации древовидных визуализаций; древовидная карта, упаковка кругов, солнечные лучи, дендрограмма, решётка и т. д.</span></p>
<p><code class="language-text">qMode: 'S'</code><span>, или </span><em><span>прямой режим</span></em><span> , является самым простым из них и дает вам структуру данных, которая выглядит как простая таблица со строками и столбцами. Для простоты объяснения остальной части гиперкуба можно предположить, что он используется.</span></p>
<h4 id="qdimensions-and-qmeasures"><span>qDimensions и qMeasures</span></h4>
<p><code class="language-text">qDimensions</code><span>и </span><code class="language-text">qMeasures</code><span>являются столбцами вашей «таблицы», нет явного ограничения на их количество, которое вы можете добавить, но часто существует ограничение на количество измерений и мер, которые может обрабатывать определенная диаграмма, и вам нужно сохранить это количество из них в виду, когда вы укажете </span><code class="language-text">qInitialDataFetch</code><span>.</span></p>
<h4 id="qinitialdatafetch"><span>qInitialDataFetch</span></h4>
<p><span>Ассоциативный движок Qlik &#8211; это решение на основе памяти, что означает, что объем данных, которые он может обрабатывать, полностью зависит от ресурсов памяти, к которым у него есть доступ. Таким образом, он может содержать миллиарды значений данных, и поэтому количество строк в гиперкубе также потенциально может достигать миллиардов.</span></p>
<p><span>Чтобы избежать случаев, когда такие огромные объемы данных передаются в интерфейсную часть, гиперкуб по умолчанию вообще не включает никаких строк. Чтобы контролировать это, вы можете установить количество строк и столбцов, которое вы хотите изначально </span><code class="language-text">qInitialDataFetch</code><span>. Это свойство позволяет вам установить </span><em><span>страницы данных, которые</span></em><span> вы хотите извлечь из всего гиперкуба, поэтому вы можете, например, выбрать получение первых 50 строк:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">qHyperCubeDef: {
  qInitialDataFetch: [{ qLeft: 0, qTop: 0, qHeight: 50, qWidth: 4 }];
}</pre>
<p><span>Если вы думаете о прямой таблице как о сетке, из которой вы хотите извлечь некоторые данные, тогда </span><code class="language-text">qLeft</code><span>и </span><code class="language-text">qTop</code><span>&#8211; это верхний левый угол подмножества, которое вы хотите извлечь, а </span><code class="language-text">qHeight</code><span>и </span><code class="language-text">qWidth</code><span>&#8211; количество строк и столбцов.</span></p>
<p><span>Однако существует максимальный предел в 10 000 ячеек, которые вы можете извлечь за один раз, и это количество вызывает ошибку. Поэтому вам нужно следить за количеством столбцов может потребоваться для обеспечения общей не превышает 10 000. Если вы, например , знаете , что вы никогда не нужно больше , чем 4 колонки, то вы можете установить </span><code class="language-text">qHeight</code><span>на </span><code class="language-text">10000/4</code><span>:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">qInitialDataFetch: [{ qLeft: 0, qTop: 0, qHeight: 2500, qWidth: 4 }];</pre>
<p><span>Первоначальная выборка данных указывает только самую большую возможную часть всего гиперкуба в макете, если в гиперкубе всего 7 строк, вы не получите больше 7. Вы также можете динамически получать больше данных позже.</span></p>
<h3 id="consuming-the-hypercube"><span>Потребление HyperCube</span></h3>
<p><span>Выход, или </span><em><span>компоновка</span></em><span> , из </span><code class=" language-text">HyperCubeDef</code><span>является </span><a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas%2Fentries%2FHyperCube"><span>гиперкубом</span></a><span> . В макете он расположен в том же месте, что и вы определили в своих свойствах, но без </span><code class=" language-text">Def</code><span>, например ввода:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  properties: {
    qHyperCubeDef: {},
    another: {
      one: {
        qHyperCubeDef: {}
      }
    }
  }
}</pre>
<p><span>приводит к выводу:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">{
  layout: {
    qHyperCube: {},
    another: {
      one: {
        qHyperCube: {}
      }
    }
  }
}</pre>
<p><span>Рядом с </span><code class=" language-text">qDimensionInfo</code><span>и </span><code class=" language-text">qMeasureInfo</code><span>свойствами , которые содержат ваши размеры и меры, наиболее важную часть гиперкуба являются </span><em><span>страницы данных</span></em><span> .</span></p>
<h4 id="data-pages"><span>Страницы данных</span></h4>
<p><span>На страницах данных содержатся фактические значения данных гиперкуба, где именно и какая структура они имеют, зависит от </span><code class=" language-text">qMode</code><span>значения, которое вы установили ранее. Для режима </span><code class=" language-text">'S'</code><span>это место </span><code class=" language-text">qDataPages</code><span>, которое, в свою очередь, содержит </span><code class=" language-text">qArea</code><span>и </span><code class=" language-text">qMatrix</code><span>.</span></p>
<p><span>Предполагая, что гиперкуб содержит одно измерение, </span><em><span>название фильма</span></em><span> , и одну меру, </span><em><span>средний рейтинг</span></em><span> , содержимое может выглядеть следующим образом:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">qDataPages: [
  {
    qMatrix: [
      [
        // first row
        { qText: '2 Fast 2 Furious', qNum: 'NaN', qElemNumber: 447, qState: 'O' }, // NxCell
        { qText: '6.2', qNum: 6.2, qElemNumber: 0, qState: 'L' },
      ],
      [
        // second
        { qText: '2 Guns', qNum: 'NaN', qElemNumber: 681, qState: 'O' },
        { qText: '6.6', qNum: 6.6, qElemNumber: 0, qState: 'L' },
      ],
    ],
    qArea: { qTop: 0, qLeft: 0, qWidth: 2, qHeight: 2 },
  },
];</pre>
<p><span>Помимо текстовых и числовых значений, каждая </span><a href="https://qlik.dev/apis/json-rpc/qix/schemas#%23%2Fdefinitions%2Fschemas%2Fentries%2FNxCell"><span>ячейка NxCell</span></a><span> содержит </span><code class=" language-text">qElemNumber</code><span>свойство, известное как </span><em><span>ранг</span></em><span> . Ранг для ячейки измерения можно рассматривать как свойство, которое однозначно идентифицирует текстовое значение этой ячейки в своем поле во всей модели данных. Вы можете использовать это свойство для обеспечения единообразного поведения во всем приложении, вы можете, например, установить постоянный цвет значений измерения в поле, когда и где бы они ни использовались:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">// color scheme
const colors = ['#26A0A7', '#79D69F', '#F9EC86', '#EC983D'];

const cellColor = colors[cell.qElemNumber % colors.length];</pre>
<p><span>Это свойство также необходимо отслеживать, когда вы хотите сделать выбор в своей диаграмме.</span></p>
<h4 id="getting-more-data"><span>Получение дополнительных данных</span></h4>
<p><span>Из-за ограничения объема данных, которые вы можете получить в исходном макете, могут возникнуть ситуации, когда вам потребуется получить остальные данные, если вы хотите отобразить их больше. Вы можете сделать это с помощью методов, представленных в </span><em><span>модели</span></em><span> универсального объекта. Какой метод использовать, опять же, зависит </span><code class=" language-text">qMode</code><span>от гиперкуба, для </span><code class=" language-text">'S'</code><span>режима это </span><a href="https://qlik.dev/apis/json-rpc/qix/genericobject#%23%2Fentries%2FGenericObject%2Fentries%2FGetHyperCubeData"><span>GetHyperCubeData</span></a><span> .</span></p>
<p><span>При подкачке данных в прямом режиме вы должны начать с просмотра </span><code class=" language-text">qHyperCubeDef.qSize</code><span>свойства, которое содержит информацию о ширине и высоте полного гиперкуба. Исходя из этого, вы можете рассчитать количество страниц, которые вам нужно получить:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useModel, useLayout, useEffect } from '@nebula.js/stardust';

const NUM_CELLS_PER_PAGE = 10000;
const MAX_PAGES = 10;
// ...
component() {
  const model = useModel();
  const layout = useLayout();

  useEffect(() =&gt; {
    const Y = layout.qHyperCube.qSize.qcy;
    const X = layout.qHyperCube.qSize.qcx;

    const HEIGHT_PER_PAGE = Math.ceil(NUM_CELLS_PER_PAGE / X);
    const NUM_PAGES = Math.floor(MAX_PAGES, Math.ceil(Y / HEIGHT_PER_PAGE));

    const pagesToFetch = [];
    for (let i = 0; i &lt; NUM_PAGES; i++) {
      pagesToFetch.push({ qLeft: 0, qTop: i * HEIGHT_PER_PAGE, qHeight: HEIGHT_PER_PAGE, qWidth: X });
    }

    Promise.all(pagesToFetch.map((page) =&gt; model.getHyperCubeData('/qHyperCubeDef', [page]))).then((pages) =&gt; {
      console.log(pages);
    });
  }, [layout]);

}</pre>
<p><span>Однако вы должны быть </span><strong><span>очень</span></strong><span> осторожны при динамической выборке таких данных, имейте в виду, что размер куба может исчисляться миллионами, выборка такого большого набора данных может занять время и создать очень плохое взаимодействие с пользователем. В предыдущем примере максимальное количество страниц установлено равным 10, так что всего выбирается не более 100 000 значений.</span></p>
<p><span>Вы также можете использовать другие методы, чтобы не получать все данные сразу. </span><em><span>Виртуальная прокрутка</span></em><span> в сочетании с регулированием каждого запроса может значительно повысить производительность. Вам также следует рассмотреть возможность использования сокращенного набора данных, если вам не нужны точные значения:</span></p>
<ul>
<li><a href="https://qlik.dev/apis/json-rpc/qix/genericobject#%23%2Fentries%2FGenericObject%2Fentries%2FGetHyperCubeBinnedData"><span>getHyperCubeBinnedData</span></a><span> связывает точки данных в группы и отлично подходит для тепловых карт и 2D-графиков плотности.</span></li>
<li><a href="https://qlik.dev/apis/json-rpc/qix/genericobject#%23%2Fentries%2FGenericObject%2Fentries%2FGetHyperCubeContinuousData"><span>getHyperCubeContinuousData</span></a><span> уменьшает количество точек в непрерывном измерении и отлично подходит для временных данных.</span></li>
<li><a href="https://qlik.dev/apis/json-rpc/qix/genericobject#%23%2Fentries%2FGenericObject%2Fentries%2FGetHyperCubeReducedData"><span>getHyperCubeReducedData</span></a><span> выполняет некоторую магию вейвлетов и отлично подходит для мини-диаграмм.</span></li>
</ul>
<h2>Selecting data. Выбор данных</h2>
<p><span>Выборка &#8211; это фундаментальная часть ассоциативного механизма Qlik. Все поля и связи между ними содержатся в ассоциативной модели. Когда вы применяете выбор, вы не только применяете фильтр в модели данных, но также демонстрируете связи между вашими источниками данных.</span></p>
<h3 id="applying-selections"><span>Applying selections. </span><span>Применение выделений</span></h3>
<p><span>Выборки можно применять с помощью методов, представленных в модели, возвращенной из </span><code class="language-text">useModel</code><span>хука.</span></p>
<p><span>Поскольку универсальный объект может содержать несколько гиперкубов, вам всегда нужно указать, какой гиперкуб вы хотите выбрать, указав его путь JSON в качестве первого аргумента:</span></p>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useModel } from '@nebula.js/stardust';
// ...
component() {
  const model = useModel();

  useEffect(() =&gt; {
    model.selectHyperCubeCells('/qHyperCubeDef', [1], []);
  }, [model])
}</pre>
<h3 id="selection-patterns"><span>Шаблоны выбора. Selection patterns</span></h3>
<p><span>Есть два разных шаблона выбора: мгновенный и модальный.</span></p>
<h4 id="instant-selections"><span>Мгновенный выбор. Instant selections</span></h4>
<p><span>Как видно из названия, этот тип шаблона является немедленным и фильтрует как источник выбора, так и все, на что он влияет.</span></p>
<p><span>В следующем примере, как только значение выбрано на гистограмме, фильтрация применяется мгновенно, и обе диаграммы немедленно обновляются отфильтрованными данными:</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/selections_instant_qlik_sense_nebula_js_nebulajs_api.gif"><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/selections_instant_qlik_sense_nebula_js_nebulajs_api.gif" alt="" width="912" height="388" class="aligncenter size-full wp-image-2460" /></a></p>
<h4 id="modal-selections"><span>Модальный выбор. Modal selections</span></h4>
<p><span>Когда инициируется модальный выбор, источник выбора входит в форму модального состояния, которое позволяет пользователю изменять выбор до подтверждения изменений.</span></p>
<p><span>В следующем примере пользователь сначала выбирает одно значение на линейчатой ​​диаграмме, после чего другие диаграммы обновляются, как и раньше. Однако гистограмма по-прежнему содержит все доступные данные и позволяет пользователю выбрать другое значение перед подтверждением изменений и обновлением самой гистограммы:</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/selections_modal_qlik_sense_nebula_js_nebulajs_api.gif"><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2020/11/selections_modal_qlik_sense_nebula_js_nebulajs_api.gif" alt="" width="912" height="388" class="aligncenter size-full wp-image-2462" /></a></p>
<p><span>Чтобы реализовать этот тип паттерна, вам необходимо выполнить несколько простых шагов </span><code class=" language-text">useSelections</code><span>в сочетании с </span><code class=" language-text">useModel</code><span>ними:</span></p>
<ol>
<li><span>Войдите в модальное состояние, позвонив </span><code class=" language-text">beginSelections</code><span>.</span></li>
<li><span>Выберите значения.</span></li>
<li><span>Обеспечьте визуальную обратную связь с пользователем о том, что было выбрано, например, изменив прозрачность выбранных значений.</span></li>
<li><span>Следите за выходом из модального состояния, чтобы сбросить визуальную обратную связь.</span></li>
</ol>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">import { useModel, useSelections, useElement } from '@nebula.js/stardust';
// ...
component() {
  const element = useElement();
  const model = useModel();
  const selections = useSelections();

  useEffect(() =&gt; {
    const clicked = () =&gt; {
      const clickedOnRow = 1;

      // 1. enter modal state if not already in it
      if (!selections.isActive()) {
        selections.beginSelections(['/qHyperCubeDef']);
      }
      // 2. select the clicked row
      model.selectHyperCubeCells('/qHyperCubeDef', [clickedOnRow], []);
    }

    element.addEventListener('click', clicked);
    return () =&gt; {
      element.removeEventListener('click', clicked);
    }
  }, [element, model, selections]);

  useEffect(() =&gt; {
    if (layout.qSelectionInfo.qInSelections) {
      // 3. update with visual feedback on active selections
      // YOUR CODE HERE
    } else {
      // 4. normal update
      // YOUR CODE HERE
    }
  }, [layout]);
}</pre>
<p>&nbsp;</p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/nebula-js-qlik-sense-api-javascript-library-examples/">nebula.js &#8211; Qlik Sense API Javascript библиотека. Примеры</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qliksense.ivan-shamaev.ru/nebula-js-qlik-sense-api-javascript-library-examples/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Руководство разработчика API &#8211; Справочник по Qlik Sense API</title>
		<link>https://qliksense.ivan-shamaev.ru/api-reference-qlik-sense-qliksense/</link>
					<comments>https://qliksense.ivan-shamaev.ru/api-reference-qlik-sense-qliksense/#respond</comments>
		
		<dc:creator><![CDATA[qliksense-expert]]></dc:creator>
		<pubDate>Fri, 09 Aug 2019 12:40:45 +0000</pubDate>
				<category><![CDATA[Уровень 2]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[API Qlik Engine]]></category>
		<category><![CDATA[PowerShell & Qlik Sense Engine API]]></category>
		<category><![CDATA[Python Connection Qlik API]]></category>
		<category><![CDATA[Qlik]]></category>
		<category><![CDATA[qlik sense]]></category>
		<category><![CDATA[qlik sense api]]></category>
		<category><![CDATA[Qlik Sense API & Python]]></category>
		<category><![CDATA[qlik sense method api]]></category>
		<category><![CDATA[методы api]]></category>
		<category><![CDATA[подключение к qlik sense api]]></category>
		<category><![CDATA[подключение к qlik sense desktop api]]></category>
		<guid isPermaLink="false">https://qliksense.ivan-shamaev.ru/?p=1397</guid>

					<description><![CDATA[<p>Введение в Qlik Sense API. Руководство для разработчика Engine JSON API Qlik Engine JSON API представляет собой протокол WebSocket, который использует JSON для передачи информации между Qlik Sense Engine и клиентами. Qlik Engine JSON API состоит из набора объектов , представляющих приложения, списки и так далее. Эти объекты организованы в<a class="moretag" href="https://qliksense.ivan-shamaev.ru/api-reference-qlik-sense-qliksense/"> Читать дальше&#8230;</a></p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/api-reference-qlik-sense-qliksense/">Руководство разработчика API &#8211; Справочник по Qlik Sense API</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2>Введение в Qlik Sense API. Руководство для разработчика</h2>
<h2>Engine JSON API</h2>
<p><strong>Qlik Engine JSON API</strong> представляет собой протокол WebSocket, который использует JSON для передачи информации между Qlik Sense Engine и клиентами. Qlik Engine JSON API состоит из набора объектов , представляющих приложения, списки и так далее. Эти объекты организованы в иерархическую структуру. Когда вы отправляете запросы в API, вы выполняете действия над этими объектами.</p>
<p><strong>Qlik Engine JSON API может быть использован для:</strong></p>
<ul>
<li>создания приложений и загрузки данных</li>
<li>создания историй (data stories)</li>
<li>получение системной информации</li>
</ul>
<p><strong>Типичные ситуации, в которых вы бы использовали JSON API Qlik Engine:</strong></p>
<ul>
<li>создание специализированного клиента в качестве</li>
<li>автономного или веб-приложения</li>
<li>автоматизация повторяющихся или сложных</li>
<li>обновлений или изменений в приложениях</li>
</ul>
<h2>Extension API</h2>
<p>API расширения (Extension API) состоит из методов и свойств, используемых для создания пользовательских расширений визуализации (custom visualization extensions).</p>
<h2>Backend API</h2>
<p>Backend API состоит из нескольких методов и используется для связи с ассоциативным механизмом Qlik. Он предоставляет вспомогательные функции для вызовов ассоциативного механизма Qlik и доступ к данным ассоциативного механизма Qlik. Вкратце, Backend API &#8211; это оболочка для выбранных методов Qlik Engine JSON API, но с той разницей, что Backend API знает о контексте, то есть текущем соединении WebSocket и приложении Qlik Sense.</p>
<h2>Capability APIs</h2>
<p><strong>API-интерфейсы Capability</strong> представляют собой набор API-интерфейсов JavaScript, которые позволяют легко встраивать контент Qlik Sense в веб-страницу. С помощью всего лишь нескольких строк кода можно создать визуализацию, использующую библиотеку визуализации Qlik Sense.</p>
<p>API-интерфейсы Capability зависят от AngularJS и RequireJS, поэтому вам необходимо принять это во внимание при интеграции API-возможностей Capability в существующий проект, в котором также используются эти библиотеки.</p>
<p><strong>Термин «API-интерфейс Capability»</strong> был введен в Qlik Sense 2.1. Некоторые из API-интерфейсов Capability были доступны до этой версии, опубликованной под названием Mashup API.</p>
<table width="286" style="width: 100%; height: 324px;">
<tbody>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><span style="color: #003300;"><strong>Capability API</strong></span></td>
<td width="171" style="height: 27px;"><span style="color: #003300;"><strong>Namespace</strong></span></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>Root API</strong></td>
<td width="171" style="height: 27px;"><em>qlik</em></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>App API</strong></td>
<td width="171" style="height: 27px;"><em>qlik.app</em></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>Bookmark API</strong></td>
<td width="171" style="height: 27px;"><em>qlik.app.bookmark</em></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>Field API</strong></td>
<td width="171" style="height: 27px;"><em>qlik.app.field</em></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>Selection API</strong></td>
<td width="171" style="height: 27px;"><em>qlik.app.selectionState</em></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>Variable API</strong></td>
<td width="171" style="height: 27px;"><em>qlik.app.variable</em></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>Visualization API</strong></td>
<td width="171" style="height: 27px;"><em>qlik.app.visualization</em></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>Global API</strong></td>
<td width="171" style="height: 27px;"><em>qlik.global</em></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>Navigation API</strong></td>
<td width="171" style="height: 27px;"><em>qlik.navigation</em></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>Table API</strong></td>
<td width="171" style="height: 27px;"><em>qlik.table</em></td>
</tr>
<tr style="height: 27px;">
<td width="115" style="height: 27px;"><strong>Theme API</strong></td>
<td width="171" style="height: 27px;"><em>qlik.theme</em></td>
</tr>
</tbody>
</table>
<h3>Root API</h3>
<p>Root API является внешним интерфейсом Qlik Sense и доступен в виде пространства имен qlik. Он предоставляет методы открытия приложений, получения ссылки на текущее приложение, установки определенного языка и регистрации обратных вызовов для обработки ошибок. Корневой API также содержит методы для перечисления доступных приложений и расширений, а также для регистрации расширений (extensions), которые вы создаете на лету (используя API визуализации &#8211; Visualization API).</p>
<h3>App API</h3>
<p>Метод qlik.openApp является точкой входа в API приложения и возвращает объекты JavaScript приложения с методами для работы с приложением Qlik Sense, к которому вы подключены.</p>
<h3>Bookmark API</h3>
<p>Bookmark API содержит методы для работы с закладками в приложении Qlik Sense, к которому вы подключены.</p>
<h3>Field API</h3>
<p>Метод qlik.app.field является точкой входа в Field API. Он возвращает объект QField с методами и свойствами, которые можно использовать для управления полем.</p>
<h3>Global API</h3>
<p>Метод qlik.global является точкой входа в Global API. Возвращает объект JavaScript с глобальными методами.</p>
<h3>Navigation API</h3>
<p>Navigation API (API навигации) позволяет вам перемещаться в приложении Qlik Sense и предназначен для использования в виджетах и ​​расширениях визуализации, и не будет работать в сценариях Mashup.</p>
<h3>Selection API</h3>
<p>Selection API является внешним интерфейсом для изменения выборки по модели данных Qlik Sense (фильтрация данных) и позволяет разработчикам работать с ассоциативной моделью.</p>
<h3>Table API</h3>
<p>Table API (API таблиц) позволяет разработчикам работать с табличными данными, возвращаемыми из ассоциативного механизма Qlik, не имея глубоких знаний о внутренних конструкциях, таких как, например, Гиперкуб (Hypercube).</p>
<h3>Theme API</h3>
<p>Theme API &#8211; это внешний интерфейс для тем Qlik Sense. Он позволяет настраивать визуализации, включая расширения и виджеты, вне Qlik Sense.</p>
<h3>Variable API</h3>
<p><span>Variable API &#8211; это внешний интерфейс для управления переменными </span><span class="CommonComponentsQlik Sense"><span>Qlik Sense</span></span><span>.</span></p>
<h3>Visualization API</h3>
<p>Visualization API (API визуализации) &#8211; это внешний интерфейс для визуализаций Qlik Sense. Вы можете создавать новые визуализации на лету на основе объекта сессии. Эти визуализации не сохраняются в приложении. Вы также можете получить уже существующие визуализации из приложения, используя Visualization API.</p>
<h2>Custom Component API</h2>
<p>API для создания пользовательских компонентов (собственных компонентов).</p>
<p><span>Пользовательские компоненты содержат следующие элементы:</span></p>
<ul>
<li><span>Файл определения (QEXT).</span></li>
<li><span>Основной файл JavaScript.</span></li>
<li><span>Дополнительные ресурсы, такие как библиотеки JavaScript, изображения и шрифты.</span></li>
</ul>
<p><span>Пользовательские компоненты &#8211; это в основном директивы AngularJS. </span><span>Цель файла JavaScript &#8211; вернуть подпись директивы AngularJS.</span></p>
<h2>App Integration API<span style="color: #ff6600;"><em><strong></strong></em></span></h2>
<p>Используется для embedded аналитика, позволяет генерировать ссылки url для встраивания в iframe.</p>
<h2>Single Integration API</h2>
<p><span>Single Integration API позволяет создавать URL-адреса, который возвращает полную HTML-страницу, содержащую, например, встроенную визуализацию </span><span class="CommonComponentsQlik Sense"><span>Qlik Sense</span></span><span> . Этот URL-адрес можно встроить в веб-страницу, например, включив его в iframe.</span></p>
<h2>qlik-visual web component</h2>
<p>Qlik-Visual Web Component &#8211; это определение пользовательского элемента &lt;qlik-visual&gt;, которое использует API визуализации и представляет его как веб-компонент. Он позволяет создавать и изменять визуализации на лету, не используя клиент Qlik Sense.</p>
<p><strong>Qlik Visual поддерживает:</strong></p>
<ul>
<li>Отображение существующей визуализации (путем определения видимости элемента) на веб-странице.</li>
<li>Создание визуализаций на лету с использованием существующего приложения путем внедрения их в веб-страницу.</li>
<li>Динамически изменяющие свойства и атрибуты визуализаций.</li>
</ul>
<h2>enigma.js</h2>
<p><strong>Библиотека enigma.js</strong> помогает вам общаться с ассоциативным механизмом Qlik в Qlik Sense и Qlik Sense Desktop. Вы можете использовать его для создания своего собственного клиента или для создания собственного сервиса Node.js. <strong>Примерами использования могут быть создание ваших собственных аналитических инструментов на основе браузера, серверных служб или сценариев командной строки.</strong></p>
<p>Библиотека <strong>enigma.js</strong> может использоваться в качестве SDK или для выполнения операций CRUD (то есть создания, чтения, обновления и удаления) в приложениях и в сущностях приложений.</p>
<p><span><strong>enigma.js</strong> &#8211; это библиотека, предназначенная исключительно для <strong>Engine API (websocket)</strong>. </span><span>Экспорт изображений / PDF-файлов &#8211; это API-интерфейсы REST в Qlik Sense для других служб (отчеты), которые предоставляются через интерфейс capability API:</span></p>
<ul>
<li><a href="https://help.qlik.com/en-US/sense-developer/September2019/Subsystems/APIs/Content/Sense_ClientAPIs/CapabilityAPIs/VisualizationAPI/exportImg-method.htm" target="_blank" rel="noopener noreferrer">https://help.qlik.com/en-US/sense-developer/September2019/Subsystems/APIs/Content/Sense_ClientAPIs/CapabilityAPIs/VisualizationAPI/exportImg-method.htm</a></li>
<li><a href="https://help.qlik.com/en-US/sense-developer/September2019/Subsystems/APIs/Content/Sense_ClientAPIs/CapabilityAPIs/VisualizationAPI/exportPdf-method.htm" target="_blank" rel="noopener noreferrer">https://help.qlik.com/en-US/sense-developer/September2019/Subsystems/APIs/Content/Sense_ClientAPIs/CapabilityAPIs/VisualizationAPI/exportPdf-method.htm</a></li>
</ul>
<p><strong>Официальная документация Enigma.JS:</strong> <a href="https://github.com/qlik-oss/enigma.js" target="_blank" rel="noopener noreferrer">https://github.com/qlik-oss/enigma.js</a></p>
<h2>enigma-go</h2>
<p>Библиотека enigma-go помогает вам общаться с ассоциативным механизмом Qlik в Qlik Sense и Qlik Sense Desktop. Примерами использования могут быть создание ваших собственных аналитических инструментов, серверных служб или других инструментов, взаимодействующих с ассоциативным механизмом Qlik. Библиотека enigma-go может использоваться в качестве SDK или для выполнения операций CRUD (то есть создания, чтения, обновления и удаления) в приложениях и в сущностях приложений.</p>
<h2>leonardo-ui</h2>
<p>leonardo-ui &#8211; это библиотека с открытым исходным кодом, которая используется в Qlik Sense и предоставляет множество графических компонентов пользовательского интерфейса. Разметка этих компонентов может использоваться в расширениях, гибридных приложениях и виджетах. Библиотека поддерживается и поддерживается Qlik. leonardo-ui можно использовать как с Qlik Sense, так и с Qlik Sense Desktop.</p>
<h2>picasso.js</h2>
<p>Библиотека диаграмм picasso.js оптимизирована для создания пользовательских, интерактивных и мощных визуализаций для платформы Qlik Sense Analytics.</p>
<h2><madcap:concept term="Building visualization extensions" xmlns:madcap="http://www.madcapsoftware.com/Schemas/MadCap.xsd"><span class="OpenSourceNebula">nebula.js</span></madcap:concept></h2>
<p><strong><span class="OpenSourceNebula">nebula.js</span></strong><span> &#8211; это библиотека с открытым исходным кодом, разработанная на GitHub. </span><span class="OpenSourceNebula"><span>nebula.js</span></span><span> &#8211; это набор библиотек и API-интерфейсов JavaScript, не <span class="OpenSourceNebula">зависящих</span> от продукта и инфраструктуры, который помогает разработчикам интегрировать визуализации и гибридные приложения поверх </span><span class="CommonComponentsEngineName"><span>ассоциативного механизма </span></span><span></span><span class="CommonComponentsSenseDesktopName"><span>Qlik</span></span><span> в <span class="CommonComponentsSenseDesktopName">Qlik Sense Desktop</span> , </span><span class="CommonComponentsQlik Sense Enterprise for Windows, with Multi-Cloud"><span>Qlik Sense Enterprise для Windows</span></span><span> и </span><span class="CommonComponentsQlikSenseCloudEnvironments"><span>SaaS-версиях Qlik Sense</span></span><span> . Он предлагает разработчикам альтернативу capability APIs, которые исторически использовались для создания гибридных приложений.</span></p>
<p><span>Чтобы использовать </span><span class="OpenSourceNebula"><span>nebula.js</span></span><span> , вы должны быть знакомы с JavaScript, promises, websockets и библиотеками с открытым исходным кодом. Вам понадобится Node.js и доступ к </span><span class="CommonComponentsEngineName"><span>ассоциативному движку Qlik</span></span><span> . Также будет полезно знание таких концепций Qlik, как generic objects и гиперкубы.</span></p>
<h1>Qlik Explorer для разработчиков</h1>
<p><strong>Qlik Explorer для разработчиков</strong> &#8211; это инструмент, созданный для упрощения процесса интеграции функциональности Qlik Sense в другие среды.</p>
<p><strong>Qlik Explorer</strong> для разработчиков обеспечивает быстрый доступ к соответствующей информации из вашей среды Qlik Sense, что, например, позволяет легко интегрировать визуализации Qlik Sense в существующий веб-сайт.</p>
<p><strong>Автоматическое обновление</strong><br />Qlik Explorer для разработчиков автоматически обновляется при появлении новой версии.</p>
<h2>Как подключить Qlik Explorer к Qlik Sense Desktop Hub</h2>
<p>В настройках вбиваете http://localhost:4848/</p>
<p><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_qliksense_api_explorer_developer_1.jpg" alt="" width="942" height="658" class="aligncenter wp-image-1429 size-full" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_qliksense_api_explorer_developer_1.jpg 942w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_qliksense_api_explorer_developer_1-300x210.jpg 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_qliksense_api_explorer_developer_1-768x536.jpg 768w" sizes="(max-width: 942px) 100vw, 942px" /></p>
<p>После подключения отобразится список приложений со свойствами и методами. <strong>Profit <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></strong></p>
<p><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_qliksense_api_explorer_developer_2.jpg" alt="" width="1365" height="615" class="aligncenter size-full wp-image-1428" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_qliksense_api_explorer_developer_2.jpg 1365w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_qliksense_api_explorer_developer_2-300x135.jpg 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_qliksense_api_explorer_developer_2-768x346.jpg 768w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_qliksense_api_explorer_developer_2-1024x461.jpg 1024w" sizes="(max-width: 1365px) 100vw, 1365px" /></p>
<h1><span>Engine API Explorer в браузере</span></h1>
<p><span>http://localhost:4848/dev-hub/engine-api-explorer</span></p>
<iframe src="//docs.google.com/viewer?url=https%3A%2F%2Fqliksense.ivan-shamaev.ru%2Fwp-content%2Fuploads%2F2019%2F08%2FQlik_Engine_API_05242016.docx&hl=ru&embedded=true" class="gde-frame" style="width:100%; height:500px; border: none;" scrolling="no"></iframe>
<p class="gde-text"><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/Qlik_Engine_API_05242016.docx" class="gde-link">Скачать (DOCX, 661KB)</a></p>
<h1>Подключение к API Qlik Engine</h1>
<p><span style="color: #ff6600;"><em><strong>todo</strong></em></span></p>
<h2 _ngcontent-c2="">Подключение к Qlik Sense API с помощью PowerShell</h2>
<p>https://community.qlik.com/t5/Qlik-Sense-Integration/How-to-export-an-app-to-a-folder-using-API-and-Powershell/td-p/1608192</p>
<h2 _ngcontent-c2="" class="gp-title gp-indi-project">Qlik Sense python API client for QPS and QRS interfaces</h2>
<p>https://developer.qlik.com/garden/570e73c36c8c33c066a0f11c</p>
<h2>Пример подключения Python 3 к Qlik Sense Engine API</h2>
<p>Для подключения и работы необходимо установить библиотеки:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">pip3 install asyncio
pip3 install websocket-client
pip3 install requests_ntlm
pip3 install requests
pip3 install json</pre>



<p>Дальше приведен скрипт подключения Python 3 к Qlik Sense Desktop:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">from websocket import create_connection

import json

ws = create_connection("ws://localhost:4848/app/")

data=json.dumps({
    'jsonrpc': '2.0',
    'id': 2,
    'method': 'GetActiveDoc',
    'handle': 1,
    'params': ['C:\\Users\\User\\Documents\\Qlik\\Sense\\Apps\\Анализ продаж - простое приложение.qvf']
})

print("Sending req...")
ws.send(data)

print("Receiving...")
result = ws.recv()

print("Received '%s'" % result)

qclosed = ws.close()
print("Closed '%s'" % qclosed)
</pre>
<p>Результат работы скрипта:</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">&gt;&gt;&gt; 
 RESTART: D:/QlikProject/Подключаемся к Qlik Sense из Python.py 
Sending req...
Receiving...
Received '{"jsonrpc":"2.0","method":"OnConnected","params":{"qSessionState":"SESSION_CREATED"}}'
Closed 'None'</pre>
<h2>Пример скрипта Python 3 для получения списка документов с hub Qlik Sense Desktop</h2>
<pre class="EnlighterJSRAW" data-enlighter-language="null">from websocket import create_connection

import json

ws = create_connection("ws://localhost:4848/app/")

ws.send(json.dumps({
  "handle": -1,
  "method": "GetDocList",
  "params": [],
  "outKey": -1,
  "id": 1
}))

result = ws.recv()

while result:
    result=ws.recv()
    y = json.loads(result)
    print(y)

ws.close()</pre>
<p><strong>Список классов, свойств и методов</strong> <a href="https://betahelp.qlik.com/en-US/sense-developer/June2019/apis/EngineAPI/index.html" target="_blank" rel="noopener noreferrer">https://betahelp.qlik.com/en-US/sense-developer/June2019/apis/EngineAPI/index.html</a></p>
<p><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/Qlik_Sense_Request_Response.png" alt="" width="505" height="246" class="aligncenter size-full wp-image-1436" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/Qlik_Sense_Request_Response.png 505w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/Qlik_Sense_Request_Response-300x146.png 300w" sizes="(max-width: 505px) 100vw, 505px" /></p>
<h2>Подключаемся к Qlik Sense Engine API с помощью Node.JS</h2>
<p>Рассматривается пример подключения к Qlik Sense Desktop</p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">const WebSocket = require('ws');

const ws = new WebSocket('ws://localhost:4848/app/engineData');

var request = {
    "handle": -1,
    "method": "GetDocList",
    "params": {},
    "outKey": -1,
    "id": 2
}

ws.onopen = function(event){
    ws.send(JSON.stringify(request));
    
    ws.onmessage = function (event) {
        var response = JSON.parse(event.data);

        if(response.method != ' OnConnected'){
            
            var obj = response.result;
            str = JSON.stringify(obj, null, 4);
            console.log(str);

        }
   }
}</pre>
<h2>Получаем перечень приложений Qlik Sense Desktop с помощью Enigma JS</h2>
<pre class="EnlighterJSRAW" data-enlighter-language="js">const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');

// create a new session:
const session = enigma.create({
  schema,
  url: 'ws://localhost:4848/app/engineData',
  createSocket: url =&gt; new WebSocket(url),
});

// bind traffic events to log what is sent and received on the socket:
session.on('traffic:sent', data =&gt; console.log('sent:', data));
session.on('traffic:received', data =&gt; console.log('received:', data));

// open the socket and eventually receive the QIX global API, and then close
// the session:
session.open()
    .then(function(global) {
        global.getDocList().then(function(docList) {
            for (i = 0; i &lt; docList.length; i++) {
                var AppName = docList[i].qDocName;
                console.log('App list:',JSON.stringify(AppName));
            }

            session.close();
        })
    });</pre>
<h2>Получаем свойства документа Qlik Sense с помощью запроса Enigma.JS через QS API Engine</h2>
<pre class="EnlighterJSRAW" data-enlighter-language="null">const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');

// create a new session:
const session = enigma.create({
  schema,
  url: 'ws://localhost:4848/app/engineData',
  createSocket: url =&gt; new WebSocket(url),
});

// bind traffic events to log what is sent and received on the socket:
session.on('traffic:sent', data =&gt; console.log('sent:', data));
session.on('traffic:received', data =&gt; console.log('received:', data));

// open the socket and eventually receive the QIX global API, and then close
// the session:
session.open()
    .then(function(global) {
        global.getDocList().then(docs=&gt;{
            global.openDoc("Анализ продаж - простое приложение.qvf").then(doc=&gt;{
                doc.getAppProperties().then(appProp =&gt; {
                    console.log(doc)
                    console.log(appProp)
                })
            })
        })
    })</pre>
<h2>Пример получения списка полей в Qlik Sense API Engine, с помощью Enigma.JS</h2>
<p>Пример актуален для Qlik Sense Desktop</p>
<pre class="EnlighterJSRAW" data-enlighter-language="null">const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');

// Создаем новую сессию:
const session = enigma.create({
  schema,
  url: 'ws://localhost:4848/app/engineData',
  createSocket: url =&gt; new WebSocket(url),
});

// Привязываем traffic events к log (что отправлено и что получено socket)
session.on('traffic:sent', data =&gt; console.log('sent:', data));
session.on('traffic:received', data =&gt; console.log('received:', data));

var config = { 
    schema: schema,
    docId: "Анализ продаж - простое приложение.qvf"
}

// Открываем сессию
session.open()
    .then(function(global) {

        global.openDoc(config.docId).then(function(doc){
            //Создаем SessionObject для FieldList
            doc.createSessionObject( {
                qFieldListDef: {
                    qShowSystem: false,
                    qShowHidden: false,
                    qShowSrcTables: true,
                    qShowSemantic: true,
                    qShowDerivedFields: true
                }, 
                qInfo: {
                    qId: "FieldList",
                    qType: "FieldList"
                }
            } ).then( function(list) {
                return list.getLayout();
                } ).then( function(listLayout) {
                    return listLayout.qFieldList.qItems;
                    } ).then( function(fieldItems) {
                        console.log(fieldItems)
                        } );
        })
    });</pre>
<h2>Пример javascript скрипта выгрузки / экспорта данных из QS, используя Enigma.JS</h2>
<p>В результате выполнения JS-скрипта Вы получите qURL:</p>
<blockquote>
<p class="EnlighterJSRAW" data-enlighter-language="null"><em>qUrl:&#8221;/Exports/1b2f8662-570b-4f77-b37b-94a4a347fe91\FileName(6bb5e11a-427a-4e77-ac30-e49abf602c87).xlsx&#8221;</em></p>
</blockquote>
<p data-enlighter-language="null"><strong>Код запроса exportData Enigma.JS Qlik Sense Table API:</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">const enigma = require('enigma.js');
const WebSocket = require('ws');
const schema = require('enigma.js/schemas/12.20.0.json');

// Создаем новую сессию:
const session = enigma.create({
  schema,
  url: 'ws://localhost:4848/app/engineData',
  createSocket: url =&gt; new WebSocket(url),
});

// Привязываем traffic events к log (что отправлено и что получено socket)
session.on('traffic:sent', data =&gt; console.log('sent:', data));
session.on('traffic:received', data =&gt; console.log('received:', data));

var config = { 
    schema: schema,
    docId: "Анализ продаж - простое приложение.qvf"
}

var exportOptions = {
    "qFileType": "OOXML",
    "qPath": "/qHyperCubeDef",
    "qFileName": "FileName",
    "qExportState": 1
}

// Открываем сессию
session.open()
    .then((global) =&gt; {
        console.log('We are connected!')
        global.openDoc(config.docId)
        .then(doc =&gt; {
            doc.getObject('XPbGUe')
            .then((api) =&gt; {
                api.exportData(exportOptions)
                .then((reply) =&gt; {
                    console.log(reply);
                });
            });
        });
    });</pre>
<h2>Пример javascript скрипта выгрузки / экспорта данных из Qlik Sense Enterprise, используя Enigma.JS</h2>
<p>Данные выгружаем из прямой таблицы, в поле <strong>TargetFieldSelect</strong> выбираем значение <strong>NeededValueToSelect</strong>.</p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">const enigma = require('enigma.js');
const WebSocket = require('ws');
const path = require('path');
const fs = require('fs');
const fetch = require('node-fetch');

const schema = require('enigma.js/schemas/12.20.0.json');
const { Console } = require('console');

// Your Sense Enterprise installation hostname:
const engineHost = 'qlik.company.com';

// Make sure the port below is accessible from the machine where this example
// is executed. If you changed the QIX Engine port in your installation, change this:
const enginePort = 4747;

// 'engineData' is a special "app id" that indicates you only want to use the global
// QIX interface or session apps, change this to an existing app guid if you intend
// to open that app:
const appId = 'engineData';

// The Sense Enterprise-configured user directory for the user you want to identify
// as:
const userDirectory = 'QLIKDEV';

// The user to use when creating the session:
const userId = 'username';

// Path to a local folder containing the Sense Enterprise exported certificates:
const certificatesPath = './';

// Helper function to read the contents of the certificate files:
const readCert = (filename) =&gt; fs.readFileSync(path.resolve(__dirname, certificatesPath, filename));

const session = enigma.create({
  schema,
  url: `wss://${engineHost}:${enginePort}/app/${appId}`,
  // Notice the non-standard second parameter here, this is how you pass in
  // additional configuration to the 'ws' npm library, if you use a different
  // library you may configure this differently:
  createSocket: (url) =&gt; new WebSocket(url, {
    ca: [readCert('root.pem')],
    key: readCert('client_key.pem'),
    cert: readCert('client.pem'),
    headers: {
      'X-Qlik-User': `UserDirectory=${encodeURIComponent(userDirectory)}; UserId=${encodeURIComponent(userId)}`,
    },
  }),
});


// Открываем сессию
session.open()
    .then((global) =&gt; {
        global.openDoc('03h5ed8-5gdfb-40a5-b733-41fc4beb718e')
        .then(doc =&gt; {
            doc.getField("TargetFieldSelect")
            .then((appField) =&gt; {
              appField.select('NeededValueToSelect',false,0)
              .then((selectResult) =&gt; {
                console.log(selectResult);

                doc.getObject('jwAJbyL')
                .then((objectTable) =&gt; {
                  objectTable.getHyperCubeData("/qHyperCubeDef", [{ qTop: 0, qWidth: 10, qLeft: 0, qHeight: 1000 }])
                  .then(function (data) {
                    let dataSTR = JSON.stringify(data[0].qMatrix);
                    fs.writeFileSync('DataOutput.json', dataSTR);

                    session.close();
                  })
                })   

                
              })
            })
            
        })
              
                


    });</pre>
<p>_____</p>



<h1>Описание архитектуры Qlik Engine API</h1>
<h2>Структура объектов</h2>
<p><strong>Схемка сделана &#8220;на глаз&#8221;, но вероятно так и работает.</strong></p>
<p><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_structure_object_api_nodejs_enigmajs.png" alt="" width="417" height="344" class="aligncenter size-full wp-image-1459" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_structure_object_api_nodejs_enigmajs.png 417w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/qlik_sense_structure_object_api_nodejs_enigmajs-300x247.png 300w" sizes="(max-width: 417px) 100vw, 417px" /></p>
<p><strong>API Component Overview</strong></p>
<p><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/API_components_overview.png" alt="" width="1932" height="1016" class="aligncenter wp-image-1460 size-full" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/API_components_overview.png 1932w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/API_components_overview-300x158.png 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/API_components_overview-768x404.png 768w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/API_components_overview-1024x539.png 1024w" sizes="(max-width: 1932px) 100vw, 1932px" /></p>
<p><strong>MindMap API Integration</strong></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/mindmap_API_Integration_QlikSense_Qlik.png" target="_blank" rel="noopener noreferrer"><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/mindmap_API_Integration_QlikSense_Qlik.png" alt="" width="993" height="983" class="aligncenter wp-image-1462 size-full" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/mindmap_API_Integration_QlikSense_Qlik.png 993w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/mindmap_API_Integration_QlikSense_Qlik-300x297.png 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/mindmap_API_Integration_QlikSense_Qlik-768x760.png 768w" sizes="(max-width: 993px) 100vw, 993px" /></a></p>
<p>Схема по-умолчанию для процесса authenticate (default flowchart)</p>
<p><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/default_flowchart_how_to_authenticate.png" alt="" width="952" height="1122" class="aligncenter size-full wp-image-1492" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/default_flowchart_how_to_authenticate.png 952w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/default_flowchart_how_to_authenticate-255x300.png 255w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/default_flowchart_how_to_authenticate-768x905.png 768w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/default_flowchart_how_to_authenticate-869x1024.png 869w" sizes="(max-width: 952px) 100vw, 952px" /></p>
<p><img loading="lazy" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/capabilities_API_DIV_tag_Saas_platform_to_proxy.png" alt="" width="904" height="644" class="aligncenter size-full wp-image-1744" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/capabilities_API_DIV_tag_Saas_platform_to_proxy.png 904w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/capabilities_API_DIV_tag_Saas_platform_to_proxy-300x214.png 300w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2019/08/capabilities_API_DIV_tag_Saas_platform_to_proxy-768x547.png 768w" sizes="(max-width: 904px) 100vw, 904px" /></p>
<p>&nbsp;</p>
<h2>YouTube Enigma.JS Qlik Sense API Development</h2>
<p><iframe title="Qlik Sense Development - Enigma.js to RxQ in ONE LINE OF CODE" width="750" height="563" src="https://www.youtube.com/embed/E4x6bMjyn74?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<h2>Youtube Другие видео по Qlik Sense API</h2>
<p><iframe title="Using the Qlik Sense Field API" width="750" height="422" src="https://www.youtube.com/embed/GJ0ImZR2ig0?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p><iframe title="Using the Qlik Sense Bookmark API" width="750" height="422" src="https://www.youtube.com/embed/OBGJErIwrto?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<p><iframe title="Qlik Sense API Based Mashups" width="750" height="422" src="https://www.youtube.com/embed/1rOu0sgvwwM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<h2><strong>Полезные ссылки по Enigma.JS и Qlik Sense API</strong></h2>
<ul>
<li><a href="https://dev.to/qlikbranch/getting-started-with-qlik-core-2781" target="_blank" rel="noopener noreferrer">https://dev.to/qlikbranch/getting-started-with-qlik-core-2781</a> &#8211; Getting Started with Qlik Core</li>
<li><a href="https://branch-blog.qlik.com/system-integration-with-qliks-apis-why-and-how-1663025cf54d" target="_blank" rel="noopener noreferrer">https://branch-blog.qlik.com/system-integration-with-qliks-apis-why-and-how-1663025cf54d</a> &#8211; System Integration with Qlik’s APIs — Why and How</li>
<li><a href="https://alcmst.net/2019/03/01/quiz-sense-who-wants-to-be-a-qlikionnaire/" target="_blank" rel="noopener noreferrer">https://alcmst.net/2019/03/01/quiz-sense-who-wants-to-be-a-qlikionnaire/</a> &#8211; Quiz Sense – Who wants to be a Qlikionnaire?</li>
</ul>
<p>_____</p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/api-reference-qlik-sense-qliksense/">Руководство разработчика API &#8211; Справочник по Qlik Sense API</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qliksense.ivan-shamaev.ru/api-reference-qlik-sense-qliksense/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
