problemas de enumeración visual personalizada

Un usuario Pregunto ✅

joao_pires

Estoy desarrollando un visual personalizado para PowerBI. Tengo una pregunta . Después de investigar y la documentación no es muy detallada, no puedo insertar elementos en el dropbox de los objetos de capacidades, es decir, quiero tener las columnas de mi tabla dinámicamente en un objeto de propiedad como la tabla de la matriz.

zzzzz.jpg_ei.jpgnúmero.jpg

En respuesta a joao_pires

¿Está intentando agregar una propiedad dinámica para cada columna que se ha agregado a un objeto visual personalizado? Si es así, describiré lo que estoy usando para lograr ese resultado donde agrega los valores de su propiedad en la colección de objetos para una columna específica usando el DataViewMetadataColumn. A continuación, se muestra un ejemplo de un objeto visual personalizado de demostración denominado elegante tabla que produce una tabla personalizada donde he agregado tres columnas. Como puede ver, esta imagen personalizada le brinda al usuario la capacidad de configurar el formato en negrita en cada columna por separado.

El formato en negrita se puede habilitar / deshabilitar en cada columna por separadoEl formato en negrita se puede habilitar / deshabilitar en cada columna por separado

Me tomó un poco de tiempo descubrir cómo trabajar con objetos dinámicos, pero la clave es reconocer que muchos objetos en la API de objetos visuales de Power BI tienen los suyos propios. objetos colecciones para rastrear propiedades personalizadas. Por ejemplo, los metadatos de la columna denominada Los ingresos por ventas se conserva en la siguiente ruta.

CustomColumnPropertyMetadata.png

He aquí cómo recrear este efecto. Empiece en el capacidades.json archivo definiendo una propiedad tal como lo haría para una sola propiedad estática.

"objects": {
    "columnFormatting": {
      "displayName": "Bold Column Formatting",
      "properties": {
        "fontBold": {
          "displayName": "Font Bold",
          "type": { "bool": true }
        }
      }
    }
  }

A continuación, defina un método genérico para recuperar valores de propiedad de metadatos. Aquí está mi implementación genérica de getValue.

public getValue<T>(objects: DataViewObjects, objectName: string, propertyName: string, defaultValue: T): T {
  if (objects) {
    let object = objects[objectName];
    if (object) {
      let property: T = <T>object[propertyName];
      if (property !== undefined) {
        return property;
      }
    }
  }
  return defaultValue;
}

Ahora viene la parte complicada. Cuando implementas enumerateObjectInstance, debe utilizar un selector especial para los metadatos de columna que invoca la creación selector objeto con metadatos property para hacer referencia a la columna específica.

selector: { metadata: "YourColumnQueryNameHere" }

Aquí está la implementación completa de enumerateObjectInstance. En particular, verifique cómo recorre cada columna de metadatos y agrega una nueva propiedad con un selector que incluye el nombre de la consulta de la columna.

public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstanceEnumeration {
  let objectName = options.objectName;
  let objectEnumeration: VisualObjectInstance[] = [];

  var metadataColumns: DataViewMetadataColumn[] = this.dataView.metadata.columns;

  switch (objectName) {
    case 'columnFormatting':
      for (var i = 0; i < metadataColumns.length; i++) {
        var currentColumn: DataViewMetadataColumn = metadataColumns[i];
        objectEnumeration.push({
          objectName: objectName,
          displayName: currentColumn.displayName,
          properties: {
            fontBold: this.getValue<boolean>(currentColumn.objects, objectName, "fontBold", false)
          },
          selector: { metadata: currentColumn.queryName }
        });

      };
      break;
  }
  return objectEnumeration;
}

Eso es todo lo que se necesita para mostrar las propiedades en el panel Formato y hacer que estas propiedades sean editables para el usuario que diseña un informe. La última parte en realidad está haciendo algo diferente una vez que el usuario establece un valor de propiedad de columna. Yo manejo esto en el método de actualización consultando el valor de propiedad de columna y usando el resultado para determinar cuándo poner la celda en negrita o no.

if (this.getValue<boolean>(columns[columnIndex].objects, "columnFormatting", "fontBold", false)) {
  tableCell.css({ "font-weight": "bold" });
}

Aquí hay un enlace al código fuente de snazzyTable en un repositorio de GitHub.

https://github.com/CriticalPathTraining/CustomVisualsForPowerBI/tree/master/snazzyTable

@joao_pires,

Según mi investigación, puede usar dataViews en VisualUpdateOptions para hacerlo.

joao_pires

En respuesta a v-chuncz-msft

Hola @ v-chuncz-msft,

si, tengo datos de columnas de dataViews en VisualUpdateOptions, pero ¿cómo hacer un combo dinámico con estos valores?

Saludos

joão

En respuesta a joao_pires

