d3 / d3-zoom

Pan and zoom SVG, HTML or Canvas using mouse or touch input.
https://d3js.org/d3-zoom
ISC License
507 stars 143 forks source link

transform event with x and y NaN #149

Closed oufresh closed 6 years ago

oufresh commented 6 years ago

Hello,

I'm trying to do something like this example:

http://bl.ocks.org/mbostock/5914438

using the current these version: d3: 5.5.0 d3-tile: 0.0.4 d3-zoom: 1.7.1

and installing the packages with npm. I have these imports:

import as d3 from 'd3'; import as d3Tile from "d3-tile"; import as d3Zoom from 'd3-zoom'; import as topojson from 'topojson';

When the data are loaded and the function zoomed is called, this part of code ha sa problem:

var transform = d3.event.transform;

transform.x and transform.y are 'NaN'

All the code is basically here

stringify(scale: number, translate: Array<number>): string
{
    var k = scale / 256, r = scale % 1 ? Number : Math.round;
    return "translate(" + r(translate[0] * scale) + "," + r(translate[1] * scale) + ") scale(" + k + ")";
}

zoomed()
{
    var transform = d3.event.transform;
    console.log(d3.event);

    //transform.x = 1600.7111111111112;
    //transform.y = 739.9404171566814;

    var tiles = this.tile
        .scale(transform.k)
        .translate([transform.x, transform.y])
        ();

    this.vector
        .attr("transform", transform)
        .style("stroke-width", 1 / transform.k);

    var image = this.raster
        .attr("transform", this.stringify(tiles.scale, tiles.translate))
      .selectAll("image")
      .data(tiles, function(d) { return d; });

    image.exit().remove();

    image.enter().append("image")
        .attr("xlink:href", function(d) { return "http://" + "abc"[d[1] % 3] + ".tile.openstreetmap.org/" + d[2] + "/" + d[0] + "/" + d[1] + ".png"; })
        .attr("x", function(d) { return d[0] * 256; })
        .attr("y", function(d) { return d[1] * 256; })
        .attr("width", 256)
        .attr("height", 256);
}

_initV()
{
    const width = this.svgCanvas.clientWidth;
    const height = this.svgCanvas.clientHeight;

    const projection = d3.geoMercator()
        .scale(1 / (2*Math.PI))
        .translate([0, 0]);

    var path = d3.geoPath()
        .projection(projection);

    this.tile = d3Tile.tile()
        .size([width, height]);

    var zoom = d3Zoom.zoom()
        .scaleExtent([1 << 11, 1 << 14])
        .on("zoom", this.zoomed);

    this.svg = d3.select("svg")
        .attr("width", width)
        .attr("height", height);

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

    this.vector = this.svg.append("path");

    fetch('http://localhost:8080/us.json').then(resp => {
            if (resp.ok)
                return resp.json();
            else {
                console.error(resp.statusText);
                throw new Error('Response error');
            }
        }).then(us => {
            var center = projection([-98.5, 39.5]);

            this.svg
                .call(zoom)
                .call(zoom.transform, d3.zoomIdentity
                .translate(width / 2, height / 2)
                .scale(1 << 12)
                .translate(-center[0], -center[1]));

            this.vector
                .attr("d", path(topojson.mesh(us, us.objects.counties)));
        }).catch(error => {
            console.error(error);
    });
}

Can you please help me if there are differences with the new version of d3? In teh example it refers to V4 and it is not updated.

Many thanks.

oufresh commented 6 years ago

Solution on d3-tile