Vad är inbäddning för externa användare?

På den här sidan beskrivs hur inbäddning för externa användare fungerar, hur du konfigurerar din Azure Databricks arbetsyta för säker delning av inbäddade instrumentpaneler och hur du använder exempelprogram för att komma igång. Inbäddning för externa användare använder tjänstens huvudnamn och begränsade åtkomsttoken för att autentisera och auktorisera åtkomst till inbäddade instrumentpaneler. Med den här metoden kan du dela instrumentpaneler med tittare utanför organisationen, till exempel partner och kunder, utan att etablera Azure Databricks konton för dessa användare.

Mer information om andra inbäddningsalternativ, inklusive inbäddning av instrumentpaneler för användare i din organisation, finns i Bädda in en instrumentpanel.

Så här fungerar inbäddning för externa användare

Diagrammet och de numrerade stegen som följer förklarar hur användare autentiseras och instrumentpaneler fylls med användaromfattande resultat när du bäddar in en instrumentpanel för externa användare.

Ett flödesdiagram som visar nödvändiga tokenutbyten mellan ditt program och Databricks-arbetsytan.

  1. Användarautentisering och begäran: Användaren loggar in på ditt program. Programmets klientdel skickar en autentiserad begäran till servern om en åtkomsttoken för instrumentpanelen.
  2. Autentisering med tjänstens huvudnamn: Servern använder tjänstens huvudhemlighet för att begära och ta emot en OAuth-token från Databricks-servern. Det här är en omfattande token som kan anropa alla instrumentpanels-API:er som Azure Databricks har åtkomst till på uppdrag av tjänsthuvudkontot. Servern anropar /tokeninfo slutpunkten med den här token och skickar grundläggande användarinformation, till exempel external_viewer_id och external_value. Se Presentera instrumentpaneler på ett säkert sätt för enskilda användare.
  3. Generering av token med användaromfattning: Med hjälp av svaret från /tokeninfo slutpunkten och OIDC-slutpunkten (Databricks OpenID Connect) genererar servern en ny strikt begränsad token som kodar användarinformationen som du har skickat in.
  4. Dashboard rendering och datafiltrering: Applikationssidan instansierar DatabricksDashboard från @databricks/aibi-client och skickar en användarspecifik token under konstruktionen. Instrumentpanelen visas med användarens kontext. Den här token auktoriserar åtkomst, stöder granskning med external_viewer_idoch utför external_value för datafiltrering. Frågor i dataset i instrumentpanelen kan referera __aibi_external_value för att tillämpa filter per användare, vilket säkerställer att varje användare endast ser data som de får visa.

Ask Genie är inte tillgänglig för extern integrering

Knappen Fråga Genie stöds inte i inbäddning för externa användare. Om du vill ge funktioner för datafrågor på naturligt språk till externa användare använder du Genie Conversation API i stället. Med konversations-API:et kan du integrera Genie-funktioner i ditt program programmässigt, oberoende av inbäddning av instrumentpaneler.

För instrumentpaneler med grundläggande inbäddning är Ask Genie tillgänglig. Se Fråga Genie i inbäddade instrumentpaneler.

Presentera instrumentpaneler på ett säkert sätt för enskilda användare

Konfigurera programservern så att den genererar en unik användarbaserad token för varje användare utifrån deras external_viewer_id. På så sätt kan du spåra instrumentpanelsvyer och användning via granskningsloggar. external_viewer_id är parat med en external_value, som fungerar som en global variabel som kan infogas i SQL-frågor som används i instrumentpanelsdatauppsättningar. På så sätt kan du filtrera data som visas på instrumentpanelen för varje användare.

external_viewer_id skickas till instrumentpanelens granskningsloggar och får inte innehålla personligt identifierbar information. Det här värdet bör också vara unikt per användare.

external_value används vid frågebearbetning och kan innehålla personligt identifierbar information.

Anmärkning

