Visualizações personalizadas em dashboards de IA/BI

Importante

Este recurso está no Public Preview.

Visualizações personalizadas permitem-lhe personalizar gráficos em dashboards de IA/BI para além dos tipos de visualização incorporados. Visualizações personalizadas usam a biblioteca Vega-Lite para renderizar gráficos a partir de uma especificação JSON.

Visualizações personalizadas podem renderizar tipos de gráficos especializados que vão além das opções incorporadas. A seguinte árvore filogenética utiliza uma disposição orientada pela força para agrupar registos relacionados em torno de centros partilhados de grupo e família:

Exemplo de gráfico de árvore filogenética

Para construir um gráfico passo a passo, veja Exemplos de visualizações. Para referenciar as especificações de outros tipos de cartas, veja Mais especificações de cartas.

Crie uma visualização personalizada

Para criar uma visualização personalizada:

  1. Selecione um conjunto de dados.
  2. No painel de configuração de visualização, selecione Visualização Personalizada na secção Visualização Avançada .
  3. Na secção de Campos , adiciona os campos que queres usar. Cada campo tem um nome único. Consulte os campos na sua especificação Vega-Lite utilizando estes nomes.
  4. Insira a sua especificação Vega-Lite JSON no editor de especificaçõesVega-Lite .

Colunas de conjunto de dados de referência

Colunas de referência numa Vega-Lite especificação de uma das seguintes formas:

  • Utilize "field": "{columnName}". O exemplo seguinte atribui a xField coluna ao eixo x:

    "encoding": {
      "x": { "field": "xField", "type": "quantitative" }
    }
    
  • Em expressões, use datum["{columnName}"] ou datum.{columnName}. O exemplo seguinte define uma nova x coluna a partir das r colunas e:angle

    { "calculate": "datum.r * cos(datum.angle)", "as": "x" }
    

Para mais informações, consulte datum na documentação de expressões do Vega.

Herdar o tema do dashboard

Visualizações personalizadas adaptam-se automaticamente ao tema do painel, incluindo o modo claro e escuro. Os seguintes elementos do gráfico herdam os valores do tema sem quaisquer alterações à sua especificação:

  • As fontes de eixo, legenda, título e cabeçalho correspondem às fontes configuradas do dashboard.
  • As linhas da grelha dos eixos correspondem à cor da grelha do painel para o modo ativo.
  • O fundo do gráfico é transparente sobre o fundo temático do widget.

As definições que defines no bloco da config tua especificação têm prioridade sobre os valores predefinidos herdados.

Valores de tema de referência em expressões

Para estilizar marcas com valores adaptados ao tema, consulte os seguintes sinais numa expressão Vega-Lite ({ "expr": "..." }):

Sinal Description
colors Tokens de cor pré-resolvidos para o modo ativo. Use-os para valores comuns como colors.textPrimary.default, colors.gridColor, e colors.markHighlightColor. Não indexe estes com [mode]; já estão resolvidos.
mode O modo de cor ativa, seja 'light' ou 'dark'. Use-o para indexar dashboardTheme campos que fornecem variantes por modo.
dashboardTheme O tema completo configurado pelo proprietário do painel, incluindo fontes (resolvedFontSettings), a paleta categórica (visualizationColors) e as cores por modo (gridLineColor). Campos com variantes para cada modo exigem o índice [mode].

Os sinais colors e dashboardTheme são independentes. O colors sinal fornece tokens de conveniência resolvidos para o modo ativo, enquanto dashboardTheme expõe o tema completo configurado pelo proprietário. Use colors primeiro e use dashboardTheme para tipos de letra, a paleta completa ou qualquer valor que colors não disponibilize.

Os exemplos seguintes demonstram como referenciar os valores do tema:

  • Use o tipo de letra do corpo do painel para uma marca textual:

    { "expr": "dashboardTheme.resolvedFontSettings.fieldValue.fontFamily" }
    
  • Utilize a cor do título do painel para o modo ativo:

    { "expr": "dashboardTheme.resolvedFontSettings.fieldTitle.fontColor[mode]" }
    
  • Use uma cor da paleta categórica do tablier:

    { "expr": "dashboardTheme.visualizationColors[0]" }
    

Note

Os colors tokens já estão resolvidos para o modo ativo. Ignora o [mode] índice e usa colors.markHighlightColor, não colors.markHighlightColor[mode]. Campos sob dashboardTheme isso têm variantes por modo, como dashboardTheme.gridLineColor[mode], requerem o [mode] índice.

Filtrar outros widgets com base na seleção

