Forum Discussion
custom table visual
- 6 years ago
Hi sheetalshettiga - it's a lot more helpful if you can paste your code as text rather than as a screengrab so that it's easier to copy into my dev environment 🙂
Looks like you're using d3, so you can refer to the event handling documentation for more details, but there's not a lot of resource on how to do this, as it's not a common use case for d3 (particularly with TypeScript), so I've had to figure some of it out.
Here's some working code with a single text element and a <p> element that proves we can update the value once we tab out of the box (so you will need to adapt to your code):
This will fire once the elment is tabbed out of, so you might need to adapt for a different event type - but it will grab the element you typed into, get the value and pass it to the percent function (which I just stubbed out to display the message with the number interpolated; it would take me too long to manually type in your function code and I don't have your DOM anyway so it wouldn't work as intended).
For reference, here's my code - I just created a blank visual and worked from there:
/** 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); } }If you need further assistance, this is more of a web development question rather than custom visuals specifically, so you might get more readily available assistance (and better than mine) on a wider forum more geared towards JavaScript and TypeScript in general, but I'm hoping that this may get you moving, and thanks for the question - it's not something I'd tried before 🙂
Good luck!
Daniel
Thank you for the respose dm-p
I am creating text box as below how can i add event to this.
My table is getting reflected only when i resize it.
Hi sheetalshettiga - it's a lot more helpful if you can paste your code as text rather than as a screengrab so that it's easier to copy into my dev environment 🙂
Looks like you're using d3, so you can refer to the event handling documentation for more details, but there's not a lot of resource on how to do this, as it's not a common use case for d3 (particularly with TypeScript), so I've had to figure some of it out.
Here's some working code with a single text element and a <p> element that proves we can update the value once we tab out of the box (so you will need to adapt to your code):
This will fire once the elment is tabbed out of, so you might need to adapt for a different event type - but it will grab the element you typed into, get the value and pass it to the percent function (which I just stubbed out to display the message with the number interpolated; it would take me too long to manually type in your function code and I don't have your DOM anyway so it wouldn't work as intended).
For reference, here's my code - I just created a blank visual and worked from there:
/** 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);
}
}
If you need further assistance, this is more of a web development question rather than custom visuals specifically, so you might get more readily available assistance (and better than mine) on a wider forum more geared towards JavaScript and TypeScript in general, but I'm hoping that this may get you moving, and thanks for the question - it's not something I'd tried before 🙂
Good luck!
Daniel
- sheetalshettiga6 years agoHelper IV
Thank you dm-p you took time to solve my problem.
I was not known how to use keyEvent.The explanation and example you provided helped me understanding it better.Thank you for solving it.