L'API Visualization di Looker è un'API JavaScript che viene eseguita in un iframe sandbox ed è ospitata all'interno dell'applicazione Looker.
Puoi utilizzare lo stesso codice di visualizzazione per fornire una visualizzazione ovunque in Looker: esplorazioni, Look, dashboard, incorporamenti, PDF o immagini sottoposte a rendering.
Ogni visualizzazione rappresenta una visualizzazione di una singola query di Looker. Looker esegue la query e passa i risultati al codice di visualizzazione. Looker passa anche un elemento DOM in cui il codice di visualizzazione può disegnare.
Requisiti
Prima di iniziare, assicurati di soddisfare i seguenti requisiti:
- Sono necessarie alcune conoscenze di JavaScript e sviluppo web.
- È necessario l'accesso amministratore di Looker per creare e aggiornare i file manifest del progetto LookML.
Creare una visualizzazione "Hello World"
Questa sezione descrive come creare uno script di visualizzazione personalizzato che visualizza la prima dimensione di una determinata query.
Il risultato finale dovrebbe essere simile all'immagine seguente:

Configurazione
Per sviluppare e testare una visualizzazione in Looker, hai due opzioni:
- Salva il codice sorgente della visualizzazione direttamente nel progetto LookML (opzione consigliata).
- Ospita la visualizzazione tramite HTTPS e fai riferimento a essa da Looker.
Dopo aver configurato una di queste opzioni, puoi seguire l'esempio in questa sezione per creare hello_world.js.
Struttura del codice essenziale
Per visualizzare il codice sorgente finale di questo esempio, consulta il repository GitHub.
Nella cartella di hosting, crea un nuovo file JavaScript vuoto e chiamalo hello_world.js.
Per registrare una nuova visualizzazione personalizzata con Looker, chiama la funzione looker.plugins.visualizations.add e passale un oggetto di visualizzazione.
Questo oggetto contiene la definizione della visualizzazione e della relativa UI di configurazione.
L'esempio seguente mostra lo scheletro di una visualizzazione con tutte le proprietà richieste compilate. Contiene una funzione create e una funzione updateAsync in cui puoi scrivere il codice di visualizzazione:
looker.plugins.visualizations.add({
create: function(element, config) {
},
updateAsync: function(data, element, config, queryResponse, details, done) {
}
})
Questo codice è una visualizzazione di Looker valida, ma non è ancora visiva e viene visualizzata come una casella vuota.
Prima del ciak
Considera la funzione create, che ha due argomenti: element e config.
Looker fornisce un element, ovvero l'
elemento DOM
in cui Looker richiede di inserire la visualizzazione.
Looker crea questo elemento e lo ridimensiona correttamente; devi inserire i contenuti al suo interno.
La funzione create offre l'opportunità di eseguire la configurazione iniziale dell'elemento. Per questo esempio, vuoi creare un grafico simile alla seguente struttura HTML:
<style>
/* custom styles for your chart */
</style>
<div class="hello-world-vis">
<div>Data Goes Here</div>
</div>
Utilizzando JavaScript, puoi inserire elementi nell'elemento DOM in modo che corrispondano a questa struttura.
L'esempio seguente mostra questa funzione con maggiori dettagli:
create: function(element, config) {
// Insert a <style> tag with some styles to use later.
var css = element.innerHTML = `
<style>
.hello-world-vis {
/* Vertical centering */
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
</style>
`;
// Create a container element to center the text.
var container = element.appendChild(document.createElement("div"));
container.className = "hello-world-vis";
// Create an element to contain the text.
this._textElement = container.appendChild(document.createElement("div"));
},
Questo codice aggiunge CSS, crea il contenitore hello-world-vis e aggiunge un div al suo interno.
Il codice assegna anche this._textElement al contenitore in cui vuoi eseguire il rendering. Si tratta di una comodità per non doverlo cercare di nuovo in un secondo momento quando il grafico inizia il rendering.
La funzione create è un luogo pratico per eseguire attività di configurazione che devono essere eseguite una sola volta.
Rendering
Questa sezione descrive come espandere il metodo updateAsync per visualizzare i dati. Questo metodo viene chiamato ogni volta che il grafico deve visualizzare le modifiche o quando si verifica un altro evento che potrebbe influire sul rendering del grafico (ad esempio, il grafico viene ridimensionato o un'opzione di configurazione viene modificata).
Per questo esempio, devi trovare solo la prima dimensione nella prima cella.
Puoi farlo utilizzando data, che è un array di ogni riga del set di dati, e queryResponse, che contiene metadati sulla query, come nomi e tipi di campi.
Puoi anche utilizzare un metodo helper chiamato LookerCharts.Utils.htmlForCell per fornire la rappresentazione HTML corretta del punto dati in quella cella. Questo metodo gestisce automaticamente elementi come link di drill-down, formattazione e azioni sui dati:
updateAsync: function(data, element, config, queryResponse, details, done) {
// Grab the first cell of the data.
var firstRow = data[0];
var firstCell = firstRow[queryResponse.fields.dimensions[0].name];
// Insert the data into the page.
this._textElement.innerHTML = LookerCharts.Utils.htmlForCell(firstCell);
// Always call done to indicate a visualization has finished rendering.
done()
}
In questo modo, hai completato i passaggi necessari per avere una visualizzazione personalizzata funzionante. Tuttavia, è importante includere un metodo per la gestione degli errori.
Gestire gli errori
Il codice updateAsync recupera la prima riga di dati, ma possono verificarsi errori se la query non restituisce risultati o non contiene dimensioni.
Senza la gestione degli errori, nella console del browser viene visualizzato un errore JavaScript, che potrebbe confondere gli utenti quando il grafico non viene sottoposto a rendering.
I grafici possono visualizzare messaggi di errore personalizzati se si verificano problemi durante il tentativo di rendering. Looker aggiunge due funzioni all'oggetto di visualizzazione: addError e clearErrors. Puoi utilizzare queste funzioni per visualizzare un messaggio di errore che abbia senso per tutti gli utenti.
Poiché queste funzioni vengono aggiunte all'oggetto di visualizzazione, sono disponibili dal contesto della funzione updateAsync tramite l'oggetto this.
Puoi modificare l'inizio del metodo updateAsync per rilevare una condizione di errore, notificare all'utente un problema e uscire anziché tentare di eseguire il rendering:
updateAsync: function(data, element, config, queryResponse, details, done) {
// Clear any errors from previous updates.
this.clearErrors();
// Throw some errors and exit if the shape of the data isn't what this chart needs.
if (queryResponse.fields.dimensions.length == 0) {
this.addError({title: "No Dimensions", message: "This chart requires dimensions."});
// Always call done() before exiting early to avoid dashboard exports hanging
done();
return;
}
if (!data || data.length === 0) {
this.addError({title: "No Data", message: "The query returned no results."});
done();
return;
}
// ... the rest of the update code here ...
Se l'utente crea una query che contiene solo misure, viene visualizzato un messaggio di errore simile al seguente:

Rendering asincrono ed esportazioni in PDF
Nell'esempio "Hello World" precedente, la funzione done() viene chiamata immediatamente dopo l'aggiornamento del DOM. Questo approccio è appropriato perché l'impostazione di innerHTML è sincrona.
Tuttavia, se utilizzi librerie di grafici come D3.js, Chart.js o React, il rendering è probabilmente asincrono. Se chiami done() nella parte inferiore dello script, Looker potrebbe acquisire lo screenshot per un'esportazione in PDF o PNG prima che il grafico finisca di disegnare, il che può comportare un riquadro vuoto.
Quando Looker esporta una dashboard, utilizza un browser headless e si basa sul callback done() per sapere quando è sicuro acquisire uno screenshot.
Per assicurarti che i grafici vengano esportati correttamente, devi collegare il callback done() all'evento di completamento della libreria e disattivare le animazioni durante le esportazioni utilizzando il flag details.print.
L'esempio seguente mostra come gestire il rendering asincrono utilizzando D3.js:
updateAsync: function(data, element, config, queryResponse, details, done) {
this.clearErrors();
// Check if Looker is exporting the chart to a PDF/PNG
const isExport = details && details.print === true;
// Clear previous elements
this.svg.selectAll("*").remove();
const circle = this.svg.append("circle")
.attr("cx", 50)
.attr("cy", 50);
if (isExport) {
// Instant render for exports. Draw the final state immediately with no transitions
circle.attr("r", 40);
// Tell Looker to take the screenshot right now
done();
} else {
// If it's for the browser, start small and animate
circle.attr("r", 0)
.transition()
.duration(1000)
.attr("r", 40)
.on("end", () => {
// Tell Looker the animation is fully complete
done();
});
}
}
Se utilizzi React, assicurati di passare il callback done come terzo argomento alla funzione di rendering in modo che Looker attenda che React monti i componenti:
this.chart = ReactDOM.render(
<MyCustomChart data={data} />,
element,
done // Looker waits for React to finish
);
Configurazione
Puoi consentire agli utenti di personalizzare alcuni aspetti della visualizzazione.
Oltre alle altre proprietà dell'oggetto di visualizzazione, è disponibile una proprietà denominata options.
Puoi utilizzare questa proprietà per specificare il tipo di opzioni richieste dal grafico:
looker.plugins.visualizations.add({
options: {
font_size: {
type: "string",
label: "Font Size",
values: [
{"Large": "large"},
{"Small": "small"}
],
display: "radio",
default: "large"
}
},
// ... rest of visualization object ...
Questo esempio crea un'opzione font_size che viene visualizzata come pulsanti di opzione, consentendo agli utenti di scegliere tra le dimensioni dei caratteri "small" e "large".
La specifica della proprietà options è obbligatoria per aggiungere l'opzione al selettore di visualizzazione.
Per utilizzare questa opzione nel codice, ricorda che nel metodo updateAsync è presente un parametro config. Questo parametro contiene le seguenti opzioni selezionate:
updateAsync: function(data, element, config, queryResponse, details, done) {
L'oggetto config è simile al seguente:
{font_size: "large"}
Quando aggiorni il grafico, puoi controllare questo oggetto e rispondere di conseguenza. Aggiungi il seguente controllo alla fine del metodo di aggiornamento per implementare le modifiche alle dimensioni dei caratteri:
if (config.font_size == "small") {
this._textElement.className = "hello-world-text-small";
} else {
this._textElement.className = "hello-world-text-large";
}
Devi anche aggiornare il tag <style> aggiunto nel metodo create per definire le classi CSS
hello-world-text-small e hello-world-text-large:
.hello-world-text-large {
font-size: 72px;
}
.hello-world-text-small {
font-size: 18px;
}
Poiché la funzione updateAsync viene chiamata ogni volta che la configurazione viene modificata e Looker salva automaticamente la configurazione, questo è tutto ciò che devi fare per rispondere alle impostazioni di configurazione.
Passaggi successivi
Puoi visualizzare il codice sorgente completo di questa visualizzazione "Hello World" nel repository GitHub open source di Looker.
Per ulteriori informazioni sulle funzionalità aggiuntive, consulta il riferimento API Visualization.