Uma visualização personalizada pode funcionar como uma fonte de filtro cruzado: quando um utilizador clica numa marca, a seleção filtra os outros widgets no dashboard. Para permitir isto, adicione um parâmetro de seleção de pontos com o nome databricks_mark_selectionreservado . O renderizador deteta este nome e liga a seleção ao estado de filtro cruzado do dashboard.

"params": [
  {
    "name": "databricks_mark_selection",
    "select": { "type": "point", "fields": ["categoryName"] }
  }
]

Aplicam-se os seguintes requisitos:

  • O parâmetro name deve ser exatamente databricks_mark_selection. Qualquer outro nome é tratado como um parâmetro normal e não aciona a filtragem cruzada.
  • select.type deve ser point. As seleções de intervalo (escova) não são suportadas como fontes para filtro cruzado.
  • select.fields deve listar os nomes dos campos definidos na secção Campos da configuração do widget, não os nomes das colunas brutas.
  • Liste apenas os campos de dimensão (agrupamento) em select.fields. Medidas agregadas, como SUM(...) ou AVG(...), não podem controlar um filtro cruzado.
  • Para selecionar em vários campos, liste-os juntos: "fields": ["categoryName", "regionName"].

Destaque marcas selecionadas

Para destacar marcas selecionadas, use as condições stroke e strokeWidth numa marca com base em preenchimento (como bar, arc ou rect) e mantenha a codificação color associada ao seu campo. Use { "expr": "colors.markHighlightColor" } para o traço, para que o destaque se mantenha legível tanto nos modos claro e escuro.

O exemplo seguinte filtra o resto do painel por categoryName ao clicar numa barra. As barras selecionadas têm um traço temático, e as barras não selecionadas escurecem, mantendo a codificação de cores.

Especificação JSON
{
  "$schema": "https://vega.github.io/schema/vega-lite/v6.json",
  "data": { "name": "databricks_query" },
  "width": "container",
  "height": "container",
  "config": { "autosize": { "type": "fit", "contains": "padding" } },
  "params": [
    {
      "name": "databricks_mark_selection",
      "select": { "type": "point", "fields": ["categoryName"] }
    }
  ],
  "mark": { "type": "bar", "stroke": null },
  "encoding": {
    "x": { "field": "categoryName", "type": "nominal" },
    "y": { "field": "salesValue", "type": "quantitative" },
    "color": { "field": "categoryName", "type": "nominal" },
    "fillOpacity": {
      "condition": { "param": "databricks_mark_selection", "value": 1 },
      "value": 0.3
    }
    "stroke": {
      "condition": {
        "param": "databricks_mark_selection",
        "empty": false,
        "value": { "expr": "colors.markHighlightColor" }
      },
      "value": null
    },
    "strokeWidth": {
      "condition": { "param": "databricks_mark_selection", "empty": false, "value": 2 },
      "value": 0
    }
  }
}

Redimensione automaticamente um gráfico

Para fazer um gráfico redimensionar para se ajustar ao seu contentor, adicione as seguintes definições ao nível superior da sua especificação:

"width": "container",
"height": "container",
"config": {
  "autosize": {
    "type": "fit",
    "contains": "padding"
  }
}

Exemplos de visualizações

Os exemplos seguintes explicam a construção de uma visualização personalizada passo a passo, desde um simples gráfico em camadas até uma árvore filogenética mais avançada.

Gráfico em camadas com média móvel

Este exemplo cria um gráfico em camadas que traça pontos de dados de temperatura em bruto com uma linha de média móvel sobreposta, utilizando dados meteorológicos dos conjuntos de dados de exemplo da Databricks.

Gráfico de temperatura em camadas com uma linha média móvel vermelha sobre pontos dispersos

  1. Crie um conjunto de dados com a seguinte consulta:

    SELECT date, temperature AS temp_max
    FROM samples.accuweather.historical_hourly_imperial
    WHERE city_name = 'singapore'
    ORDER BY date;
    
  2. No painel de configuração de visualização, em Avançado, selecione Visualização Personalizada.

  3. Selecione o conjunto de dados que criou na etapa anterior.

  4. Na secção Campos , adicione um campo para a coluna de data e defina o seu Nome para date.

  5. Adicione um campo para a coluna de temperatura e defina o seu Nome para temp_max.

  6. Copie a seguinte especificação no editor de especificação Vega-Lite. Se o eixo x estiver cortado, veja Redimensionar um gráfico automaticamente.

    Especificação JSON
    {
      "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
      "width": "container",
      "height": "container",
      "config": {
        "autosize": { "type": "fit", "contains": "padding" }
      },
      "data": { "name": "databricks_query" },
      "transform": [
        {
          "window": [{ "field": "temp_max", "op": "mean", "as": "rolling_mean" }],
          "frame": [-15, 15]
        }
      ],
      "encoding": {
        "x": { "field": "date", "type": "temporal", "title": "Date" },
        "y": {
          "type": "quantitative",
          "scale": { "zero": false },
          "axis": { "title": "Max temperature and rolling mean" }
        }
      },
      "layer": [
        {
          "mark": { "type": "point", "opacity": 0.3 },
          "encoding": { "y": { "field": "temp_max", "title": "Max temperature" } }
        },
        {
          "mark": { "type": "line", "color": "red", "size": 3 },
          "encoding": { "y": { "field": "rolling_mean", "title": "Rolling mean of max temperature" } }
        }
      ]
    }
    