Den kombinerade storleken på external_viewer_id och external_value får inte överstiga 1 KB.

I följande exempel visas hur du använder det externa värdet som ett filter i datamängdsfrågor:

SELECT *
FROM sales
WHERE region = __aibi_external_value

Översikt över installation

Det här avsnittet innehåller en översikt över de steg du behöver utföra för att konfigurera för att bädda in en instrumentpanel på en extern plats.

Om du vill bädda in en instrumentpanel i ett externt program skapar du först ett huvudnamn för service i Azure Databricks och genererar en hemlighet. Tjänstens huvudnamn måste beviljas läsbehörighet till instrumentpanelen och dess underliggande data. Servern använder serviceprincipalens hemlighet för att hämta en token som kan få åtkomst till API:er för instrumentpaneler för serviceprincipalen. Med den här token anropar /tokeninfo servern API-slutpunkten, en OpenID Connect-slutpunkt (OIDC) som returnerar grundläggande användarprofilinformation, inklusive external_value värdena och external_viewer_id . Med de här värdena kan du associera begäranden med enskilda användare.

Med hjälp av den token som erhålls från tjänstehuvudkontot genererar servern en ny token för den specifika användare som har åtkomst till instrumentpanelen. Den här användarspecifika token skickas till applikationssidan, där programmet instansierar DatabricksDashboard-objektet från biblioteket @databricks/aibi-client. Token innehåller användarspecifik information som stöder granskning och framtvingar filtrering så att varje användare bara ser de data som de har behörighet att komma åt. Från användarens perspektiv ger inloggning till programmet automatiskt åtkomst till den inbäddade instrumentpanelen med rätt datasynlighet.

Hastighetsbegränsningar och prestandaöverväganden

Extern inbäddning har en hastighetsgräns på 20 instrumentpanelladdningar per sekund. Du kan öppna fler än 20 instrumentpaneler samtidigt, men högst 20 kan börja laddas samtidigt.

Förutsättningar

Om du vill implementera extern inbäddning ser du till att du uppfyller följande krav:

Steg 1: Skapa ett huvudnamn för tjänsten

Skapa ett huvudnamn för tjänsten för att fungera som identitet för ditt externa program inom Azure Databricks. Tjänstehuvudprincipal autentiserar begäranden på uppdrag av din ansökan.

Så här skapar du ett huvudnamn för tjänsten:

  1. Logga in på Azure Databricks arbetsytan som arbetsytans administratör.
  2. Klicka på ditt användarnamn i det övre fältet på arbetsytan Azure Databricks och välj Inställningar.
  3. Klicka på Identitet och åtkomst i det vänstra fönstret.
  4. Bredvid Tjänstens huvudnamn klickar du på Hantera.
  5. Klicka på Lägg till tjänstens huvudnamn.
  6. Klicka på Lägg till ny.
  7. Ange ett beskrivande namn för tjänstens huvudnamn.
  8. Klicka på Lägg till.
  9. Öppna tjänstens huvudnamn som du nyss skapade från listsidan tjänsthuvudnamn . Använd Filter textinmatningsfält för att söka efter det genom att ange namnet, om det behövs.
  10. På sidan Information om tjänstens huvudnamn registrerar du program-ID:t. Kontrollera att kryssrutorna Databricks SQL-åtkomst och åtkomst till arbetsyta är markerade.

Steg 2: Skapa en OAuth-hemlighet

Generera en hemlighet för tjänstens huvudnamn och samla in följande konfigurationsvärden, som du behöver för ditt externa program:

  • Tjänstens huvudnamn (klient)-ID
  • Klienthemlighet

Tjänstens service principal använder en OAuth-hemlighet för att verifiera sin identitet när den begär en åtkomsttoken från ditt externa program.

