Referência da API 2.0 de visualização personalizada

Uma chamada para a função looker.plugins.visualizations.add é o ponto de entrada na API Visualization. Essa função aceita um objeto de visualização que define totalmente a visualização personalizada.

Confira um exemplo de visualização:

looker.plugins.visualizations.add({
    create: function(element, config){
        element.innerHTML = "<h1>Ready to render!</h1>";
    },
    updateAsync: function(data, element, config, queryResponse, details, doneRendering){
        var html = "";
        for(var row of data) {
            var cell = row[queryResponse.fields.dimensions[0].name];
            html += LookerCharts.Utils.htmlForCell(cell);
        }
        element.innerHTML = html;
        doneRendering()
    }
});

Ambiente

Como a API Visualization é JavaScript simples, você pode usar qualquer biblioteca JavaScript para visualizar seus dados.

O código JavaScript será executado em um iframe em sandbox, separado da instância do Looker. Mesmo assim, os autores de visualizações personalizadas são responsáveis por garantir que o código escrito seja seguro.

Assim como todo desenvolvimento da Web, o suporte a diferentes navegadores da Web (Chrome, Edge, Firefox) pode ser um problema ocasionalmente. A API Visualization funciona em todos os navegadores compatíveis com o Looker, mas é sua responsabilidade garantir o suporte do navegador para o código personalizado. Por exemplo, usos do ES6, como let ou ()=>, funcionarão na maioria dos navegadores, mas poderão causar falhas no IE11 ou ao renderizar PDFs usando o PhantomJS.

Instalação

Você instala visualizações personalizadas definindo um manifesto com o formulário Admin > Platform > Visualizations. Um manifesto consiste em um ID de string exclusivo, um rótulo legível por humanos, o URI da visualização e links para todas as dependências necessárias (por exemplo, d3, jQuery, underscore).

As visualizações personalizadas precisam ser veiculadas como conteúdo HTTPS externamente ao Looker. Se você estiver migrando da primeira versão da API de visualização personalizada, talvez tenha arquivos no diretório looker/plugins/visualizations. Esse local ainda está acessível, e um caminho relativo para a visualização pode ser fornecido, mas recomendamos que você migre o conteúdo para um local diferente. Como o diretório /plugins não está no sistema de arquivos compartilhados, os ambientes clusterizados não terão acesso aos arquivos de visualização em todos os nós.

O objeto de visualização

O objeto de visualização usa as seguintes propriedades obrigatórias, opcionais e adicionadas.

Propriedades obrigatórias

  • create função

    Essa função é chamada uma vez, quando a visualização é desenhada pela primeira vez na página. Espera-se que ela configure tudo o que você quer que a visualização sempre tenha disponível. Você pode carregar uma biblioteca ou criar um conjunto de elementos e controles que serão usados mais tarde.

    Confira detalhes sobre a função create →

  • updateAsync / update função

    Essa função é chamada sempre que o estado da visualização precisa mudar. Ela sempre será chamada após create e poderá ser chamada muitas vezes. Portanto, ela precisa ser o mais rápida possível.

    Essa função pode ser chamada por muitos motivos, mas geralmente é quando a consulta a ser visualizada foi alterada, uma opção de configuração foi alterada ou a visualização foi redimensionada.

    Essa função tem uma versão síncrona e assíncrona :emdash; você só precisa especificar uma. É um erro definir as duas. O método assíncrono é mais confiável para renderização de PDF devido à natureza dos iframes.

    Confira detalhes sobre essas funções update →

Propriedades opcionais

  • options objeto

    Um objeto que detalha as opções que os usuários podem definir na visualização.

    Confira detalhes sobre como expor uma UI de configuração →

  • destroy função Ainda não implementada na API V2

    Uma função que é chamada pouco antes de a visualização ser removida da página. Use essa função para limpar listeners de eventos ou outros estados. Ela nunca poderá ser chamada se, por exemplo, o usuário fechar a janela.

Propriedades do anúncio adicionadas

O Looker adiciona as seguintes propriedades ao objeto automaticamente depois que a visualização é transmitida para looker.plugins.visualizations.add. É possível fazer referência a elas usando this no contexto das funções create, update, updateAsync e destroy.

  • addError função

    Uma função que o código de visualização pode chamar para informar à UI que mostre uma mensagem de erro em vez da visualização. Ela usa um objeto error.

    Depois que um erro é adicionado, ele permanece visível até que clearErrors seja chamado.

    Exemplo:

    this.addError({
        title: "Two Dimensions Required",
        message: "This really great visualization requires two dimensions."
    });
    
  • clearErrors função

    Uma função que o código de visualização pode chamar para limpar todos os erros adicionados usando addError.

    Exemplo:

    this.clearErrors();
    
  • trigger função

    Uma função que pode ser chamada para acionar um evento fora da visualização.

    Confira detalhes sobre eventos →

    Exemplo:

    this.trigger("limit", [20]);
    