Árvore filogenética

Este exemplo utiliza um pequeno conjunto de dados amostrais para construir a árvore filogenética mostrada no topo desta página. Vega-Lite apresenta pontos nas coordenadas que forneces, mas não calcula as posições dos nós para um diagrama de rede em si. Esse cálculo ocorre na consulta antes dos dados chegarem ao gráfico, onde a consulta pré-calcula as coordenadas x e y de cada ponto. A consulta emite três tipos de registo que a especificação renderiza como camadas separadas: path as linhas desenham os ramos curvos, node as linhas desenham os círculos das folhas e label as linhas posicionam as etiquetas dos grupos.

  1. Faça o download dos dados de exemplo. Cada linha representa uma descoberta fóssil, com dig_longitude e dig_latitude indicando as coordenadas do local de escavação.

    Descarregue os dados de exemplo

  2. Clique em Ícone Painéis de ControloPainéis de Controlo na barra lateral.

  3. Clique em Criar painel de controlo.

  4. Clique na aba Dados.

  5. Clica em Adicionar dados, depois clica em Carregar dados.

  6. Coloque o ficheiro descarregado na tabela Criar ou modificar a partir do painel de upload do ficheiro .

  7. Escolhe o Catálogo e o Esquema onde queres guardar a tabela e depois insere o nome da tabela.

  8. Clique Criar a tabela. A tabela completa é automaticamente adicionada como um conjunto de dados.

  9. Clique em Adicionar conjunto de dados SQL e cole a consulta. Na cláusula da FROM consulta, substitua os nomes do catálogo, esquema e tabelas pelos que usou quando criou a tabela.

  10. Crie a visualização personalizada, seguindo os passos em Criar uma visualização personalizada. Na secção Campos, adicione os seguintes campos, usando cada nome de campo como o seu Nome: record_type, x, y, fossil_tagpoint_order, , suborder, roar_score, clade_labelgenus_symbolfamily_taxone .label_text Use a especificação como Vega-Lite JSON.

