Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Compete to become Power BI Data Viz World Champion! First round ends August 18th. Get started.

Reply
Husain
Advocate I
Advocate I

d3.mouse

Hi

I am trying to get X,Y coordinates of mouse position using d3.mouse function

 

 

 

export class Visual implements IVisual {
    private host: IVisualHost;
    private svg: Selection<SVGElement>;
    private container: Selection<SVGElement>;

  constructor(options: VisualConstructorOptions) {     
        this.svg = d3.select(options.element)
            .append('svg')
        this.container = this.svg.append("g")
            .classed('container', true)  


this.container
        .on("mousemove", function () {
            d3.select(".tooltip").remove()
                var mouse = d3.mouse(this.container)
//I get following error with d3.mouse(parameter). I tried d3.mouse(this) as well
//Argument of type 'SVGElement' is not assignable to parameter of type 'ContainerElement'.
  //Type 'SVGElement' is missing the following properties from type 'SVGGElement': transform, //getBBox, getCTM, getScreenCTM, and 2 more.

 

 

 

 

1 ACCEPTED SOLUTION
dm-p
Super User
Super User

Hi @Husain,

This is where the problem starts:

private container: Selection<SVGElement>;

In your constructor, you're correctly assigning the 'g' element, but TypeScript thinks it's a SVGElement due to your property declaration and gets upset when you try to call d3.mouse on it. This needs to be declared as a ContainerElement.

To make the code in your post work to that point, change the container declaration as follows:

private container: Selection<ContainerElement>;

Then, your d3.mouse function can work on this, which is scoped as the element you're calling the event function on. This line should now read as follows:

.on("mousemove", function () {
    d3.select(".tooltip").remove()
        var mouse = d3.mouse(this)

 Your partial listing would now look as follows if you just want to copy/paste the whole thing:

export class Visual implements IVisual {
    private host: IVisualHost;
    private svg: Selection<SVGElement>;
    private container: Selection<ContainerElement>; /** Now has correct type */

  constructor(options: VisualConstructorOptions) {     
        this.svg = d3.select(options.element)
            .append('svg')
        this.container = this.svg.append("g")
            .classed('container', true)  


this.container
        .on("mousemove", function () {
            d3.select(".tooltip").remove()
                var mouse = d3.mouse(this) /** `this` is declared as the element (this.container) in the listener function */

This block of code will now compile correctly.

Good luck!

Daniel


If my post solves your challenge, then please consider accepting as a solution to help other forum members find the answer more quickly 🙂

 





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!


On how to ask a technical question, if you really want an answer (courtesy of SQLBI)




View solution in original post

1 REPLY 1
dm-p
Super User
Super User

Hi @Husain,

This is where the problem starts:

private container: Selection<SVGElement>;

In your constructor, you're correctly assigning the 'g' element, but TypeScript thinks it's a SVGElement due to your property declaration and gets upset when you try to call d3.mouse on it. This needs to be declared as a ContainerElement.

To make the code in your post work to that point, change the container declaration as follows:

private container: Selection<ContainerElement>;

Then, your d3.mouse function can work on this, which is scoped as the element you're calling the event function on. This line should now read as follows:

.on("mousemove", function () {
    d3.select(".tooltip").remove()
        var mouse = d3.mouse(this)

 Your partial listing would now look as follows if you just want to copy/paste the whole thing:

export class Visual implements IVisual {
    private host: IVisualHost;
    private svg: Selection<SVGElement>;
    private container: Selection<ContainerElement>; /** Now has correct type */

  constructor(options: VisualConstructorOptions) {     
        this.svg = d3.select(options.element)
            .append('svg')
        this.container = this.svg.append("g")
            .classed('container', true)  


this.container
        .on("mousemove", function () {
            d3.select(".tooltip").remove()
                var mouse = d3.mouse(this) /** `this` is declared as the element (this.container) in the listener function */

This block of code will now compile correctly.

Good luck!

Daniel


If my post solves your challenge, then please consider accepting as a solution to help other forum members find the answer more quickly 🙂

 





Did I answer your question? Mark my post as a solution!

Proud to be a Super User!


On how to ask a technical question, if you really want an answer (courtesy of SQLBI)




Helpful resources

Announcements
August Power BI Update Carousel

Power BI Monthly Update - August 2025

Check out the August 2025 Power BI update to learn about new features.

August 2025 community update carousel

Fabric Community Update - August 2025

Find out what's new and trending in the Fabric community.