imagen de tabla personalizada

Un usuario Pregunto ✅

laminasalshettiga

Hola,

Estoy creando una imagen personalizada como se muestra a continuación,

imagen.PNG

En la columna de entrada doy algunos números y calcula el porcentaje como Totalsalescost/Input

Pero en la columna de porcentaje, el resultado se refleja solo cuando aumento o disminuyo el tamaño de la tabla creada. ¿Cómo puedo resolver esto para que la columna de porcentaje se refleje tan pronto como ingrese el valor de entrada?

Este es el fragmento que usé

img1.PNG

Por favor, ayúdame con esto

dm-p

En respuesta a laminasalshettiga

Hola, @sheetalshettiga: es mucho más útil si puede pegar su código como texto en lugar de como una captura de pantalla para que sea más fácil copiarlo en mi entorno de desarrollo. 🙂

Parece que está usando d3, por lo que puede consultar la documentación de manejo de eventos para obtener más detalles, pero no hay muchos recursos sobre cómo hacer esto, ya que no es un caso de uso común para d3 (particularmente con TypeScript), entonces He tenido que averiguar algo de eso.

Aquí hay un código de trabajo con un solo elemento de texto y un

elemento que prueba que podemos actualizar el valor una vez que salgamos de la caja (por lo que deberá adaptarse a su código):

tipo.gif

Esto se activará una vez que se elimine el elemento, por lo que es posible que deba adaptarse a un tipo de evento diferente, pero tomará el elemento en el que escribió, obtendrá el valor y lo pasará a la función de porcentaje (que acabo de apagar para mostrar el mensaje con el número interpolado; me llevaría demasiado tiempo escribir manualmente su código de función y no tengo su DOM de todos modos, por lo que no funcionaría según lo previsto).

Como referencia, aquí está mi código: acabo de crear una imagen en blanco y trabajé desde allí:

/** Visual.ts */
"use strict";

import "core-js/stable";
import "./../style/visual.less";
import powerbi from "powerbi-visuals-api";
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
import IVisual = powerbi.extensibility.visual.IVisual;
import EnumerateVisualObjectInstancesOptions = powerbi.EnumerateVisualObjectInstancesOptions;
import VisualObjectInstance = powerbi.VisualObjectInstance;
import DataView = powerbi.DataView;
import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject;
import * as d3 from 'd3';

import { VisualSettings } from "./settings";
export class Visual implements IVisual {
    private target: HTMLElement;
    private settings: VisualSettings;

    constructor(options: VisualConstructorOptions) {
        console.log('Visual constructor', options);
        this.target = options.element;
    }

    public update(options: VisualUpdateOptions) {
        this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]);
        console.log('Visual update', options);

        /** This is just a quick PoC */
            const container = d3.select(this.target);
            container.selectAll('*').remove();
            
            /** Simple test element to add output to */
            const display = container
                .append('p')
                .attr('id', 'myReplacedValue')
                .text('Initial');
            
            /** input with initial value */
            const inp = container
                .append('input')
                    .attr('type', 'text')
                    .attr('value', 0)
                    /** I'm doing as a fat arrow function so that 'this' is still the visual class */
                    .on('change', () => {
                        const
                            keyEvent: KeyboardEvent = <KeyboardEvent>d3.event,
                            eventTarget: EventTarget = keyEvent.target,
                            value = d3.select(<HTMLInputElement>eventTarget).node().value;
                        this.percent(Number.parseFloat(value));
                    });
    }

    private percent(n: number) {
        /** 
         *  This is a stub, to prove we can get and use the number from the box
         */
         d3.select('#myReplacedValue')
            .text(`The entered percentage was ${n}.`);
    }

    private static parseSettings(dataView: DataView): VisualSettings {
        return <VisualSettings>VisualSettings.parse(dataView);
    }

    /**
     * This function gets called for each of the objects defined in the capabilities files and allows you to select which of the
     * objects and properties you want to expose to the users in the property pane.
     *
     */
    public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
        return VisualSettings.enumerateObjectInstances(this.settings || VisualSettings.getDefault(), options);
    }
}

Si necesita más ayuda, esta es más una pregunta de desarrollo web en lugar de imágenes personalizadas específicamente, por lo que puede obtener asistencia disponible más fácilmente (y mejor que la mía) en un foro más amplio más orientado a JavaScript y TypeScript en general, pero yo Espero que esto pueda hacer que te muevas y gracias por la pregunta. No es algo que haya intentado antes. 🙂

¡Buena suerte!

Daniel

laminasalshettiga

@dm-p

