<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>article Custom Visualizations in AI/BI Dashboards: Build a Pareto Chart with Vega-Lite in Technical Blog</title>
    <link>https://community.databricks.com/t5/technical-blog/custom-visualizations-in-ai-bi-dashboards-build-a-pareto-chart/ba-p/163659</link>
    <description>&lt;P class="p1"&gt;&lt;SPAN class="s1"&gt;Databricks AI/BI dashboards ship with a solid set of &lt;A href="https://docs.databricks.com/aws/en/dashboards/manage/visualizations/types" target="_blank" rel="noopener"&gt;&lt;SPAN class="s2"&gt;visualization types&lt;/SPAN&gt;&lt;/A&gt;. But every so often you want something the point-and-click widgets can't quite do.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="p1"&gt;&lt;SPAN class="s1"&gt;That's what &lt;A href="https://docs.databricks.com/aws/en/dashboards/manage/visualizations/custom-visualizations" target="_blank" rel="noopener"&gt;&lt;SPAN class="s2"&gt;custom visualizations&lt;/SPAN&gt;&lt;/A&gt; (currently Public Preview) are for. You describe the chart in a &lt;A href="https://vega.github.io/vega-lite/examples/" target="_blank" rel="noopener"&gt;&lt;SPAN class="s2"&gt;Vega-Lite&lt;/SPAN&gt;&lt;/A&gt; spec (a block of JSON), and that spec controls every part of the chart in one place. Since your custom viz reads your Unity Catalog (UC) data through the dashboards dataset, you get all the governance of UC you’ve come to expect on Databricks.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="p1"&gt;&lt;SPAN class="s1"&gt;To show it off, we'll build a custom &lt;A href="https://en.wikipedia.org/wiki/Pareto_chart" target="_blank" rel="noopener"&gt;&lt;SPAN class="s2"&gt;Pareto chart&lt;/SPAN&gt;&lt;/A&gt; of manufacturing defects. It has the usual bars and cumulative line, but the focus is on what a built-in combo widget in AI/BI Dashboards can’t do in the UI today:&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="ul1"&gt;
