<?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>Methods Qlik Sense Extension API - Qlik Sense - Обучение, учебник, онлайн курс</title>
	<atom:link href="https://qliksense.ivan-shamaev.ru/tag/methods-qlik-sense-extension-api/feed/" rel="self" type="application/rss+xml" />
	<link>https://qliksense.ivan-shamaev.ru/tag/methods-qlik-sense-extension-api/</link>
	<description>Qlik Sense на русском языке. Пошаговые уроки для изучения Клик Сенс</description>
	<lastBuildDate>Mon, 01 May 2023 15:08:55 +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>Methods Qlik Sense Extension API - Qlik Sense - Обучение, учебник, онлайн курс</title>
	<link>https://qliksense.ivan-shamaev.ru/tag/methods-qlik-sense-extension-api/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Доступ к системным данным и переменным в Extension Qlik Sense</title>
		<link>https://qliksense.ivan-shamaev.ru/accessing-system-data-and-variables-in-a-qlik-sense-extension/</link>
					<comments>https://qliksense.ivan-shamaev.ru/accessing-system-data-and-variables-in-a-qlik-sense-extension/#respond</comments>
		
		<dc:creator><![CDATA[qliksense-expert]]></dc:creator>
		<pubDate>Mon, 21 Feb 2022 06:57:50 +0000</pubDate>
				<category><![CDATA[Уровень 2]]></category>
		<category><![CDATA[Building visualization extensions]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[Methods Qlik Sense Extension API]]></category>
		<category><![CDATA[Доступ к системным переменным]]></category>
		<guid isPermaLink="false">https://qliksense.ivan-shamaev.ru/?p=2759</guid>

					<description><![CDATA[<p>Введение Иногда при создании расширения Qlik Sense вам необходимо получить доступ к системным данным. Это особенно актуально, если вы пытаетесь создать что-то более общее. Возможно, вам нужен список полей, измерений или показателей. Или вам нужно работать с переменными. Если вы новичок в разработке Qlik Sense, вы можете посмотреть в документации<a class="moretag" href="https://qliksense.ivan-shamaev.ru/accessing-system-data-and-variables-in-a-qlik-sense-extension/"> Читать дальше&#8230;</a></p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/accessing-system-data-and-variables-in-a-qlik-sense-extension/">Доступ к системным данным и переменным в Extension Qlik Sense</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Введение</h2>
<span>Иногда при создании расширения Qlik Sense вам необходимо получить доступ к системным данным. Это особенно актуально, если вы пытаетесь создать что-то более общее. Возможно, вам нужен список полей, измерений или показателей. Или вам нужно работать с переменными.</span>

<span>Если вы новичок в разработке Qlik Sense, вы можете посмотреть в документации по API способы получения необходимых данных. </span>

<strong><span>Не делай этого !!! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f615.png" alt="😕" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </span></strong>

<span>Модель расширения Qlik Sense основана на идее использования одного универсального объекта, описанного в расширениях <strong>initialProperties</strong> и измененного пользователем на панели свойств и, возможно, программно (но это действительно продвинуто). Таким образом, хотя использование методов API для получения дополнительных данных является одним из описанных подходов в Qlik Help, которые используются в гибридных приложениях или веб-приложения и обращаются к данным Qlik, вам следует избегать их использования в mashups.</span>
<h2><span>Почему не нужно использовать вызовы API</span></h2>
<span>Если вы используете эти вызовы API в своем расширении, у вас возникнут проблемы:</span>
<ul>
 	<li><span>вы можете легко получить утечку памяти или «утечку общих объектов», когда вы создаете множество общих объектов.</span></li>
 	<li><span>вы можете легко потерять контроль над всеми работающими функциями обратного вызова при повторной проверке общих объектов.</span></li>
 	<li><span>если пользователь делает снимок, вызовы API будут обращаться к последней версии данных, а не к той, что в снимке, и, возможно, дадут неправильные данные.</span></li>
 	<li><span>если пользователь попытается экспортировать ваше расширение в PDF или Excel, оно может сломаться, поскольку служба, отвечающая за этот экспорт, не имеет доступа к оперативным данным, а только к моментальному снимку.</span></li>
</ul>
<span>Если вам абсолютно необходимо использовать эти вызовы, вы должны по крайней мере включить экспорт в PDF и Excel и не разрешать моментальные снимки вашего расширения.</span>
<h2><span>Что нужно делать вместо этого</span></h2>
<span>К счастью, есть альтернативы. Все эти вызовы API создают общие объекты, но, поскольку общий объект является очень гибкой структурой, вы можете фактически настроить общий объект за своим расширением для предоставления необходимых вам данных. Вот небольшая таблица того, что вы можете использовать:</span>
<table id="tablepress-1" class="tablepress tablepress-id-1">
<thead>
<tr class="row-1 odd">
<th class="column-1"><strong>Что нужно</strong></th>
<th class="column-2"><strong>Не использовать вызов API</strong></th>
<th class="column-3"><strong>Вместо этого добавьте в initialProperties</strong></th>
</tr>
</thead>
<tbody class="row-hover">
<tr class="row-2 even">
<td class="column-1">List of fields</td>
<td class="column-2">app.getList(&#8220;FieldList&#8221;)</td>
<td class="column-3">qFieldListDef</td>
</tr>
<tr class="row-3 odd">
<td class="column-1">List of measures</td>
<td class="column-2">app.getList(&#8220;MeasureList&#8221;)</td>
<td class="column-3">qMeasureListDef</td>
</tr>
<tr class="row-4 even">
<td class="column-1">List of dimensions</td>
<td class="column-2">app.getList(&#8220;DimensionList&#8221;)</td>
<td class="column-3">qDimensionListDef</td>
</tr>
<tr class="row-5 odd">
<td class="column-1">List of variables</td>
<td class="column-2">app.getList(&#8220;VariableList&#8221;)</td>
<td class="column-3">qVariableListDef</td>
</tr>
<tr class="row-6 even">
<td class="column-1">Variable value</td>
<td class="column-2">app.variable.getContent(..)</td>
<td class="column-3">qStringExpression or
qValueExpression</td>
</tr>
</tbody>
</table>
<span>Вы найдете рабочий пример этого в репозитории  </span><a href="https://github.com/erikwett/syslist"><span>расширении системного списка, </span></a><span> просто не используйте его, он предназначен как пример того, как получить данные и на самом деле не делает ничего полезного. Но возьмите ту часть initialProperties, которая вам нужна для расширения.</span>

<strong>Это выглядит так:</strong>
<pre class="EnlighterJSRAW" data-enlighter-language="generic">initialProperties: {
                moneyFormat: {
                    qStringExpression: '=MoneyFormat'
                },
                qMeasureListDef: {
                    qType: "measure",
                    qData: {
                        qMeasure: "/qMeasure"
                    }
                },
                qDimensionListDef: {
                    qType: "dimension",
                    qData: {
                        qDim: "/qDim",
                        qDimInfos: "/qDimInfos"
                    }
                },
                qVariableListDef: {
                    qType: "variable",
                    qShowReserved: true,
                    qShowConfig: true
                },
                qFieldListDef: {
                    qShowSystem: true,
                    qShowHidden: true,
                    qShowSemantic: true,
                    qShowSrcTables: true,
                    qShowDerivedFields: true,
                    qShowImplicit: true
                }
            }</pre>
<h2><span>Когда следует использовать эти вызовы API</span></h2>
<span>Ну нет правил без исключений. Хотя вам следует избегать использования этих вызовов в API для части рендеринга вашего расширения, вы должны использовать их на своей панели свойств, если вам, например, нужно предоставить список полей пользователю. А в мэшапе они определенно очень полезны. И у API есть другие вызовы, которые вы, возможно, захотите использовать, но в основном это когда пользователь что-то делает, например, нажимает кнопку и т.д.</span>
<h2>Источник</h2>
https://extendingqlik.upper88.com/accessing-system-data-and-variables-in-a-qlik-sense-extension/<div class="learnpress"><div
	class="learn-press-message error lp-content-area">Этот шорткод LP Profile должен использоваться только на странице <a href="https://qliksense.ivan-shamaev.ru/wp-admin/admin.php?page=learn-press-settings"><strong>Учетная запись</strong></a></div>
</div>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/accessing-system-data-and-variables-in-a-qlik-sense-extension/">Доступ к системным данным и переменным в Extension Qlik Sense</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qliksense.ivan-shamaev.ru/accessing-system-data-and-variables-in-a-qlik-sense-extension/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Обзор Extension API и описание методов расширений</title>
		<link>https://qliksense.ivan-shamaev.ru/overview-qlik-extension-api-and-methods/</link>
					<comments>https://qliksense.ivan-shamaev.ru/overview-qlik-extension-api-and-methods/#respond</comments>
		
		<dc:creator><![CDATA[qliksense-expert]]></dc:creator>
		<pubDate>Sat, 09 Jan 2021 20:42:37 +0000</pubDate>
				<category><![CDATA[Уровень 2]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[extension api]]></category>
		<category><![CDATA[Methods Qlik Sense Extension API]]></category>
		<category><![CDATA[Qlik Sense Extension]]></category>
		<category><![CDATA[Qlik Sense Extensions]]></category>
		<category><![CDATA[Методы Qlik Sense Extension API]]></category>
		<guid isPermaLink="false">https://qliksense.ivan-shamaev.ru/?p=2494</guid>

					<description><![CDATA[<p>Введение в Extension API Extension API состоит из методов и свойств, используемых для создания custom расширений визуализации (или custom visualization extensions). Обзор Visualization extension templates Для начала рассмотрим шаблоны Visualization extension templates. В dev-hub при создании Extension вам предлагают выбрать шаблон. Basic Visualization template Назовем наш Extension &#8220;1_BVT&#8221;. При инициализации<a class="moretag" href="https://qliksense.ivan-shamaev.ru/overview-qlik-extension-api-and-methods/"> Читать дальше&#8230;</a></p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/overview-qlik-extension-api-and-methods/">Обзор Extension API и описание методов расширений</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h1>Введение в Extension API</h1>
<p><span><strong>Extension API</strong> состоит из методов и свойств, используемых для создания custom расширений визуализации (или <strong>custom visualization extensions</strong>).</span></p>
<h2>Обзор Visualization extension templates</h2>
<p>Для начала рассмотрим шаблоны <strong>Visualization extension templates</strong>. В <strong>dev-hub</strong> при создании Extension вам предлагают выбрать шаблон.</p>
<h3>Basic Visualization template</h3>
<p>Назовем наш Extension <strong>&#8220;1_BVT&#8221;</strong>. При инициализации создадутся два файла:</p>
<p><strong>1_BVT.qext</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
    "name": "1_BVT",
    "description": "Basic empty visualization template",
    "type": "visualization",
    "version": "1.0.0",
    "icon": "extension",
    "author": "",
    "homepage": "",
    "keywords": "qlik-sense, visualization",
    "license": "",
    "repository": "",
    "dependencies": {
        "qlik-sense": "&gt;=3.0.x"
    }
}</pre>
<p><strong>1_BVT.js</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">define( [ "qlik"
],
function ( qlik) {

    return {
        support : {
            snapshot: true,
            export: true,
            exportData : false
        },
        paint: function ($element) {
            //add your rendering code here
            $element.html( "1_BVT" );
            //needed for export
            return qlik.Promise.resolve();
        }
    };

} );</pre>
<h3>Chart Template</h3>
<p>Назовем наш Extension <strong>&#8220;2_CT&#8221;</strong>. При инициализации создадутся 4 файла:</p>
<p><strong>2_CT.qext</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
    "name": "2_CT",
    "description": "Chart visualization template",
    "icon": "bar-chart-horizontal",
    "type": "visualization",
    "version": "1.0.0",
    "author": "",
    "homepage": "",
    "keywords": "qlik-sense, visualization",
    "license": "",
    "repository": "",
    "dependencies": {
        "qlik-sense": "&gt;=3.0.x"
    }
}</pre>
<p><strong>2_CT.js</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">define( ["qlik", "text!./2_CT.ng.html", "css!./2_CT.css"],
    function ( qlik, template ) {
        "use strict";
        return {
            template: template,
            initialProperties: {
                qHyperCubeDef: {
                    qDimensions: [],
                    qMeasures: [],
                    qInitialDataFetch: [{
                        qWidth: 2,
                        qHeight: 50
                    }]
                }
            },
            definition: {
                type: "items",
                component: "accordion",
                items: {
                    dimensions: {
                        uses: "dimensions",
                        min: 1,
                        max: 1
                    },
                    measures: {
                        uses: "measures",
                        min: 1,
                        max: 1
                    },
                    sorting: {
                        uses: "sorting"
                    }
                }
            },
            support: {
                snapshot: true,
                export: true,
                exportData: true
            },
            paint: function () {
                //needed for export
                this.$scope.selections = [];
                return qlik.Promise.resolve();
            },
            controller: ["$scope", "$element", function ( $scope ) {
                $scope.getPercent = function ( val ) {
                    return Math.round( (val * 100 / $scope.layout.qHyperCube.qMeasureInfo[0].qMax) * 100 ) / 100;
                };

                $scope.selections = [];

                $scope.sel = function ( $event ) {
                    if ( $event.currentTarget.hasAttribute( "data-row" ) ) {
                        var row = parseInt( $event.currentTarget.getAttribute( "data-row" ), 10 ), dim = 0,
                            cell = $scope.$parent.layout.qHyperCube.qDataPages[0].qMatrix[row][0];
                        if ( cell.qIsNull !== true ) {
                            cell.qState = (cell.qState === "S" ? "O" : "S");
                            if ( $scope.selections.indexOf( cell.qElemNumber ) === -1 ) {
                                $scope.selections.push( cell.qElemNumber );
                            } else {
                                $scope.selections.splice( $scope.selections.indexOf( cell.qElemNumber ), 1 );
                            }
                            $scope.selectValues( dim, [cell.qElemNumber], true );
                        }
                    }
                };
            }]
        };

    } );</pre>
<p><strong>2_CT.css</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="css">.qv-object-2_CT .css_bars_row {
    transition: all 0.3s ease;
    float: left;
    width: 98%;
    overflow: hidden;
    border: 1px solid #ccc;
    background-color: #f0f0f0;
    margin-bottom: 2px;
    border-radius: 0 10px 10px 0;
    -moz-border-radius: 0 10px 10px 0;
    cursor: pointer;
}

.qv-object-2_CT .css_bars_bar {
    float: left;
    clear: left;
    height: 30px;
    background-color: #5f5f5f;
}

.qv-object-2_CT .css_bars_bar span {
    font-weight: bold;
    float: left;
    margin-left: 5px;
    margin-right: 5px;
    margin-top: 7px;
    color: #f0f0f0;
    overflow: hidden;
    text-overflow: ellipsis;
    width: 90%;
    white-space: nowrap;
}

.qv-object-2_CT .css_bars_per {
    position: relative;
}

.qv-object-2_CT .css_bars_per span {
    font-weight: bold;
    float: left;
    margin-right: 5px;
    margin-top: 5px;
    margin-left: 5px;
}

.qv-object-2_CT .css_bars_per span.over {
    position: absolute;
    right: 15px;
    color: #f0f0f0;
}

.qv-object-2_CT .css_bars_row:hover, .qv-object-2_CT .css_bars_row.selected {
    border: 1px solid #000;
}</pre>
<p><strong>2_CT.ng.html</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="html">&lt;div qv-extension style="height: 100%; position: relative; overflow: auto;"&gt;
    &lt;div class="css_bars_row" ng-repeat="item in layout.qHyperCube.qDataPages[0].qMatrix" title="{{item[0].qText}}" data-row="{{ $index }}"
         ng-click="sel($event)" data-value="{{ item[0].qElemNumber }}" ng-class="{selected: (item[0].qState) === 'S' || selections.indexOf(item[0].qElemNumber) !== -1 }"&gt;
        &lt;div class="css_bars_bar" ng-style="{'width':getPercent(item[1].qNum)+'%'}"&gt;&lt;span&gt;{{item[0].qText}}&lt;/span&gt;&lt;/div&gt;
        &lt;div class="css_bars_per"&gt;
            &lt;span ng-class="{over: (getPercent(item[1].qNum)&gt;95)}"&gt;{{getPercent(item[1].qNum)}} %&lt;/span&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;</pre>
<h3>Listbox template</h3>
<p>Назовем наш Extension &#8220;3_LBT&#8221;. При инициализации создадутся 3 файла:</p>
<p><strong>3_LBT.js</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">define( ["qlik", "jquery", "text!./style.css"], function ( qlik, $, cssContent ) {
    'use strict';
    $( "&lt;style&gt;" ).html( cssContent ).appendTo( "head" );
    return {
        initialProperties: {
            qListObjectDef: {
                qShowAlternatives: true,
                qFrequencyMode: "V",
                qInitialDataFetch: [{
                    qWidth: 2,
                    qHeight: 50
                }]
            }
        },
        definition: {
            type: "items",
            component: "accordion",
            items: {
                dimension: {
                    type: "items",
                    label: "Dimensions",
                    ref: "qListObjectDef",
                    min: 1,
                    max: 1,
                    items: {
                        label: {
                            type: "string",
                            ref: "qListObjectDef.qDef.qFieldLabels.0",
                            label: "Label",
                            show: true
                        },
                        libraryId: {
                            type: "string",
                            component: "library-item",
                            libraryItemType: "dimension",
                            ref: "qListObjectDef.qLibraryId",
                            label: "Dimension",
                            show: function ( data ) {
                                return data.qListObjectDef &amp;&amp; data.qListObjectDef.qLibraryId;
                            }
                        },
                        field: {
                            type: "string",
                            expression: "always",
                            expressionType: "dimension",
                            ref: "qListObjectDef.qDef.qFieldDefs.0",
                            label: "Field",
                            defaultValue: "=ValueList('A','B','C')",
                            show: function ( data ) {
                                return data.qListObjectDef &amp;&amp; !data.qListObjectDef.qLibraryId;
                            }
                        },
                        frequency: {
                            type: "string",
                            component: "dropdown",
                            label: "Frequency mode",
                            ref: "qListObjectDef.qFrequencyMode",
                            options: [{
                                value: "N",
                                label: "No frequency"
                            }, {
                                value: "V",
                                label: "Absolute value"
                            }, {
                                value: "P",
                                label: "Percent"
                            }, {
                                value: "R",
                                label: "Relative"
                            }],
                            defaultValue: "V"
                        }
                    }
                },
                settings: {
                    uses: "settings"
                }
            }
        },
        support : {
            snapshot: true,
            export: true,
            exportData : false
        },
        paint: function ( $element,layout ) {
            var self = this, html = "&lt;ul&gt;";
            layout.qListObject.qDataPages[0].qMatrix.forEach( function ( row ) {
                html += '&lt;li class="data state' + row[0].qState + '" data-value="' + row[0].qElemNumber + '"&gt;' + row[0].qText;
                if ( row[0].qFrequency ) {
                    html += '&lt;span&gt;' + row[0].qFrequency + '&lt;/span&gt;';
                }
                html += '&lt;/li&gt;';
            } );
            html += "&lt;/ul&gt;";
            $element.html( html );
            if ( this.selectionsEnabled ) {
                $element.find( 'li' ).on( 'click', function () {
                    if ( this.hasAttribute( "data-value" ) ) {
                        var value = parseInt( this.getAttribute( "data-value" ), 10 ), dim = 0;
                        self.selectValues( dim, [value], true );
                        this.classList.toggle("selected");
                    }
                } );
            }
            return qlik.Promise.resolve();
        }
    };
} );
</pre>
<p><strong>3_LBT.qext</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
    "name": "3_LBT",
    "description": "Listbox visualization template",
    "icon": "list",
    "type": "visualization",
    "version": "1.0.0",
    "author": "",
    "homepage": "",
    "keywords": "qlik-sense, visualization",
    "license": "",
    "repository": "",
    "dependencies": {
        "qlik-sense": "&gt;=3.0.x"
    }
}</pre>
<p><strong>style.css</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="css">.qv-object-3_LBT div.qv-object-content-container {
    overflow: auto;
}
.qv-object-3_LBT ul {
    list-style: none;
}
.qv-object-3_LBT li.data {
    padding: 4px;
    border-bottom: 1px solid #ddd;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* frequency */
.qv-object-3_LBT li.data span
{
    padding-left: 10px;
    font-style: italic;
    float:right;
}
/* colors when NOT in selection mode */

.qv-object-3_LBT li.stateS, .qv-object-3_LBT li.stateL {
    background-image: linear-gradient(top, #52cc52, #4dc04d);
    background-image: -o-linear-gradient(top, #52cc52, #4dc04d);
    background-image: -moz-linear-gradient(top, #52cc52, #4dc04d);
    background-image: -webkit-linear-gradient(top, #52cc52, #4dc04d);
    background-image: -ms-linear-gradient(top, #52cc52, #4dc04d);
    color: #fff;
}

.qv-object-3_LBT li.stateX, .qv-object-3_LBT li.stateXL, .qv-object-3_LBT li.stateXS {
    background-color: #A9A9A9;
    color: #fff;
}

.qv-object-3_LBT li.stateA {
    background-image: none;
    background-color: #ddd;
    color: #000;
}
/* colors when in selection mode */
.qv-object-3_LBT.qv-selections-active li {
    background-image: none;
    background-color: #ddd;
    color: #000;
}

.qv-object-3_LBT.qv-selections-active li.selected {
    background-image: linear-gradient(top, #52cc52, #4dc04d);
    background-image: -o-linear-gradient(top, #52cc52, #4dc04d);
    background-image: -moz-linear-gradient(top, #52cc52, #4dc04d);
    background-image: -webkit-linear-gradient(top, #52cc52, #4dc04d);
    background-image: -ms-linear-gradient(top, #52cc52, #4dc04d);
    color: #fff;
}</pre>
<h3>Angular Basic Visualization template</h3>
<p>Назовем наш Extension <strong>&#8220;4_ABVT&#8221;</strong>. При инициализации создадутся 3 файла:</p>
<p><strong>4_ABVT.qext</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
    "name": "4_ABVT",
    "description": "Basic empty visualization template based on angular.js",
    "type": "visualization",
    "version": "1.0.0",
    "author": "",
    "homepage": "",
    "keywords": "qlik-sense, visualization",
    "license": "",
    "repository": "",
    "dependencies": {
        "qlik-sense": "&gt;=3.0.x"
    }
}</pre>
<p><strong>4_ABVT.js</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">define( ["qlik", "text!./template.html"],
    function ( qlik, template ) {

        return {
            template: template,
            support: {
                snapshot: true,
                export: true,
                exportData: false
            },
            paint: function () {
                return qlik.Promise.resolve();
            },
            controller: ['$scope', function ( $scope ) {
                //add your rendering code here
                $scope.html = "Hello World";
            }]
        };

    } );</pre>
<p><strong>template.html</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="html">&lt;div qv-extension style="height: 100%; position: relative; overflow: auto;" class="ng-scope"&gt;
    {{ html }} 
&lt;/div&gt;</pre>
<h3>Angular Table template</h3>
<p>Назовем наш Extension <strong>&#8220;5_ATT&#8221;</strong>. При инициализации создадутся 4 файла:</p>
<p><strong>5_ATT.js</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">define( ["qlik","jquery", "text!./style.css", "text!./template.html"], function (qlik, $, cssContent, template ) {'use strict';
    $("&lt;style&gt;").html(cssContent).appendTo("head");
    return {
       template: template,
       initialProperties : {
            qHyperCubeDef : {
                qDimensions : [],
                qMeasures : [],
                qInitialDataFetch : [{
                    qWidth : 10,
                    qHeight : 50
                }]
            }
        },
        definition : {
            type : "items",
            component : "accordion",
            items : {
                dimensions : {
                    uses : "dimensions",
                    min : 1
                },
                measures : {
                    uses : "measures",
                    min : 0
                },
                sorting : {
                    uses : "sorting"
                },
                settings : {
                    uses : "settings",
                    items : {
                        initFetchRows : {
                            ref : "qHyperCubeDef.qInitialDataFetch.0.qHeight",
                            label : "Initial fetch rows",
                            type : "number",
                            defaultValue : 50
                        }
                    }
                }
            }
        },
        support : {
            snapshot: true,
            export: true,
            exportData : true
        },
        paint: function ( ) {
            //setup scope.table
            if ( !this.$scope.table ) {
                this.$scope.table = qlik.table( this );
            }
            return qlik.Promise.resolve();
        },
        controller: ['$scope', function (/*$scope*/) {
        }]
    };

} );
</pre>
<p><strong>5_ATT.qext</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
    "name": "5_ATT",
    "description": "Table visualization template based on angular.js",
    "icon": "table",
    "type": "visualization",
    "version": "1.0.0",
    "author": "",
    "homepage": "",
    "keywords": "qlik-sense, visualization",
    "license": "",
    "repository": "",
    "dependencies": {
        "qlik-sense": "&gt;=3.0.x"
    }
}</pre>
<p><strong>style.css</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="css">.qv-object-5_ATT div.qv-object-content-container {
    overflow: auto;
}
.qv-object-5_ATT td,
.qv-object-5_ATT th {
    border-top: 0px solid #fff;
    border-bottom: 1px solid #ddd;
    border-right: 1px solid #ddd;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
    cursor: default;
    font-size: 12px;
}
.qv-object-5_ATT td.numeric {
    text-align: right;
}
.qv-object-5_ATT button {
    width: 100%;
}</pre>
<p><strong>template.html</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="html">&lt;div qv-extension style="height: 100%; position: relative; overflow: auto;"&gt;
    &lt;table&gt;
        &lt;thead&gt;
        &lt;tr&gt;
            &lt;th ng-repeat="head in table.headers track by $index" ng-click="head.orderBy()"&gt;{{head.qFallbackTitle}}&lt;/th&gt;
        &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
        &lt;tr ng-repeat="row in table.rows track by $index"&gt;
            &lt;td ng-repeat="cell in row.cells track by $index" class="selectable" ng-class="{'selected':cell.selected,'numeric':cell.qNum}" ng-click="cell.select($event)"&gt;{{cell.qText}}&lt;/td&gt;
        &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;button ng-if="table.rowCount&gt;table.rows.length" ng-click="table.getMoreData()" class="lui-button more"&gt;More...&lt;/button&gt;
&lt;/div&gt;
</pre>
<h3>Table template</h3>
<p>Назовем наш Extension <strong>&#8220;6_TT&#8221;</strong>. При инициализации создадутся 3 файла:</p>
<p><strong>6_TT.js</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">/*globals define*/
define( ["qlik", "jquery", "text!./style.css"], function ( qlik, $, cssContent ) {
    'use strict';
    $( "&lt;style&gt;" ).html( cssContent ).appendTo( "head" );
    function createRows ( rows, dimensionInfo ) {
        var html = "";
        rows.forEach( function ( row ) {
            html += '&lt;tr&gt;';
            row.forEach( function ( cell, key ) {
                if ( cell.qIsOtherCell ) {
                    cell.qText = dimensionInfo[key].othersLabel;
                }
                html += "&lt;td ";
                if ( !isNaN( cell.qNum ) ) {
                    html += "class='numeric'";
                }
                html += '&gt;' + cell.qText + '&lt;/td&gt;';
            } );
            html += '&lt;/tr&gt;';
        } );
        return html;
    }

    return {
        initialProperties: {
            qHyperCubeDef: {
                qDimensions: [],
                qMeasures: [],
                qInitialDataFetch: [{
                    qWidth: 10,
                    qHeight: 50
                }]
            }
        },
        definition: {
            type: "items",
            component: "accordion",
            items: {
                dimensions: {
                    uses: "dimensions",
                    min: 1
                },
                measures: {
                    uses: "measures",
                    min: 0
                },
                sorting: {
                    uses: "sorting"
                },
                settings: {
                    uses: "settings"
                }
            }
        },
        snapshot: {
            canTakeSnapshot: true
        },
        paint: function ( $element, layout ) {
            var html = "&lt;table&gt;&lt;thead&gt;&lt;tr&gt;", self = this,
                morebutton = false,
                hypercube = layout.qHyperCube,
                rowcount = hypercube.qDataPages[0].qMatrix.length,
                colcount = hypercube.qDimensionInfo.length + hypercube.qMeasureInfo.length;
            //render titles
            hypercube.qDimensionInfo.forEach( function ( cell ) {
                html += '&lt;th&gt;' + cell.qFallbackTitle + '&lt;/th&gt;';
            } );
            hypercube.qMeasureInfo.forEach( function ( cell ) {
                html += '&lt;th&gt;' + cell.qFallbackTitle + '&lt;/th&gt;';
            } );
            html += "&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;";
            //render data
            html += createRows( hypercube.qDataPages[0].qMatrix, hypercube.qDimensionInfo );
            html += "&lt;/tbody&gt;&lt;/table&gt;";
            //add 'more...' button
            if ( hypercube.qSize.qcy &gt; rowcount ) {
                html += "&lt;button class='more'&gt;More...&lt;/button&gt;";
                morebutton = true;
            }
            $element.html( html );
            if ( morebutton ) {
                $element.find( ".more" ).on( "click", function () {
                    var requestPage = [{
                        qTop: rowcount,
                        qLeft: 0,
                        qWidth: colcount,
                        qHeight: Math.min( 50, hypercube.qSize.qcy - rowcount )
                    }];
                    self.backendApi.getData( requestPage ).then( function ( dataPages ) {
                        rowcount += dataPages[0].qMatrix.length;
                        if ( rowcount &gt;= hypercube.qSize.qcy ) {
                            $element.find( ".more" ).hide();
                        }
                        var html = createRows( dataPages[0].qMatrix, hypercube.qDimensionInfo );
                        $element.find( "tbody" ).append( html );
                    } );
                } );
            }
            return qlik.Promise.resolve();
        }
    };
} );
</pre>
<p><strong>6_TT.qext</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="json">{
    "name": "6_TT",
    "description": "Table visualization template",
    "icon": "table",
    "type": "visualization",
    "version": "1.0.0",
    "author": "",
    "homepage": "",
    "keywords": "qlik-sense, visualization",
    "license": "",
    "repository": "",
    "dependencies": {
        "qlik-sense": "&gt;=3.0.x"
    }
}</pre>
<p><strong>style.css</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="css">.qv-object-6_TT div.qv-object-content-container {
    overflow: auto;
}
.qv-object-6_TT td,
.qv-object-6_TT th {
    border-top: 0px solid #fff;
    border-bottom: 1px solid #ddd;
    border-right: 1px solid #ddd;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: middle;
    cursor: default;
    font-size: 12px;
}
.qv-object-6_TT td.numeric {
    text-align: right;
}
.qv-object-6_TT button {
    width: 100%;
}</pre>
<h2>Структура расширения</h2>
<p>Как мы видим из примеров стандартных шаблонов экстеншенов для создания расширения необходимо минимум 2 файла &#8211; js и qext. Для более богатой функциональности добавляются css и html.</p>
<p><strong>Опишем зачем нужны файлы:</strong></p>
<ul>
<li><span style="color: #ff6600;"><em><strong>&lt;name_extension&gt;</strong></em></span>.<strong>js</strong> &#8211; это код Javascript &#8211; фактически это ядро вашего Extension. Здесь происходит отрисовка визуализации (например, в цикле заполняется html код с тегами при обходе гиперкуба qlik sense), настраивается логика работы с выборкой и другие действия.</li>
<li><span style="color: #ff6600;"><em><strong>&lt;name_extension&gt;</strong></em></span>.<strong>qext</strong> &#8211; <span><span style="color: #339966;"><strong>extension metadata file (QEXT)</strong></span> &#8211; файл JSON, который используется <span class="CommonComponentsQlik Sense">Qlik Sense</span> для идентификации расширения визуализации. В этом файле указывается название расширения, тип расширения, версия, автор, ключевые слова. И другие атрибуты, которые будут расмотрены в дальнейших разделах.</span></li>
<li><span style="color: #ff6600;"><em><strong>&lt;name_extension&gt;</strong></em></span>.<strong>css</strong> &#8211; в этом файле прописываются стили для кастомной визуализации (т.е. вашего экстеншена).</li>
<li><span style="color: #ff6600;"><em><strong>&lt;name_extension&gt;</strong></em></span>.<strong>html</strong> &#8211; шаблон html кода, который будет использоваться в js коде и заполняться внутри js кода (например в цикле). Этот прием используется, например, в Angular Framework.</li>
<li><strong>wbfolder.wbl<sup>*</sup></strong> (<span>не является обязательным</span>) &#8211; <span>Файл загрузки Workbench &#8211; используется редактором Extension &amp; Mashup и содержит список файлов, которые должны быть загружены в редактор dev-hub (без него вы не сможете открыть или продублировать расширение в dev-hub).</span><br />
<span>Когда вы сохраняете проект расширения или Mashup из редактора, WBL-файл автоматически создается и включается в проект. Если вы сделаете копию расширения или мэшапа, то будут скопированы только файлы, перечисленные в wbfolder.wbl.<br />
Добавляя дополнительные имена файлов &#8211; разделенные точкой с запятой и переносом строки &#8211; в wbfolder.wbl, вы также можете разрешить загрузку этих дополнительных файлов. При отсутствии файла может возникнуть ошибка <span style="color: #800080;"><em><strong>Incomplete visualization. The visualization is incomplete and cannot be opened or duplicated (wbfolder.wbl file missing).</strong></em></span></span></li>
</ul>
<p><strong>Рассмотрим процесс отрисовки экстеншена:</strong></p>
<p><span>Когда пользователь открывает лист, </span><span class="PrimaryGenericName"><span>Qlik Sense</span></span><span> извлекает визуализации на этом листе, а затем выполняет стандартный рабочий процесс для каждой визуализации.</span></p>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2021/01/Qlik_Sense_Extension_API_concepts_Overview.png"><img fetchpriority="high" decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2021/01/Qlik_Sense_Extension_API_concepts_Overview.png" alt="" width="536" height="698" class="aligncenter size-full wp-image-2504" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2021/01/Qlik_Sense_Extension_API_concepts_Overview.png 536w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2021/01/Qlik_Sense_Extension_API_concepts_Overview-230x300.png 230w" sizes="(max-width: 536px) 100vw, 536px" /></a></p>
<p>Пример <strong>Hello World</strong> можно посмотреть на сайте <strong><a href="http://qliksite.io/tutorials/qliksense-visualization-extensions/part-01/03-Lets-Get-Started--Hello-World-Example/" target="_blank" rel="noopener">http://qliksite.io/tutorials/qliksense-visualization-extensions/part-01/03-Lets-Get-Started&#8211;Hello-World-Example/</a></strong></p>
<h2>Схема работы JS кода в QS Extension</h2>
<p><code>define</code> <span>&#8211; это концепция, введенная </span><strong><a href="https://requirejs.org/" target="_blank" rel="noopener">RequireJS</a></strong><span><strong> </strong>для определения зависимостей в ваших файлах JavaScript. Идея состоит в том, чтобы загрузить внешние зависимости до того, как будет выполнен ваш основной скрипт. </span></p>
<p><span><strong>Зависимости</strong> – внешние модули (скрипты/библиотеки), которые необходимы для работы нашего расширения.</span></p>
<p><code>paint</code><span> &#8211; основной метод визуализации визуализации, который будет вызываться каждый раз, когда визуализация должна быть отрисована, либо из-за новых данных с сервера, либо из-за изменения размера.</span></p>
<p><span>Метод paint получает два параметра </span><code>$element</code><span>и </span><code>layout</code><span>.</span></p>
<table>
<thead>
<tr>
<th><strong>Параметр</strong></th>
<th><strong>Описание</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><code>$element</code></td>
<td><span>Оболочка jQuery, содержащая родительский элемент HTML, в котором должна отображаться визуализация.</span></td>
</tr>
<tr>
<td><code>layout</code></td>
<td><span>Данные и свойства для визуализации.</span></td>
</tr>
</tbody>
</table>
<p><a href="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2021/01/qliksense_requirejs_define.png"><img decoding="async" src="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2021/01/qliksense_requirejs_define.png" alt="" width="674" height="882" class="aligncenter size-full wp-image-2507" srcset="https://qliksense.ivan-shamaev.ru/wp-content/uploads/2021/01/qliksense_requirejs_define.png 674w, https://qliksense.ivan-shamaev.ru/wp-content/uploads/2021/01/qliksense_requirejs_define-229x300.png 229w" sizes="(max-width: 674px) 100vw, 674px" /></a></p>
<p>todo</p>
<h1>Видео &#8220;How to build Qlik Sense Visualization Extensions &#8211; Introduction&#8221;</h1>
<p><iframe title="How to build Qlik® Sense Visualization Extensions - 1. Introduction" width="750" height="422" src="https://www.youtube.com/embed/n7RICsLGiCE?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></p>
<h1>Методы Qlik Sense Extension API</h1>
<h2>beforeDestroy</h2>
<p><span>Выполняется до того, как объект будет уничтожен путем его удаления, переключения листа, открытия инструмента выделения или любых других средств удаления расширения. </span><span>Используйте этот метод для того, чтобы удалить привязки и предотвратить утечку памяти.</span></p>
<blockquote><p><span><strong>Утечка памяти</strong> — это, в широком смысле, фрагмент памяти, выделенной приложению, который больше не нужен этому приложению, но не может быть возвращён операционной системе для дальнейшего использования. Другими словами это — блок памяти, который захвачен приложением без намерения пользоваться этой памятью в будущем.</span></p>
<p><strong>Источник:</strong> <a href="https://habr.com/ru/company/ruvds/blog/495898/" target="_blank" rel="noopener">Практическое руководство по борьбе с утечками памяти в Node.js</a></p></blockquote>
<h2>mounted</h2>
<p><span>Выполняется один раз при инициализации объекта.</span></p>
<p><code><span>mounted($element)</span></code></p>
<h2>paint</h2>
<p><span>Отрисовывает (или render) визуализацию расширения. </span><span>Вызовите этот метод, когда необходимо отрисовать visualization extension либо из-за новых данных с сервера, либо из-за изменения размера расширения визуализации.</span></p>
<h3>Параметры метода paint</h3>
<h4>$element</h4>
<p><span>Оболочка jQuery, содержащая HTML-элемент, в котором должна отображаться визуализация.</span></p>
<h4>layout</h4>
<p><span>Данные и свойства для визуализации.</span></p>
<h4>layout.qHyperCube.qDimensionInfo</h4>
<p><span>Массив с данными об используемых dimensions. Включает <code>qFallbackTitle</code></span><span>, заголовок и </span><code><span class="syntax"><span>qCardinal</span></span></code><span> , количество различных значений.</span></p>
<h4>layout.qHyperCube.qMeasureInfo</h4>
<p><span>Массив с данными об используемых мерах. Включает </span><code><span class="syntax"><span>qFallbackTitle</span></span></code><span>, заголовок (title), </span><code><span class="syntax"><span>qCardinal</span></span></code><span>, количество различных значений, </span><code><span class="syntax"><span>qMin</span></span></code><span> и </span><code><span class="syntax"><span>qMax</span></span></code><span> для минимального и максимального значений.</span></p>
<h4>layout.qHyperCube.qDataPages[0].qMatrix</h4>
<p><span>Массив с данными из </span><span class="CommonComponentsQlik Sense"><span>Qlik Sense</span></span><span> . Каждому объекту соответствует строка в результате. Значения измерения (dimension) и меры (measure) являются объектами JavaScript в этом массиве.</span></p>
<h4>layout.qHyperCube.qDataPages[0].qMatrix[0..#dimensions – 1]</h4>
<p><span>Значения Dimension для строки результата. Каждый объект содержит текст ( </span><code><span class="syntax"><span>qText</span></span></code><span>), используемый для рендеринга, и значение ( </span><code><span class="syntax"><span>qElemNumber</span></span></code><span> ), используемое для selections, и состояние значения ( </span><code><span class="syntax"><span>qState</span></span></code><span> ).</span></p>
<h4>layout.qHyperCube.qDataPages[0].qMatrix[#dimensions..]</h4>
<p><span>Массив со значениями measure для строки результата. Каждый объект содержит данные, фактическое значение ( </span><code><span class="syntax"><span>qNum</span></span></code><span> ) и текст ( </span><code><span class="syntax"><span>qText</span></span></code><span> ), форматированное значение.</span></p>
<h4>layout.qHyperCube.qSize</h4>
<p><span>Общее количество строк (</span><code><span class="syntax"><span>qcy</span></span></code><span>) и столбцов (</span><code><span class="syntax"><span>qcx</span></span></code><span>) в результирующем наборе.</span></p>
<h4>layout.qInfo.qId</h4>
<p><span><code>qId</code> &#8211; Уникальный идентификатор объекта. </span><span>При необходимости полезно для создания уникального HTML-идентификатора.</span></p>
<h4>layout.qSelectionInfo</h4>
<p><span>Если пользователь находится в режиме выбора, это будет объект с двумя флагами: </span><code><span class="syntax"><span>qInSelections</span></span></code><span> и </span><code><span class="syntax"><span>qMadeSelections</span></span></code><span>.</span></p>
<h2>updateData</h2>
<p><span>Выполняется каждый раз при изменении layout или данных, например при осуществлении выборок или изменении свойств. </span><span>Получает новый layout и возвращает promise.</span></p>
<p><code><span>updateData(layout)</span></code></p>
<p>&nbsp;</p>
<h1>Properties Qlik Sense Extension API</h1>
<h2>initialProperties</h2>
<p><code><span>initialProperties()</span></code></p>
<p><span>Задает свойства, которые объект должен иметь при создании. Определите либо как гиперкуб ( </span><code><span class="syntax"><span>qHyperCubeDef</span></span></code><span> ), либо как объект списка ( </span><code><span class="syntax"><span>qListObjectDef</span></span></code><span> ).</span></p>
<p><span>Настройте все свойства и назначьте значения по умолчанию для <strong>custom properties</strong>.</span></p>
<p><span>Максимальное количество ячеек ( </span><code><span class="statement"><span>qWidth</span></span></code><span> * </span><code><span class="statement"><span>qHeight</span></span></code><span> ), разрешенное при исходной <span class="statement">выборке</span> данных, составляет 10 000. Получите дополнительные данные по частям с помощью метода </span><code><span class="syntax"><span>getData</span></span></code><span> в <strong>Backend API</strong>.</span></p>
<p><strong><span class="autonumber">Пример:</span> использование гиперкуба</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">initialProperties : {
    qHyperCubeDef : {
        qDimensions : [],
        qMeasures : [],
        qInitialDataFetch : [{
            qWidth : 2,
            qHeight : 50
        }]
    }
}</pre>
<p><strong><span class="autonumber">Пример</span>, в котором используется объект списка, а также определяются некоторые custom properties</strong></p>
<pre class="EnlighterJSRAW" data-enlighter-language="js">initialProperties : {
    qListObjectDef : {
        qShowAlternatives : true,
        qFrequencyMode : "V",
        qInitialDataFetch : [{
            qWidth : 2,
            qHeight : 50
        }]
    },
    fixed : true,
    width : 25,
    percent : true,
    selectionMode : "CONFIRM"
}</pre>
<h3>Ограничение 10000 ячеек</h3>
<p>Ходят упорные слухи, что при работе с HyperCube с использованием клиентских API (в расширениях визуализации или мэшапах) можно загрузить только 10 000 ячеек данных.</p>
<p><span style="color: #ff9900;"><strong>Этот слух не соответствует действительности !!!</strong></span></p>
<p>Вместо этого верно, что вы можете получить только 10 000 записей на страницу данных из Engine, но вы, безусловно, можете запросить получение дополнительных страниц данных.<br />
Таким образом, разработчик полностью решает, сколько точек данных из источника данных используется в пользовательском интерфейсе.</p>
<h2>snapshot</h2>
<p><span>Включает или отключает возможность делать снимки расширения визуализации для использования в Data Storytelling.</span></p>
<p><code><span>snapshot(enable)</span></code></p>
<h2>export</h2>
<p><span>Включает или отключает возможность экспорта расширения визуализации как изображения или как <strong>PDF-файл.</strong> Это также позволяет включить расширение визуализации в <strong>экспорт из Storytelling</strong> (PowerPoint или PDF).</span></p>
<p><span>Если задано значение </span><code><span class="syntax"><span>true</span></span></code><span> , включены параметры контекстного меню <strong>«</strong></span><strong><span class="ui_item">Экспорт как изображение»</span></strong><span> и <strong>«</strong></span><strong><span class="ui_item">Экспорт в PDF»</span></strong><span> для расширения визуализации. Это также позволяет расширениям визуализации быть частью историй, экспортируемых в PowerPoint или PDF, в параметрах контекстного меню «</span><span class="ui_item"><span>Экспорт истории в PowerPoint»</span></span><span> и «</span><span class="ui_item"><span>Экспорт истории в PDF»</span></span><span>.</span></p>
<h2>exportData</h2>
<p><span>Включает или отключает возможность экспорта данных из расширения визуализации и сохранения их в файле XLSX. Если задано значение </span><code><span class="syntax"><span>true</span></span></code><span>, параметр контекстного меню <strong>«</strong></span><strong><span class="ui_item">Экспорт данных»</span></strong><span> включен для расширения визуализации.</span></p>
<h2>Пример</h2>
<pre class="EnlighterJSRAW" data-enlighter-language="js">var ext = {
    support: {
        snapshot: true,
        export: true,
        exportData: true
    }
};</pre>
<h1>Property definitions</h1>
<h2>Array</h2>
<p>todo</p>
<h2>Integer</h2>
<p>todo</p>
<h2>Number</h2>
<p>todo</p>
<h2>String</h2>
<p>todo</p>
<h2>Text</h2>
<p>todo</p>
<h2>Button</h2>
<p>todo</p>
<h2>Button group</h2>
<p>todo</p>
<h2>Check box</h2>
<p>todo</p>
<h2>Color-picker</h2>
<p>todo</p>
<h2>Drop down list</h2>
<p>todo</p>
<h2>Link</h2>
<p>todo</p>
<h2>Media</h2>
<p>todo</p>
<h2>Radio button</h2>
<p>todo</p>
<h2>Slider</h2>
<p>todo</p>
<h2>Range-slider</h2>
<p>todo</p>
<h2>Switch</h2>
<p>todo</p>
<h2>Textarea</h2>
<p>todo</p>
<p>Сообщение <a href="https://qliksense.ivan-shamaev.ru/overview-qlik-extension-api-and-methods/">Обзор Extension API и описание методов расширений</a> появились сначала на <a href="https://qliksense.ivan-shamaev.ru">Qlik Sense - Обучение, учебник, онлайн курс</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://qliksense.ivan-shamaev.ru/overview-qlik-extension-api-and-methods/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
