Extensões são componentes Qlik Sense criados com HTML CSS e JavaScript para serem utilizados dentro de QVFs ou Mashups.

Servem para uma infinidade de propósitos, como criar gráficos customizados, botões, tabelas, comentários, etc.

Neste breve post, mostrarei como criar uma extensão do zero. Será um gráfico de linhas customizado utilizando a biblioteca gráfica ECharts.

O resultado será o da imagem abaixo, e você poderá utilizar nas suas aplicações e criar novas funcionalidades, conforme desejar!

Ferramentas necessárias:

– Qlik Sense Desktop
– Editor de texto (utilizo Visual Studio Code)
– Biblioteca ECharts (https://echarts.apache.org/)
– Conhecimentos básicos de HTML e JS
– Browser (acessaremos o Qlik Sense através do endereço http://localhost:4848/hub)

Criando a estrutura de arquivos básica:

Com o Qlik Sense Desktop instalado, criamos a pasta ClusterLineChart dentro da pasta /Extensions/, geralmente em Documents/Qlik/Sense/Extensions/.

– ClusterLinechart.qext
– ClusterLinechart.js

O QEXT é responsável por indicar ao Qlik Sense o que aquele conjunto de arquivos representa. No caso, o type sera “visualization”.

Conteúdo do arquivo ClusterLinechart.qext

{
 "name" : "Cluster Line Chart",
 "description" : "Minha primeira extensão!",
 "icon" : "extension",
 "type" : "visualization",
 "version": "0.1",
 "author": "Thomas Pessato"
}

E a estrutura básica do arquivo Javascript:

Conteúdo do arquivo ClusterLinechart.js

define( [
    'jquery'
],
function ( $ , echarts) {
    'use strict';
    return {
        paint: function ( $element, layout ) {
            $element.append("teste");
            //deverá aparecer escrito ‘teste’ ao inserir a extensão
        }
    };
} );

Feito isto, já conseguiremos enxergar nossa extensão na aba “objetos customizados”, dentro de um QVF.

Obs 1: a variável $element é o quadrado da nossa extensão. Ou seja, qualquer coisa que colocarmos dentro deste elemento, aparecerá na tela. Isto inclui texto ou qualquer elemento html.

Obs 2: O método paint é executado toda vez que uma ação ocorre na tela, seja um resize da janela, resize do objeto na sheet, um filtro aplicado, etc. Ele é responsável por ‘pintar’ o objeto na tela.

Para fins de teste, incluiremos o texto “teste” na extensão. Ao inserirmos a extensão em uma sheet, o texto “teste” deverá aparecer:

Ótimo! Temos uma extensão que pode ser incluída em um QVF e já mostra algum tipo de informação!

Agora devemos nos certificar de que todas as nossas dependências estão incluídas na nossa extensão. Neste caso, significa incluir a biblioteca ECharts.

define( [
    'jquery',
    'https://cdnjs.cloudflare.com/ajax/libs/echarts/4.2.1/echarts.min.js'
],
function ( $ , echarts) {
   //repare na variável echarts, logo depois de $.
   ...
} );

Neste ponto, devemos conseguir “printar” a variável “echarts” dentro da nossa extensão e verificar no console (F12 no browser) sua existência. Obs: para isto funcionar, devemos inserir a extensão em uma sheet.

Ou seja, agora já é possível utilizar a biblioteca gráfica ECharts para construir nossas visualizações!

Precisamos agora definir quais serão as propriedades / dados que queremos que o Sense nos retorne. Isto significa, os dados, as opções de título, subtítulo e footnote do objeto, etc. Para que isto funcione, devemos declarar algumas propriedades dentro do nosso código JavaScript, que estão dentro do “return”.

define( [
    'jquery',
    'https://cdnjs.cloudflare.com/ajax/libs/echarts/4.2.1/echarts.min.js'
],
function ( $, echarts ) {
    'use strict';
    return {
        initialProperties: {
            qHyperCubeDef : {
                qDimensions : [],
                qMeasures : [],
                qInitialDataFetch : [{
                    qWidth : 2,
                    qHeight : 50
                }]
            }
        },
        definition: {
            type: "items",
            component: "accordion",
            items: {
                data: {
                    uses: "data",
                    dimensions: {
                        uses: "dimensions"
                    },
                    measures: {
                        uses: "measures"
                    }
                },
                sorting: {
                    uses: "sorting"
                },
                appearance: {
                    uses: "settings",
                }
            }
        },
        paint: function ( $element, layout ) {
             ...
        };
} );

Para mais informações a respeito do que cada uma das propriedades significa: Construindo um painel de propriedades para sua extensão

Enfim, mãos à obra. Com estas propriedades, ao inserirmos a extensão em uma sheet, a opção Add dimension e Add measure aparecerá, como geralmente aparece em extensões da própria Qlik.

Ao escolhermos os dados (uma medida e uma dimensão) que queremos relacionar, a engine do Qlik nos retornará os dados e metadados dentro da variável layout, que está dentro da função paint: function( $element, layout) {…}.

paint: function ( $element, layout ) {
            var data = layout.qHyperCube.qDataPages[0].qMatrix;
            console.log(data);
        }

Adicionando este trecho de código, percorrendo o objeto JavaScript layout, encontraremos a propriedade qMatrix, a qual possui os dados. Podemos observar através do console do browser que os dados retornam. Obs: Para que consiga visualizar os dados como abaixo, é necessário selecionar uma dimensão e uma medida para a extensão.

O que precisamos agora é transformar estes dados que estão no console em uma visualização mais amigável.

Para a estrutura de dados retornada do Qlik, sabe-se que a posição 0 do array corresponde à dimensão, e a posição 1 corresponde à medida. Logo, faremos esta separação.

var dimensions = layout.qHyperCube.qDataPages[0].qMatrix.map((item) => {       return item[0].qText;
});
var measures = layout.qHyperCube.qDataPages[0].qMatrix.map((item) => {
    return {
         value: item[1].qNum,
         itemStyle: {
             color: "red"
         }
    } 
});

Utilizei o método map para otimizar o código. O resultado deste código serão dois arrays, um contendo o texto das dimensões (qText), e o segundo conterá 2 variáveis: value (qNum) itemStyle. O value corresponderá ao valor da medida, e o itemStyle corresponderá a customizações da linha. Neste caso, decidi apenas colocar uma variável “color” com o valor “red”, que será utilizada para renderizar o gráfico do ECharts. Poderíamos colocar estilo da linha, espessura, etc.

Enfim passaremos os dados para a biblioteca gráfica e retornaremos o elemento para a nossa extensão.

paint: function ( $element, layout ) {
     var dimensions = layout.qHyperCube.qDataPages[0].qMatrix.map((item) => {
     return item[0].qText;
     });
     var measures = layout.qHyperCube.qDataPages[0].qMatrix.map((item) => {
         return {
              value: item[1].qNum,
              itemStyle: {
                  color: "red"
               }
        } 
     });
     var myChart = echarts.init($element[0]); 
     //inicializando o gráfico no quadrado da extensão. Como o $element é um elemento jQuery, acessamos pelo índice 0.
 
	//aqui passamos todas as variáveis para o objeto de configuração do gráfico, conforme a documentação do Echarts. xAxis para as dimensões, e passo as medidas nas chamadas “series” de dados.
     var option = {
                legend: {
                    data:[layout.qHyperCube.qMeasureInfo[0].qFallbackTitle]
                },
                xAxis: {
                    data: dimensions // variável 'dimensions', declarada no início
                }, 
                yAxis: {},
                series: [{
                    lineStyle: {
                        normal: {
                            color: "red",
                            width: 3,
                            type: "solid"
                        }
                    },
                    name: 'Sales',
                    type: 'line',
                    data: measures // variável 'measure', declarada no início
                }]
            }; // o que define ser um gráfico de linha é a prop “type”

            myChart.setOption(option);
            myChart.resize(); //sempre que uma ação é feita, deve-se realizar o resize() do gráfico. este é um método das instâncias do echarts.
        }

Para mais customizações (e são MUITAS), pode-se consultar a documentação do ECharts e testar as possibilidades (https://echarts.apache.org/en/option.html).

O resultado, utilizando o Consumer Sales.qvf da própria Qlik e utilizando a dimensão City juntamente com “Avg Sales”:

Reparem que o painel de customização funciona, com suas configurações basicas neste momento:

Existem diversas customizações e implementações adicionais, como:

  • filtros no gráfico;
  • zoom;
  • exportar os dados;
  • customizar cores;
  • adicionar linha de referência;
  • customizar os pontos;
  • tooltip com os valores;
  • etc.

Mas estes serão abordados em outros posts. Espero que seja de bom uso! Para mais detalhes sobre extensões e gráficos customizados, entre em contato consco!