Forum Discussion
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-pSuper 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 🙂