Starting December 3, join live sessions with database experts and the Microsoft product team to learn just how easy it is to get started
Learn moreGet certified in Microsoft Fabric—for free! For a limited time, get a free DP-600 exam voucher to use by the end of 2024. Register now
Hello,
For my other js dependencies I need d3.v4.
I tried to install newest version (npm ) and types.
But as I try to create svg element for d3.Selection I get the following error: error TYPESCRIPT /src/visual.ts : (34,22) Generic type 'Selection<GElement, Datum, PElement, PDatum>' requires 4 type argument(s).
I tried to follow the instruction in this post: https://community.powerbi.com/t5/Developer/Setting-up-D3-V4-with-Custom-Visuals-and-Types/m-p/330101... but it did not seem to help.
How can I get it work?
Many thanks in advance !!!
Solved! Go to Solution.
Hi @Anonymous,
Could you please share all of files including package.json, pbiviz.json, and other files?
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
I'm currently trying to change
d3.Selection<SVGElement,any,any,any> is supposed to work well.
Please resolve other issues to make sure everything is working well.
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
Well it works. Kind of...
I've followed the steps in https://microsoft.github.io/PowerBI-visuals/docs/how-to-guide/migrating-to-powerbi-visuals-tools-3-0..., with the extra note:
npm install powerbi-visuals-tools@beta -g
I was unable to just upgrade my project, so I started a new one, and move in the functions one by one. Some work, some don't. I'm now trying to get the circlecard to work. It compiles and runs, but it only shows the lower half of the circle.
Here is the semi-working code:
"use strict"; import "@babel/polyfill"; 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; //default: //private updateCount: number; //private textNode: Text; //circlecard: private svg: d3.Selection<SVGElement,any,any,any>; private container: d3.Selection<SVGElement,any,any,any>; private circle: d3.Selection<SVGElement,any,any,any>; private textValue: d3.Selection<SVGElement,any,any,any>; private textLabel: d3.Selection<SVGElement,any,any,any>; constructor(options: VisualConstructorOptions) { //default: //console.log('Visual constructor', options); //this.target = options.element; //this.updateCount = 0; //if (typeof document !== "undefined") { // const new_p: HTMLElement = document.createElement("p"); // new_p.appendChild(document.createTextNode("Update count:")); // const new_em: HTMLElement = document.createElement("em"); // this.textNode = document.createTextNode(this.updateCount.toString()); // new_em.appendChild(this.textNode); // new_p.appendChild(new_em); // this.target.appendChild(new_p); //} //circlecard: this.target = options.element; const new_p: HTMLElement = document.createElement("p"); this.target.appendChild(new_p); this.svg = d3.select(new_p) .append('svg') .classed('circleCard', true); this.container = this.svg.append("g") .classed('container', true); this.circle = this.container.append("circle") .classed('circle', true); this.textValue = this.container.append("text") .classed("textValue", true); this.textLabel = this.container.append("text") .classed("textLabel", true); } public update(options: VisualUpdateOptions) { //default: //this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]); //console.log('Visual update', options); //if (typeof this.textNode !== "undefined") { // this.textNode.textContent = (this.updateCount++).toString(); //} //circlecard: let width: number = options.viewport.width; let height: number = options.viewport.height; this.svg.attr("width", width) .attr("height", "height"); let radius: number = Math.min(width, height) / 2.2; this.circle .style("fill", "white") .style("fill-opacity", 0.5) .style("stroke", "black") .style("stroke-width", 2) .attr("r", radius) .attr("cx", width / 2) .attr("cy:", height / 2); let fontSizeValue: number = Math.min(width, height) / 5; this.textValue .text("Value") .attr("x", "50%") .attr("y", "50%") .attr("dy", "0.35em") .attr("text-anchor", "middle") .style("font-size", fontSizeValue + "px"); let fontSizeLabel: number = fontSizeValue / 4; this.textLabel .text("Label") .attr("x", "50%") .attr("y", height / 2) .attr("dy", fontSizeValue / 1.2) .attr("text-anchor", "middle") .style("font-size", fontSizeLabel + "px"); } }
Ok, it works. There was a small bug (a colon where there shouldn't be one).
So just use d3.Selection<SVGElement,any,any,any> and it should work fine.
"use strict"; import "@babel/polyfill"; 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; //default: //private updateCount: number; //private textNode: Text; //circlecard: private svg: d3.Selection<SVGElement,any,any,any>; private container: d3.Selection<SVGElement,any,any,any>; private circle: d3.Selection<SVGElement,any,any,any>; private textValue: d3.Selection<SVGElement,any,any,any>; private textLabel: d3.Selection<SVGElement,any,any,any>; constructor(options: VisualConstructorOptions) { //default: //console.log('Visual constructor', options); //this.target = options.element; //this.updateCount = 0; //if (typeof document !== "undefined") { // const new_p: HTMLElement = document.createElement("p"); // new_p.appendChild(document.createTextNode("Update count:")); // const new_em: HTMLElement = document.createElement("em"); // this.textNode = document.createTextNode(this.updateCount.toString()); // new_em.appendChild(this.textNode); // new_p.appendChild(new_em); // this.target.appendChild(new_p); //} //circlecard: this.target = options.element; const new_p: HTMLElement = document.createElement("p"); this.target.appendChild(new_p); this.svg = d3.select(new_p) .append('svg') .classed('circleCard', true); this.container = this.svg.append("g") .classed('container', true); this.circle = this.container.append("circle") .classed('circle', true); this.textValue = this.container.append("text") .classed("textValue", true); this.textLabel = this.container.append("text") .classed("textLabel", true); } public update(options: VisualUpdateOptions) { //default: //this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]); //console.log('Visual update', options); //if (typeof this.textNode !== "undefined") { // this.textNode.textContent = (this.updateCount++).toString(); //} //circlecard: let width: number = options.viewport.width; let height: number = options.viewport.height; this.svg.attr("width", width) .attr("height", "height"); let radius: number = Math.min(width, height) / 2.2; this.circle .style("fill", "white") .style("fill-opacity", 0.5) .style("stroke", "black") .style("stroke-width", 2) .attr("r", radius) .attr("cx", width / 2) .attr("cy", height / 2); let fontSizeValue: number = Math.min(width, height) / 5; this.textValue .text("Value") .attr("x", "50%") .attr("y", "50%") .attr("dy", "0.35em") .attr("text-anchor", "middle") .style("font-size", fontSizeValue + "px"); let fontSizeLabel: number = fontSizeValue / 4; this.textLabel .text("Label") .attr("x", "50%") .attr("y", height / 2) .attr("dy", fontSizeValue / 1.2) .attr("text-anchor", "middle") .style("font-size", fontSizeLabel + "px"); } }
I did find the solution for the part of the problem.
module powerbi.extensibility.visual { "use strict"; export class Visual implements IVisual { private target: HTMLElement; private updateCount: number; private settings: VisualSettings; private textNode: Text; private svg: d3.Selection<d3.BaseType, any, HTMLElement, any>; constructor(options: VisualConstructorOptions) { console.log('Visual constructor', options); this.target = options.element; this.svg = d3.select<SVGElement, any>(options.element as any) .append('svg') .classed('graph', true); } public update(options: VisualUpdateOptions) { this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]); // Set up an SVG group so that we can translate the final graph. let svg = d3.select("svg"); let inner = svg.append("g"); // Create a new directed graph var g = new dagreD3.graphlib.Graph(); g.setGraph({}); // Fill node "A" with the color green g.setNode("A", { style: "fill: #afa" }); // Create the renderer var render = new dagreD3.render(); // Run the renderer. This is what draws the final graph. //render(inner, g); // inner.call(render,g); render(inner, g); }
I put the
What arguments the render accepts? Can you sahre the whole source code?
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
Hi v-viig,
Thank you for your answer. What I am trying to do is rendering Dagre Graph with D3 (actually Dagre-D3). Inside of Javascript I have no problems with rendering at all. I tried it with D3.V3 but it does not render my graph and I do not get any errros. So I thought I would give it a try in D3.V4. I have following dependencies in my pbiviz.json:
"externalJS": [ "node_modules/powerbi-visuals-utils-dataviewutils/lib/index.js", "node_modules/d3/build/d3.min.js", "node_modules/graphlib/dist/graphlib.core.js", "node_modules/dagre/dist/dagre.core.js", "node_modules/dagre-d3/dist/dagre-d3.min.js" ],
I did npm install and @types install for all the files (newest version). My visuals.ts looks as follows:
/* * 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. */ module powerbi.extensibility.visual { "use strict"; export class Visual implements IVisual { private target: HTMLElement; private updateCount: number; private settings: VisualSettings; private textNode: Text; private svg: d3.Selection<d3.BaseType, any, HTMLElement, any>; constructor(options: VisualConstructorOptions) { console.log('Visual constructor', options); this.target = options.element; this.svg = d3.select<SVGElement, any>(options.element as any) .append('svg') .classed('graph', true); } public update(options: VisualUpdateOptions) { this.settings = Visual.parseSettings(options && options.dataViews && options.dataViews[0]); // Set up an SVG group so that we can translate the final graph. let svg = d3.select("svg"); let inner = svg.append("g"); // Create a new directed graph var g = new dagreD3.graphlib.Graph(); g.setGraph({}); // Fill node "A" with the color green g.setNode("A", { style: "fill: #afa" }); // Create the renderer var render = new dagreD3.render(); // Run the renderer. This is what draws the final graph. render(inner, g); } 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); } } }
The error message that I get: [ts]
Das Argument vom Typ "Render" kann dem Parameter vom Typ "(selection: Selection<BaseType, {}, HTMLElement, any>, ...args: any[]) => void" nicht zugewiesen werden.
Die Typen der Parameter "selection" und "selection" sind nicht kompatibel.
Der Typ "Selection<BaseType, {}, HTMLElement, any>" kann dem Typ "Selection<any>" nicht zugewiesen werden.
Die Eigenschaft "length" fehlt im Typ "Selection<BaseType, {}, HTMLElement, any>".
So it should some kind of length parameter haben. But I do not see where should it come from.
Can you help me further with that ? I could send you the whole package but the forum does not seem to be the right place.
Best regargs,
feelfine
Hi @Anonymous,
Could you please share all of files including package.json, pbiviz.json, and other files?
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
We have not received whole source code to investigate this issue yet.
If you have similar issues please send us source code for investigating.
If you found a solution please post it here.
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
Hi @v-viig, Thanks for your reply.
I have worked on d3 but this is the first time, I am trying dagre-d3. In Angular 5 application, I was exploring with arrows.html (we can take any other html) sample provided in https://github.com/dagrejs/dagre-d3/tree/master/demo.
On render method, i.e. render(inner, g); I am getting the same error mentioned above by @Anonymous.
i.e.
Argument of type 'Selection<BaseType, {}, HTMLElement, any>' is not assignable to parameter of type 'Selection<any>'.
Property 'length' is missing in type 'Selection<BaseType, {}, HTMLElement, any>'.
I have installed 5.5.0 version of d3 and 0.6.1 version dagre-d3. The same error I am getting on React application. Not sure if there is any breaking change in dagre-d3 version.
These issues come from TypeScript. Could you please share what type definitions you installed?
Can you share source code to check it from our end?
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
hi @v-viig
You are right, even I found the same thing yesterday, the type defination was causing the issue. Any version of 4 or 5 of @types/d3 has different signature of d3 select method than that of what dagre-d3 expects. If we switch back to verion 3 of d3, it solves that issue. For the moment I have uninsalled the @types/d3 and it is working fine now.
For detail, the issue was, the version 4 or 5 of d3 expects the return type of select method as Selection<BaseType, {}, HTMLElement, any> but dagre-d3 render method expects first parameter of type Selection<any>. In version 3 of @types/d3, the return type is Selection<any>, so it works fine with all the V3 versions.
I have to write a method which will do that typecasting, incase I want to use the defination file for other features.
Thanks
Sameer
Before using type casting please make sure dagre-d3 supports this d3 version well.
Since d3v3 and d3v4 are not compatible such type casting might produce compatibility issue on JavaScript level.
Ignat Vilesov,
Software Engineer
Microsoft Power BI Custom Visuals
Starting December 3, join live sessions with database experts and the Fabric product team to learn just how easy it is to get started.
March 31 - April 2, 2025, in Las Vegas, Nevada. Use code MSCUST for a $150 discount! Early Bird pricing ends December 9th.