Forum Discussion

Anonymous's avatar
Anonymous
Not applicable
6 years ago
Solved

pbiviz package Error

I am trying to add tooltip to my R visual. I tried following some tutorials such as

https://radacad.com/interactive-map-using-r-and-power-bi-create-custom-visual-part-1

https://towardsdatascience.com/custom-html-visuals-in-power-bi-using-r-2b0494894ff

 

But when I tried 'pbiviz package' in node, I got the following error message. It took me many days but I am still able to find a solution.

 

 

  • Anonymous's avatar
    Anonymous
    6 years ago

    So I got an answer from Microsoft support team. We need to replace NodeListOf with HTMLCollectionOf in visual.ts.

20 Replies

  • Anonymous's avatar
    Anonymous
    Not applicable

    And it happens even when I do not change anything in the script r file. I've also attached my visual.ts code.

     

    /*
    * Power BI Visual CLI
    *
    * Copyright (c) Microsoft Corporation
    * All rights reserved.
    * MIT License
    *
    * Permission is hereby granted, free of charge, to any person obtaining a copy
    * of this software and associated documentation files (the ""Software""), to deal
    * in the Software without restriction, including without limitation the rights
    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    * copies of the Software, and to permit persons to whom the Software is
    * furnished to do so, subject to the following conditions:
    *
    * The above copyright notice and this permission notice shall be included in
    * all copies or substantial portions of the Software.
    *
    * THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    * THE SOFTWARE.
    */
    "use strict";
    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 IViewport = powerbi.IViewport;
    import VisualObjectInstanceEnumerationObject = powerbi.VisualObjectInstanceEnumerationObject;

    import { VisualSettings } from "./settings";
    import { ParseElement, ResetInjector, RunHTMLWidgetRenderer } from "./htmlInjectionUtility";

    enum VisualUpdateType {
    Data = 2,
    Resize = 4,
    ViewMode = 8,
    Style = 16,
    ResizeEnd = 32,
    All = 62,
    }

    // below is a snippet of a definition for an object which will contain the property values
    // selected by the users
    /*interface VisualSettings {
    lineColor: string;
    }*/

    // to allow this scenario you should first the following JSON definition to the capabilities.json file
    // under the "objects" property:
    // "settings": {
    // "displayName": "Visual Settings",
    // "description": "Visual Settings Tooltip",
    // "properties": {
    // "lineColor": {
    // "displayName": "Line Color",
    // "type": { "fill": { "solid": { "color": true }}}
    // }
    // }
    // }

    // in order to improve the performance, one can update the <head> only in the initial rendering.
    // set to 'true' if you are using different packages to create the widgets
    const updateHTMLHead: boolean = false;
    const renderVisualUpdateType: number[] = [
    VisualUpdateType.Resize,
    VisualUpdateType.ResizeEnd,
    VisualUpdateType.Resize + VisualUpdateType.ResizeEnd
    ];

    export class Visual implements IVisual {
    private rootElement: HTMLElement;
    private headNodes: Node[];
    private bodyNodes: Node[];
    private settings: VisualSettings;

    public constructor(options: VisualConstructorOptions) {
    if (options && options.element) {
    this.rootElement = options.element;
    }
    this.headNodes = [];
    this.bodyNodes = [];
    }

    public update(options: VisualUpdateOptions): void {

    if (!options ||
    !options.type ||
    !options.viewport ||
    !options.dataViews ||
    options.dataViews.length === 0 ||
    !options.dataViews[0]) {
    return;
    }
    const dataView: DataView = options.dataViews[0];
    this.settings = Visual.parseSettings(dataView);

    let payloadBase64: string = null;
    if (dataView.scriptResult && dataView.scriptResult.payloadBase64) {
    payloadBase64 = dataView.scriptResult.payloadBase64;
    }

    if (renderVisualUpdateType.indexOf(options.type) === -1) {
    if (payloadBase64) {
    this.injectCodeFromPayload(payloadBase64);
    }
    } else {
    this.onResizing(options.viewport);
    }
    }

    public onResizing(finalViewport: IViewport): void {
    /* add code to handle resizing of the view port */
    }

    private injectCodeFromPayload(payloadBase64: string): void {
    // inject HTML from payload, created in R
    // the code is injected to the 'head' and 'body' sections.
    // if the visual was already rendered, the previous DOM elements are cleared

    ResetInjector();

    if (!payloadBase64) {
    return;
    }

    // create 'virtual' HTML, so parsing is easier
    let el: HTMLHtmlElement = document.createElement("html");
    try {
    el.innerHTML = window.atob(payloadBase64);
    } catch (err) {
    return;
    }

    // if 'updateHTMLHead == false', then the code updates the header data only on the 1st rendering
    // this option allows loading and parsing of large and recurring scripts only once.
    if (updateHTMLHead || this.headNodes.length === 0) {
    while (this.headNodes.length > 0) {
    let tempNode: Node = this.headNodes.pop();
    document.head.removeChild(tempNode);
    }
    let headList: NodeListOf<HTMLHeadElement> = el.getElementsByTagName("head");
    if (headList && headList.length > 0) {
    let head: HTMLHeadElement = headList[0];
    this.headNodes = ParseElement(head, document.head);
    }
    }

    // update 'body' nodes, under the rootElement
    while (this.bodyNodes.length > 0) {
    let tempNode: Node = this.bodyNodes.pop();
    this.rootElement.removeChild(tempNode);
    }
    let bodyList: NodeListOf<HTMLBodyElement> = el.getElementsByTagName("body");
    if (bodyList && bodyList.length > 0) {
    let body: HTMLBodyElement = bodyList[0];
    this.bodyNodes = ParseElement(body, this.rootElement);
    }

    RunHTMLWidgetRenderer();
    }

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

    /**
    * 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);
    }
    }

    • Anonymous's avatar
      Anonymous
      Not applicable

      So I got an answer from Microsoft support team. We need to replace NodeListOf with HTMLCollectionOf in visual.ts.

  • Anonymous's avatar
    Anonymous
    Not applicable

    Anonymous 

    Hello, I got the same error as yours but  I didn't see any change from your code of changing NodeListOf to HTMLCollectionOf, could you please teach me how to do it?

     

    Thanks.

  • Anonymous's avatar
    Anonymous
    Not applicable

    dm-p  Anonymous  Anonymous Hello, I would like to ask you to please help me with this error, as I understand it has to do with the visualPlugin.ts, can you help me fix it. Thank you very much.

     

     
    • dm-p's avatar
      dm-p
      Super User
      Hi Anonymous - this appears to be an issue recently introduced into babel which is one of the dependencies the SDK relies on. None of my visuals will currently build either 😞

      I'll try to put together a bug report for the custom visuals team. Will come back if I can find a workaround.
      • Anonymous's avatar
        Anonymous
        Not applicable

        Thank you, I recommend it because I have been looking for an answer for two days and not a survey. Thank you so much