Så här genererar du en hemlighet:

  1. Klicka på Hemligheter på sidan Information om tjänstens huvudnamn .
  2. Klicka på Generera hemlighet.
  3. Ange ett livslängdsvärde för den nya hemligheten i dagar (t.ex. mellan 1 och 730 dagar).
  4. Kopiera hemligheten omedelbart. Du kan inte visa den här hemligheten igen när du har lämnat den här skärmen.

Steg 3: Tilldela behörigheter till din serviceprincipal

Tjänstens huvudnamn som du skapade fungerar som den identitet som ger åtkomst till instrumentpanelen via ditt program. Dess behörigheter gäller endast om instrumentpanelen inte är publicerad med delade databehörigheter. Om delade databehörigheter används får utgivarens autentiseringsuppgifter åtkomst till data. Mer information och rekommendationer finns i Bädda in autentiseringsmetoder.

  1. Klicka på Instrumentpaneler i sidofältet på arbetsytan för att öppna instrumentpanelens listsida.
  2. Klicka på namnet på instrumentpanelen som du vill bädda in. Den publicerade instrumentpanelen öppnas.
  3. Klicka på Dela.
  4. Använd textinmatningsfältet i dialogrutan Delning för att hitta tjänstens huvudnamn och klicka sedan på det. Ställ in behörighetsnivån på CAN RUN. Klicka sedan på Lägg till.
  5. Registrera instrumentpanelens ID. Du hittar instrumentpanels-ID:t i instrumentpanelens URL (t.ex. https://<your-workspace-url>/dashboards/<dashboard-id>). Se Information om Databricks-arbetsytan.

Anmärkning

Om du publicerar en instrumentpanel med enskilda databehörigheter måste du ge tjänstens huvudkonto åtkomst till de data som används i instrumentpanelen. Beräkningsåtkomst använder alltid utgivarens autentiseringsuppgifter, så du behöver inte bevilja beräkningsbehörighet till service-principal.

För att kunna läsa och visa data måste tjänstens huvudnamn ha minst SELECT behörighet för tabeller och vyer som refereras till på instrumentpanelen. Se Vem kan hantera behörigheter?.

Steg 4: Använd exempelappen för att autentisera och generera token

Använd ett exempelprogram för att öva extern inbäddning av instrumentpanelen. Programmen innehåller instruktioner och kod som initierar det nödvändiga tokenutbytet för att generera begränsade token. Följande kodblock har inga beroenden. Kopiera och spara något av följande program.

Python

Kopiera och spara detta i en fil med namnet example.py.

#!/usr/bin/env python3

import os
import sys
import json
import base64
import urllib.request
import urllib.parse
from http.server import HTTPServer, BaseHTTPRequestHandler

# -----------------------------------------------------------------------------
# Config
# -----------------------------------------------------------------------------
CONFIG = {
    "instance_url": os.environ.get("INSTANCE_URL"),
    "dashboard_id": os.environ.get("DASHBOARD_ID"),
    "service_principal_id": os.environ.get("SERVICE_PRINCIPAL_ID"),
    "service_principal_secret": os.environ.get("SERVICE_PRINCIPAL_SECRET"),
    "external_viewer_id": os.environ.get("EXTERNAL_VIEWER_ID"),
    "external_value": os.environ.get("EXTERNAL_VALUE"),
    "workspace_id": os.environ.get("WORKSPACE_ID"),
    "port": int(os.environ.get("PORT", 3000)),
}

basic_auth = base64.b64encode(
    f"{CONFIG['service_principal_id']}:{CONFIG['service_principal_secret']}".encode()
).decode()

# -----------------------------------------------------------------------------
# HTTP Request Helper
# -----------------------------------------------------------------------------
def http_request(url, method="GET", headers=None, body=None):
    headers = headers or {}
    if body is not None and not isinstance(body, (bytes, str)):
        raise ValueError("Body must be bytes or str")

    req = urllib.request.Request(url, method=method, headers=headers)
    if body is not None:
        if isinstance(body, str):
            body = body.encode()
        req.data = body

    try:
        with urllib.request.urlopen(req) as resp:
            data = resp.read().decode()
            try:
                return {"data": json.loads(data)}
            except json.JSONDecodeError:
                return {"data": data}
    except urllib.error.HTTPError as e:
        raise RuntimeError(f"HTTP {e.code}: {e.read().decode()}") from None

# -----------------------------------------------------------------------------
# Token logic
# -----------------------------------------------------------------------------
def get_scoped_token():
    # 1. Get all-api token
    oidc_res = http_request(
        f"{CONFIG['instance_url']}/oidc/v1/token?o={CONFIG['workspace_id']}",
        method="POST",
        headers={
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": f"Basic {basic_auth}",
        },
        body=urllib.parse.urlencode({
            "grant_type": "client_credentials",
            "scope": "all-apis"
        })
    )
    oidc_token = oidc_res["data"]["access_token"]

    # 2. Get token info
    token_info_url = (
        f"{CONFIG['instance_url']}/api/2.0/lakeview/dashboards/"
        f"{CONFIG['dashboard_id']}/published/tokeninfo"
        f"?o={CONFIG['workspace_id']}"
        f"&external_viewer_id={urllib.parse.quote(CONFIG['external_viewer_id'])}"
        f"&external_value={urllib.parse.quote(CONFIG['external_value'])}"
    )
    token_info = http_request(
        token_info_url,
        headers={"Authorization": f"Bearer {oidc_token}"}
    )["data"]

    # 3. Generate scoped token
    params = token_info.copy()
    authorization_details = params.pop("authorization_details", None)
    params.update({
        "grant_type": "client_credentials",
        "authorization_details": json.dumps(authorization_details)
    })

    scoped_res = http_request(
        f"{CONFIG['instance_url']}/oidc/v1/token?o={CONFIG['workspace_id']}",
        method="POST",
        headers={
            "Content-Type": "application/x-www-form-urlencoded",
            "Authorization": f"Basic {basic_auth}",
        },
        body=urllib.parse.urlencode(params)
    )
    return scoped_res["data"]["access_token"]

# -----------------------------------------------------------------------------
# HTML generator
# -----------------------------------------------------------------------------
def generate_html(token):
    return f"""<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dashboard Demo</title>
    <style>
        body {{ font-family: system-ui; margin: 0; padding: 20px; background: #f5f5f5; }}
        .container {{ max-width: 1200px; margin: 0 auto; height:calc(100vh - 40px) }}
    </style>
</head>
<body>
    <div id="dashboard-content" class="container"></div>
    <script type="module">
        import {{ DatabricksDashboard }} from "https://cdn.jsdelivr.net/npm/@databricks/aibi-client@0.0.0-alpha.7/+esm";
        const dashboard = new DatabricksDashboard({{
            instanceUrl: "{CONFIG['instance_url']}",
            workspaceId: "{CONFIG['workspace_id']}",
            dashboardId: "{CONFIG['dashboard_id']}",
            token: "{token}",
            container: document.getElementById("dashboard-content")
        }});
        dashboard.initialize();
    </script>
</body>
</html>"""

# -----------------------------------------------------------------------------
# HTTP server
# -----------------------------------------------------------------------------
class RequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path != "/":
            self.send_response(404)
            self.send_header("Content-Type", "text/plain")
            self.end_headers()
            self.wfile.write(b"Not Found")
            return

        try:
            token = get_scoped_token()
            html = generate_html(token)
            status = 200
        except Exception as e:
            html = f"<h1>Error</h1><p>{e}</p>"
            status = 500

        self.send_response(status)
        self.send_header("Content-Type", "text/html")
        self.end_headers()
        self.wfile.write(html.encode())

def start_server():
    missing = [k for k, v in CONFIG.items() if not v]
    if missing:
        print(f"Missing: {', '.join(missing)}", file=sys.stderr)
        sys.exit(1)

    server = HTTPServer(("localhost", CONFIG["port"]), RequestHandler)
    print(f":rocket: Server running on http://localhost:{CONFIG['port']}")
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        sys.exit(0)

if __name__ == "__main__":
    start_server()

JavaScript

Kopiera och spara detta i en fil med namnet example.js.

#!/usr/bin/env node

const http = require('http');
const https = require('https');
const { URL, URLSearchParams } = require('url');

// This constant is just a mapping of environment variables to their respective
// values.
const CONFIG = {
  instanceUrl: process.env.INSTANCE_URL,
  dashboardId: process.env.DASHBOARD_ID,
  servicePrincipalId: process.env.SERVICE_PRINCIPAL_ID,
  servicePrincipalSecret: process.env.SERVICE_PRINCIPAL_SECRET,
  externalViewerId: process.env.EXTERNAL_VIEWER_ID,
  externalValue: process.env.EXTERNAL_VALUE,
  workspaceId: process.env.WORKSPACE_ID,
  port: process.env.PORT || 3000,
};

const basicAuth = Buffer.from(`${CONFIG.servicePrincipalId}:${CONFIG.servicePrincipalSecret}`).toString('base64');

// ------------------------------------------------------------------------------------------------
// Main
// ------------------------------------------------------------------------------------------------

function startServer() {
  const missing = Object.keys(CONFIG).filter((key) => !CONFIG[key]);
  if (missing.length > 0) throw new Error(`Missing: ${missing.join(', ')}`);

  const server = http.createServer(async (req, res) => {
    // This is a demo server, we only support GET requests to the root URL.
    if (req.method !== 'GET' || req.url !== '/') {
      res.writeHead(404, { 'Content-Type': 'text/plain' });
      res.end('Not Found');
      return;
    }

    let html = '';
    let status = 200;

    try {
      const token = await getScopedToken();
      html = generateHTML(token);
    } catch (error) {
      html = `<h1>Error</h1><p>${error.message}</p>`;
      status = 500;
    } finally {
      res.writeHead(status, { 'Content-Type': 'text/html' });
      res.end(html);
    }
  });

  server.listen(CONFIG.port, () => {
    console.log(`🚀 Server running on http://localhost:${CONFIG.port}`);
  });

  process.on('SIGINT', () => process.exit(0));
  process.on('SIGTERM', () => process.exit(0));
}

async function getScopedToken() {
  // 1. Get all-api token. This will allow you to access the /tokeninfo
  // endpoint, which contains the information required to generate a scoped token
  const {
    data: { access_token: oidcToken },
  } = await httpRequest(`${CONFIG.instanceUrl}/oidc/v1/token?o=${CONFIG.workspaceId}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: `Basic ${basicAuth}`,
    },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      scope: 'all-apis',
    }),
  });

  // 2. Get token info. This information is **required** for generating a token that is correctly downscoped.
  // A correctly downscoped token will only have access to a handful of APIs, and within those APIs, only
  // a the specific resources required to render the dashboard.
  //
  // This is essential to prevent leaking a privileged token.
  //
  // At the time of writing, OAuth tokens in Databricks are valid for 1 hour.
  const tokenInfoUrl = new URL(
    `${CONFIG.instanceUrl}/api/2.0/lakeview/dashboards/${CONFIG.dashboardId}/published/tokeninfo?o=${CONFIG.workspaceId}`,
  );
  tokenInfoUrl.searchParams.set('external_viewer_id', CONFIG.externalViewerId);
  tokenInfoUrl.searchParams.set('external_value', CONFIG.externalValue);

  const { data: tokenInfo } = await httpRequest(tokenInfoUrl.toString(), {
    headers: { Authorization: `Bearer ${oidcToken}` },
  });

  // 3. Generate scoped token. This call is very similar to what was issued before, but now we are providing the scoping to make the generated token
  // safe to pass to a browser.
  const { authorization_details, ...params } = tokenInfo;
  const {
    data: { access_token },
  } = await httpRequest(`${CONFIG.instanceUrl}/oidc/v1/token?o=${CONFIG.workspaceId}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
      Authorization: `Basic ${basicAuth}`,
    },
    body: new URLSearchParams({
      grant_type: 'client_credentials',
      ...params,
      authorization_details: JSON.stringify(authorization_details),
    }),
  });

  return access_token;
}

