Master_T
Master_T

Reputation: 7987

Power Bi Custom Visual: column order is incorrect

I'm developing a Power Bi custom visual, but I have a problem: when the user adds dimensions to the visual, the order shown in the UI does not reflect the actual order of the columns in the data I get from Power Bi. See for example this screenshot:

enter image description here

This is very limiting in a lot of scenarios, for example if I want to draw a table with columns in the order that the user sets.

Why does the API behave like this? Doesn't seem logical to me, am I doing something wrong? Here is the data binding definition if it helps:

"dataRoles": [
    {
        "displayName": "Fields",
        "name": "fields",
        "kind": "Grouping"
    },
    {
        "displayName": "Measures",
        "name": "measures",
        "kind": "Measure"
    }

],
"dataViewMappings": [
    {
        "table": {
            "rows": {
                "select": [
                    {
                        "for": {
                            "in": "fields"
                        }
                    },
                    {
                        "for":{
                            "in": "measures"
                        }
                    }
                ],
                "dataReductionAlgorithm": {
                    "window": {
                        "count": 30000
                    }
                }
            }
        }

    }
]

Upvotes: 1

Views: 297

Answers (2)

gwruck
gwruck

Reputation: 793

@Master_T , You can also go one step further and iterate through all data roles using an extension of your code.

          dataView.metadata.columns.forEach(col => {
        let rolesIndex = col['rolesIndex'];
        console.log("rolesIndex:",  rolesIndex )

        if (rolesIndex) {
            // Iterate through the roles
            Object.keys(rolesIndex).forEach(roleName => {
                console.log(`Role Name: ${roleName}`);
    
                // Iterate through the indices for this role
                rolesIndex[roleName].forEach(index => {
                    console.log(`Role Index for ${roleName}: ${index}`);
                });
            });
        } else {
            console.log("rolesIndex is undefined for this column.");
        }
      });

Note that we need to be cautious using this approach since it is not using the published api and it is possible it could change in future, but my understanding is that this is the only way it is currently possible to determine the order of the columns, so I will be using it until it either breaks or is replaced by an "approved" method.

Upvotes: 0

Master_T
Master_T

Reputation: 7987

I think I solved it. You can get the actual column order like this:

dataView.metadata.columns.forEach(col => {
  let columnOrder = col['rolesIndex'].XXX[0];
});

where XXX is the name of the Data Role, which in the example in my question would be fields.

Note that you have to access the rolesIndex property by key name like I did above (or alternatively cast to any before accessing it), because the DataViewMetadataColumn type is missing that property for some reason.

Upvotes: 1

Related Questions