【问题标题】:D3 Functions Not Working When Multiple Data Sources Are Used使用多个数据源时 D3 函数不起作用
【发布时间】:2018-06-13 08:11:24
【问题描述】:

我已将这个“使用 d3、topojson 和 csv 制作世界地图”教程改编为可用的 v5 版本:https://www.youtube.com/watch?v=aNbgrqRuoiE&t=216s

但是,问题在于我要引入一个单独的数据源,即 CSV 文件。当我把它带进来并检查数据时,我得到了一个对象数组,这很好。但是为了使用长纬度坐标值将 CSV 中的位置转换为地图上的点,我显然需要访问 CSV 中的这些列值。在教程中,作者很容易做到这一点,使用以下方法:

svg.selectAll("state-circle")
.data(data)
.enter().append("circle")
.attr("class", "state-circle")
.attr("r",2)
.attr("cx", function(d) {
    var coords = projection([d.long, d.lat])
    return coords[0];})
.attr("cy", function(d) {
    var coords = projection([d.long, d.lat])
    return coords[1];});

但考虑到他使用的 D3 版本,他编写代码的方式让这一切变得简单。我不知道如何使用 v5 语法适配来做到这一点。

所以为了完成他所做的事情,我需要找到一种方法来访问对象内部的纬度和经度属性。现在我对 D3 很陌生,但我设法使用以下计算来实现这一点(但我对更好的方法持开放态度,因为我不确定这在技术上是最好的方法,或者它是否适用于他在上面所做的事情):

var long = d3.entries({longitude: true});
var lat = d3.entries({latitude: true});

问题是该代码仅在我在单独的 .js 文件中测试时才有效,其中 CSV 是唯一的数据源。当我尝试在也包含 .json 数据源的 .js 文件中运行代码时,它不起作用。它继续返回原始对象数组及其所有属性。

这是我目前使用的所有代码:

var margin = {top: 50, left: 50, right: 50, bottom: 50},
        height = 400 - margin.top - margin.bottom,
        width = 1600 - margin.left - margin.right;

var svg = d3.selectAll("body")
        .append("svg")
        .attr("height", height + margin.top + margin.bottom)
        .attr("width", width + margin.left + margin.right)
        .append("g");

d3.json("https://d3js.org/world-50m.v1.json").then(function (data)
    {console.log(data);

var countries = topojson.feature(data,data.objects.countries).features;

// console.log(countries);

var projection = d3.geoMercator()
    .translate([width/2, height/2])
    .scale(100);

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

svg.selectAll(".country")
    .data(countries)
    .enter().append("path")
    .attr("class", "country")
    .attr("d", path)
    .on("mouseover", function(d)
        {d3.select(this).classed("hover", true)})
    .on("mouseout", function(d)
        {d3.select(this).classed("hover", false)});
    });

    d3.csv("TData.csv", function(d) {
              return {
                city: d.City,
                continent: d.Continent,
                country: d.Country,
                dimension: d.Dimension,
                identity: d.Identity,
                score: +d.Score,
                state: d.Subdivision,
                trait: d.Trait,
                index: d.Index,
                longitude: d.Latitude,
                latitude: d.Longitude
              }
            }).then(function(data) {
                // console.log(data);

                    var long = d3.entries({longitude: true});
                    var lat = d3.entries({latitude: true});

    console.log(long);
    console.log(lat);

            });

CSV 文件的示例,是:

City,Continent,Country,Dimension,Identity,Score,Subdivision,Trait,Index,Latitude,Longitude
Wilmington,North America,United States,Pride,1270858,45,Delaware,Ego,1,"39,7932","-75,6181"
Wilmington,North America,United States,Humility,1270858,23,Delaware,Selflessness,2,"39,7932","-75,6181"
Wilmington,North America,United States,Humility,1270858,23,Delaware,Generosity,3,"39,7932","-75,6181"
Wilmington,North America,United States,Anger,1270858,48,Delaware,Impatience,4,"39,7932","-75,6181"

【问题讨论】:

    标签: javascript json csv d3.js world-map


    【解决方案1】:

    使用给定的 csv 文件,您必须将字符串坐标解析为浮点变量——为此,您还需要替换那里的逗号——以下代码有效

    var margin = {top: 50, left: 50, right: 50, bottom: 50},
    	height = 400 - margin.top - margin.bottom,
    	width = 1600 - margin.left - margin.right;
    
    var svg = d3.selectAll("body")
    	.append("svg")
    	.attr("height", height + margin.top + margin.bottom)
    	.attr("width", width + margin.left + margin.right)
    	.append("g");
    
    var gBackground = svg.append("g"); // appended first
    var gDataPoints = svg.append("g"); // appended second
    			
    d3.json("https://d3js.org/world-50m.v1.json").then(function (data) {
    	console.log(data);
    
    	var countries = topojson.feature(data,data.objects.countries).features;
    	var long = d3.entries({longitude: true});
    	var lat = d3.entries({latitude: true});
    
    	console.log(long);
    	console.log(lat);
    
    	gBackground.selectAll(".country")
    		.data(countries)
    		.enter().append("path")
    		.attr("class", "country")
    		.attr("d", path)
    		.on("mouseover", function(d)
    			{d3.select(this).classed("hover", true)})
    		.on("mouseout", function(d)
    			{d3.select(this).classed("hover", false)});
    });	
    
    var projection = d3.geoMercator();
    // .translate([width/2, height/2])
    // .scale(100);
    // need fixing - not sure why they're not working
    
    var path = d3.geoPath()
    	.projection(projection);
    
    		
    d3.csv("TruityData.csv", function(d) {
    	return {
    		city: d.City,
    		continent: d.Continent,
    		country: d.Country,
    		dimension: d.Dimension,
    		identity: d.Identity,
    		score: +d.Score,
    		state: d.Subdivision,
    		trait: d.Trait,
    		index: d.Index,
    		latitude: d.Latitude,
    		longitude: d.Longitude
    	}
    }).then(function(data) {
    	// console.log(data[0]);
    	
    	gDataPoints.selectAll("state-circle")
    		.data(data)
    		.enter().append("circle")
    		.attr("class", "state-circle")
    		.attr("r",3)
    		.attr("cx", function(d) {
    			var dln = parseFloat(d.longitude.replace(",", "."));
    			var dlt = parseFloat(d.latitude.replace(",", "."));
    			var coords = projection([dln, dlt]);
    			return coords[0];})
    		.attr("cy", function(d) {
    			var dln = parseFloat(d.longitude.replace(",", "."));
    			var dlt = parseFloat(d.latitude.replace(",", "."));
    			var coords = projection([dln, dlt]);
    			return coords[1];});
    		
    });

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-22
      • 2017-12-25
      • 2012-06-09
      • 1970-01-01
      • 1970-01-01
      • 2020-01-25
      • 2013-04-12
      • 1970-01-01
      相关资源
      最近更新 更多