startServer();

// ------------------------------------------------------------------------------------------------
// Helper functions
// ------------------------------------------------------------------------------------------------

/**
 * Helper function to create HTTP requests.
 * @param {string} url - The URL to make the request to.
 * @param {Object} options - The options for the request.
 * @param {string} options.method - The HTTP method to use.
 * @param {Object} options.headers - The headers to include in the request.
 * @param {Object} options.body - The body to include in the request.
 * @returns {Promise<Object>} A promise that resolves to the response data.
 */
function httpRequest(url, { method = 'GET', headers = {}, body } = {}) {
  return new Promise((resolve, reject) => {
    const isHttps = url.startsWith('https://');
    const lib = isHttps ? https : http;
    const options = new URL(url);
    options.method = method;
    options.headers = headers;

    const req = lib.request(options, (res) => {
      let data = '';
      res.on('data', (chunk) => (data += chunk));
      res.on('end', () => {
        if (res.statusCode >= 200 && res.statusCode < 300) {
          try {
            resolve({ data: JSON.parse(data) });
          } catch {
            resolve({ data });
          }
        } else {
          reject(new Error(`HTTP ${res.statusCode}: ${data}`));
        }
      });
    });

    req.on('error', reject);

    if (body) {
      if (typeof body === 'string' || Buffer.isBuffer(body)) {
        req.write(body);
      } else if (body instanceof URLSearchParams) {
        req.write(body.toString());
      } else {
        req.write(JSON.stringify(body));
      }
    }
    req.end();
  });
}