Consulta SQL
WITH base AS (
  SELECT
    fossil_tag,
    genus_symbol,
    clade_label,
    suborder,
    family_taxon,
    dig_longitude,
    dig_latitude,
    roar_score
  FROM
    `my_catalog`.`default`.`dino_table`
),
root_pt AS (
  SELECT
    AVG(dig_longitude) AS rx,
    AVG(dig_latitude) AS ry
  FROM
    base
),
group_pts AS (
  SELECT
    suborder,
    AVG(dig_longitude) AS gx,
    AVG(dig_latitude) AS gy
  FROM
    base
  GROUP BY
    suborder
),
family_pts AS (
  SELECT
    suborder,
    family_taxon,
    AVG(dig_longitude) AS fx,
    AVG(dig_latitude) AS fy
  FROM
    base
  GROUP BY
    suborder,
    family_taxon
),
ctx AS (
  SELECT
    b.fossil_tag,
    b.suborder,
    b.family_taxon,
    b.clade_label,
    b.genus_symbol,
    b.dig_longitude,
    b.dig_latitude,
    b.roar_score,
    r.rx,
    r.ry,
    g.gx,
    g.gy,
    f.fx,
    f.fy
  FROM
    base b
      CROSS JOIN root_pt r
      JOIN group_pts g
        ON b.suborder = g.suborder
      JOIN family_pts f
        ON b.suborder = f.suborder
        AND b.family_taxon = f.family_taxon
),
waypoints AS (
  SELECT
    fossil_tag,
    suborder,
    family_taxon,
    clade_label,
    genus_symbol,
    roar_score,
    0 AS point_order,
    rx AS x,
    ry AS y
  FROM
    ctx
  UNION ALL
  SELECT
    fossil_tag,
    suborder,
    family_taxon,
    clade_label,
    genus_symbol,
    roar_score,
    1,
    rx + 0.30 * (gx - rx),
    ry + 0.30 * (gy - ry)
  FROM
    ctx
  UNION ALL
  SELECT
    fossil_tag,
    suborder,
    family_taxon,
    clade_label,
    genus_symbol,
    roar_score,
    2,
    gx + 0.15 * (fx - gx),
    gy + 0.15 * (fy - gy)
  FROM
    ctx
  UNION ALL
  SELECT
    fossil_tag,
    suborder,
    family_taxon,
    clade_label,
    genus_symbol,
    roar_score,
    3,
    gx + 0.50 * (fx - gx) + 0.03 * (dig_longitude - fx),
    gy + 0.50 * (fy - gy) + 0.03 * (dig_latitude - fy)
  FROM
    ctx
  UNION ALL
  SELECT
    fossil_tag,
    suborder,
    family_taxon,
    clade_label,
    genus_symbol,
    roar_score,
    4,
    fx + 0.15 * (dig_longitude - fx),
    fy + 0.15 * (dig_latitude - fy)
  FROM
    ctx
  UNION ALL
  SELECT
    fossil_tag,
    suborder,
    family_taxon,
    clade_label,
    genus_symbol,
    roar_score,
    5,
    fx + 0.65 * (dig_longitude - fx),
    fy + 0.65 * (dig_latitude - fy)
  FROM
    ctx
  UNION ALL
  SELECT
    fossil_tag,
    suborder,
    family_taxon,
    clade_label,
    genus_symbol,
    roar_score,
    6,
    dig_longitude,
    dig_latitude
  FROM
    ctx
)
SELECT
  fossil_tag,
  suborder,
  point_order,
  x,
  y,
  family_taxon,
  clade_label,
  genus_symbol,
  roar_score,
  'path' AS record_type,
  CAST(NULL AS STRING) AS label_text
FROM
  waypoints
UNION ALL
SELECT
  fossil_tag,
  suborder,
  99 AS point_order,
  dig_longitude AS x,
  dig_latitude AS y,
  family_taxon,
  clade_label,
  genus_symbol,
  roar_score,
  'node' AS record_type,
  CAST(NULL AS STRING) AS label_text
FROM
  base
UNION ALL
SELECT
  g.suborder AS fossil_tag,
  g.suborder AS suborder,
  100 AS point_order,
  g.gx
    + (g.gx - r.rx)
      * CASE LOWER(g.suborder)
        WHEN 'titanosauria' THEN 0.10
        WHEN 'hadrosauria' THEN 0.25
        WHEN 'ornithopoda' THEN 1.30
        WHEN 'stegosauria' THEN 0.73
        ELSE 0.55
      END AS x,
  g.gy
    + (g.gy - r.ry)
      * CASE LOWER(g.suborder)
        WHEN 'titanosauria' THEN 0.10
        WHEN 'hadrosauria' THEN 0.25
        WHEN 'ornithopoda' THEN 1.30
        WHEN 'stegosauria' THEN 0.73
        ELSE 0.55
      END AS y,
  CAST(NULL AS STRING) AS family_taxon,
  CAST(NULL AS STRING) AS clade_label,
  CAST(NULL AS STRING) AS genus_symbol,
  CAST(NULL AS DOUBLE) AS roar_score,
  'label' AS record_type,
  g.suborder AS label_text
FROM
  group_pts g CROSS JOIN root_pt r

