Введение в Extension API

Extension API состоит из методов и свойств, используемых для создания custom расширений визуализации (или custom visualization extensions).

Обзор Visualization extension templates

Для начала рассмотрим шаблоны Visualization extension templates. В dev-hub при создании Extension вам предлагают выбрать шаблон.

Basic Visualization template

Назовем наш Extension “1_BVT”. При инициализации создадутся два файла:

1_BVT.qext

{
    "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": ">=3.0.x"
    }
}

1_BVT.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();
        }
    };

} );

Chart Template

Назовем наш Extension “2_CT”. При инициализации создадутся 4 файла:

2_CT.qext

{
    "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": ">=3.0.x"
    }
}

2_CT.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 );
                        }
                    }
                };
            }]
        };

    } );

2_CT.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;
}

2_CT.ng.html

<div qv-extension style="height: 100%; position: relative; overflow: auto;">
    <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 }">
        <div class="css_bars_bar" ng-style="{'width':getPercent(item[1].qNum)+'%'}"><span>{{item[0].qText}}</span></div>
        <div class="css_bars_per">
            <span ng-class="{over: (getPercent(item[1].qNum)>95)}">{{getPercent(item[1].qNum)}} %</span></div>
    </div>
</div>

Listbox template

Назовем наш Extension “3_LBT”. При инициализации создадутся 3 файла:

3_LBT.js

define( ["qlik", "jquery", "text!./style.css"], function ( qlik, $, cssContent ) {
    'use strict';
    $( "<style>" ).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 && 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 && !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 = "<ul>";
            layout.qListObject.qDataPages[0].qMatrix.forEach( function ( row ) {
                html += '<li class="data state' + row[0].qState + '" data-value="' + row[0].qElemNumber + '">' + row[0].qText;
                if ( row[0].qFrequency ) {
                    html += '<span>' + row[0].qFrequency + '</span>';
                }
                html += '</li>';
            } );
            html += "</ul>";
            $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();
        }
    };
} );

3_LBT.qext

{
    "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": ">=3.0.x"
    }
}

style.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;
}

Angular Basic Visualization template

Назовем наш Extension “4_ABVT”. При инициализации создадутся 3 файла:

4_ABVT.qext

{
    "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": ">=3.0.x"
    }
}

4_ABVT.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";
            }]
        };

    } );

template.html

<div qv-extension style="height: 100%; position: relative; overflow: auto;" class="ng-scope">
    {{ html }} 
</div>

Angular Table template

Назовем наш Extension “5_ATT”. При инициализации создадутся 4 файла:

5_ATT.js

define( ["qlik","jquery", "text!./style.css", "text!./template.html"], function (qlik, $, cssContent, template ) {'use strict';
    $("<style>").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*/) {
        }]
    };

} );

5_ATT.qext

{
    "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": ">=3.0.x"
    }
}

style.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%;
}

template.html

<div qv-extension style="height: 100%; position: relative; overflow: auto;">
    <table>
        <thead>
        <tr>
            <th ng-repeat="head in table.headers track by $index" ng-click="head.orderBy()">{{head.qFallbackTitle}}</th>
        </tr>
        </thead>
        <tbody>
        <tr ng-repeat="row in table.rows track by $index">
            <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)">{{cell.qText}}</td>
        </tr>
        </tbody>
    </table>
    <button ng-if="table.rowCount>table.rows.length" ng-click="table.getMoreData()" class="lui-button more">More...</button>
</div>

Table template

Назовем наш Extension “6_TT”. При инициализации создадутся 3 файла:

6_TT.js

/*globals define*/
define( ["qlik", "jquery", "text!./style.css"], function ( qlik, $, cssContent ) {
    'use strict';
    $( "<style>" ).html( cssContent ).appendTo( "head" );
    function createRows ( rows, dimensionInfo ) {
        var html = "";
        rows.forEach( function ( row ) {
            html += '<tr>';
            row.forEach( function ( cell, key ) {
                if ( cell.qIsOtherCell ) {
                    cell.qText = dimensionInfo[key].othersLabel;
                }
                html += "<td ";
                if ( !isNaN( cell.qNum ) ) {
                    html += "class='numeric'";
                }
                html += '>' + cell.qText + '</td>';
            } );
            html += '</tr>';
        } );
        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 = "<table><thead><tr>", 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 += '<th>' + cell.qFallbackTitle + '</th>';
            } );
            hypercube.qMeasureInfo.forEach( function ( cell ) {
                html += '<th>' + cell.qFallbackTitle + '</th>';
            } );
            html += "</tr></thead><tbody>";
            //render data
            html += createRows( hypercube.qDataPages[0].qMatrix, hypercube.qDimensionInfo );
            html += "</tbody></table>";
            //add 'more...' button
            if ( hypercube.qSize.qcy > rowcount ) {
                html += "<button class='more'>More...</button>";
                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 >= hypercube.qSize.qcy ) {
                            $element.find( ".more" ).hide();
                        }
                        var html = createRows( dataPages[0].qMatrix, hypercube.qDimensionInfo );
                        $element.find( "tbody" ).append( html );
                    } );
                } );
            }
            return qlik.Promise.resolve();
        }
    };
} );