A função create

A função create vai receber dois parâmetros, element e config.

create: function(element, config){
  // Your update code here.
},

Parâmetros

  • element DOMElement

    Um elemento DOM que representa um contêiner para renderizar a visualização.

  • config objeto

    Um objeto que representa os valores de todas as opções de configuração options definidas pelo usuário para esse gráfico.

    Exemplo: {my_configuration_option: "User Value"}

As funções updateAsync e update

O método preferencial de atualização da visualização é o updateAsync. Esse método permite que a visualização execute uma ação assíncrona, como carregar um arquivo ou enviar uma solicitação da Web.

Essa versão da função tem um parâmetro adicional, que é um callback a ser chamado quando a renderização for concluída:

updateAsync: function(data, element, config, queryResponse, details, done){
    // An example of an asynchronous update, fetching a file.
    d3.request("https://example.com/fun-file.docx").response(function(xhr) {
        // Your update code here that uses this file.
        done();
    });
}

Alertar o Looker quando a visualização terminar a renderização permite que o Looker otimize a renderização de PDF e garante que as imagens das visualizações sejam capturadas corretamente.

Algumas visualizações mais antigas usam a função update. Essa função ainda funciona, mas não é o método preferencial, já que o uso dela significa que o Looker não será alertado quando uma visualização for totalmente renderizada. A função update vai receber cinco parâmetros:

update: function(data, element, config, queryResponse, details){
  // Your update code here.
}

Parâmetros

  • data array

    Uma matriz de linhas que representam os dados atuais na consulta. Pode ser null.

    Cada linha é um objeto com as chaves que representam nomes de campos e o valor que representa um objeto "célula". Confira detalhes sobre como lidar com o objeto de célula.

  • element DOMElement

    Um elemento DOM que representa um contêiner para renderizar a visualização.

  • config objeto

    Um objeto que representa os valores de todas as opções de configuração options definidas pelo usuário para esse gráfico.

    Exemplo: {my_configuration_option: "User Value"}

  • queryResponse objeto

    Um objeto que representa metadados sobre a consulta atual, como metadados sobre campos. Pode ser null.

  • details objeto

    Detalhes sobre o contexto de renderização atual. Contém informações sobre por que o gráfico está sendo renderizado e o que mudou. Normalmente, essas informações são usadas apenas em casos avançados.

    Referente aos filtros cruzados nos painéis do Looker que usam a nova experiência de painel, os atributos permitidos incluem crossfilterEnabled e crossfilters.

    O atributo print pode ser usado em conjunto com a função done para melhorar a renderização de PDF para visualizações personalizadas, especialmente aquelas que incluem animação. Por exemplo:

    if (details.print) {
            done();
    }
    
  • done função

    Um callback para indicar que a visualização está totalmente renderizada. Essa função é especialmente importante para chamar se a visualização precisar executar chamadas assíncronas ou precisar ser renderizada como um PDF.

Renderização de dados

O Looker tem um conjunto avançado de ferramentas de formatação de dados no LookML que podem ser usadas para personalizar a aparência e o comportamento dos pontos de dados. Essas ferramentas incluem configurações do LookML no nível do campo, como formatos de valores personalizados, HTML, links de detalhamento e ações de dados.

As células têm uma propriedade value, que é a única propriedade que existe em todos os casos. Essa propriedade é um tipo JavaScript que corresponde ao tipo de campo a que a célula pertence. No entanto, não é seguro inserir uma propriedade value diretamente em HTML ou SVG, já que nenhum escape HTML foi realizado, e alguns valores de campo são objetos JavaScript ou matrizes complexos que serão renderizados de maneiras indesejáveis ou confusas.

Para garantir que todas as visualizações renderizem esses itens de forma consistente e segura, há várias funções utilitárias para transformar os metadados da célula transmitidos ao gráfico em data em representações diferentes para fins diferentes. Os metadados da célula podem compactar ou omitir determinados campos em alguns casos, e essas funções auxiliares permitem oferecer uma experiência consistente.