&lt;LI class="li1"&gt;&lt;SPAN class="s1"&gt;Sort the bars by value and add markers.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li1"&gt;&lt;SPAN class="s1"&gt;Shade a band over the key drivers and minor issues.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li1"&gt;&lt;SPAN class="s1"&gt;Add multiple text annotations, placed in specific spots, that label themselves from the data.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p1"&gt;&lt;SPAN class="s1"&gt;The final custom visualization we will create below.&amp;nbsp;Feel free to follow along in &lt;A href="https://www.databricks.com/learn/free-edition" target="_blank"&gt;Databricks Free Edition&lt;/A&gt;!&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="p1"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="final-pareto-chart.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/29326iA1A40ACCEE5FDDB7/image-size/large?v=v2&amp;amp;px=999" role="button" title="final-pareto-chart.png" alt="final-pareto-chart.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P class="p2"&gt;&lt;FONT size="5"&gt;&lt;SPAN class="s1"&gt;Vega-Lite Overview&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class="p3"&gt;&lt;SPAN class="s1"&gt;Vega-Lite is a JSON grammar for charts. Instead of writing drawing code, you describe the chart it renders. To summarize what’s needed for this post, we draw attention to the following key ideas:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="ul1"&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;mark&lt;/STRONG&gt; is the shape to draw: "bar", "line", "point", "area", "rule", "text".&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;encoding&lt;/STRONG&gt; maps a column to a visual channel: x, y, color, and so on.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;layer&lt;/STRONG&gt; stacks multiple marks on the same axes (this is how bars and a line share one chart).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;The &lt;STRONG&gt;width&lt;/STRONG&gt;, &lt;STRONG&gt;height&lt;/STRONG&gt;, and &lt;STRONG&gt;config&lt;/STRONG&gt; settings make a chart resize to &lt;A href="https://docs.databricks.com/aws/en/dashboards/manage/visualizations/custom-visualizations#-resize-a-chart-automatically" target="_blank" rel="noopener"&gt;&lt;SPAN class="s2"&gt;fit its container&lt;/SPAN&gt;&lt;/A&gt;.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;FONT size="4"&gt;Connect your data to the custom visualization&lt;/FONT&gt;&lt;/P&gt;
&lt;UL class="ul1"&gt;
&lt;LI class="li5"&gt;&lt;SPAN class="s3"&gt;Point the spec at your dataset with&lt;/SPAN&gt; &lt;SPAN class="s4"&gt;"data": { "name": "databricks_query" }&lt;/SPAN&gt;&lt;SPAN class="s3"&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Every column you use must first be added to the widget's &lt;STRONG&gt;Fields&lt;/STRONG&gt; section in the AI/BI dashboard.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Reference columns with "&lt;STRONG&gt;field&lt;/STRONG&gt;": "&lt;STRONG&gt;columnName&lt;/STRONG&gt;".&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p2"&gt;&lt;FONT size="6"&gt;&lt;SPAN class="s1"&gt;Create the Custom Pareto Chart&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class="p2"&gt;&lt;FONT size="6"&gt;&lt;SPAN class="s1"&gt;&lt;FONT size="5"&gt;Step 1: Create the dashboard&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;OL class="ol1"&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;In the main navigation bar, select &lt;STRONG&gt;Dashboards&lt;/STRONG&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Click&lt;STRONG&gt; Create dashboard&lt;/STRONG&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;At the top left of the dashboard definition panel, you'll see a placeholder name like &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN class="s2"&gt;New Dashboard 20XX-01-01 12:00:00&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Click the placeholder name and change it to &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN class="s2"&gt;FirstName-LastInitials - Custom Pareto&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;At the top right, select a &lt;STRONG&gt;Serverless SQL Warehouse&lt;/STRONG&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="p4"&gt;&lt;FONT size="5"&gt;&lt;SPAN class="s1"&gt;Step 2: Create the data&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;SPAN class="s1"&gt;In the Dashboard, select the&amp;nbsp;&lt;STRONG&gt;Data&lt;/STRONG&gt; tab.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="s1"&gt;Choose &lt;STRONG&gt;Add SQL dataset.&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="s1"&gt;&lt;SPAN class="s1"&gt;Add the following SQL code:&lt;/SPAN&gt;&lt;/SPAN&gt;
&lt;TABLE border="1" width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="100%"&gt;&lt;LI-CODE lang="markup"&gt;SELECT * FROM VALUES
  ('Surface Scratch',   450, 28.13,  28.13, 'Key Issue Drivers', 1),
  ('Paint Defect',      320, 20.00,  48.13, 'Key Issue Drivers', 2),
  ('Missing Component', 240, 15.00,  63.13, 'Key Issue Drivers', 3),
  ('Alignment Issue',   180, 11.25,  74.38, 'Key Issue Drivers', 4),
  ('Loose Fastener',    140,  8.75,  83.13, 'Key Issue Drivers', 5),
  ('Electrical Fault',   95,  5.94,  89.06, 'Minor Issues',      6),
  ('Packaging Damage',   75,  4.69,  93.75, 'Minor Issues',      7),
  ('Label Error',        55,  3.44,  97.19, 'Minor Issues',      8),
  ('Sensor Failure',     35,  2.19,  99.38, 'Minor Issues',      9),
  ('Other',              10,  0.63, 100.00, 'Minor Issues',     10)
