Niestandardowe wizualizacje w panelach AI/BI

Important

Ta funkcja jest dostępna w publicznej wersji testowej.

Wizualizacje niestandardowe umożliwiają dostosowywanie wykresów na pulpitach nawigacyjnych sztucznej inteligencji/analizy biznesowej poza wbudowanymi typami wizualizacji. Wizualizacje niestandardowe używają biblioteki Vega-Lite do renderowania wykresów ze specyfikacji JSON.

Własne wizualizacje mogą renderować specjalistyczne typy wykresów, które wykraczają poza wbudowane opcje. Poniższe drzewo filogenetyczne wykorzystuje układ kierowany siłą do grupowania powiązanych rekordów wokół wspólnych grup i centrów rodzinnych:

Przykład wykresu drzewa filogenetycznego

Aby zbudować wykres krok po kroku, zobacz Przykładowe wizualizacje. Aby odnieść się do specyfikacji innych typów wykresów, zobacz Więcej specyfikacji wykresów.

Tworzenie wizualizacji niestandardowej

Aby stworzyć własną wizualizację:

  1. Wybierz zestaw danych.
  2. W okienku konfiguracji wizualizacji wybierz pozycję Custom Viz w sekcji Wizualizacja zaawansowana .
  3. W sekcji Pola dodaj pola, których chcesz użyć. Każde pole ma unikatową nazwę. Odwołuj się do pól w swojej specyfikacji Vega-Lite, używając tych nazw.
  4. Wprowadź swoją specyfikację JSON Vega-Lite w edytorze specyfikacji Vega-Lite.

Kolumny referencyjnego zestawu danych

Referencje kolumn w specyfikacji Vega-Lite w jeden z następujących sposobów:

  • Użyj "field": "{columnName}". Poniższy przykład przypisuje kolumnę xField do osi x:

    "encoding": {
      "x": { "field": "xField", "type": "quantitative" }
    }
    
  • W wyrażeniach użyj polecenia datum["{columnName}"] lub datum.{columnName}. W poniższym przykładzie zdefiniowano nową kolumnę x z kolumn r i angle:

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

Więcej informacji znajdziesz w dokumentacji wyrażeń Vega: datum

Dziedzicz motyw panelu

Wizualizacje niestandardowe automatycznie dostosowują się do motywu pulpitu nawigacyjnego, w tym do trybu jasnego i ciemnego. Następujące elementy wykresu dziedziczą wartości motywu bez żadnych zmian w specyfikacji:

  • Czcionki osi, legendy, tytułu i nagłówka są zgodne ze skonfigurowanymi czcionkami pulpitu nawigacyjnego.
  • Linie siatki osi odpowiadają kolorowi linii deski rozdzielczej dla trybu aktywnego.
  • Tło wykresu jest przezroczyste na tle motywu widżetu.

Ustawienia zdefiniowane w bloku specyfikacji config mają pierwszeństwo przed odziedziczonymi wartościami domyślnymi.

Odwoływanie się do wartości motywu w wyrażeniach

Aby nadać znacznikom styl za pomocą wartości zależnych od motywu, odwołaj się do następujących sygnałów w wyrażeniu Vega-Lite ({ "expr": "..." }):

Sygnał Opis
colors Wstępnie rozpoznane tokeny kolorów dla trybu aktywnego. Użyj ich dla typowych wartości, takich jak colors.textPrimary.default, colors.gridColori colors.markHighlightColor. Nie indeksuj ich przy użyciu [mode]; są już rozwiązane.
mode Aktywny tryb kolorów, czyli 'light' lub 'dark'. Służy do indeksowania pól dashboardTheme, które udostępniają warianty dla poszczególnych trybów.
dashboardTheme Pełny motyw skonfigurowany przez właściciela pulpitu nawigacyjnego, w tym czcionki (resolvedFontSettings), paletę kategorii (visualizationColors) i kolory dla trybu (gridLineColor). Pola z wariantami trybów wymagają indeksu [mode] .

Sygnały colors i dashboardTheme są niezależne. Sygnał colors zapewnia tokeny wygody rozwiązywane dla trybu aktywnego, jednocześnie dashboardTheme odsłaniając pełny motyw skonfigurowany przez właściciela. Najpierw użyj colors, a dashboardTheme używaj do czcionek, pełnej palety lub dowolnej wartości, której colors nie zapewnia.

