Entrada de texto visual personalizada (búsqueda)

Un usuario Pregunto ✅

Silko

Hola,

Creé una imagen personalizada con una entrada de texto, que quería usar para una búsqueda a través de la segmentación. Para empezar, solo hice una búsqueda en la tabla. Funcionó perfectamente bien en las herramientas de desarrollo.

buscar.png

buscar1.png

Pero cuando lo importo a power bi desktop, no puedo usar la entrada. Parece que está deshabilitado o que los eventos del teclado no se están procesando.
escritorio.png
¿Porqué es eso?

Silko

En respuesta a Silko

Si alguien no lo vio, Microsoft ya creó una imagen personalizada con capacidad de búsqueda. Se llama Attribute Slicer. Lo puedes encontrar aquí:
https://app.powerbi.com/visuals/show/AttributeSlicer1652434005853

mike_honey

Este es un gran concepto, realmente me gustaría ayudar a que funcione. ¿Puedes compartir tu código hasta ahora? Github?

¿Ha intentado publicar ese archivo de PBI Desktop en el servicio web de PBI y probarlo allí?

Silko

En respuesta a mike_honey

Hola, gracias por tu repetición. Probé el servicio web también, pero es lo mismo.

Compartiré mi código aquí:

module powerbi.visuals {
    export interface CategoryViewModel {
        value: string;
        identity: string;
        color: string;
    }

    export interface ValueViewModel {
        values: any[];
    }

    export interface ViewModel {
        header: any;
        values: ValueViewModel[];
    }

    export class MySlicer implements IVisual {
        public static capabilities: VisualCapabilities = {
            // This is what will appear in the 'Field Wells' in reports
            dataRoles: [
                {
                    name: 'Category',
                    kind: powerbi.VisualDataRoleKind.Grouping,
                }
            ],
            // This tells power bi how to map your roles above into the dataview you will receive
            dataViewMappings: [{
                categorical: {
                    categories: {
                        for: { in: 'Category' },
                        dataReductionAlgorithm: { top: {} }
                    }
                }
            }],
            // Objects light up the formatting pane
            objects: {
                general: {
                    displayName: data.createDisplayNameGetter('Visual_General'),
                    properties: {
                        formatString: {
                            type: { formatting: { formatString: true } },
                        },
                    },
                },
            }
        };

        public static converter(dataView: DataView, colors: IDataColorPalette): ViewModel {
            var viewModel: ViewModel = {
                header: 'Default Header',
                values: []
            }
            if (dataView) {
                var data = dataView.categorical.categories;
                var metadata = dataView.metadata;
                
                viewModel.header = metadata.columns[0].displayName;
                if (data && data.length > 0) {
                    for (var i = 0, catLength = data[0].values.length; i < catLength; i++) {
                        viewModel.values.push(data[0].values[i]);
                    }
                }
            }

            return viewModel;
        }

        private hostContainer: JQuery;
        private table: D3.Selection;
        private tHead: D3.Selection;
        private tBody: D3.Selection;
        private colorPalette: IDataColorPalette;
        private searchInput: D3.Selection;
        private searchString: string;

        /** This is called once when the visual is initialially created */
        public init(options: VisualInitOptions): void {
            this.colorPalette = options.style.colorPalette.dataColors;
            // element is the element in which your visual will be hosted.
            this.hostContainer = options.element.css('overflow-x', 'hidden');
            this.searchInput = d3.select(options.element.get(0))
                .append("input")
                .classed("my-input", true)
                .attr("type", "text");
            this.table = d3.select(options.element.get(0))
                .append("table")
                .classed('powerbi-sample-table', true);

            this.tHead = this.table.append('thead').append('tr').append('th');
            this.tBody = this.table.append('tbody');
            
            var slicerVisual = this;
            this.searchInput.on("keyup", function () {
                var searchString = slicerVisual.searchString =  $(this).val().toLowerCase();
                slicerVisual.onSearchInput(slicerVisual, searchString);
            });
        }
        
        public onSearchInput(slicerVisual, searchString) {
            var tds = slicerVisual.hostContainer.find("tbody tr");
            tds.each(function() {
                var rowString = $(this).text().toLowerCase();
                if(!searchString || rowString.indexOf(searchString) > -1)
                    $(this).removeClass("hidden");
                else
                    $(this).addClass("hidden");
            })
        }