AS t(defect_category, defect_count, defect_percent, cumulative_percent, pareto_group, sort_order);&lt;/LI-CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;SPAN class="s1"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;Rename the dataset to &lt;STRONG style="color: #1b3139; font-family: inherit;"&gt;pareto_summary&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN&gt;Select &lt;STRONG&gt;Run&lt;/STRONG&gt; to execute the cell and view the data.&amp;nbsp;&lt;SPAN class="s1"&gt;Your table will look like this:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="table.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/29324i30B59CB27FBC2BDD/image-size/large?v=v2&amp;amp;px=999" role="button" title="table.png" alt="table.png" /&gt;&lt;/span&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="p3"&gt;&lt;SPAN class="s1"&gt;A &lt;STRONG&gt;custom viz&lt;/STRONG&gt; draws what's in your dataset to start, so for a Pareto chart the data summary is where the majority of work happens.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="p3"&gt;&lt;SPAN class="s1"&gt;Unlike a plain bar chart, the summary data in a Pareto is order-dependent. It requires:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="ul1"&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;The categories have to be ranked largest to smallest first, because the cumulative-percentage line is a running total computed in that order (the first category, then the first two, then the first three, up to 100%).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Each row needs its count, cumulative percentage, sort order, and group flag computed up front. This has been completed for you in the example down below.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Sort it wrong and the line, the split, and the whole chart go with it.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;The 80% split between the key drivers and the minor issues then falls out of that running total.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p1"&gt;&lt;SPAN class="s1"&gt;The columns that matter for the chart&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="ul1"&gt;
&lt;LI class="li2"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;defect_category &lt;/STRONG&gt;specifies the specific defect.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li2"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;defect_count&lt;/STRONG&gt; drives the bar height.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li2"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;defect_percent&lt;/STRONG&gt; is the percentage of defects by category.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li2"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;cumulative_percent&lt;/STRONG&gt; is the running total, which becomes the line.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li2"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;pareto_group&lt;/STRONG&gt; flags each category as a Key Issue Driver or a Minor Issue, used for bar color. Determined by the 80% threshold.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li2"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;sort_order&lt;/STRONG&gt; ranks categories by count so the bars stay in descending order (the defining feature of a Pareto chart).&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p1"&gt;&lt;FONT size="5"&gt;&lt;SPAN class="s1"&gt;Step 3: Build the custom visualization&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class="p2"&gt;&lt;FONT size="4"&gt;&lt;SPAN class="s1"&gt;In the dashboard UI&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;OL class="ol1"&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Select the &lt;STRONG&gt;Untitled&lt;/STRONG&gt; page.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Add a visualization widget to the canvas.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;Expand its width across &lt;STRONG&gt;¾&lt;/STRONG&gt; of the canvas and to a height of about &lt;STRONG&gt;8 blocks&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Add the title: &lt;STRONG&gt;Defect Category Pareto Analysis&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Add the description: &lt;STRONG&gt;Focus improvement efforts on the categories contributing to the first 80% of defects. These key issue drivers offer the greatest opportunity for impact for improvement.&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;Set its Dataset to &lt;STRONG style="color: #1b3139; font-family: inherit;"&gt;pareto_summary &lt;/STRONG&gt;(if you have only one table, it will automatically be set)&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;In the visualization field, under the &lt;STRONG&gt;Advanced&lt;/STRONG&gt; section, select &lt;STRONG style="color: #1b3139; font-family: inherit;"&gt;Custom Viz&lt;/STRONG&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;In the &lt;STRONG style="color: #1b3139; font-family: inherit;"&gt;Fields&lt;/STRONG&gt;&lt;SPAN&gt; section, add these columns (the names are how the spec references them):&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;UL class="ul1"&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;cumulative_percent&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;defect_count&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;sort_order&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;defect_category&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;pareto_group&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;With your widget set, now p&lt;SPAN class="s1"&gt;aste the spec below into the &lt;STRONG&gt;Vega-Lite Specification&lt;/STRONG&gt; editor.&lt;/SPAN&gt;&lt;/P&gt;
&lt;TABLE border="1" width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="100%"&gt;&lt;LI-CODE lang="markup"&gt;{
  "$schema": "https://vega.github.io/schema/vega-lite/v6.json",
  "width": "container",
  "height": "container",
  "data": { "name": "databricks_query" },
  "encoding": {
    "x": {
      "field": "defect_category",
      "type": "nominal",
      "sort": { "op": "min", "field": "sort_order", "order": "ascending" },
      "axis": { "title": "Defect category", "labelAngle": -40 }
    }
  },
  "layer": [
    {
      "transform": [{ "filter": "datum.pareto_group === 'Key Issue Drivers'" }],
      "mark": { "type": "rect", "color": "#FF5F46", "opacity": 0.15 }
    },
    {
      "mark": { "type": "bar", "width": { "band": 0.8 } },
      "encoding": {
        "y": {
          "field": "defect_count",
          "type": "quantitative",
          "axis": { "title": "Defect count" }
        },
        "color": {
          "field": "pareto_group",
          "type": "nominal",
          "scale": {
            "domain": ["Key Issue Drivers", "Minor Issues", "Cumulative %"],
            "range": ["#FF5F46", "#C4CCD6", "#1B5162"]
          },
          "legend": { "title": null, "orient": "top" }
        }
      }
    },
    {
      "layer": [
        {
          "mark": { "type": "area", "color": "#1B5162", "opacity": 0.05, "line": false },
          "encoding": {
            "y": { "field": "cumulative_percent", "type": "quantitative", "axis": { "title": "Cumulative %", "orient": "right" } }
          }
        },
        {
          "mark": { "type": "line", "point": { "size": 80, "filled": true } },
          "encoding": {
            "y": { "field": "cumulative_percent", "type": "quantitative" },
            "color": { "datum": "Cumulative %", "type": "nominal" }
          }
        },
        {
          "transform": [
            { "calculate": "round(datum.cumulative_percent) + '%'", "as": "cum_label" }
          ],
          "mark": { "type": "text", "dy": -12, "fontSize": 12, "fontWeight": "bold", "color": "#1B5162" },
          "encoding": {
            "y": { "field": "cumulative_percent", "type": "quantitative" },
            "text": { "field": "cum_label", "type": "nominal" }
          }
        },
        {
          "mark": { "type": "rule", "color": "#0b2026", "strokeDash": [6, 4], "size": 2 },
          "encoding": {
            "x": null,
            "y": { "datum": 80 }
          }
        },
        {
          "transform": [
            { "filter": "datum.defect_category === 'Label Error'" }
          ],
          "mark": { "type": "text", "text": "80% of defects", "align": "center", "baseline": "bottom", "dy": -1, "fontSize": 13, "fontWeight": "bold", "color": "#0b2026" },
          "encoding": {
            "y": { "datum": 80 }
          }
        },
        {
          "transform": [
            { "filter": "datum.pareto_group === 'Key Issue Drivers'" },
            { "joinaggregate": [{ "op": "max", "field": "sort_order", "as": "max_rank" }] },
            { "filter": "datum.sort_order === round((1 + datum.max_rank) / 2)" }
          ],
          "mark": { "type": "text", "text": "Fix these first", "align": "center", "baseline": "middle", "fontSize": 15, "fontWeight": "bold", "color": "#98102A" },
          "encoding": {
            "y": { "datum": 92 }
          }
        },
        {
          "transform": [
            { "calculate": "datum.pareto_group === 'Key Issue Drivers' ? 1 : 0", "as": "is_kd" },
            { "calculate": "datum.pareto_group === 'Key Issue Drivers' ? datum.cumulative_percent : 0", "as": "kd_cum_val" },
            { "joinaggregate": [
                { "op": "count", "as": "total_cats" },
                { "op": "sum", "field": "is_kd", "as": "kd_count" },
                { "op": "max", "field": "kd_cum_val", "as": "kd_cum" }
            ] },
            { "filter": "datum.sort_order === round(datum.total_cats * 0.7)" },
            { "calculate": "datum.kd_count + ' of ' + datum.total_cats + ' categories drive ' + round(datum.kd_cum) + '% of all defects'", "as": "summary" }
          ],
          "mark": { "type": "text", "align": "center", "baseline": "middle", "fontSize": 15, "fontWeight": "bold", "color": "#1B3139" },
          "encoding": {
            "y": { "datum": 55 },
            "text": { "field": "summary", "type": "nominal" }
          }
        }
      ]
    }
  ],
  "resolve": { "scale": { "y": "independent" } },
  "config": { "autosize": { "type": "fit", "contains": "padding" } }
}
&lt;/LI-CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P class="p3"&gt;&lt;SPAN class="s1"&gt;&lt;I&gt;In the era of AI Agents and LLMs, you should expect to not have to write this by hand and the same is true on Databricks. This was generated with Genie Code and refined from there, so treat the JSON as something to read and modify as you would with any piece of code generated by AI.&lt;/I&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="p3"&gt;&lt;SPAN class="s1"&gt;&lt;I&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="initial-pareto-chart.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/29328iFF74F499F5F8987E/image-size/large?v=v2&amp;amp;px=999" role="button" title="initial-pareto-chart.png" alt="initial-pareto-chart.png" /&gt;&lt;/span&gt;&lt;/I&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="p1"&gt;&lt;FONT size="5"&gt;&lt;SPAN class="s1"&gt;Spec overview&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class="p3"&gt;&lt;SPAN class="s1"&gt;We will highlight a few main areas of interest in this task:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;Data binding and sorting&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="s1"&gt;The spec uses &lt;/SPAN&gt;&lt;STRONG&gt;&lt;SPAN class="s2"&gt;databricks_query&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN class="s1"&gt; as its dataset and sorts defect categories using &lt;STRONG&gt;sort_order&lt;/STRONG&gt; to control the x-axis order.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;Layering builds the visualization&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="s1"&gt;Bars, the cumulative line, shaded regions, labels, reference lines, and annotations are separate layers drawn together into one chart.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;Independent y-axes&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="s1"&gt;Defect counts use the left axis while cumulative percentage uses the right.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="s1"&gt;Independent y-scales allow both measures to coexist.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;Transforms add logic&amp;nbsp;&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="s1"&gt;Filters, calculations, and aggregations identify key issue drivers, shading, calculate percentages, and determine where annotations should appear.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN class="s1"&gt;&lt;STRONG&gt;Dynamic annotations&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="s1"&gt;Summary text like &lt;I&gt;5 of 10 categories drive 83%&lt;/I&gt; of all defects is calculated from the data, so it updates automatically when the underlying data changes.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p1"&gt;&lt;FONT size="5"&gt;&lt;SPAN class="s1"&gt;Step 3: Polish with Genie Code (Output can vary)&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class="p2"&gt;&lt;SPAN class="s1"&gt;You don't have to manually write or update the JSON. Genie Code can create or edit the spec for you in natural language throughout this entire process. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="p2"&gt;&lt;SPAN class="s1"&gt;Use Genie Code to update the current visualization.&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI class="p2"&gt;&lt;SPAN class="s1"&gt;Select the Genie Code icon at the top right of the workspace. &lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="p2"&gt;&lt;SPAN class="s1"&gt;Then with the &lt;STRONG&gt;custom viz&lt;/STRONG&gt; selected, try a prompt like:&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;TABLE border="1" width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="100%"&gt;&lt;LI-CODE lang="markup"&gt;This visualization is a Vega-Lite custom viz. Edit the JSON spec directly. Apply these formatting changes and leave everything else unchanged:
1. Remove the horizontal gridlines (the y-axis grid).
2. Set the axis titles ("Defect category", "Defect count", "Cumulative %") to font size 14.
3. Set the axis tick labels on all three axes to font size 13.
4. On the right Cumulative % axis only, append a "%" to each tick value.
5. Set the legend label font size to 13.
&lt;/LI-CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P&gt;&lt;SPAN class="s1"&gt;Genie applies the edits and you keep iterating from there!&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="s1"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="final-pareto-chart.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/29327i2EF64EF1ECF59907/image-size/large?v=v2&amp;amp;px=999" role="button" title="final-pareto-chart.png" alt="final-pareto-chart.png" /&gt;&lt;/span&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="p1"&gt;&lt;FONT size="5"&gt;&lt;SPAN class="s1"&gt;Building it with AI (Genie Code here): what to watch for&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class="p3"&gt;&lt;SPAN class="s1"&gt;AI output varies. If you build this from scratch or update with AI, keep an eye on a few things:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="ul1"&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;You may get a &lt;STRONG&gt;combo chart&lt;/STRONG&gt;, not a &lt;STRONG&gt;custom viz&lt;/STRONG&gt;. Combo widgets have some limitations when creating a Pareto chart.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN class="s1"&gt;Some options live only in the widget JSON spec, not the UI. For example, sort-by-value and line markers can exist only in the widget's JSON, and editing the widget in the UI can silently revert them.&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;Dynamic, computed annotations and shaded bands aren't available in the combo chart, those need a custom viz.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;Make sure you sort the bars by their values (or a computed rank), not a custom sort order. A manual sort looks right today but won't re-rank when the data changes.&lt;/LI&gt;
&lt;LI class="li3"&gt;When creating a custom visualization, it's important to understand your data. AI may hardcode values in the JSON spec, so if your backend data is updated the visualization can be off. Always check the work.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="p2"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class="p4"&gt;&lt;FONT size="6"&gt;&lt;SPAN class="s1"&gt;Your turn! Can you make it better?&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P class="p3"&gt;&lt;SPAN class="s1"&gt;The Vega-Lite spec above is one solution, but it can be improved. See what you can come up with. Try it in &lt;A href="https://www.databricks.com/learn/free-edition" target="_self"&gt;Databricks Free Edition&lt;/A&gt;!&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="p3"&gt;Made it better? Share your spec and a screenshot in the comments. The best ideas help everyone learn new techniques for building custom visualizations.&lt;/P&gt;
&lt;P class="p4"&gt;&lt;FONT size="4"&gt;&lt;SPAN class="s1"&gt;Learn more&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;UL class="ul1"&gt;
&lt;LI class="li5"&gt;&lt;SPAN class="s2"&gt;&lt;A href="https://docs.databricks.com/aws/en/dashboards/manage/visualizations/custom-visualizations" target="_blank" rel="noopener"&gt;Custom visualizations in AI/BI dashboards&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li5"&gt;&lt;SPAN class="s2"&gt;&lt;A href="https://vega.github.io/vega-lite/" target="_blank" rel="noopener"&gt;Vega-Lite documentation&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li5"&gt;&lt;SPAN class="s2"&gt;&lt;A href="https://docs.databricks.com/aws/en/genie-code/" target="_blank" rel="noopener"&gt;Genie Code&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="s1"&gt;&lt;A href="https://www.databricks.com/learn/free-edition" target="_blank" rel="noopener"&gt;Databricks Free Edition&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI class="li3"&gt;&lt;SPAN class="s1"&gt;New to AI/BI Dashboards? The &lt;A href="https://www.databricks.com/training/catalog/aibi-for-data-analysts-3707" target="_blank" rel="noopener"&gt;&lt;SPAN class="s3"&gt;AI/BI for Data Analysts&lt;/SPAN&gt;&lt;/A&gt; course covers building interactive dashboards, creating visualizations, using Genie Code and AI-assisted analytics, publishing, scheduling, and more.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;EM&gt;&lt;SPAN class="s1"&gt;Special thanks to Maggie Li, Matthew McCoy and Marcelino Mayorga.&lt;/SPAN&gt;&lt;/EM&gt;&lt;/P&gt;</description>
    <pubDate>Mon, 03 Aug 2026 19:50:51 GMT</pubDate>
    <dc:creator>pstyld</dc:creator>
    <dc:date>2026-08-03T19:50:51Z</dc:date>
    <item>
      <title>Custom Visualizations in AI/BI Dashboards: Build a Pareto Chart with Vega-Lite</title>
      <link>https://community.databricks.com/t5/technical-blog/custom-visualizations-in-ai-bi-dashboards-build-a-pareto-chart/ba-p/163659</link>
      <description>&lt;P&gt;&lt;SPAN&gt;Need a visualization your standard AI/BI dashboard widgets can't create? Databricks AI/BI custom visualizations let you use Vega-Lite to build highly tailored charts. Learn how to craft a dynamic Pareto analysis with automated sorting, dynamic labels, background shading and Genie-assisted code enhancements.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 03 Aug 2026 19:50:51 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/custom-visualizations-in-ai-bi-dashboards-build-a-pareto-chart/ba-p/163659</guid>
      <dc:creator>pstyld</dc:creator>
      <dc:date>2026-08-03T19:50:51Z</dc:date>
    </item>
    <item>
      <title>Re: Custom Visualizations in AI/BI Dashboards: Build a Pareto Chart with Vega-Lite</title>
      <link>https://community.databricks.com/t5/technical-blog/custom-visualizations-in-ai-bi-dashboards-build-a-pareto-chart/bc-p/165057#M1160</link>
      <description>&lt;P&gt;Super cool to see Vega Lite to create custom visuals in Databricks dashboards! One thing I am missing, which is key of interactive dashboards: Can you also click and mark something on the Vega Lite custom visual which is then used to filter or highlight in other standard visuals or tables of the dashboard? Is that maybe on your roadmap for custom visuals?&lt;/P&gt;</description>
      <pubDate>Thu, 06 Aug 2026 22:12:35 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/custom-visualizations-in-ai-bi-dashboards-build-a-pareto-chart/bc-p/165057#M1160</guid>
      <dc:creator>hschimanski</dc:creator>
      <dc:date>2026-08-06T22:12:35Z</dc:date>
    </item>
    <item>
      <title>Re: Custom Visualizations in AI/BI Dashboards: Build a Pareto Chart with Vega-Lite</title>
      <link>https://community.databricks.com/t5/technical-blog/custom-visualizations-in-ai-bi-dashboards-build-a-pareto-chart/bc-p/165383#M1166</link>
      <description>&lt;P class="wnfdntu _1ibi0s3f5 _1ibi0s3ce _1ibi0s3ea"&gt;Great question &lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/164109"&gt;@hschimanski&lt;/a&gt;&lt;BR /&gt;&lt;BR /&gt;Here is the doc for it:&amp;nbsp;&lt;A href="https://docs.databricks.com/aws/en/dashboards/manage/visualizations/custom-visualizations#filter-other-widgets-on-selection" target="_blank" rel="noopener"&gt;Filter other widgets on selection.&lt;/A&gt;&lt;/P&gt;