Especificação JSON
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": { "name": "databricks_query" },
  "width": "container",
  "height": "container",
  "background": "white",
  "config": {
    "autosize": { "type": "fit", "contains": "padding" },
    "view": { "stroke": null }
  },
  "layer": [
    {
      "transform": [{ "filter": "datum.record_type === 'path'" }],
      "mark": {
        "type": "line",
        "interpolate": "basis",
        "strokeCap": "round",
        "strokeJoin": "round"
      },
      "encoding": {
        "x": {
          "field": "x",
          "type": "quantitative",
          "axis": null,
          "scale": { "zero": false, "nice": false }
        },
        "y": {
          "field": "y",
          "type": "quantitative",
          "axis": null,
          "scale": { "zero": false, "nice": false }
        },
        "detail": { "field": "fossil_tag", "type": "nominal" },
        "order": { "field": "point_order", "type": "quantitative" },
        "color": {
          "field": "suborder",
          "type": "nominal",
          "scale": { "scheme": "tableau10" },
          "legend": null
        },
        "opacity": { "value": 0.3 },
        "strokeWidth": { "value": 0.8 }
      }
    },
    {
      "transform": [{ "filter": "datum.record_type === 'node'" }],
      "mark": {
        "type": "circle",
        "opacity": 0.9,
        "stroke": "white",
        "strokeWidth": 0.3
      },
      "encoding": {
        "x": {
          "field": "x",
          "type": "quantitative",
          "axis": null,
          "scale": { "zero": false, "nice": false }
        },
        "y": {
          "field": "y",
          "type": "quantitative",
          "axis": null,
          "scale": { "zero": false, "nice": false }
        },
        "color": {
          "field": "suborder",
          "type": "nominal",
          "scale": { "scheme": "tableau10" },
          "legend": { "title": "Suborder", "orient": "right" }
        },
        "size": {
          "field": "roar_score",
          "type": "quantitative",
          "scale": { "domain": [0, 100], "range": [4, 150] },
          "legend": null
        },
        "tooltip": [
          { "field": "clade_label", "title": "Clade" },
          { "field": "genus_symbol", "title": "Symbol" },
          { "field": "suborder", "title": "Suborder" },
          { "field": "family_taxon", "title": "Family" },
          { "field": "roar_score", "title": "Roar Score", "format": ".1f" }
        ]
      }
    },
    {
      "transform": [{ "filter": "datum.record_type === 'label'" }],
      "mark": {
        "type": "text",
        "fontSize": 12,
        "fontWeight": "bold",
        "opacity": 0.85
      },
      "encoding": {
        "x": {
          "field": "x",
          "type": "quantitative",
          "axis": null,
          "scale": { "zero": false, "nice": false }
        },
        "y": {
          "field": "y",
          "type": "quantitative",
          "axis": null,
          "scale": { "zero": false, "nice": false }
        },
        "text": { "field": "label_text", "type": "nominal" },
        "color": {
          "field": "suborder",
          "type": "nominal",
          "scale": { "scheme": "tableau10" },
          "legend": null
        }
      }
    }
  ]
}

Mais especificações de cartas

As seguintes especificações mostram gráficos que não estão disponíveis como tipos de visualização incorporados. Para mais exemplos, consulte as galerias de exemplosVega-Lite.

Quadro de pontos

Exemplo de tabela de marcadores.

Defina categoryField, currentField, paceField, e targetField na secção Campos .

Especificação JSON
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "width": "container",
  "height": "container",
  "data": { "name": "databricks_query" },
  "config": {
    "autosize": { "type": "fit", "contains": "padding" }
  },
  "transform": [
    {
      "fold": ["targetField", "paceField", "currentField"],
      "as": ["measure_name", "measure_value"]
    },
    {
      "calculate": "toNumber(datum.measure_value)",
      "as": "measure_value"
    },
    {
      "calculate": "{ \"targetField\": \"Target\", \"paceField\": \"Pace\", \"currentField\": \"Current\" }[datum.measure_name]",
      "as": "measure_label"
    },
    {
      "calculate": "indexof([\"Target\", \"Pace\", \"Current\"], datum.measure_label)",
      "as": "measure_order"
    }
  ],
  "layer": [
    {
      "mark": "bar",
      "params": [
        {
          "name": "legend_click",
          "select": { "type": "point", "fields": ["measure_label"] },
          "bind": "legend"
        }
      ],
      "encoding": {
        "color": { "field": "measure_label" },
        "opacity": { "value": 0 }
      }
    },
    {
      "transform": [{ "filter": { "param": "legend_click" } }],
      "layer": [
        {
          "layer": [
            {
              "mark": { "type": "bar", "tooltip": true },
              "encoding": { "color": { "field": "measure_label", "legend": null } },
              "transform": [{ "filter": { "field": "measure_label", "oneOf": ["Pace"] } }]
            },
            {
              "mark": { "type": "bar", "height": 7, "tooltip": true },
              "encoding": { "color": { "field": "measure_label", "legend": null } },
              "transform": [{ "filter": { "field": "measure_label", "oneOf": ["Current"] } }]
            },
            {
              "mark": { "type": "tick", "tooltip": true, "thickness": 3 },
              "encoding": { "color": { "field": "measure_label", "legend": null } },
              "transform": [{ "filter": { "field": "measure_label", "oneOf": ["Target"] } }]
            }
          ],
          "encoding": {
            "x": {
              "field": "measure_value",
              "type": "quantitative",
              "stack": null,
              "title": "Value",
              "axis": { "orient": "bottom" }
            },
            "color": {
              "scale": {
                "domain": ["Target", "Pace", "Current"],
                "range": ["#000000", "#bcbcbc", "#A66BBF"]
              }
            },
            "order": {
              "field": "measure_order",
              "type": "quantitative",
              "sort": "descending"
            }
          }
        }
      ],
      "encoding": {
        "y": {
          "field": "categoryField",
          "type": "ordinal",
          "title": "Category",
          "axis": { "labelOverlap": true }
        },
        "tooltip": [
          { "field": "categoryField", "type": "nominal", "title": "Category" },
          { "field": "currentField", "type": "quantitative", "title": "Current" },
          { "field": "paceField", "type": "quantitative", "title": "Pace" },
          { "field": "targetField", "type": "quantitative", "title": "Target" }
        ]
      }
    }
  ]
}

