使用多个数据源时 D3 函数不起作用
D3 Functions Not Working When Multiple Data Sources Are Used
我已将此 "Making a world map with d3, topojson, and a csv" 教程改编成可用的 v5 版本:https://www.youtube.com/watch?v=aNbgrqRuoiE&t=216s
但是,问题出现在我要引入一个单独的数据源,即 CSV 文件的时候。当我把它带进来检查数据时,我得到了一个对象数组,这很好。但是为了使用 long 和 lat 坐标值将 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 文件中的代码时,它不起作用。它继续 return 原始对象数组及其所有属性。
这是我目前使用的所有代码:
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"
对于给定的 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];});
});
我已将此 "Making a world map with d3, topojson, and a csv" 教程改编成可用的 v5 版本:https://www.youtube.com/watch?v=aNbgrqRuoiE&t=216s
但是,问题出现在我要引入一个单独的数据源,即 CSV 文件的时候。当我把它带进来检查数据时,我得到了一个对象数组,这很好。但是为了使用 long 和 lat 坐标值将 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 文件中的代码时,它不起作用。它继续 return 原始对象数组及其所有属性。
这是我目前使用的所有代码:
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"
对于给定的 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];});
});