Essas funções auxiliares estão disponíveis no objeto global LookerCharts.Utils.

  • LookerCharts.Utils.textForCell(cell)

    Essa função aceita uma célula e retorna uma representação de string dela adequada para exibição. Ela sempre será uma string. Essa função nunca retorna null ou qualquer outro tipo.

  • LookerCharts.Utils.htmlForCell(cell)

    Essa função aceita uma célula e retorna uma string que contém HTML. Ela sempre será uma string. Essa função nunca retorna null ou qualquer outro tipo.

    A saída dessa função é escapada corretamente e adequada para inserção direta no HTML do elemento. O HTML de saída também vai mostrar corretamente o menu de detalhamento ao clicar quando for apropriado para os dados.

  • LookerCharts.Utils.filterableValueForCell(cell)

    Essa função aceita uma célula e retorna uma string de sintaxe de filtro avançado do Looker que corresponderia ao valor dessa célula.

  • LookerCharts.Utils.toggleCrossfilter({row, pivot, event})

    Essa função aceita uma linha, uma tabela dinâmica ou um evento e é usada para verificar se a filtragem cruzada está ativada para uma visualização. O exemplo a seguir mostra como adicionar um listener de eventos a um elemento que verifica se a filtragem cruzada está ativada quando o evento ocorre:

    d3.select("#myElement")
    .on("click", function (d) {
        if (details.crossfilterEnabled) {
                LookerCharts.Utils.toggleCrossfilter({
                    row: d.row,
                    event: d3.event,
                });
        } else {
          // ... handle click when cross-filtering is not enabled
        }
    });
    
  • LookerCharts.Utils.getCrossfilterSelection(row, pivot?)

    Essa função aceita uma linha ou tabela dinâmica e é usada para verificar se essa linha ou tabela dinâmica está selecionada em uma visualização personalizada. A função retorna um tipo enumerado para CrossfilterSelection {NONE, SELECTED, UNSELECTED} de 0 se NONE, 1 se SELECTED e 2 se UNSELECTED.

    O exemplo a seguir aplica condicionalmente uma cor de preenchimento a uma linha se ela estiver sendo filtrada cruzada e aplica cores padrão se a filtragem cruzada não estiver ativada para essa linha:

    d3.select("#myElement")
    .attr("fill", function (d) {
        const crossfilter = LookerCharts.Utils.getCrossfilterSelection(d.row)
        if (details.crossfilterEnabled && crossfilter === 1) {
                return d.color
        } else {
                return "#DEE1E5" //Hex used for unselected elements in native visualizations
    ...
    
  • LookerCharts.Utils.openDrillMenu(options)

    A saída de htmlForCell vai mostrar automaticamente o menu de detalhamento, se necessário, mas isso pode não ser apropriado para determinados tipos de renderização. Por exemplo, o SVG não pode renderizar HTML, mas talvez você queira capturar um evento de clique para iniciar um detalhamento.

    O objeto options tem os seguintes parâmetros:

    • links Obrigatório array

      Uma matriz dos objetos retornados da propriedade links de uma célula. Se você quiser mostrar links para várias células de uma só vez, primeiro concatene essas matrizes. Para links personalizados, forneça uma matriz de objetos com o seguinte formato:

      { label: string, type: 'drill', type_label: string, url: url }

    • event Evento HTML DOM

      O evento de clique (ou outro) que causou o evento de detalhamento. O Looker vai usar isso para determinar onde colocar o menu de detalhamento. Se você não tiver um, tente transmitir um objeto com as coordenadas pageX e pageY.

    Exemplo:

    for (var row of data) {
        var cell = row[queryResponse.fields.dimensions[0].name];
        var cellElement = myBuildElementFunction(cell);
        cellElement.onclick = function(event) {
            LookerCharts.Utils.openDrillMenu({
                links: cell.links,
                event: event
            });
        };
        // ... more visualization stuff...
    }
    

Apresentação da UI de configuração

O parâmetro options é um objeto em que as chaves são um identificador arbitrário para um nome de opção, e o valor é um objeto que descreve informações sobre a opção.

Exemplo:

options: {
    color_range: {
      type: "array",
      label: "Color Range",
      display: "colors"
    },
   top_label: {
      type: "string",
      label: "Label (for top)",
      placeholder: "My Great Chart"
    },
    transport_mode: {
      type: "string",
      label: "Mode of Transport",
      display: "select",
      values: [
         {"Airplane": "airplane"},
         {"Car": "car"},
         {"Unicycle": "unicycle"}
      ],
      default: "unicycle"
    }
}

Parâmetros do objeto de opção

O objeto option tem os seguintes parâmetros básicos, propriedades específicas de exibição e opções de organização.

Parâmetros básicos

  • type string

    O tipo de dados da opção.

    Valores permitidos:string (padrão), number, boolean, array

  • label string

    O rótulo legível por humanos da opção que será mostrado ao usuário.

  • default

    O valor padrão da opção. Quando não especificado, o valor da opção é null. Esse precisa ser um valor do mesmo tipo que type.

  • display string

    Determinados valores type podem ser apresentados na UI de maneiras diferentes.

    • quando type é string:

      Valores permitidos:text (padrão), select, radio

    • quando type é number:

      Valores permitidos:number (padrão), range

    • quando type é array:

      Valores permitidos: text (padrão), color, colors

  • placeholder string

    Para valores display compatíveis, um valor de exemplo ou explicação para dar ao usuário uma dica sobre o que digitar.

Propriedades específicas de exibição

  • values array de objetos

    Quando display é radio ou select, uma matriz que contém rótulos e valores que serão listados na interface.

    Cada item na matriz precisa ser um objeto com um único par de chave-valor, que representa o rótulo e o valor da opção. O rótulo será apresentado apenas na UI. No tempo de renderização, você receberá apenas o valor.

    Exemplo:

    values: [
        {"Center": "c"},
        {"Left": "l"},
        {"Right": "r"}
    ]
    

    Se display for radio, cada opção também poderá receber uma description:

    values: [
        {"Cool": "c"},
        {"Uncool": {
                value: "unc",
                description: "Only choose this if the data is very uncool."
            }
        }
    ]
    
  • max number

    Quando display é range, o número máximo permitido para ser selecionado pelo controle deslizante de intervalo.

  • min number

    Quando display é range, o número mínimo permitido para ser selecionado pelo controle deslizante de intervalo.

  • step number

    Quando display é range, o valor que cada marca do controle deslizante de intervalo representa.

Opções de organização

  • section string

    Para gráficos com muitas opções, um rótulo para a seção em que uma opção deve aparecer. A interface vai agrupar as opções pelos valores section. Se houver apenas uma seção, a UI da seção não será mostrada.

    Se você estiver usando section, ela precisará ser definida em todas as opções.

  • order number

    Um número que representa a ordem das opções para apresentação na UI. Se especificado, as opções serão classificadas de acordo com essa ordem.

  • display_size string

    Uma classe de tamanho que representa a largura da opção na UI. Por exemplo, se você quiser mostrar uma opção "Mínimo" e uma "Máximo" lado a lado, defina cada um dos tamanhos de exibição como half.

    Valores permitidos:normal (padrão), half, third

Eventos

Os eventos podem ser acionados pelo gráfico (geralmente em resposta à interação do usuário) que podem atualizar as propriedades da visualização ou consulta.

Eles podem ser acionados chamando a função trigger no objeto de visualização. O primeiro parâmetro é sempre o nome do evento e o segundo é uma matriz de argumentos.

this.trigger("limit", [20]);

Eventos disponíveis

  • updateConfig

    Atualize as configurações atuais do gráfico.

    Argumento:um objeto que contém chaves de configuração a serem atualizadas. As chaves não especificadas não são alteradas.

    Exemplo:

    var vis = this;
    $(element).find(".axis").click(function(){
        vis.trigger("updateConfig", [{axis_hidden: true}]);
    });
    
  • limit

    Atualize o limite da consulta subjacente:

    Argumento:um número inteiro que representa um novo limite para a consulta.

    var vis = this;
    $(element).find(".show-all").click(function(){
        vis.trigger("limit", [500]);
    });
    
  • filter

    Atualize o valor de um filtro na consulta subjacente:

    var vis = this;
    $(element).find(".show-all-tommys").click(function(){
        vis.trigger("filter", [{
            field: "users.name", // the name of the field to filter
            value: "%tommy%", // the "advanced syntax" for the filter
            run: true, // whether to re-run the query with the new filter
        }]);
    });
    
  • loadingStart

    Marque a visualização como carregando. Na maioria das vezes, isso não é necessário, mas, se a visualização carregar um objeto de um local remoto ou realizar um cálculo longo, você poderá usar essa opção para continuar mostrando o indicador de carregamento.

    Ele vai aparecer carregando até que loadingEnd seja acionado.

  • loadingEnd

    Marque a visualização como não carregando mais.

  • printSize (Looker 26.0 ou mais recente)

    Permite que as visualizações aproveitem a opção "Abrir tabelas para mostrar todas as linhas" ao renderizar painéis de dados em PDF. O uso desse evento permite que o aplicativo saiba a altura do conteúdo renderizado e possa expandir o bloco do painel de dados adequadamente para que todas as informações fiquem visíveis para impressão.

      this.trigger('printSize', {
        heightExpanded: FULL_HEIGHT_IN_PIXELS
      });
    
  • registerOptions (Looker 5.24 ou mais recente)

    Permite que as visualizações registrem outras opções depois que a visualização for registrada:

      update: function(data, element, config, queryResponse, details){
        options = {}
        // Create an option for each measure in your query
        queryResponse.fields.measure_like.forEach(function(field) {
          id = "color_" + field.name
          options[id] =
          {
        label: field.label_short + " Color",
        default: "#8B7DA8",
        section: "Style",
        type: "string",
        display: "color"
          }
        })
        this.trigger('registerOptions', options) // register options with parent page to update visConfig
        ...
      }
    });