Medidor

Exemplo de gráfico de indicador.

Defina $valueField e $totalField na secção de Campos .

Especificação JSON
{
  "$schema": "https://vega.github.io/schema/vega-lite/v6.json",
  "width": "container",
  "height": "container",
  "data": { "name": "databricks_query" },
  "config": {
    "concat": { "spacing": 0 },
    "autosize": { "type": "fit", "contains": "padding" }
  },
  "params": [
    { "name": "ring_max", "expr": "min(width, height) / 2 - 16" },
    { "name": "ring_width", "expr": "max(12, (min(width, height) / 2) * 0.12)" },
    { "name": "ring_gap", "expr": "max(4, (min(width, height) / 2) * 0.03)" },
    { "name": "label_color", "value": "#000000" },
    { "name": "ring_background_opacity", "value": 0.3 },
    { "name": "ring0_percent", "value": 100 },
    { "name": "ring0_outer", "expr": "ring_max + 2" },
    { "name": "ring0_inner", "expr": "ring_max + 1" },
    { "name": "ring1_outer", "expr": "ring0_inner - ring_gap" },
    { "name": "ring1_inner", "expr": "ring1_outer - ring_width" },
    { "name": "ring1_middle", "expr": "(ring1_outer + ring1_inner) / 2" },
    { "name": "arc_size", "expr": "220" }
  ],
  "transform": [
    { "as": "ratio", "calculate": "datum['$valueField'] / datum['$totalField']" },
    { "as": "_arc_start_degrees", "calculate": "360 - ( arc_size / 2 )" },
    { "as": "_arc_end_degrees", "calculate": "0 + ( arc_size / 2 )" },
    { "as": "_arc_start_radians", "calculate": "2 * 3.14 * ( datum['_arc_start_degrees'] - 360 ) / 360" },
    { "as": "_arc_end_radians", "calculate": "2 * 3.14 * datum['_arc_end_degrees'] / 360" },
    { "as": "_arc_total_radians", "calculate": "datum['_arc_end_radians'] - datum['_arc_start_radians']" },
    { "as": "_ring_start_radians", "calculate": "datum['_arc_start_radians']" },
    {
      "as": "_ring_end_radians",
      "calculate": "datum['_arc_start_radians'] + ( datum['_arc_total_radians'] * datum['ratio'] )"
    }
  ],
  "layer": [
    {
      "mark": {
        "type": "arc",
        "color": "lightgrey",
        "theta": { "expr": "datum['_arc_start_radians']" },
        "radius": { "expr": "ring1_outer" },
        "theta2": { "expr": "datum['_arc_end_radians']" },
        "radius2": { "expr": "ring1_inner" },
        "cornerRadius": 10
      }
    },
    {
      "name": "RING",
      "mark": {
        "type": "arc",
        "theta": { "expr": "datum['_ring_start_radians']" },
        "radius": { "expr": "ring1_outer" },
        "theta2": { "expr": "datum['_ring_end_radians']" },
        "radius2": { "expr": "ring1_inner" },
        "cornerRadius": 10
      },
      "encoding": {
        "color": {
          "value": "#307E31",
          "condition": [
            { "test": "datum['ratio'] < 0.33", "value": "#880808" },
            { "test": "datum['ratio'] < 0.66", "value": "#E49B0F" }
          ]
        }
      }
    },
    {
      "mark": { "type": "text", "fontSize": 40 },
      "encoding": {
        "text": { "field": "$valueField" },
        "color": {
          "value": "#307E31",
          "condition": [
            { "test": "datum['ratio'] < 0.33", "value": "#880808" },
            { "test": "datum['ratio'] < 0.66", "value": "#E49B0F" }
          ]
        }
      }
    }
  ]
}