&lt;P class="wnfdntu _1ibi0s3f5 _1ibi0s3ce _1ibi0s3ea"&gt;There are some requirements listed in the doc. Here is the &lt;STRONG&gt;updated vega lite spec from this blog&lt;/STRONG&gt; that uses &lt;STRONG&gt;cross filtering&lt;/STRONG&gt;.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A few key points:&lt;/P&gt;
&lt;UL&gt;
&lt;LI class="css-1ksqbpg"&gt;&lt;SPAN class="du-bois-light-typography css-dulbl6"&gt;params&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;goes inside the &lt;STRONG&gt;layer with the clickable mark&lt;/STRONG&gt;, not at the root of the layered spec&lt;/LI&gt;
&lt;LI class="css-1ksqbpg"&gt;&lt;SPAN class="du-bois-light-typography css-dulbl6"&gt;fields&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;must reference the &lt;STRONG&gt;field names from your widget's Fields config&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI class="css-1ksqbpg"&gt;Only &lt;STRONG&gt;dimension fields&lt;/STRONG&gt; work (not aggregated measures)&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;To test it, try this.&lt;/STRONG&gt; &lt;BR /&gt;1. Create a new &lt;STRONG&gt;bar chart widget&lt;/STRONG&gt;&amp;nbsp;(or any widget you want) that uses the following:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;X axis - &lt;STRONG&gt;defect_category&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Y axis - &lt;STRONG&gt;SUM(defect_count)&lt;BR /&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;2.&amp;nbsp;Then update the &lt;STRONG&gt;vega lite in the custom viz&lt;/STRONG&gt; with this:&lt;/P&gt;
&lt;DIV&gt;
&lt;DIV&gt;
&lt;TABLE border="1" width="100%"&gt;
&lt;TBODY&gt;
&lt;TR&gt;
&lt;TD width="100%"&gt;&lt;LI-CODE lang="markup"&gt;{
  "$schema": "https://vega.github.io/schema/vega-lite/v6.json",
  "width": "container",
  "height": "container",
  "data": {
    "name": "databricks_query"
  },
  "encoding": {
    "x": {
      "field": "defect_category",
      "type": "nominal",
      "sort": {
        "op": "min",
        "field": "sort_order",
        "order": "ascending"
      },
      "axis": {
        "title": "Defect category",
        "labelAngle": -40
      }
    }
  },
  "layer": [
    {
      "transform": [
        {
          "filter": "datum.pareto_group === 'Key Issue Drivers'"
        }
      ],
      "mark": {
        "type": "rect",
        "color": "#FF5F46",
        "opacity": 0.15
      }
    },
    {
      "params": [
        {
          "name": "databricks_mark_selection",
          "select": {
            "type": "point",
            "fields": [
              "defect_category"
            ]
          }
        }
      ],
      "mark": {
        "type": "bar",
        "width": {
          "band": 0.8
        },
        "stroke": null
      },
      "encoding": {
        "y": {
          "field": "defect_count",
          "type": "quantitative",
          "axis": {
            "title": "Defect count"
          }
        },
        "color": {
          "field": "pareto_group",
          "type": "nominal",
          "scale": {
            "domain": [
              "Key Issue Drivers",
              "Minor Issues",
              "Cumulative %"
            ],
            "range": [
              "#FF5F46",
              "#C4CCD6",
              "#1B5162"
            ]
          },
          "legend": {
            "title": null,
            "orient": "top"
          }
        },
        "fillOpacity": {
          "condition": {
            "param": "databricks_mark_selection",
            "value": 1
          },
          "value": 0.4
        },
        "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
        }
      }
    },
    {
      "layer": [
        {
          "mark": {
            "type": "area",
            "color": "#1B5162",
            "opacity": 0.05,
            "line": false
          },
          "encoding": {
            "y": {
              "field": "cumulative_percent",
              "type": "quantitative",
              "axis": {
                "title": "Cumulative %",
                "orient": "right"
              }
            }
          }
        },
        {
          "mark": {
            "type": "line",
            "point": {
              "size": 80,
              "filled": true
            }
          },
          "encoding": {
            "y": {
              "field": "cumulative_percent",
              "type": "quantitative"
            },
            "color": {
              "datum": "Cumulative %",
              "type": "nominal"
            }
          }
        },
        {
          "transform": [
            {
              "calculate": "round(datum.cumulative_percent) + '%'",
              "as": "cum_label"
            }
          ],
          "mark": {
            "type": "text",
            "dy": -12,
            "fontSize": 12,
            "fontWeight": "bold",
            "color": "#1B5162"
          },
          "encoding": {
            "y": {
              "field": "cumulative_percent",
              "type": "quantitative"
            },
            "text": {
              "field": "cum_label",
              "type": "nominal"
            }
          }
        },
        {
          "mark": {
            "type": "rule",
            "color": "#0b2026",
            "strokeDash": [
              6,
              4
            ],
            "size": 2
          },
          "encoding": {
            "x": null,
            "y": {
              "datum": 80
            }
          }
        },
        {
          "transform": [
            {
              "filter": "datum.defect_category === 'Label Error'"
            }
          ],
          "mark": {
            "type": "text",
            "text": "80% of defects",
            "align": "center",
            "baseline": "bottom",
            "dy": -1,
            "fontSize": 13,
            "fontWeight": "bold",
            "color": "#0b2026"
          },
          "encoding": {
            "y": {
              "datum": 80
            }
          }
        },
        {
          "transform": [
            {
              "filter": "datum.pareto_group === 'Key Issue Drivers'"
            },
            {
              "joinaggregate": [
                {
                  "op": "max",
                  "field": "sort_order",
                  "as": "max_rank"
                }
              ]
            },
            {
              "filter": "datum.sort_order === round((1 + datum.max_rank) / 2)"
            }
          ],
          "mark": {
            "type": "text",
            "text": "Fix these first",
            "align": "center",
            "baseline": "middle",
            "fontSize": 15,
            "fontWeight": "bold",
            "color": "#98102A"
          },
          "encoding": {
            "y": {
              "datum": 92
            }
          }
        },
        {
          "transform": [
            {
              "calculate": "datum.pareto_group === 'Key Issue Drivers' ? 1 : 0",
              "as": "is_kd"
            },
            {
              "calculate": "datum.pareto_group === 'Key Issue Drivers' ? datum.cumulative_percent : 0",
              "as": "kd_cum_val"
            },
            {
              "joinaggregate": [
                {
                  "op": "count",
                  "as": "total_cats"
                },
                {
                  "op": "sum",
                  "field": "is_kd",
                  "as": "kd_count"
                },
                {
                  "op": "max",
                  "field": "kd_cum_val",
                  "as": "kd_cum"
                }
              ]
            },
            {
              "filter": "datum.sort_order === round(datum.total_cats * 0.7)"
            },
            {
              "calculate": "datum.kd_count + ' of ' + datum.total_cats + ' categories drive ' + round(datum.kd_cum) + '% of all defects'",
              "as": "summary"
            }
          ],
          "mark": {
            "type": "text",
            "align": "center",
            "baseline": "middle",
            "fontSize": 15,
            "fontWeight": "bold",
            "color": "#1B3139"
          },
          "encoding": {
            "y": {
              "datum": 55
            },
            "text": {
              "field": "summary",
              "type": "nominal"
            }
          }
        }
      ]
    }
  ],
  "resolve": {
    "scale": {
      "y": "independent"
    }
  },
  "config": {
    "autosize": {
      "type": "fit",
      "contains": "padding"
    }
  }
}&lt;/LI-CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;STRONG&gt;Example&lt;/STRONG&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;EM&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="filtering.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/29903iCAFAAF5762D8B281/image-size/large?v=v2&amp;amp;px=999" role="button" title="filtering.png" alt="filtering.png" /&gt;&lt;/span&gt;&lt;/EM&gt;&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P class="wnfdntu _1ibi0s3f5 _1ibi0s3ce _1ibi0s3ea"&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 11 Aug 2026 14:12:38 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/custom-visualizations-in-ai-bi-dashboards-build-a-pareto-chart/bc-p/165383#M1166</guid>
      <dc:creator>pstyld</dc:creator>
      <dc:date>2026-08-11T14:12:38Z</dc:date>
    </item>
  </channel>
</rss>

