xViz
ProductPricingCommunity
  • Welcome to xViz Docs!
  • Project Management
    • Project Management - xViz Gantt Chart | Introduction
    • Hierarchy and Additional Columns
    • 🔸Milestones
      • Milestone Formatting
    • Planned Bars
      • Planned Bars Formatting
    • Connectors
      • Primary & Secondary Connectors
      • Multiple Connectors
      • Connectors Formatting
    • Progress
      • Tracking the progress
      • Progress Bar Display
      • Progress Base
      • Bar Formatting
    • Timeline Configurations
      • Timeline Start/End
      • Timeline Range
      • Header Levels
      • Zoom Levels
      • Zoom Options
      • Fiscal Year Support
      • Timeline Format
      • Language Support for Timeline
    • ✨Alerting Techniques
      • Steps to enable Conditional Formatting
      • Conditional Formatting
    • Reference Lines and Reference Range
      • Introduction
      • Static Approach
      • Data Driven Approach
    • Resource Gantt
    • ➡️Other Features
      • Data Colors
        • Row Background Color
        • Bar Border Color
        • Bar Selection Color
        • Bar Fill Color
        • Connectors
      • Duration Data field
      • Display Duration
      • Display Totals
      • Hide Blanks
      • Date Formats
      • DaysOff
        • Weekday
        • Custom Date
      • Setting Up Drill-through
      • Configure External URLs
      • Splitter Position
      • Text Customization
      • Row Numbering
      • Indentation
      • Sorting
    • Parent Level Calculations
      • Aggregation Types
    • Tooltip
    • Release Notes
    • ❓FAQs
  • Performance Management
    • Performance Flow - Introduction
      • Installing from AppSource
      • Get Started
    • Use Cases
      • Organization Performance
      • Microsoft Tenant Data Analytics
        • Organization Chart using Microsoft Graph API
      • Process Flow
      • Sales Performance Analysis
      • Cost Center Analysis
      • KPI Tree
      • Warehouse Management
      • Supply Chain Network
    • Configuring the chart structure
      • Hierarchy structure
      • Grouping / Swim Lanes
        • Data Structure for Columnar Group View
        • Data Structure for Wide Group Views
      • Invisible Group
    • 🪪Display Data in the Cards
      • Title, Subtitle
      • 👨‍💼Images
        • Converting HTTPs link images/icons to Base 64 in Power BI
        • Handling long Base 64 URLs in Power BI
      • 🔢Displaying KPIs
        • Number Formatting
      • 🔻Displaying Variance
      • Sparkline Trends
      • 🔗Hyperlinks
    • Card Formatting
      • Data-Driven Color
      • Templates
      • Customize Template
        • Insert additional data
        • Alignment
        • Wrap Text
        • Styling
        • Margin & Split
        • Modify (Delete / Cope-Paste)
        • Import/Export
    • Links
    • 🗒️Notes & Annotation
    • 🚦Conditional Formatting
    • Layout & Orientation
    • ✨Search
    • ✨Viewing Subtrees
      • Cross Filtering with Subtrees
    • 🔐✨User Context - RLS Experience
    • ✨Filter Context
    • 🎨Formatting Features
      • Formatting Font & Colors
      • Connectors
      • Expand Collapse Button
      • Dimensions
    • Toolbar Ribbon Configuration
    • Simulation
    • ❓FAQs
      • Circular Dependency message
    • Tips & Tricks
      • Bookmark
      • Report Page Tooltip
      • Field Parameters
      • Drill Through
    • Release Notes
Powered by GitBook
On this page

Was this helpful?

  1. Performance Management
  2. Configuring the chart structure
  3. Grouping / Swim Lanes

Data Structure for Wide Group Views

PreviousData Structure for Columnar Group ViewNextInvisible Group

Last updated 5 months ago

Was this helpful?

This document explains the process to dynamically convert a standard data structure to the data structure required to plot a wide group view in the xViz Performance Flow visual

Prerequisite - Before proceeding with this page, please go through the following pages to ensure a comprehensive understanding of the configurations required:

Let’s explore this with an example of Warehouse Management. We have a dataset with specific IDs, but we don't have the Parent ID, Group ID, and Subtree ID included. However, we can easily create these columns in Power Query using a few transformation steps.

Steps to create Group ID, Parent ID & Sub Tree ID in Power Query:

  1. We have a Source table with the columns Id, Racks, Section, and City.

This will result in a new column named "Text After Delimiter", where the section category is displayed, as shown in the image below:

We can use this column to create the Subtree ID. If you want to use a different column for the Subtree ID and you already have that column in your dataset, you can skip these steps.

// Define number of columns/subtree IDs of each section based on Merged column
    NumberOfColumnsByMerged = [
        #"Chicago- A1" = 4,
        #"Chicago- B1" = 3,
        #"Chicago- A2" = 4,
        #"Chicago- B2" = 2,
        #"Berlin- A1" = 3,
        #"Berlin- A2" = 2,
        #"Mumbai- A1" = 4,
        #"Mumbai- A2" = 5,
        #"Mumbai- B1" = 3,
        #"Melbourne- A1" = 3,
        #"Melbourne- B1" = 5
    ]

You can adjust the number of racks here to modify the structure of the sections according to your needs.

  1. We will now create a function to retrieve the number of vertical racks for each section based on the Warehouse Section column. Copy the code below and paste it into the Advanced Editor after the final step:

// Function to get the number of columns/subtree IDs for each Merged value
    GetNumberOfColumns = (warehousesection) => try Record.Field(NumberOfColumnsByMerged, warehousesection) otherwise 5
