d3具有悬停效果的Choropleth贴图不显示工具提示

时间:2019-10-30 14:32:51

标签: javascript d3.js svg geojson topojson

我正在尝试从此页面https://www.d3-graph-gallery.com/graph/choropleth_hover_effect.html向具有悬停效果的d3 Choropleth地图添加工具提示 d3 Chroropleth map工具提示似乎附加到了svg上,因为我可以检查地图并看到一个内部div,其中包含在悬停国家时应显示的假定文字,但是这样做时,即使工具提示参数似乎在每个不同的悬停时都会更新。

我从另一张图中获取了工具提示,因为我要实现的当前地图没有工具提示。我试过在函数ready(error,topo)内以及在mouseover和mouseleave函数内的样式/数据中创建工具提示变量,但是它不会在各个国家/地区显示工具提示

这是我的xhtml中的蠢货

<head>
        <!-- Load d3.js and the geo projection plugin -->
        <script src="https://d3js.org/d3.v4.js"></script>
        <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
        <script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>

        <script>
            jQuery(document).ready(function() {
                // The svg
                var svg = d3.select("svg"),
                width = +svg.attr("width"),
                height = +svg.attr("height");

                // Map and projection
                var path = d3.geoPath();
                var projection = d3.geoMercator()
                .scale(70)
                .center([0,20])
                .translate([width / 2, height / 2]);

                // Data and color scale
                var data = d3.map();
                var colorScale = d3.scaleThreshold()
                .domain([100000, 1000000, 10000000, 30000000, 100000000, 500000000])
                .range(d3.schemeBlues[7]);

                // Load external data and boot
                d3.queue()
                .defer(d3.json, "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson")
                .defer(d3.csv, "https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world_population.csv", function(d) { data.set(d.code, +d.pop); })
                .await(ready);

                var tooltip = d3.select("#my_dataviz")
                    .append("div")
                    .style("opacity", 0)
                    .attr("class", "tooltip")
                    .style("background-color", "white")
                    .style("border", "solid")
                    .style("border-width", "2px")
                    .style("border-radius", "5px")
                    .style("padding", "5px")

                function ready(error, topo) {

                    let mouseOver = function(d) {
                        d3.selectAll(".Country")
                        .transition()
                        .duration(200)
                        .style("opacity", .5)
                        d3.select(this)
                        .transition()
                        .duration(200)
                        .style("opacity", 1)
                        .style("stroke", "black")
                        tooltip.style("opacity", 1)
                            .html("The exact value of<br/>this cell is: " + d.pop)
                            .style("left", (d3.mouse(this)[0]+70) + "px")
                            .style("top", (d3.mouse(this)[1]) + "px")
                    }

                    let mouseLeave = function(d) {
                        d3.selectAll(".Country")
                        .transition()
                        .duration(200)
                        .style("opacity", .8)
                        d3.select(this)
                        .transition()
                        .duration(200)
                        .style("stroke", "transparent")
                        tooltip.style("opacity", 0)
                    }

                    // Draw the map
                    svg.append("g")
                        .selectAll("path")
                        .data(topo.features)
                        .enter()
                        .append("path")
                        // draw each country
                        .attr("d", d3.geoPath()
                            .projection(projection)
                        )
                        // set the color of each country
                        .attr("fill", function (d) {
                            d.total = data.get(d.id) || 0;
                            return colorScale(d.total);
                        })
                        .style("stroke", "transparent")
                        .attr("class", function(d){ return "Country" } )
                        .style("opacity", .8)
                        .on("mouseover", mouseOver )
                        .on("mouseleave", mouseLeave )
                }
            })
        </script>
    </head>

    <div>
        <div>
    <h1>Graphs</h1>

    <!-- Create an element where the map will take place -->
    <svg id="my_dataviz" width="400" height="300"></svg>

    </div>
    </div>

渲染地图后(仅使用悬停功能),我对其进行了检查,并可以看到以下内容。

Map hovering on Russia and showing data on tooltip div over console

如果我更改国家/地区,则工具提示div上的数据会有所不同。

Map hovering on EEUU and showing different data on tooltip div over console

-更新-

按照@enxaneta的建议,我尝试将div移到svg之外。结果是将工具提示放在单独的div中。这次,工具提示出现在页面中,但是显示在地图的底部,而不是显示在地图的底部,这是我希望如何查看的。

Tooltip outside svg

我仍在弄清楚如何实现foreignObject。

-更新2-

添加工具提示位置绝对标记div,并将其相对于鼠标悬停。但是,即使它与所选国家/地区垂直对齐,也位于页面顶部。

<style>
    .tooltip{position:absolute;}
</style>

tooltip floating arround

tooltip floating arround 2

0 个答案:

没有答案