Marc Pincince
Marc Pincince

Reputation: 5192

Trouble with d3 zoom transform. Error: [ts] Property 'translate' does not exist on type 'Event | BaseEvent'

I'm trying to add zoom, but am failing miserably. I have a container for the zoom:

        this.container = svg.append("g");  

and this:

        var zoom = d3.behavior.zoom()
            .scaleExtent([1, 10])
            .on("zoom", function () {
                alert("here")
                this.container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")")
                alert("here 2");
            });

and this call:

       .call(zoom);

The transform part ... this.container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")") ... is causing me a problem. It gives me this error: [ts] Property 'translate' does not exist on type 'Event | BaseEvent'. And won't compile.

If I change the d3.event.translate and d3.event.scale to (<any>d3.event).translate and (<any>d3.event).scale, or to (<any>d3).event.translate and (<any>d3).event.scale, the error goes away, but the zoom doesn't work.

With those <any> changes incorporated, when I double-click my mouse or scroll (the first time) I get my first alert. I never make it to my second alert.

I'm pretty sure the problem is with this line: this.container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"). How can I fix it?

I'm using TypeScript and d3 v3.5.5 to build a Power BI custom visual.

Thanks!

Upvotes: 3

Views: 3034

Answers (1)

Marc Pincince
Marc Pincince

Reputation: 5192

I figured it out. Here are the parts of what worked for me:

I added this at the start of the visual's class...after the part that says "export class [VISUAL'S NAME (e.g., scatterChart)] implements IVisual {":

        private container: d3.Selection<SVGElement>;

I added this in the 'constructor' as a wrapper:

        this.container = svg.append("g");  

The rest of this, I put in 'update'.

This, I believe, is referred to as a 'listener':

        var zoom = d3.behavior.zoom()
            .scaleExtent([1, 10])
            .on("zoom", this.zoomed.bind(this));

Here's the call to zoom.

        this.svg.call(zoom);

And this is the 'zoomed' function, which does the zoom and pan:

    private zoomed() {
        this.container.attr("transform", "translate(" + ((<any>d3.event).translate) + ")scale(" + ((<any>d3.event).scale) + ")");}

You can see I still used basically the same line that I thought was the problem (this.container.attr("transform", "translate(" + ((<any>d3.event).translate) + ")scale(" + ((<any>d3.event).scale) + ")");. It turned out that the real problem was that I needed to add the .bind(this) in the call to zoomed.

Upvotes: 1

Related Questions