function generateHTML(token) {
  return `<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dashboard Demo</title>
    <style>
        body { font-family: system-ui; margin: 0; padding: 20px; background: #f5f5f5; }
        .container { max-width: 1200px; margin: 0 auto; height:calc(100vh - 40px) }
    </style>
</head>
<body>
    <div id="dashboard-content" class="container"></div>
    <script type="module">
        /**
         * We recommend bundling the dependency instead of using a CDN. However, for demonstration purposes,
         * we are just using a CDN.
         * 
         * We do not recommend one CDN over another and encourage decoupling the dependency from third-party code.
         */
        import { DatabricksDashboard } from "https://cdn.jsdelivr.net/npm/@databricks/aibi-client@0.0.0-alpha.7/+esm";
    
        const dashboard = new DatabricksDashboard({
            instanceUrl: "${CONFIG.instanceUrl}",
            workspaceId: "${CONFIG.workspaceId}",
            dashboardId: "${CONFIG.dashboardId}",
            token: "${token}",
            container: document.getElementById("dashboard-content")
        });
        
        dashboard.initialize();
    </script>
</body>
</html>`;
}

Steg 5: Kör exempelprogrammet

Ersätt följande värden och kör sedan kodblocket från terminalen. Dina värden ska inte vara omgivna av vinkelparenteser (< >):

  • Använd arbetsytans URL för att hitta och ersätta följande värden:
    • <your-instance>
    • <workspace_id>
    • <dashboard_id>
  • Ersätt följande värden med de värden som du skapade när du skapade tjänstens huvudnamn (steg 2):
    • <service_principal_id>
    • <service_principal_secret> (klienthemlighet)
  • Ersätt följande värden med identifierare som är associerade med användare av det externa programmet:
    • <some-external-viewer>
    • <some-external-value>
  • Ersätt </path/to/example> med sökvägen till .py filen eller .js som du skapade i föregående steg. Inkludera filnamnstillägget.