6_TT.qext

{
    "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": ">=3.0.x"
    }
}

style.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%;
}

Структура расширения

Как мы видим из примеров стандартных шаблонов экстеншенов для создания расширения необходимо минимум 2 файла – js и qext. Для более богатой функциональности добавляются css и html.

Опишем зачем нужны файлы:

  • <name_extension>.js – это код Javascript – фактически это ядро вашего Extension. Здесь происходит отрисовка визуализации (например, в цикле заполняется html код с тегами при обходе гиперкуба qlik sense), настраивается логика работы с выборкой и другие действия.
  • <name_extension>.qextextension metadata file (QEXT) – файл JSON, который используется Qlik Sense для идентификации расширения визуализации. В этом файле указывается название расширения, тип расширения, версия, автор, ключевые слова. И другие атрибуты, которые будут расмотрены в дальнейших разделах.
  • <name_extension>.css – в этом файле прописываются стили для кастомной визуализации (т.е. вашего экстеншена).
  • <name_extension>.html – шаблон html кода, который будет использоваться в js коде и заполняться внутри js кода (например в цикле). Этот прием используется, например, в Angular Framework.
  • wbfolder.wbl* (не является обязательным) – Файл загрузки Workbench – используется редактором Extension & Mashup и содержит список файлов, которые должны быть загружены в редактор dev-hub (без него вы не сможете открыть или продублировать расширение в dev-hub).
    Когда вы сохраняете проект расширения или Mashup из редактора, WBL-файл автоматически создается и включается в проект. Если вы сделаете копию расширения или мэшапа, то будут скопированы только файлы, перечисленные в wbfolder.wbl.
    Добавляя дополнительные имена файлов – разделенные точкой с запятой и переносом строки – в wbfolder.wbl, вы также можете разрешить загрузку этих дополнительных файлов. При отсутствии файла может возникнуть ошибка Incomplete visualization. The visualization is incomplete and cannot be opened or duplicated (wbfolder.wbl file missing).

Рассмотрим процесс отрисовки экстеншена:

Когда пользователь открывает лист, Qlik Sense извлекает визуализации на этом листе, а затем выполняет стандартный рабочий процесс для каждой визуализации.

Пример Hello World можно посмотреть на сайте http://qliksite.io/tutorials/qliksense-visualization-extensions/part-01/03-Lets-Get-Started–Hello-World-Example/

Схема работы JS кода в QS Extension

define – это концепция, введенная RequireJS для определения зависимостей в ваших файлах JavaScript. Идея состоит в том, чтобы загрузить внешние зависимости до того, как будет выполнен ваш основной скрипт.

Зависимости – внешние модули (скрипты/библиотеки), которые необходимы для работы нашего расширения.

paint – основной метод визуализации визуализации, который будет вызываться каждый раз, когда визуализация должна быть отрисована, либо из-за новых данных с сервера, либо из-за изменения размера.

Метод paint получает два параметра $elementи layout.

Параметр Описание
$element Оболочка jQuery, содержащая родительский элемент HTML, в котором должна отображаться визуализация.
layout Данные и свойства для визуализации.

todo

Видео “How to build Qlik Sense Visualization Extensions – Introduction”

Методы Qlik Sense Extension API

beforeDestroy

Выполняется до того, как объект будет уничтожен путем его удаления, переключения листа, открытия инструмента выделения или любых других средств удаления расширения. Используйте этот метод для того, чтобы удалить привязки и предотвратить утечку памяти.

Утечка памяти — это, в широком смысле, фрагмент памяти, выделенной приложению, который больше не нужен этому приложению, но не может быть возвращён операционной системе для дальнейшего использования. Другими словами это — блок памяти, который захвачен приложением без намерения пользоваться этой памятью в будущем.

Источник: Практическое руководство по борьбе с утечками памяти в Node.js

mounted

Выполняется один раз при инициализации объекта.

mounted($element)

paint

Отрисовывает (или render) визуализацию расширения. Вызовите этот метод, когда необходимо отрисовать visualization extension либо из-за новых данных с сервера, либо из-за изменения размера расширения визуализации.

Параметры метода paint

$element

Оболочка jQuery, содержащая HTML-элемент, в котором должна отображаться визуализация.

layout

Данные и свойства для визуализации.

layout.qHyperCube.qDimensionInfo