Como adjunté la captura de pantalla de la tabla visual personalizada en la primera publicación que creé, obtengo un valor predeterminado para el porcentaje de columna como infinito. ¿Puede verificar esto ya que el valor debe ser cero o vacío y luego, según la entrada, debería cambiar?

a continuación se muestra el fragmento que utilicé para agregar valor de celda a cada fila

dejar filas = esta.cuerpo.seleccionar todo(«tr»)
.datos(verModelo.puntos de datos)
.ingresar()
.adjuntar(«tr»)
.atributo(«identificación», identificación + 1);
dejar id2: número = 0;
dejar células = filas.seleccionar todo(«td»)
.datos(función (hilera) {
regreso columnas.mapa(función (columna) {
regreso {
columna: columna,
valor: hilera[column]
}
})
})
.ingresar()
.adjuntar(«td»)
.atributo(«identificación», id2 + 1)
.estilo(«texto alineado», «centrar»)
.estilo(«alineación vertical», «medio»)
.texto(función (D, I) {
regreso D.valor;
});

dm-p

En respuesta a laminasalshettiga

Hola @sheetalshettiga,

Gracias por publicar esto, pero solo ver un pequeño fragmento crea los siguientes desafíos para mí:

  • Puedo ver que está enlazando sus datos de su verModelo, pero no puedo ver cómo se mapea esto en primer lugar, por lo que está accediendo a propiedades de las que yo (como lector) no sé nada
  • Entonces estás tratando de iterar a través de una variable llamada columnas pero la declaración de esto no está en su fragmento, por lo que no puedo saber su estructura o cómo se ensambla en primer lugar
  • No veo nada en el código que sea un cálculo de porcentaje, o llama a un método que calcula un porcentaje, por lo que el problema podría estar en otro lugar que no esté en el código proporcionado.

Como tal, realmente no puedo saber qué está haciendo el resto de su código. Por ejemplo, no creo que realmente necesites usar el .datos() funcionar dos veces, ya que los datos ya deberían estar vinculados a sus filas la primera vez y como td elemento es un hijo del tr, puede acceder al dato de ese elemento sin tener que volver a enlazarlo. Esto puede o no causarle problemas, pero de cualquier manera complicará su código y hará que sea más difícil de depurar.

Si puede proporcionar todo su visual.ts y tu capacidades.json de alguna manera, para poder replicar su visual localmente, echaré un vistazo a su código y veré si puedo hacerle alguna recomendación, pero como anticipo, me llevará un par de horas de trabajo, todo lo que pueda para para ayudar a encontrarme a mitad de camino sería agradecido.

Considero que GitHub Gists es una buena manera de compartir código si no está utilizando el control total de la fuente, ya que puede consolidar uno o más archivos en una sola ubicación y hacerlo privado si es necesario. Si desea hacer algo como esto y enviarme un mensaje privado con el enlace si no desea hacerlo público, entonces puedo extraer el código, intentar replicar el problema y buscarlo.

Gracias,

Daniel

laminasalshettiga

En respuesta a dm-p

Gracias por la respuesta. He encontrado que el problema estaba en el cálculo del porcentaje.

dm-p

En respuesta a laminasalshettiga

Sí, acabo de ver tu publicación original en mi feed de correo electrónico y pensé que sería un problema de división por cero. Me alegro de que estés resuelto 🙂

dm-p

Hola @sheetalshettiga,

Como los cuadros de texto son simplemente elementos simples, no tendrán manejo de eventos o lógica a menos que conecte algo; como mínimo, esto sería algo así como agregar un controlador para el evento de cambio. Este evento tendría que llamar a su por ciento funcionar en consecuencia. El artículo vinculado tiene un ejemplo para un elemento de texto.

Deberá aplicar recursivamente este evento a cada elemento de texto en la tabla, por lo que las personas generalmente pueden administrar esto usando un marco como jQuery para eliminar el dolor de administrar esto con JS / TS sin formato: aquí hay una solución de ejemplo de Stack Overflow que aconseja cómo hacer esto.

Tenga en cuenta que si no está redibujando el DOM visual en los eventos de actualización, deberá asegurarse de no vincular el mismo evento varias veces al mismo elemento, ya que esto activará múltiples eventos. llama cada vez que el valor cambia en un cuadro en particular. Si está volviendo a dibujar los elementos cada vez que se actualiza la imagen, entonces debería estar bien.

¡Buena suerte!

Daniel

laminasalshettiga

En respuesta a dm-p

Gracias por la respuesta @dm-p

Estoy creando un cuadro de texto como se muestra a continuación, ¿cómo puedo agregar un evento a esto?