let
        CurrentCategory = [Warehouse Section],
        Numberofrows = GetNumberOfColumns(CurrentCategory),

        // list of unique Section values
        UniqueSections = List.Distinct(#"Added Index"[Warehouse Section]),
        
        // mapping table from Section values to Sub Tree Id
        SectionMapping = List.Zip({UniqueSections, List.Transform({1..List.Count(UniqueSections)}, each _)}),
        
        // mapping list to a record for lookup
        SectionRecord = Record.FromList(List.Transform(SectionMapping, each _{1}), List.Transform(SectionMapping, each _{0})),
        
        // Lookup the section number from record
        SectionNumber = Record.Field(SectionRecord, [Warehouse Section]),
        
        // Sub Tree ID
        SubtreeID = "G" & Text.From(SectionNumber),

        CurrentSection = [Warehouse Section],
        CurrentIndex = [Index],
        PreviousRows = Table.SelectRows(#"Added Index", each [Warehouse Section] = CurrentSection and [Index] < CurrentIndex),
        RowCountInSection = Table.RowCount(PreviousRows),
        
        // Assign Subtree Id
        IsWithinNumberofrows = RowCountInSection < Numberofrows
    in
        if IsWithinNumberofrows then SubtreeID else null

Make sure to replace the "Warehouse Section" text with the name of your grouping column.

This will result in a new column named "Sub Tree Id" is displayed in the image below:

Subtree Id must be populated only for the first node of every vertical column (rack, in this case) within a group (section, in this case). Child nodes reside in the group of their respective parent nodes.

llet
    // Get the current row's Section, Index, and Id
    CurrentSection = [Warehouse Section],
    CurrentIndex = [Index],

    // Get the number of rows for the current warehouse section
    NumberofRows = GetNumberOfColumns(CurrentSection),

    // Get the first `NumberofRows` in the current section
    FirstRowsInSection = Table.FirstN(Table.SelectRows(#"Added Subtree Id", each [Warehouse Section] = CurrentSection), NumberofRows),

    // Determine the Parent Id logic
    Pid = 
        if CurrentIndex <= NumberofRows then null // First `NumberofRows` get null
        else 
            // For rows beyond the first `NumberofRows`, find the Parent Id dynamically based on prior rows in the same section
            let
                // Get all rows in the current section before the current index
                PreviousRowsInSection = Table.SelectRows(#"Added Subtree Id", each [Warehouse Section] = CurrentSection and [Index] < CurrentIndex),
                PreviousRowCount = Table.RowCount(PreviousRowsInSection),

                // Assign the Parent Id based on previous rows, ensuring index is valid
                ParentIdRow = if PreviousRowCount > 0 and PreviousRowCount - NumberofRows >= 0 then 
                                PreviousRowsInSection{PreviousRowCount - NumberofRows}[Id] 
                              else 
                                null
            in
                // Return Parent Id if there are previous rows
                if PreviousRowCount > 0 then ParentIdRow else null
in
    Pid

Make sure to replace the "Warehouse Section" text with the name of your grouping column and "Id" text with the unqie identifier column in your data.

This will result in a new column named "Parent Id", displayed in the image below:

This will result in a blank column named "Group Id" is displayed in the image below:

  1. We will now perform basic transformations, such as changing data types and reordering columns, as shown in the image below:

  1. Now, we will create a static table to define the groups in the visual.

    1. Enter the same values in both the Group Id and Id columns which we got in Subtree Id during transformation.

    2. Then, add the Section Names to the Racks column to create a suitable structure for swim lanes, leaving the remaining columns blank.

  • After entering the data, we will append both queries. Ensure that the structure and column names in the static table match those in the source table.

  • You can choose to maintain this table in any data source of your choice and connect to the report

Our data structure is now ready!

Finally, populate the data columns in the visual to display the data in Groups, as shown in the image below:

Download the sample report file:

This example is inspired by common, real-life dataset structures. Your source data structure may vary and may require additional data transformations to align with this example.

We can now extract the Section Column using the . The delimiter in this dataset is the hyphen (-)

Let's create a "Warehouse Section" column that will be the group for the nodes. We will - City and Category with a hyphen (-) as the separator. Name the column as "Warehouse Section"

Now, we define a variable that sets the number of vertical racks in each section. Simply copy the code below and paste it into the after the Merged Columns step.

Add an Index column starting from 1 -

We will now add the "Subtree Id" column - Create a Custom Column - paste the code below as its definition and name the column as "Subtree Id"

Then, we will add the "Parent Id" column - Create a Custom Column - paste the code below as its definition and name the column as "PId":

Now, we will add the "Group Id" column- Create a Custom Column. Then enter double quotes in the custom formula tab to create a blank column for now. Name this column as "Group Id":

Click on "Enter Data" in the Home tab of Power Query Editor and input the data -

Finally, we will append the Static Groups table to the Source table -

"Text After Delimiter" option
merge the columns
Advanced Editor
Add an index column | Power Query
Add a custom column | Power Query
Add a custom column | Power Query
Add a custom column | Power Query
Enter Data Directly | Power BI
Append Queries | Power Query
Data Structure
Swim Lanes
LogoxViz Performance Flow - Warehouse managementxViz
Image 1: Group Structure in xViz Performance Flow
Image 2: Source table
Image 3: Extract Section Category
Image 4: Extracted Category Column
Image 5: Merged Columns
Image 6: Add Index Column
Image 7: Sub Tree Id Column added
Image 8: Added Parent Id Column
Image 9: Group Id column definition
Image 10: Blank Group ID column added
Image 11: Basic Transformations
Image 12: Static Table of Groups
Image 13: Appending Static Table to the Source Table
Image 14: Data Structure suitable for Wide Groups
Image 15: Group Structure in xViz Performance Flow