javascript - 在现有元素之上附加 SVG 项目

标签 javascript d3.js svg visualization

我正在尝试使用 d3.js 库向 map 添加点。 (我试图从这个 gist 改编脚本)。

问题是 map 是在点之上渲染的。 我尝试使用另一个 SO 答案,它提出了这样的建议: svg.append("g").attr("id", "map").attr("id", "points")...但我无法让它工作。我是 python 的长期用户...JavaScript 对我来说是新的(所以请原谅我的天真)。

我正在使用以下 CSS:

  <style>
    body {
      background-color: white;
    }
    svg {
        border: 1px solid black;
        background-color: #a4bac7;
    }
        .land {
          fill: #d7c7ad;
          stroke: #8999ab;
        }
        .boundary {
          fill: none;
          stroke: #a5967f;
        }
  </style>

正文:

    <script type="text/javascript" src="d3/d3.js"></script>
    <script src="http://d3js.org/topojson.v0.min.js"></script>

    <script>
        var width = 960;
        var height = 480;
        var dataURL = "https://gist.githubusercontent.com/abenrob/787723ca91772591b47e/raw/8a7f176072d508218e120773943b595c998991be/world-50m.json";

        var svg = d3.select("body").append("svg")
            .attr("width", width)
            .attr("height", height);

回应this所以回答答案,添加这个:

        svg.append("g")
                .attr("id", "map")
                .attr("id", "points");

        var projection = d3.geoEquirectangular()
            .scale(153)
            .translate([width/2,height/2])

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

        d3.json(dataURL, function(error, world) {
            svg.append("g")
                .select("#map").selectAll(".map")
                .attr("class", "land")
                .selectAll("path")
                .data([topojson.object(world, world.objects.land)])
                .enter().append("path")
                .attr("d", path);
            svg.append("g")
                .select("#map").selectAll(".map")
                .attr("class", "boundary")
                .selectAll("boundary")
                .data([topojson.object(world, world.objects.countries)])
                .enter().append("path")
                .attr("d", path);
            }
        );

        var lngLatExtract = function(d, i){
            return projection([d['lng'], d['lat']])[i];
        };

        d3.csv("cities.csv", function(data){
                svg.append("g")
                        .select("#points").selectAll(".points")
                        .data(data)
                        .enter()
                            .append('circle')
                            .attr("cx", function(d){
                                return lngLatExtract(d, 0);
                            })
                            .attr('cy', function(d){
                                return lngLatExtract(d, 1);
                            })
                            .style("fill", "blue")
                            .style("opacity", 0.75)
                            .attr("r", function(d){
                                return Math.sqrt(parseInt(d['population']) * 0.000001)
                            });
                }
        );

    </script>

cities.csv 看起来像这样:

rank,place,population,lat,lng
1,New York city,8175133,40.71455,-74.007124
2,Los Angeles city,3792621,34.05349,-118.245323

最佳答案

d3.jsond3.csv 都是 async 函数。他们的回调触发的顺序不是给定的,事实上,由于您的 csv 文件较小,它的回调可能首先触发。这意味着您的 csv 回调中的 svg.append("g") 发生在 之前 svg.append("g") 中json 回调。您可以通过检查 DOM 并查看首先附加的内容来确认这一点。

也就是说,我会改用 d3.queue .这允许您触发 d3.jsond3.csv 异步请求,然后在两者都完成时触发一个回调。

另一个不太精简的选项是将您的 d3.csv 代码放在 d3.json 调用的回调中。

关于javascript - 在现有元素之上附加 SVG 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39835468/

相关文章:

javascript - 在动画功能中添加类型

javascript - 支持力定向图中的平移和缩放以及画笔操作

svg - 如何在D3轴刻度中获取数字值而不是对数值?

javascript - 对象内部的函数

javascript - 聊天室的可靠计时器

javascript - D3、设置y轴线的最大条数

javascript - 将 d3.js JavaScript 函数翻译成 CoffeeScript

javascript - 使用多个变换获取 svg 中 svg 元素的位置

html - 使用 SVG 路径数据在 Canvas 中绘制路径(SVG 路径到 Canvas 路径)

javascript - Microsoft Outlook 邮件中的可运行代码片段?