Poniższe przykłady pokazują, jak odnosić się do wartości tematycznych:

  • Użyj czcionki treści pulpitu nawigacyjnego dla znacznika tekstu:

    { "expr": "dashboardTheme.resolvedFontSettings.fieldValue.fontFamily" }
    
  • Użyj koloru tytułu pulpitu nawigacyjnego dla trybu aktywnego:

    { "expr": "dashboardTheme.resolvedFontSettings.fieldTitle.fontColor[mode]" }
    
  • Użyj koloru z palety kategorii pulpitu nawigacyjnego:

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

Note

Tokeny colors są już rozstrzygnięte dla trybu aktywnego. Pomiń [mode] indeks i użyj colors.markHighlightColor, nie colors.markHighlightColor[mode]. Pola poniżej dashboardTheme , które mają warianty dla poszczególnych trybów, takie jak dashboardTheme.gridLineColor[mode], wymagają indeksu [mode] .

Filtruj inne widżety po wybraniu

Wizualizacja niestandardowa może działać jako źródło filtru krzyżowego: gdy użytkownik kliknie znacznik, wybór filtruje inne widżety na pulpicie nawigacyjnym. Aby to włączyć, dodaj parametr wyboru punktu z nazwą databricks_mark_selectionzarezerwowaną . Moduł renderujący wykrywa tę nazwę i łączy zaznaczenie ze stanem filtrów krzyżowych panelu.

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

Obowiązują następujące wymagania:

  • Parametr name musi mieć dokładnie databricks_mark_selectionwartość . Każda inna nazwa jest traktowana jako zwykły parametr i nie powoduje filtrowania krzyżowego.
  • select.type musi mieć wartość point. Opcje interwału (pędzla) nie są obsługiwane jako źródła filtrów krzyżowych.
  • select.fields musi zawierać listę nazw pól zdefiniowanych w sekcji Pola konfiguracji widżetu, a nie nieprzetworzonych nazw kolumn.
  • Wyświetl tylko pola wymiaru (grupowania) w select.fields. Zagregowane miary, takie jak SUM(...) lub AVG(...), nie mogą prowadzić filtrowania krzyżowego.
  • Aby wybrać wiele pól, wyświetl je razem: "fields": ["categoryName", "regionName"].

Wyróżnij zaznaczone znaczniki

Aby wyróżnić wybrane znaczniki, użyj warunków stroke i strokeWidth dla znacznika opartego na wypełnieniu (takiego jak bar, arc lub rect) i pozostaw kanał kodowania color powiązany z Twoim polem. Użyj { "expr": "colors.markHighlightColor" } do obrysu, aby wyróżnienie pozostało czytelne zarówno w trybie jasnym, jak i ciemnym.

Poniższy przykład filtruje resztę panelu według categoryName po kliknięciu słupka. Wybrane słupki otrzymują obramowanie w kolorze motywu, a niezaznaczone słupki są przyciemniane z zachowaniem kodowania kolorami.

Specyfikacja 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
    }
  }
}

Automatycznie zmieniaj rozmiar wykresu

Aby zmienić rozmiar wykresu, aby dopasować go do kontenera, dodaj następujące ustawienia na najwyższym poziomie specyfikacji:

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

Przykładowe wizualizacje

Poniższe przykłady przeprowadzają krok po kroku tworzenie własnej wizualizacji, od prostego warstwowego wykresu po bardziej zaawansowane drzewo filogenetyczne.

Wykres warstwowy z średnią kroczącą

Ten przykład tworzy wykres warstwowy, który przedstawia surowe punkty danych temperatury z nałożoną linią średniej kroczącej, na podstawie danych pogodowych z przykładowych zbiorów danych Databricks.

Warstwowy wykres temperatur z czerwoną linią średniej rolowanej nad punktami rozproszonymi

  1. Utwórz zestaw danych przy użyciu następującego zapytania:

    SELECT date, temperature AS temp_max
    FROM samples.accuweather.historical_hourly_imperial
    WHERE city_name = 'singapore'
    ORDER BY date;
    
  2. W okienku konfiguracji wizualizacji w obszarze Zaawansowane wybierz pozycję Custom Viz.

  3. Wybierz zestaw danych utworzony w poprzednim kroku.

  4. W sekcji Pola dodaj pole dla kolumny daty i ustaw jego nazwę na date.

  5. Dodaj pole dla kolumny temperatury i ustaw jego nazwę na temp_max.

  6. Skopiuj poniższą specyfikację do edytora specyfikacji Vega-Lite. Jeśli oś x jest przycięta, zobacz Automatycznie zmieniaj rozmiar wykresu.

    Specyfikacja 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" } }
        }
      ]
    }
    