Anmärkning

Inkludera inte personligt identifierbar information (PII) i EXTERNAL_VIEWER_ID värdet.


INSTANCE_URL='https://<your-instance>.databricks.com' \
WORKSPACE_ID='<workspace_id>' \
DASHBOARD_ID='<dashboard_id>' \
SERVICE_PRINCIPAL_ID='<service-principal-id>' \
SERVICE_PRINCIPAL_SECRET='<service-principal_secret>' \
EXTERNAL_VIEWER_ID='<some-external-viewer>' \
EXTERNAL_VALUE='<some-external-value>' \
~</path/to/example>

# Terminal will output: :rocket: Server running on http://localhost:3000

Konfigurationsalternativ

När du initierar DatabricksDashboardkan du skicka ett config objekt för att anpassa utseendet och beteendet för den inbäddade instrumentpanelen. Objektet config kräver ett version fält inställt på 1.

Som standard visar inbäddade instrumentpaneler en Powered by Databricks-logotyp i sidfoten. Om du vill dölja logotypen anger du hideDatabricksLogo: true i config -objektet.

const dashboard = new DatabricksDashboard({
  instanceUrl: '<your-instance>.databricks.com',
  workspaceId: '<workspace_id>',
  dashboardId: '<dashboard_id>',
  token: '<scoped-token>',
  container: document.getElementById('dashboard-content'),
  config: {
    version: 1,
    hideDatabricksLogo: true,
  },
});
dashboard.initialize();