Mi tabla se refleja solo cuando la cambio de tamaño.

img2.PNG

dm-p

En respuesta a laminasalshettiga

Hola, @sheetalshettiga: es mucho más útil si puede pegar su código como texto en lugar de como una captura de pantalla para que sea más fácil copiarlo en mi entorno de desarrollo. 🙂

Parece que está usando d3, por lo que puede consultar la documentación de manejo de eventos para obtener más detalles, pero no hay muchos recursos sobre cómo hacer esto, ya que no es un caso de uso común para d3 (particularmente con TypeScript), entonces He tenido que averiguar algo de eso.

Aquí hay un código de trabajo con un solo elemento de texto y un

elemento que prueba que podemos actualizar el valor una vez que salgamos de la caja (por lo que deberá adaptarse a su código):

tipo.gif

Esto se activará una vez que se elimine el elemento, por lo que es posible que deba adaptarse a un tipo de evento diferente, pero tomará el elemento en el que escribió, obtendrá el valor y lo pasará a la función de porcentaje (que acabo de apagar para mostrar el mensaje con el número interpolado; me llevaría demasiado tiempo escribir manualmente su código de función y no tengo su DOM de todos modos, por lo que no funcionaría según lo previsto).

Como referencia, aquí está mi código: acabo de crear una imagen en blanco y trabajé desde allí:

/** Visual.ts */
"use strict";

import "core-js/stable";
import "./../style/visual.less";
import powerbi from "powerbi-visuals-api";
import VisualConstructorOptions = powerbi.extensibility.visual.VisualConstructorOptions;
import VisualUpdateOptions = powerbi.extensibility.visual.VisualUpdateOptions;
import IVisual = powerbi.extensibility.visual.IVisual;
import EnumerateVisualObjectInstancesOptions = powerbi.EnumerateVisualObjectInstancesOptions;
import VisualObjectInstance = powerbi.VisualObjectInstance;
import DataView = powerbi.DataView;
import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject;
import * as d3 from 'd3';

import { VisualSettings } from "./settings";
export class Visual implements IVisual {
    private target: HTMLElement;
    private settings: VisualSettings;

    constructor(options: VisualConstructorOptions) {
        console.log('Visual constructor', options);
        this.target = options.element;
    }

    public update(options: VisualUpdateOptions) {
        this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]);
        console.log('Visual update', options);

        /** This is just a quick PoC */
            const container = d3.select(this.target);
            container.selectAll('*').remove();
            
            /** Simple test element to add output to */
            const display = container
                .append('p')
                .attr('id', 'myReplacedValue')
                .text('Initial');
            
            /** input with initial value */
            const inp = container
                .append('input')
                    .attr('type', 'text')
                    .attr('value', 0)
                    /** I'm doing as a fat arrow function so that 'this' is still the visual class */
                    .on('change', () => {
                        const
                            keyEvent: KeyboardEvent = <KeyboardEvent>d3.event,
                            eventTarget: EventTarget = keyEvent.target,
                            value = d3.select(<HTMLInputElement>eventTarget).node().value;
                        this.percent(Number.parseFloat(value));
                    });
    }

    private percent(n: number) {
        /** 
         *  This is a stub, to prove we can get and use the number from the box
         */
         d3.select('#myReplacedValue')
            .text(`The entered percentage was ${n}.`);
    }

    private static parseSettings(dataView: DataView): VisualSettings {
        return <VisualSettings>VisualSettings.parse(dataView);
    }

    /**
     * This function gets called for each of the objects defined in the capabilities files and allows you to select which of the
     * objects and properties you want to expose to the users in the property pane.
     *
     */
    public enumerateObjectInstances(options: EnumerateVisualObjectInstancesOptions): VisualObjectInstance[] | VisualObjectInstanceEnumerationObject {
        return VisualSettings.enumerateObjectInstances(this.settings || VisualSettings.getDefault(), options);
    }
}

Si necesita más ayuda, esta es más una pregunta de desarrollo web en lugar de imágenes personalizadas específicamente, por lo que puede obtener asistencia disponible más fácilmente (y mejor que la mía) en un foro más amplio más orientado a JavaScript y TypeScript en general, pero yo Espero que esto pueda hacer que te muevas y gracias por la pregunta. No es algo que haya intentado antes. 🙂

¡Buena suerte!

Daniel

laminasalshettiga

En respuesta a dm-p

Gracias @dm-p, te tomaste el tiempo para resolver mi problema.

No sabía cómo usar keyEvent. La explicación y el ejemplo que proporcionaste me ayudaron a entenderlo mejor. Gracias por resolverlo.

Deja un comentario

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