D3.js:放大的topojson功能不会触发鼠标悬停

时间:2018-06-28 21:06:02

标签: d3.js zoom mouseover topojson

我有一个topojson格式的美国地图。用户从中选择州和县 下拉列表。当用户选择县时,地图将放大到选定的 县。

操作:当用户将鼠标悬停在县上时,我需要显示县名。我是 能够在首次加载地图时执行此操作,但在放大地图项时无法执行此操作。

我正在使用工具提示在鼠标悬停时显示文本。以下是我的代码:(可以在https://realtimeceap.brc.tamus.edu上查看示例版本)。

<script>
//globals: create tooptip div
var div = d3.select("body").append("xhtml:div")
    .attr("id", "divTip")
    .style("position", "absolute")
    .attr("class", "tooltip")
    .style("opacity", 0);

function zoomToCounty(stname, cnty) {
    d3.json("/topo/us-wgs84.json", function (us) {
        var conus = topojson.feature(us, us.objects.counties);

        //initialize selected county text
        d3.select("text").remove();

        //reset active to inactive size and color            
        d3.select("#svgMap2").select("#counties").select(".active")
            .style("stroke-width", "0.5px")
            .style("stroke", "#808080");

            //initialize rect
            svg.select("rect").remove();

            //zoom to selected county
            d3.selectAll(".county")
                .classed("active", function (d) {
                    if (d.properties.StateName === stname && d.properties.County === cnty) {
                        svg.append("rect")
                            .attr("class", "overlay")
                            .attr("width", width)
                            .attr("height", height)
                            .call(d3.zoom()
                                .scaleExtent([.05, 8])
                                .on("zoom", moveWheel))

                        //zoom in to max scale extent
                        var zoom_in = d3.zoom()
                            .scaleExtent([.05, 8])
                            .on("zoom", zoomedIn);

                        //get path of selected county
                        var bounds = path.bounds(d),
                            dx = bounds[1][0] - bounds[0][0],
                            dy = bounds[1][1] - bounds[0][1],
                            x = (bounds[0][0] + bounds[1][0]) / 2,
                            y = (bounds[0][1] + bounds[1][1]) / 2,
                            scale = Math.max(1, Math.min(8, 0.9 / Math.max(dx / width, dy / height))),
                            translate = [width / 2 - scale * x, height / 2 - scale * y];

                        //add text at coordinates inside a group
                        d3.select("#svgMap2").select("#counties")
                            .append("text")
                                .style("fill", "black")
                                .style("font-size", "20px")
                                .attr("x", width / 2)   //center the text
                                .attr("y", height / 2)
                                .attr("text-anchor", "middle")  //set anchor y justification
                            .text($("#countySelect").val());                            

                        d3.select("#svgMap2").select("#counties")
                            .transition()
                            .duration(1000)
                            .call(zoom_in.transform, d3.zoomIdentity.translate(translate[0], translate[1]).scale(scale));  //center  

                        return true;
            }
        });

        //hover over counties
        d3.select("#counties").selectAll(".county")             
            .enter().append("path")
            .attr("d", path)
            .attr("name", function (d) { return d.properties.County; }, true)                
            .attr("id", function (d) { return d.properties.FIPS; }, true)
            .style("stroke-width", "0.5px")     //inactive border width
            .on("mouseover", function () {
                d3.select(this)
                    .style("stroke", "#ff5800");
                div.transition()
                    .duration(300)
                div.text(function () {
                    if (d.properties.StateName === stname && d.properties.County === cnty) {
                        return $("#countySelect").val();
                    } else {
                        return d.properties.County;
                    }
                })
                    .style("opacity", 1)
                    .style("class", "label")
                    .style("left", (d3.event.pageX) - 10 + "px")
                    .style("top", (d3.event.pageY) - 5 + "px");
            })
            .on("mouseout", function () {
                d3.select(this)
                    .style("stroke", "#808080");
                div.transition()
                    .duration(300)
                    .style("opacity", 0);
            });

    }); //end d3.json

}

1 个答案:

答案 0 :(得分:0)

找到了解决方案。我需要在“矩形”上“附加”鼠标悬停代码。我将“悬停在县”上的代码替换如下:

    //initialize rect
    svg.select("rect").remove();

    //hover over counties   
    d3.selectAll(".county", function (d) {
        svg.append("rect")
            .attr("class", "overlay")
            .attr("width", width)
            .attr("height", height)
            .call(d3.zoom()
                .scaleExtent([.05, 8])
                .on("zoom", moveWheel))
                .on("mouseover", function (d, i) {
                    d3.select(this)
                        .style("stroke", "#ff5800")
                    div.transition().duration(300)
                    div.text(function (d) { return conus.features[i].properties.County })
                        .style("opacity", 1)
                        .style("class", "label")
                        .style("left", (d3.event.pageX) - 10 + "px")
                        .style("top", (d3.event.pageY) - 5 + "px");
                })
                .on("mouseout", function (d) {
                    div.transition().duration(300)
                        .style("opacity", 0);
                })
    });