October 22, 2024
Chicago 12, Melborne City, USA
javascript

Power BI JS API – difference between Slicer / Page Slicer / Filter / Page Filter / Visual Filter?


I am new to Powerbi and working on a website and successfully integrates the Powerbi using the embed-token and JavaScript API found at the Powerbi Playground.

Following are the steps, how I integrate Powerbi and how end user interacts:

enter image description here

  1. Customer already authorized by his Powerbi account, so I have the bearer access token and refresh token
  2. Using token I got the list of workspaces using Rest API and generates a dropdown for same
  3. Upon selecting a workspace, I generates another dropdown for reports of selected workspace using Rest API
  4. Upon selecting a Report, I generates another dropdown for tab/page of selected report using Rest API
  5. After that when user submit the form, I collect the submitted information and render the selected report

Everything is working fine, now the customer demanding a change in the integration.
So whenever it renders a report, it should also generates another HTML (outside of the report) for the filters available on the rendered report. So the end user can interact with the report and also I need to remember/save the choice of user, so next time when user reopen same report, it should automatically selected previously saved data in the report.

To achieve this, I did some experiment with the below code using Powerbi Slicers:

<script type="text/javascript">
function getvisuals(){
    visSlicerArr = [];
    visSlicerStateArr = [];
    slicerContainer.empty();

    try {
        var pages = report.getPages();
        // console.log('pagesPromise', pages);

        pages.then(function(pagesArr){
            $.each(pagesArr, function(index, page){
                if(page.isActive){
                    activePage = page;
                }
            });

            console.log('activePage', activePage);

            // get all Visuals
            var visuals = activePage.getVisuals();
            // console.log('visualsPromise', visuals);

            visuals.then(function(visualsArr){

                $.each(visualsArr, function(index, vis){
                    if(vis.type == 'slicer'){
                        visSlicerArr.push(vis);
                    }
                });

                console.log('slicerArr (from Visuals)', visSlicerArr);

                // get Visual State
                $.each(visSlicerArr, function(index, visS){
                    var statePromise = visS.getSlicerState();
                    // console.log('visualStatePromise', statePromise);

                    statePromise.then(function(slicerState){
                        visSlicerStateArr.push(slicerState);
                        console.log('visualState', slicerState);

                        showSlicer(index, slicerState);

                        if((visSlicerArr.length - 1) == index){
                            slicerContainer.append('<button style="position: relative;" type="button" onclick="applyFilter()">Redraw Report</button>');
                        }
                    })
                    .catch (function (err) {
                        console.log('Promise Err 3', err);
                    });
                });
            })
            .catch (function (err) {
                console.log('Promise Err 2', err);
            });
        })
        .catch (function (err) {
            console.log('Promise Err 1', err);
        });
    }
    catch (errors) {
        console.log('Try Err 1', errors);
    }
}

function showSlicer(index, slicerState) {
    console.log('in', slicerState);

    var slicerVal="";
    if(slicerState.filters.length){
        slicerValues = slicerState.filters[0].values;  // Get current slicer values
        slicerVal = slicerValues.join(', ');
        console.log("slicerVal", JSON.stringify(slicerVal), index)
    }

    var target="";
    if(slicerState.targets.length){
        slicerTargets = slicerState.targets;

        $.each(slicerTargets, function(i, t){
            if(t.table && t.column){
                target += ' (' + t.table + ' / ' + t.column + ') ';
            }
        });
    }

    var slicerName = slicerState.displayName || 'Unnamed';
    var slicerLabel = $('<label>').text('Name: ' + slicerName);
    slicerContainer.append(slicerLabel);
    slicerContainer.append('<br/>');

    var slicerLabelT = $('<label>').text('Target: ' + target);
    slicerContainer.append(slicerLabelT);
    slicerContainer.append('<br/>');

    var input = document.createElement('input')
    input.id = 'slicer_' + index
    input.type="text"
    slicerContainer.append(input);
    input.setAttribute('value', slicerVal);

    slicerContainer.append('<br/></hr><br/>');
    slicerContainer.addClass('showBox');
}

function applyFilter(){
    var updatedSlicers = [];

    // Iterate through each slicer and collect the updated values
    console.log('visSlicerStateArr', visSlicerStateArr, visSlicerStateArr.length);
    $.each(visSlicerStateArr, function(index, slicerState) {
        // Get the updated values entered by the user
        var userInput = $('#slicer_' + index).val();
        var selectedValues = userInput.split(',').map(function(value) {
            return value.trim();  // Remove any leading/trailing spaces
        });

        if(selectedValues != ''){

            // Create a new slicer state with updated values
            var newSlicerState = {
                ...slicerState,
                filters: [{
                    ...slicerState.filters[0],
                    values: selectedValues  // Update with user-selected values
                }]
            };

            // Add to the updated slicer array
            updatedSlicers.push(newSlicerState);
        }
    });

    // Apply the updated slicers to the report
    if(updatedSlicers.length){
        applySlicers(updatedSlicers);
        slicerContainer.removeClass('showBox');
    }
}

function applySlicers(updatedSlicers) {
    $.each(updatedSlicers, function(index, slicerState) {
        visSlicerArr[index].setSlicerState(slicerState)
        .then(function() {
            console.log('Slicer updated:', slicerState.displayName);
        })
        .catch(function(err) {
            console.log('Error updating slicer:', err);
            console.log(updatedSlicers);
        });
    });
}
</script>

And the output looks like this:

enter image description here

Its working too, but I am confused with the Powerbi Slicers and Filters. As I checked in general language Slicers working on the user end while Filters are working on the server end.

Following are my questions, please help me to find out the right one:

  1. For my use case, which one is more useful: Slicers or Filters?
  2. Is there any Rest API available to get the Slicers and Filters of a report?
  3. How to get the Slicers name, is it available on Powerbi or possible to fetch, so user can identify easily?
  4. If there are no pre data selected in the filter box in the report, then the JavaScript object of Slicer is not same. Can I get the same object in any case if data is selected or not?

enter image description here

  1. If there are any Powerbi library or code sample to achieve same, please suggest me.

Thanks,



You need to sign in to view this answers

Leave feedback about this

  • Quality
  • Price
  • Service

PROS

+
Add Field

CONS

+
Add Field
Choose Image
Choose Video