Styr panelen för globala filter

Som standard använder en inbäddad instrumentpanel sin egen konfiguration för att avgöra om panelen för globala filter börjar expanderad eller kollapsad. För att styra detta från din applikation, sätt globalFilterVisibility i objektet config till ett av följande värden:

  • shownByDefault: Panelen startar expanderad. Användare kan fortfarande fälla ihop den.
  • hiddenByDefault: Panelen startar i hopfällt läge. Tittarna kan fortfarande öppna den.
  • disabled: Panelen och dess växlingsknapp är helt dolda. Visningsanvändare kan inte öppna eller ändra de globala filtren.

Om du utelämnar globalFilterVisibility, gäller dashboardens standardbeteende.

Värdena shownByDefault och hiddenByDefault sätter endast initialtillståndet. Tittare kan visa eller dölja panelen efteråt, och deras sparade preferenser går före vid senare besök.

När den är inställd på disabled, är endast filterkontrollerna dolda. Filtervärden från inbäddnings-URL:en eller dashboardens författarkonfigurerade standardinställningar gäller fortfarande och fortsätter att filtrera datan.

const dashboard = new DatabricksDashboard({
  instanceUrl: '<your-instance>.databricks.com',
  workspaceId: '<workspace_id>',
  dashboardId: '<dashboard_id>',
  token: '<scoped-token>',
  container: document.getElementById('dashboard-content'),
  config: {
    version: 1,
    globalFilterVisibility: 'shownByDefault',
  },
});
dashboard.initialize();

Datanedladdningar i extern inbäddning

Som standard kan användare av inbäddade instrumentpaneler ladda ned data som CSV-, TSV- eller Excel-filer och ladda ned visualiseringar som PNG-filer. Om du vill inaktivera datanedladdningar på arbetsytan kan en administratör för arbetsytan inaktivera nedladdningsinställningen i arbetsytans administratörskonsol.

Kontrollera dashboardfilter programmatiskt

I extern inbäddning kan du läsa och ändra en dashboards filtervärden från din applikationskod. Objektet DatabricksDashboard tillhandahåller metoder för att läsa det aktuella filtertillståndet, sätta nya värden och prenumerera på filterändringar. Använd dessa metoder för att synkronisera inbäddade filter med dina egna kontroller, ställa filter från applikationsstatus eller uppdatera ditt gränssnitt när en tittare ändrar ett filter.

Filtermetoderna finns tillgängliga efter att den inbyggda instrumentpanelens kontroller är klara. Databricks buffrar anrop som görs före dess och tillämpar dem när kontrollerna blir tillgängliga.

