The Zurich release has arrived! Interested in new features and functionalities? Click here for more

How to display stacked bar graph from custom script in UI Builder [Not in Reporting]

Sharique Azim
Mega Sage

Hi everyone,

I’m trying to build a Stacked Bar chart in UI Builder using now-vis-bar-wrapper in data resource . My data comes from a Script Include that returns a hierarchical structure with these keys for each node:

{
  "value": "{SYS_ID}",   // sys_id of the user
  "label": "User Name A",                     //-> manager Display name for the chart axis
  "directCost": 16,                             // This person's own license cost
  "totalCost": 49.83,                           // directCost + all descendants' costs
  "licenseBreakdown": {                         // Self allocations only
    "Miro": 16
  },
  "rolledUpLicenseBreakdown": {                 // Allocations from reportees only
    "Autodesk": 33.83
  },
  "rolledUpLicenseUserCount": {                 // Count of reportees using each license
    "Arnold-Autodesk": 1
  },
  "children": [
    {
      "value": "{SYS_ID}",
      "label": "User Name B",
      "directCost": 0,
      "totalCost": 0,
      "licenseBreakdown": {},                   // No self allocations
      "rolledUpLicenseBreakdown": {},           // No reportees
      "rolledUpLicenseUserCount": {},           // No reportees
      "children": []
    },
    {
      "value": "{SYS_ID}",
      "label": "Sharique Azim",
      "directCost": 33.83,
      "totalCost": 33.83,
      "licenseBreakdown": {
"Autodesk": 33.83
  },
      "rolledUpLicenseBreakdown": {},
      "rolledUpLicenseUserCount": {},
      "children": []
    }
  ]
}

 

My data binding script

 console.log("chart0");
  // 1️⃣ Get the Script Include output
const rawOutput = api.data.licensecostdata_1.output || {};

const jsonPayload = rawOutput.children : {};

console.log('[STACKED-BAR] Starting transform, nodes:', jsonPayload.length);

// 2️⃣ Collect all license types from rolledUpLicenseBreakdown
const licenseTypesMap = {};
jsonPayload.forEach(node => {
    Object.keys(node.rolledUpLicenseBreakdown || {}).forEach(type => {
        licenseTypesMap[type] = true;
    });
});
const licenseList = Object.keys(licenseTypesMap);
console.log('[STACKED-BAR] License types:', licenseList);

// 3️⃣ Build chartData rows and elements array
const chartData = [];
const elements = [];

jsonPayload.forEach(node => {
    // Row for this user
    const row = { label: node.label };
    licenseList.forEach(type => {
        const cost = (node.rolledUpLicenseBreakdown && node.rolledUpLicenseBreakdown[type]) || 0;
        row[type] = String(cost);
    });
    chartData.push(row);

    // Element for this user
    elements.push({
        id: node.value,
        label: node.label,
        eventData: { query: String(node.value) }
    });
});

// 4️⃣ Build series array for metadata
const seriesArray = licenseList.map(type => ({
    id: type,
    type: 'value',
    label: type
}));

// 5️⃣ Build metadata object
const metadata = {
    dataSourceLabel: 'Reportee Cost by License Type',
    eventData: { table: 'u_sw_license_user_alloc_archive' },
    groupBy: [{
        id: 'label',
        fieldType: 'string',
        label: 'User',
        elements: elements,
        series: seriesArray
    }],
    format: { unitFormat: '$ {0}' },
    aggregateBy: 0
};

return [{
    data: chartData,
    metadata: metadata
}];

 

What I want:

  • X‑axis: each person in the hierarchy (name shown, unique internally to avoid duplicate label errors).

  • Stacks: one segment per license type,can have multiple licenses, using values from rolledUpLicenseBreakdown.

  • If a node has no applicable breakdown, the bar should be not present(obviously).

  • Managers should not have their own allocations included in rolledUpLicenseBreakdown — only their reportees’ totals. Therefore no bar them.

What I’ve tried:

  • Built licenseList from all keys in rolledUpLicenseBreakdown across the payload.

  • Created chartData rows with label and value array

  • Built elements array with matching labels and unique IDs.

  • Built metadata.groupBy[0].series from licenseList.

  • All this are done via script of data section of data visualization component.

  • Set the component’s Stacked property to true.

The issue:

  • The chart renders only the background, but it’s not showing the bar or stacking as expected.

  • I’ve confirmed elements.length matches chartData.length (say 49 entries), and labels are unique.

  • All rows have all series columns, even if zero.

Question: Has anyone successfully built a stacked bar in from hierarchical data like this? Is there anything special about how script must be formatted for stacking to work? Any working example or script to generate a stacked bar would be greatly appreciated.

 

Also find reference images.Screenshot 2025-09-06 233105.png

 

image.png

 

Thanks in advance!

Shariq

3 REPLIES 3

IronPotato
Mega Sage

Hi @Sharique Azim ,

 

make sure that the value is of type String in data array key to properly show bars not number.

 

 

 

IronPotato
Mega Sage

Here are dummy data for vertical bar visualization component: 

 

[
  {
    "data": [
      { "assignment_group": "(empty)", "value": "28" },
      { "assignment_group": "Service Desk", "value": "12" },
      { "assignment_group": "Hardware", "value": "9" },
      { "assignment_group": "Software", "value": "9" },
      { "assignment_group": "Network", "value": "6" },
      { "assignment_group": "Database", "value": "2" },
      { "assignment_group": "Openspace", "value": "1" }
    ],
    "metadata": {
      "dataSourceLabel": "Incident",
      "eventData": { "table": "incident" },
      "groupBy": [
        {
          "series": [{ "id": "value", "type": "value", "label": "Incident" }],
          "elements": [
            { "eventData": { "query": "assignment_group=" }, "id": "", "label": "(empty)" },
            { "eventData": { "query": "assignment_group=d625dccec0a8016700a222a0f7900d06" }, "id": "d625dccec0a8016700a222a0f7900d06", "label": "Service Desk" },
            { "eventData": { "query": "assignment_group=8a5055c9c61122780043563ef53438e3" }, "id": "8a5055c9c61122780043563ef53438e3", "label": "Hardware" },
            { "eventData": { "query": "assignment_group=8a4dde73c6112278017a6a4baf547aa7" }, "id": "8a4dde73c6112278017a6a4baf547aa7", "label": "Software" },
            { "eventData": { "query": "assignment_group=287ebd7da9fe198100f92cc8d1d2154e" }, "id": "287ebd7da9fe198100f92cc8d1d2154e", "label": "Network" },
            { "eventData": { "query": "assignment_group=287ee6fea9fe198100ada7950d0b1b73" }, "id": "287ee6fea9fe198100ada7950d0b1b73", "label": "Database" },
            { "eventData": { "query": "assignment_group=36c741fa731313005754660c4cf6a70d" }, "id": "36c741fa731313005754660c4cf6a70d", "label": "Openspace" }
          ],
          "id": "assignment_group",
          "fieldType": "reference",
          "label": "Assignment group"
        }
      ],
      "format": { "unitFormat": "{0}" },
      "aggregateBy": 4,
      "metricId": "ZEdGaWJHVnBibU5wWkdWdWRERTJORFl5TXpRMk5qYzBORE09MTY0NjIzNDY2OTQzMw=="
    }
  }
]

Hello @IronPotato  Thank you for your response. I am aware of the sample json available on the bar chart component. But this json would not populate stacked bar chart, which is my requirement. For reference i am already able to generate a chart like this via script and json format similar to this. 

Screenshot 2025-09-16 210646.png