¿Está intentando agregar una propiedad dinámica para cada columna que se ha agregado a un objeto visual personalizado? Si es así, describiré lo que estoy usando para lograr ese resultado donde agrega los valores de su propiedad en la colección de objetos para una columna específica usando el DataViewMetadataColumn. A continuación, se muestra un ejemplo de un objeto visual personalizado de demostración denominado elegante tabla que produce una tabla personalizada donde he agregado tres columnas. Como puede ver, esta imagen personalizada le brinda al usuario la capacidad de configurar el formato en negrita en cada columna por separado.

El formato en negrita se puede habilitar / deshabilitar en cada columna por separadoEl formato en negrita se puede habilitar / deshabilitar en cada columna por separado

Me tomó un poco de tiempo descubrir cómo trabajar con objetos dinámicos, pero la clave es reconocer que muchos objetos en la API de objetos visuales de Power BI tienen los suyos propios. objetos colecciones para rastrear propiedades personalizadas. Por ejemplo, los metadatos de la columna denominada Los ingresos por ventas se conserva en la siguiente ruta.

CustomColumnPropertyMetadata.png

He aquí cómo recrear este efecto. Empiece en el capacidades.json archivo definiendo una propiedad tal como lo haría para una sola propiedad estática.

"objects": {
    "columnFormatting": {
      "displayName": "Bold Column Formatting",
      "properties": {
        "fontBold": {
          "displayName": "Font Bold",
          "type": { "bool": true }
        }
      }
    }
  }

A continuación, defina un método genérico para recuperar valores de propiedad de metadatos. Aquí está mi implementación genérica de getValue.

public getValue<T>(objects: DataViewObjects, objectName: string, propertyName: string, defaultValue: T): T {
  if (objects) {
    let object = objects[objectName];
    if (object) {
      let property: T = <T>object[propertyName];
      if (property !== undefined) {
        return property;
      }
    }
  }
  return defaultValue;
}

Ahora viene la parte complicada. Cuando implementas enumerateObjectInstance, debe utilizar un selector especial para los metadatos de columna que invoca la creación selector objeto con metadatos property para hacer referencia a la columna específica.

selector: { metadata: "YourColumnQueryNameHere" }

Aquí está la implementación completa de enumerateObjectInstance. En particular, verifique cómo recorre cada columna de metadatos y agrega una nueva propiedad con un selector que incluye el nombre de la consulta de la columna.

public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstanceEnumeration {
  let objectName = options.objectName;
  let objectEnumeration: VisualObjectInstance[] = [];

  var metadataColumns: DataViewMetadataColumn[] = this.dataView.metadata.columns;

  switch (objectName) {
    case 'columnFormatting':
      for (var i = 0; i < metadataColumns.length; i++) {
        var currentColumn: DataViewMetadataColumn = metadataColumns[i];
        objectEnumeration.push({
          objectName: objectName,
          displayName: currentColumn.displayName,
          properties: {
            fontBold: this.getValue<boolean>(currentColumn.objects, objectName, "fontBold", false)
          },
          selector: { metadata: currentColumn.queryName }
        });

      };
      break;
  }
  return objectEnumeration;
}

Eso es todo lo que se necesita para mostrar las propiedades en el panel Formato y hacer que estas propiedades sean editables para el usuario que diseña un informe. La última parte es en realidad hacer algo diferente una vez que el usuario establece un valor de propiedad de columna. Yo manejo esto en el método de actualización consultando el valor de propiedad de columna y usando el resultado para determinar cuándo poner la celda en negrita o no.

if (this.getValue<boolean>(columns[columnIndex].objects, "columnFormatting", "fontBold", false)) {
  tableCell.css({ "font-weight": "bold" });
}

Aquí hay un enlace al código fuente de snazzyTable en un repositorio de GitHub.

https://github.com/CriticalPathTraining/CustomVisualsForPowerBI/tree/master/snazzyTable

joao_pires

En respuesta a TedPattison

Hola @TedPattison,

Gracias por el largo post, pero fue muy útil, el truco estaba en el

selector: { metadata: "YourColumnQueryNameHere" }

y

displayName: currentColumn.displayName,

Muchas gracias

Saludos

João

Anónimo

En respuesta a joao_pires

hola @joao_pires, ¿y cómo agregas datos dinámicos al cuadro combinado?

Intento todos los pasos anteriores y mi cuadro combinado todavía muestra los datos estáticos del archivo de capacidad

este es mi visual.ts

visual.ts.01.PNG

y este es el registro de la consola de mi navegadorlog.ts.01.PNG

joao_pires

En respuesta a Anónimo

hola @Anónimo,

cuando dev mi visual personalizado, esta opción no es posible.

Hago un cuadro combinado dinámico en CV en CSS.

la esperanza es ayudarte.

Anónimo

En respuesta a joao_pires

gracias @joao_pires y @TedPattison

finalmente creo un selector de color dinámico tanto como los valores de los campos seleccionados, y trazo en la vista de datos usando metadatos del selector.

Deja un comentario

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