Identifiera ett filter

Varje filter har ett id i formen <pageId>~<widgetId> som förblir oförändrat mellan redigeringar av instrumentpanelen. För att hitta ID:n för en instrumentpanel, anropa getFilters och matcha mot varje filters displayName. Använd id som den beständiga identifieraren i din kod, eftersom displayName styrs av författaren och kan ändras eller upprepas.

En dashboard-författare kan ändra ett filters ID i dashboardeditorn genom att välja widgeten eller sidan och använda åtgärden Uppdatera URL-identifierare .

Läs filtertillstånd

Ring getFilters för att läsa det aktuella tillståndet för varje filter i instrumentpanelen. Den returnerar en array av filtertillstånd, var och en med följande fält:

Field Description
id Filtrets URL-identifierare, <pageId>~<widgetId>.
widgetType Filterkontrolltypen: single-select, multi-select, , text, range, date-picker, eller date-range.
displayName Filterts titel, som återgår till dess fältnamn.
isDefault true när filtret visar sitt författarkonfigurerade standardvärde.
value Det aktuella filtervärdet, eller undefined när filtret är oinställt eller dess värde inte kan representeras.
unsupportedValue true när filtret håller ett värde som inte kan representeras. Sätt inte värden på dessa filter.
const filters = await dashboard.getFilters();
const filtersById = Object.fromEntries(filters.map((f) => [f.id, f]));
const regionFilter = filtersById['sales~region'];

Sätt filtervärden

Anropa setFilters med en array med filtervärden som ska tillämpas. Varje värde riktar sig mot ett filter med dess id och matchar filterets typ.

await dashboard.setFilters([{ id: 'sales~region', type: 'single-select', value: 'US' }]);

Värdefälten beror på filtertypen:

Type Värdefält
single-select value: en enda alternativsträng. Valfritt exclude: true matchar allt utom värdet.
multi-select values: en uppsättning alternativsträngar. Valfrittexclude: true.
text value: söktexten.
range min och max: siffror.
date-picker value: en ISO-datum- eller datumtidssträng.
date-range min och max: ISO-datum- eller datumtidssträngar.

För att återställa eller rensa ett filter, använd ett av följande inbyggda tillstånd istället för ett värde:

  • Standard: { default: true } återställer filtret till dess författarkonfigurerade standard. En tom sträng eller tom array gör samma sak.
  • Alla: { all: true } väljer varje värde. På en range eller date-range ändpunkt gör det änden obegränsad, vilket min: { all: true }, max: 10 betyder "mindre än eller lika med 10".
  • Inga: { none: true } filtrerar bort allt. Finns på single-select och multi-select filter.

För dashboards i Apply-läge, där urvalen är stegvis tills betraktaren klickar på Apply, setFilters commitar värden omedelbart som standard. För att istället lägga värden i staging-området, skicka { apply: false } och checka sedan in dem senare med applyStagedFilters eller kassera dem med cancelStagedFilters.

await dashboard.setFilters([{ id: 'sales~region', type: 'single-select', value: 'US' }], {
  apply: false,
});
await dashboard.applyStagedFilters();

Reagera på filterändringar

Anrop onFiltersChanged för att köra en callback när ett filters värde ändras, antingen genom tittarinteraktion, ett tillämpat setFilters anrop eller en URL-återställning. Callbacken får en ögonblicksbild av varje filters aktuella tillstånd. Den utlöses inte när du börjar prenumerera, så läs det initiala tillståndet med getFilters. onFiltersChanged returnerar en funktion som tar bort prenumerationen.

const unsubscribe = dashboard.onFiltersChanged((filters) => {
  console.log('filters changed', filters);
});
// Later, to stop listening:
unsubscribe();

För att köra kod efter att filterkontrollerna först blivit tillgängliga, anropa onFiltersReady. Den aktiveras en gång med den initiala filtersnapshoten och returnerar en funktion som tar bort prenumerationen.