Mapa de radar

Exemplo de mapa de radar.

Defina $key e $value na secção de Campos .

Especificação JSON
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "width": "container",
  "height": "container",
  "config": {
    "autosize": { "type": "fit", "contains": "padding" }
  },
  "data": { "name": "databricks_query" },
  "transform": [
    { "window": [{ "op": "row_number", "as": "category" }] },
    { "calculate": "datum.category - 1", "as": "category" },
    {
      "joinaggregate": [
        { "op": "count", "as": "numCategories" },
        { "op": "max", "field": "$value", "as": "maxValue" }
      ]
    },
    { "calculate": "2 * PI * datum.category / datum.numCategories", "as": "angle" },
    { "calculate": "100 * datum['$value'] / datum.maxValue", "as": "r" },
    { "calculate": "datum.r * cos(datum.angle)", "as": "x" },
    { "calculate": "datum.r * sin(datum.angle)", "as": "y" },
    { "calculate": "110 * cos(datum.angle)", "as": "label_x" },
    { "calculate": "110 * sin(datum.angle)", "as": "label_y" }
  ],
  "layer": [
    {
      "transform": [
        { "joinaggregate": [{ "op": "count", "as": "numCategories" }] },
        { "aggregate": [{ "op": "max", "field": "numCategories", "as": "numCategories" }] },
        { "calculate": "[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]", "as": "cats" },
        { "flatten": ["cats"], "as": ["cat"] },
        { "filter": "datum.cat <= datum.numCategories" },
        { "calculate": "2 * PI * datum.cat / datum.numCategories", "as": "angle" },
        { "calculate": "100 * cos(datum.angle)", "as": "x" },
        { "calculate": "100 * sin(datum.angle)", "as": "y" }
      ],
      "mark": { "type": "line", "color": "#ddd", "strokeWidth": 1 },
      "encoding": {
        "x": { "field": "x", "type": "quantitative", "scale": { "domain": [-120, 120] }, "axis": null },
        "y": { "field": "y", "type": "quantitative", "scale": { "domain": [-120, 120] }, "axis": null },
        "order": { "field": "cat" }
      }
    },
    {
      "transform": [
        { "joinaggregate": [{ "op": "count", "as": "numCategories" }] },
        { "aggregate": [{ "op": "max", "field": "numCategories", "as": "numCategories" }] },
        { "calculate": "[20,40,60,80,100]", "as": "levels" },
        { "flatten": ["levels"], "as": ["level"] },
        { "calculate": "[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]", "as": "cats" },
        { "flatten": ["cats"], "as": ["cat"] },
        { "filter": "datum.cat <= datum.numCategories" },
        { "calculate": "2 * PI * datum.cat / datum.numCategories", "as": "angle" },
        { "calculate": "datum.level", "as": "r" },
        { "calculate": "datum.r * cos(datum.angle)", "as": "x" },
        { "calculate": "datum.r * sin(datum.angle)", "as": "y" }
      ],
      "mark": { "type": "line", "color": "#ddd", "strokeWidth": 1 },
      "encoding": {
        "x": { "field": "x", "type": "quantitative" },
        "y": { "field": "y", "type": "quantitative" },
        "detail": { "field": "level" },
        "order": { "field": "cat" }
      }
    },
    {
      "mark": { "type": "line", "color": "#9467bd", "strokeWidth": 2, "interpolate": "linear-closed" },
      "encoding": {
        "x": { "field": "x", "type": "quantitative" },
        "y": { "field": "y", "type": "quantitative" },
        "order": { "field": "category" }
      }
    },
    {
      "mark": { "type": "point", "filled": true, "size": 50, "color": "#9467bd" },
      "encoding": {
        "x": { "field": "x", "type": "quantitative" },
        "y": { "field": "y", "type": "quantitative" }
      }
    },
    {
      "mark": { "type": "text", "fontSize": 14, "fontWeight": "bold" },
      "encoding": {
        "x": { "field": "label_x", "type": "quantitative" },
        "y": { "field": "label_y", "type": "quantitative" },
        "text": { "field": "$key", "type": "nominal" }
      }
    }
  ],
  "view": { "stroke": null }
}

Mapa radial

Exemplo de gráfico radial.

Defina $valueField e $colorField na secção de Campos .

