Forum Discussion

Husain's avatar
Husain
Advocate I
6 years ago
Solved

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.

 

 

 

 

  • 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 🙂

     

1 Reply

  • dm-p's avatar
    dm-p
    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 🙂