Drzewo filogenetyczne

Ten przykład wykorzystuje niewielki zestaw danych z próby do zbudowania drzewa filogenetycznego pokazanego na górze tej strony. Vega-Lite pokazuje punkty na współrzędnych, które podajesz, ale nie oblicza pozycji węzłów dla samego diagramu sieciowego. To obliczenie odbywa się w zapytaniu zanim dane dotrą do wykresu, gdzie zapytanie wstępnie oblicza współrzędne x i y każdego punktu. Zapytanie generuje trzy typy rekordów, które specyfikacja renderuje jako oddzielne warstwy: path wiersze rysują zakrzywione gałęzie, node wiersze rysują okręgi liści, a label wiersze pozycjonują etykiety grup.

  1. Pobierz przykładowe dane. Każdy wiersz reprezentuje znalezisko skamieniałości, z dig_longitude i dig_latitude podając współrzędne miejsca wykopalisk.

    Pobierz dane próbne

  2. Kliknij pozycję Ikona pulpitów nawigacyjnychPulpity nawigacyjne na pasku bocznym.

  3. Kliknij pozycję Utwórz pulpit nawigacyjny.

  4. Kliknij kartę Dane.

  5. Kliknij Dodaj dane, a następnie Wrzuć dane.

  6. Wrzuć pobrany plik do tabeli Create lub Modify z panelu przesyłania plików .

  7. Wybierz katalog i schemat, w którym chcesz przechowywać tabelę, a następnie wpisz nazwę tabeli.

  8. Kliknij pozycję Utwórz tabelę. Pełna tabela jest automatycznie dodawana jako zbiór danych.

  9. Kliknij Dodaj zbiór danych SQL i wklej zapytanie. W klauzuli FROM zapytania zastąp katalog, schemat i nazwy tabel na te, których używałeś podczas tworzenia tabeli.

  10. Stwórz własną wizualizację, postępując zgodnie z krokami w Utwórz własną wizualizację. W sekcji Pola dodaj następujące pola, używając nazwy każdego pola jako nazwy: record_type, , xy, fossil_tag, point_order, suborder, roar_scoreclade_labelgenus_symbolfamily_taxonoraz .label_text Użyj specyfikacji jako Vega-Lite JSON.

Zapytanie 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

Specyfikacja 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
        }
      }
    }
  ]
}

Więcej specyfikacji map

Poniższe specyfikacje przedstawiają wykresy, które nie są dostępne jako wbudowane typy wizualizacji. Aby uzyskać więcej przykładów, zobacz galerie przykładówVega-Lite.

Wykres punktowy

Przykład wykresu punktowego.

Zdefiniuj categoryField, currentField, paceField i targetField w sekcji Pola.

Specyfikacja 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" }
        ]
      }
    }
  ]
}

Wskaźnik

Przykład wykresu wskaźnikowego.

Zdefiniuj $valueField i $totalField w sekcji Pola.

Specyfikacja 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" }
          ]
        }
      }
    }
  ]
}

Wykres radarowy

Przykład wykresu radarowego.

Zdefiniuj $key i $value w sekcji Pola.

Specyfikacja 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 }
}

Wykres promieniowy

Przykład wykresu promieniowego.

Zdefiniuj $valueField i $colorField w sekcji Pola.

Specyfikacja 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 }
}

Wykres sunburst

Przykład wykresu Sunburst.

Zdefiniuj outerGroupField, innerGroupField i sizeField w sekcji Pola.

Specyfikacja 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" }
        ]
      }
    }
  ]
}

Limitations

  • Wykresy typu mapa drzewiasta nie są obsługiwane. Vega-Lite nie obsługuje map drzewiastych.
  • Znaczniki obrazów obsługują tylko adresy URL obrazów zakodowanych w formacie base64 i osadzonych bezpośrednio data: (na przykład data:image/png;base64,...), o rozmiarze nie większym niż 37 KB, w formacie PNG, JPEG lub WebP. Adresy URL obrazów zdalnych (https: lub http:), względne adresy URL, obrazy SVG i adresy URL obrazów opartych na polach lub wyrażeniach nie są obsługiwane.