Especificação JSON
{
  "$schema": "https://vega.github.io/schema/vega-lite/v6.json",
  "width": "container",
  "height": "container",
  "config": {
    "autosize": { "type": "fit", "contains": "padding" }
  },
  "data": { "name": "databricks_query" },
  "transform": [
    {
      "aggregate": [{ "op": "sum", "field": "$valueField", "as": "total" }],
      "groupby": ["$colorField"]
    },
    {
      "window": [{ "op": "rank", "as": "rank" }],
      "sort": [{ "field": "total", "order": "descending" }]
    }
  ],
  "layer": [
    {
      "mark": { "type": "arc", "innerRadius": 20, "stroke": "#fff" }
    }
  ],
  "encoding": {
    "theta": {
      "field": "total",
      "type": "quantitative",
      "scale": { "type": "sqrt" },
      "stack": true,
      "sort": "descending"
    },
    "radius": { "field": "total", "scale": { "type": "sqrt", "zero": true } },
    "color": {
      "field": "$colorField",
      "type": "nominal",
      "title": "Sub-Category",
      "sort": { "field": "total", "order": "descending" },
      "legend": { "orient": "right" }
    },
    "tooltip": [
      { "field": "$colorField", "type": "nominal", "title": "Sub-Category" },
      { "field": "total", "type": "quantitative", "title": "Sales" }
    ]
  },
  "view": { "stroke": null }
}

Gráfico Sunburst

Exemplo de gráfico Sunburst.

Defina outerGroupField, innerGroupField, e sizeField na secção Campos .

Especificação JSON
{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "width": "container",
  "height": "container",
  "data": { "name": "databricks_query" },
  "config": {
    "autosize": { "type": "fit", "contains": "padding" }
  },
  "transform": [
    { "calculate": "datum['outerGroupField']", "as": "OUTSIDE" },
    { "calculate": "datum['innerGroupField']", "as": "INSIDE" },
    { "calculate": "datum.OUTSIDE + '-' + datum.INSIDE", "as": "OUT_IN" },
    { "calculate": "toNumber(datum['sizeField'])", "as": "SIZE" }
  ],
  "resolve": {
    "scale": { "color": "independent" },
    "legend": { "color": "independent" }
  },
  "layer": [
    {
      "mark": {
        "type": "arc",
        "tooltip": true,
        "innerRadius": { "expr": "min(width, height)/9" },
        "outerRadius": { "expr": "min(width, height)/3" }
      },
      "encoding": {
        "theta": { "field": "SIZE", "type": "quantitative", "stack": true },
        "color": {
          "field": "OUT_IN",
          "type": "ordinal",
          "sort": "ascending",
          "title": "Inner Grouping",
          "scale": {
            "range": [
              "#1DF9B9",
              "#1DE5B9",
              "#1DD1B9",
              "#1DBDB9",
              "#1DA9B9",
              "#3DF23B",
              "#3DDA3B",
              "#3DC23B",
              "#3DAA3B",
              "#3D923B"
            ]
          }
        },
        "order": { "field": "OUT_IN", "sort": "ascending" },
        "tooltip": [
          { "field": "OUTSIDE", "type": "nominal", "title": "Outer Grouping" },
          { "field": "INSIDE", "type": "nominal", "title": "Inner Grouping" },
          { "field": "SIZE", "type": "quantitative", "title": "Count" }
        ]
      }
    },
    {
      "transform": [
        {
          "aggregate": [{ "op": "sum", "field": "SIZE", "as": "total_users" }],
          "groupby": ["OUTSIDE"]
        }
      ],
      "mark": {
        "type": "arc",
        "tooltip": true,
        "innerRadius": { "expr": "min(width, height)/3" }
      },
      "encoding": {
        "theta": {
          "field": "total_users",
          "type": "quantitative",
          "stack": true,
          "sort": "ascending",
          "title": "Users Count"
        },
        "color": {
          "field": "OUTSIDE",
          "type": "ordinal",
          "sort": "ascending",
          "title": "Outer Grouping",
          "scale": { "range": ["#1DD1B9", "#3DC23B"] }
        },
        "order": { "field": "OUTSIDE", "sort": "ascending" },
        "tooltip": [
          { "field": "OUTSIDE", "type": "nominal", "title": "Outer Grouping" },
          { "field": "total_users", "type": "quantitative", "title": "Count" }
        ]
      }
    }
  ]
}

Limitações

  • Os gráficos de treemap não são suportados. Vega-Lite não suporta treemaps.
  • As marcas de imagem suportam apenas URLs de imagem base64 data: em linha (por exemplo, data:image/png;base64,...) de 37 KB ou menos, em formatos PNG, JPEG ou WebP. URLs de imagens remotas (https: ou http:), URLs relativas, imagens SVG e URLs de imagens orientadas por campos ou expressões não são suportados.