Массив с данными об используемых dimensions. Включает qFallbackTitle, заголовок и qCardinal , количество различных значений.

layout.qHyperCube.qMeasureInfo

Массив с данными об используемых мерах. Включает qFallbackTitle, заголовок (title), qCardinal, количество различных значений, qMin и qMax для минимального и максимального значений.

layout.qHyperCube.qDataPages[0].qMatrix

Массив с данными из Qlik Sense . Каждому объекту соответствует строка в результате. Значения измерения (dimension) и меры (measure) являются объектами JavaScript в этом массиве.

layout.qHyperCube.qDataPages[0].qMatrix[0..#dimensions – 1]

Значения Dimension для строки результата. Каждый объект содержит текст ( qText), используемый для рендеринга, и значение ( qElemNumber ), используемое для selections, и состояние значения ( qState ).

layout.qHyperCube.qDataPages[0].qMatrix[#dimensions..]

Массив со значениями measure для строки результата. Каждый объект содержит данные, фактическое значение ( qNum ) и текст ( qText ), форматированное значение.

layout.qHyperCube.qSize

Общее количество строк (qcy) и столбцов (qcx) в результирующем наборе.

layout.qInfo.qId

qId – Уникальный идентификатор объекта. При необходимости полезно для создания уникального HTML-идентификатора.

layout.qSelectionInfo

Если пользователь находится в режиме выбора, это будет объект с двумя флагами: qInSelections и qMadeSelections.

updateData

Выполняется каждый раз при изменении layout или данных, например при осуществлении выборок или изменении свойств. Получает новый layout и возвращает promise.

updateData(layout)

 

Properties Qlik Sense Extension API

initialProperties

initialProperties()

Задает свойства, которые объект должен иметь при создании. Определите либо как гиперкуб ( qHyperCubeDef ), либо как объект списка ( qListObjectDef ).

Настройте все свойства и назначьте значения по умолчанию для custom properties.

Максимальное количество ячеек ( qWidth * qHeight ), разрешенное при исходной выборке данных, составляет 10 000. Получите дополнительные данные по частям с помощью метода getData в Backend API.

Пример: использование гиперкуба

initialProperties : {
    qHyperCubeDef : {
        qDimensions : [],
        qMeasures : [],
        qInitialDataFetch : [{
            qWidth : 2,
            qHeight : 50
        }]
    }
}

Пример, в котором используется объект списка, а также определяются некоторые custom properties

initialProperties : {
    qListObjectDef : {
        qShowAlternatives : true,
        qFrequencyMode : "V",
        qInitialDataFetch : [{
            qWidth : 2,
            qHeight : 50
        }]
    },
    fixed : true,
    width : 25,
    percent : true,
    selectionMode : "CONFIRM"
}

Ограничение 10000 ячеек

Ходят упорные слухи, что при работе с HyperCube с использованием клиентских API (в расширениях визуализации или мэшапах) можно загрузить только 10 000 ячеек данных.

Этот слух не соответствует действительности !!!

Вместо этого верно, что вы можете получить только 10 000 записей на страницу данных из Engine, но вы, безусловно, можете запросить получение дополнительных страниц данных.
Таким образом, разработчик полностью решает, сколько точек данных из источника данных используется в пользовательском интерфейсе.

snapshot

Включает или отключает возможность делать снимки расширения визуализации для использования в Data Storytelling.

snapshot(enable)

export

Включает или отключает возможность экспорта расширения визуализации как изображения или как PDF-файл. Это также позволяет включить расширение визуализации в экспорт из Storytelling (PowerPoint или PDF).

Если задано значение true , включены параметры контекстного меню «Экспорт как изображение» и «Экспорт в PDF» для расширения визуализации. Это также позволяет расширениям визуализации быть частью историй, экспортируемых в PowerPoint или PDF, в параметрах контекстного меню «Экспорт истории в PowerPoint» и «Экспорт истории в PDF».

exportData

Включает или отключает возможность экспорта данных из расширения визуализации и сохранения их в файле XLSX. Если задано значение true, параметр контекстного меню «Экспорт данных» включен для расширения визуализации.

Пример

var ext = {
    support: {
        snapshot: true,
        export: true,
        exportData: true
    }
};

Property definitions

Array

todo

Integer

todo

Number

todo

String

todo

Text

todo

Button

todo

Button group

todo

Check box

todo

Color-picker

todo

Drop down list

todo

Link

todo

Media

todo

Radio button

todo

Slider

todo

Range-slider

todo

Switch

todo

Textarea

todo

4 1 голос
Рейтинг статьи

Подписаться
Уведомление о
guest
0 комментариев
Встроенная Обратная Связь
Просмотр всех комментариев
0
Оставьте, пожалуйста, комментарий!x