        /** Update is called for data updates, resizes & formatting changes */
        public update(options: VisualUpdateOptions) {
            var dataViews = options.dataViews;
            if (!dataViews) return;

            this.updateContainerViewports(options.viewport);

            var viewModel = MySlicer.converter(dataViews[0], this.colorPalette);
            var slicerTitle = this.tHead.text(viewModel.header);
            var slicerData = this.tBody;
            this.tBody.html("");
            for(var row in viewModel.values) {
                var rowString = viewModel.values[row] + "";
                rowString = rowString.toLowerCase();
                if(!this.searchString || rowString.indexOf(this.searchString) > -1)
                    slicerData.append('tr').append('td').text(viewModel.values[row]);
                else    
                    slicerData.append('tr').classed("hidden", true).append('td').text(viewModel.values[row]);
            }
        }

        private updateContainerViewports(viewport: IViewport) {
            var width = viewport.width;
            var height = viewport.height;

            this.tHead.classed('dynamic', width > 400);
            this.tBody.classed('dynamic', width > 400);

            this.hostContainer.css({
                'height': height,
                'width': width
            });
            this.table.attr('width', width);
        }
        
        private format(d: number){
            var prefix = d3.formatPrefix(d);
            return d3.round(prefix.scale(d),2) + ' ' +prefix.symbol
        }
    }
}

trinidad

En respuesta a Silko

Hola,

Estoy buscando ayuda y le solicito que me ayude con un problema. Me encontré con un problema al usar Search Text Slicer. Tengo valores de columna como Co01, C0101, Co0102. Co0101, Co0102 son ramas del Co01. Cuando doy entrada en la barra de búsqueda con «Co01», la venta total también incluye Co0101 y Co0102. Esto actúa más o menos como un operador LIKE (Co01%). ¿Cómo puedo usar la misma imagen o el mismo código para tomar solo Co01 y no incluir Co0101/Co0102?

PARA ser simple, buscar datos en la frase de búsqueda exacta y no actuar como la funcionalidad del operador LIKE

v-viig

En respuesta a trinidad

@trinathreddy ¿Estás hablando de la visualización personalizada del filtro de texto?

Ignat Vilesov,

Ingeniero de software

Imágenes personalizadas de Microsoft Power BI

pbicvsupport@microsoft.com

trinidad

En respuesta a v-viig

Hola V-Viig,

Gracias por la ayuda. Sí, se trata de Filtro de texto. La entrada escrita básicamente funciona como una funcionalidad de comodín %. Le pido que por favor sepa que el desarrollador, hay algunos casos en que las personas buscan la frase exacta.

El archivador inteligente de OKVIZ (https://okviz.com/smart-filter/) funciona exactamente igual que yo quiero. Pero el filtro de texto de búsqueda funciona mucho más rápido que el filtro inteligente. Esta funcionalidad sería un gran alivio para ver información rápida sobre cómo una cuenta particular de ventas anuales.

Para ser claro, a continuación está el problema:

Funcionalidad actual: toma lo que sea la entrada e intenta hacer coincidir los valores de la columna

Esperado: si ABC y AB son los valores, necesitamos ventas solo para AB. No debe incluir ABC también. Por favor, hágamelo saber si tiene alguna pregunta.

v-viig

En respuesta a trinidad

Gracias por la aclaración.

Esta solicitud de función se informará al desarrollador para que la tenga en cuenta en las próximas versiones.

Ignat Vilesov,

Ingeniero de software

Imágenes personalizadas de Microsoft Power BI

pbicvsupport@microsoft.com

Goofr

En respuesta a Silko

Hola,

¿Algún progreso en este tema?

Gracias,

Franco

v-viig

En respuesta a Goofr

¿Podría aclarar la versión de API que utiliza?

Ignat Vilésov,

Ingeniero de software

Imágenes personalizadas de Microsoft Power BI

pbicvsupport@microsoft.com

Silko

En respuesta a Silko

Si alguien no lo vio, Microsoft ya creó una imagen personalizada con capacidad de búsqueda. Se llama Attribute Slicer. Lo puedes encontrar aquí:
https://app.powerbi.com/visuals/show/AttributeSlicer1652434005853

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *