我有一張非洲地圖,我使用 D3 加載該地圖,該地圖包含多個列,其中包括一個名為 ADMIN 的列,其中包含每個國家/地區的名稱。我正在嘗試在我的下拉串列中選擇的地圖上突出顯示該國家/地區。例如,如果我在下拉選單中選擇阿爾及利亞,阿爾及利亞將在我的地圖上突出顯示。地圖本身以及下拉選單都可以正常加載。我只是在協調下拉功能和突出顯示功能之間的互動時遇到了麻煩,以便所選國家/地區實際突出顯示。
//begin script when window loads
window.onload = setMap();
var attrArray = ["Algeria", "Angola", "Benin", "Botswana", "Burkina Faso", "Burundi", "Cabo Verde", "Cameroon", "Central African Republic", "Chad", "Comoros", "Congo", "C?te d'Ivoire", "Djibouti", "DR Congo", "Egypt", "Equatorial Guinea", "Eritrea", "Eswatini",
"Ethiopia", "Gabon", "Gambia", "Ghana", "Guinea", "Guinea-Bissau", "Kenya", "Lesotho", "Liberia", "Libya", "Madagascar", "Malawi", "Mali", "Mauritania", "Mauritius", "Morocco", "Mozambique", "Namibia", "Niger", "Nigeria", "Rwanda", "Sao Tome & Principe", "Senegal",
"Seychelles", "Sierra Leone", "Somalia", "South Africa", "South Sudan", "Sudan", "Tanzania", "Togo", "Tunisia", "Uganda", "Zambia", "Zimbabwe"
];
var expressed = attrArray[0];
//set up choropleth map
function setMap() {
//map frame dimensions
var width = 1200,
height = 1000;
//create new svg container for the map
var map = d3.select("body")
.append("svg")
.attr("class", "map")
.attr("width", width)
.attr("height", height);
//create Albers equal area conic projection centered on France
var projection = d3.geoOrthographic()
.scale(600)
.translate([width / 2, height / 2.7])
.clipAngle(85)
.precision(.1);
var path = d3.geoPath()
.projection(projection)
var graticule = d3.geoGraticule()
.step([5, 5]); //place graticule lines every 5 degrees of longitude and latitude
//create graticule background
var gratBackground = map.append("path")
.datum(graticule.outline()) //bind graticule background
.attr("class", "gratBackground") //assign class for styling
.attr("d", path) //project graticule
//Example 2.6 line 5...create graticule lines
var gratLines = map.selectAll(".gratLines")
.data(graticule.lines()) //bind graticule lines to each element to be created
.enter() //create an element for each datum
.append("path") //append each element to the svg as a path element
.attr("class", "gratLines") //assign class for styling
.attr("d", path); //project graticule lines
//use queue to parallelize asynchronous data loading
d3.queue()
.defer(d3.csv, "https://raw.githubusercontent.com/Sharitau/website/main/Portfolio/GovernanceFinal/data/AfricaCountries.csv") //load attributes from csv
.defer(d3.json, "https://raw.githubusercontent.com/Sharitau/website/main/Portfolio/GovernanceFinal/data/world.topojson") //load background spatial data
.defer(d3.json, "https://raw.githubusercontent.com/Sharitau/website/main/Portfolio/GovernanceFinal/data/Africa.TOPOJSON")
.await(callback);
function callback(error, csvData, world, africa) {
//translate europe TopoJSON
var basemapCountries = topojson.feature(world, world.objects.ne_10m_admin_0_countries),
choroplethCountries = topojson.feature(africa, africa.objects.ne_10m_admin_0_countries).features;
//select graticule elements that will be created
//add Europe countries to map
var countries = map.append("path")
.datum(basemapCountries)
.attr("class", "countries")
.attr("d", path);
//add France regions to map
var regions = map.selectAll(".regions")
.data(choroplethCountries)
.enter()
.append("path")
.attr("class", function(d) {
return "regions " d.properties.ADMIN;
})
.attr("d", path)
console.log(countries);
console.log(regions)
createDropdown(csvData);
};
function createDropdown(csvData) {
//add select element
var dropdown = d3.select("body")
.append("select")
.attr("class", "dropdown")
.attr("d", path)
.on("change", function() {
highlight(d.properties);
});
//add initial option
var titleOption = dropdown.append("option")
.attr("class", "titleOption")
.attr("disabled", "true")
.text("Select Country");
//add attribute name options
var attrOptions = dropdown.selectAll("attrOptions")
.data(attrArray)
.enter()
.append("option")
.attr("value", function(d) {
return d
})
.text(function(d) {
return d
});
};
//function to highlight enumeration units and bars
function highlight(props) {
//change stroke
var selected = d3.selectAll("." props.ADMIN)
.style("stroke", "blue")
.style("stroke-width", "2")
console.log(props.ADMIN);
};
};
.countries {
fill: #0B1E38;
stroke: #fff;
stroke-width: 2px;
}
.map {
position: absolute;
right: 0;
}
.regions {
fill: #316331;
}
.gratLines {
fill: none;
stroke: #999;
stroke-width: 1px;
}
.gratBackground {
fill: #0B1E38;
}
.dropdown {
position: absolute;
top: 30px;
left: 500px;
z-index: 10;
font-family: sans-serif;
font-size: 1em;
font-weight: bold;
padding: 2px;
border: 1px solid #999;
box-shadow: 2px 2px 4px #999;
}
option {
font-weight: normal;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<script src="https://d3js.org/topojson.v3.min.js"></script>
uj5u.com熱心網友回復:
要使用此答案回答您的問題,您需要使用元素value上的屬性獲取所選選項的值select-this在此函式中可用。
var attrArray = ["Algeria", "Angola", "Benin", "Botswana", "Burkina Faso", "Burundi", "Cabo Verde", "Cameroon", "Central African Republic", "Chad", "Comoros", "Congo", "C?te d'Ivoire", "Djibouti", "DR Congo", "Egypt", "Equatorial Guinea", "Eritrea", "Eswatini",
"Ethiopia", "Gabon", "Gambia", "Ghana", "Guinea", "Guinea-Bissau", "Kenya", "Lesotho", "Liberia", "Libya", "Madagascar", "Malawi", "Mali", "Mauritania", "Mauritius", "Morocco", "Mozambique", "Namibia", "Niger", "Nigeria", "Rwanda", "Sao Tome & Principe", "Senegal",
"Seychelles", "Sierra Leone", "Somalia", "South Africa", "South Sudan", "Sudan", "Tanzania", "Togo", "Tunisia", "Uganda", "Zambia", "Zimbabwe"
];
//map frame dimensions
var width = 1200,
height = 1000;
//create new svg container for the map
var map = d3.select("body")
.append("svg")
.attr("class", "map")
.attr("width", width)
.attr("height", height);
//create Albers equal area conic projection centered on France
var projection = d3.geoOrthographic()
.scale(600)
.translate([width / 2, height / 2.7])
.clipAngle(85)
.precision(.1);
var path = d3.geoPath()
.projection(projection)
var graticule = d3.geoGraticule()
.step([5, 5]); //place graticule lines every 5 degrees of longitude and latitude
//create graticule background
var gratBackground = map.append("path")
.datum(graticule.outline()) //bind graticule background
.attr("class", "gratBackground") //assign class for styling
.attr("d", path) //project graticule
//Example 2.6 line 5...create graticule lines
var gratLines = map.selectAll(".gratLines")
.data(graticule.lines()) //bind graticule lines to each element to be created
.enter() //create an element for each datum
.append("path") //append each element to the svg as a path element
.attr("class", "gratLines") //assign class for styling
.attr("d", path); //project graticule lines
//use queue to parallelize asynchronous data loading
d3.queue()
.defer(d3.json, "https://raw.githubusercontent.com/Sharitau/website/main/Portfolio/GovernanceFinal/data/world.topojson") //load background spatial data
.defer(d3.json, "https://raw.githubusercontent.com/Sharitau/website/main/Portfolio/GovernanceFinal/data/Africa.TOPOJSON")
.await(callback);
function callback(error, world, africa) {
//translate europe TopoJSON
var basemapCountries = topojson.feature(world, world.objects.ne_10m_admin_0_countries),
choroplethCountries = topojson.feature(africa, africa.objects.ne_10m_admin_0_countries).features;
//select graticule elements that will be created
//add Europe countries to map
var countries = map.append("path")
.datum(basemapCountries)
.attr("class", "countries")
.attr("d", path);
//add France regions to map
var regions = map.selectAll(".regions")
.data(choroplethCountries)
.enter()
.append("path")
.attr("class", function(d) {
return "regions " d.properties.ADMIN;
})
.attr("d", path);
createDropdown();
};
function createDropdown() {
//add select element
var dropdown = d3.select("body")
.append("select")
.attr("class", "dropdown")
.on("change", function() {
// The value is the name of the country
var countryName = this.value;
highlight(countryName);
});
//add initial option
var titleOption = dropdown.append("option")
.attr("class", "titleOption")
.attr("disabled", "true")
.text("Select Country");
//add attribute name options
var attrOptions = dropdown.selectAll("attrOptions")
.data(attrArray)
.enter()
.append("option")
.attr("value", function(d) {
return d;
})
.text(function(d) {
return d;
});
};
//function to highlight enumeration units and bars
function highlight(countryName) {
//change stroke
var selected = d3.selectAll("." countryName)
.style("stroke", "blue")
.style("stroke-width", "2")
console.log(countryName);
};
.countries {
fill: #0B1E38;
stroke: #fff;
stroke-width: 2px;
}
.map {
position: absolute;
right: 0;
}
.regions {
fill: #316331;
}
.gratLines {
fill: none;
stroke: #999;
stroke-width: 1px;
}
.gratBackground {
fill: #0B1E38;
}
.dropdown {
position: absolute;
top: 30px;
left: 500px;
z-index: 10;
font-family: sans-serif;
font-size: 1em;
font-weight: bold;
padding: 2px;
border: 1px solid #999;
box-shadow: 2px 2px 4px #999;
}
option {
font-weight: normal;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<script src="https://d3js.org/topojson.v3.min.js"></script>
請注意,這class不是存盤國家/地區名稱的正確位置,即使它是一個簡單的選擇器。多個單詞的國家名稱未正確注冊,例如“塞拉利昂”的選擇器是".Sierra.Leone"而不是".Sierra Leone"。此外,嘗試選擇“剛果”;每個包含“剛果”一詞的國家都會被突出顯示。通過創建自定義屬性“data-country”并使用d3.select("[data-country='" countryName "']"). 另請參閱有關屬性選擇器的檔案。
此外,attrArray國家地圖中的名稱和國家/地區地圖中的名稱沒有對齊,因此一些突出顯示根本不起作用。我建議只從 TopoJSON 中獲取名稱或創建從 CSV 名稱到 TopoJSON 名稱的映射。
//map frame dimensions
var width = 1200,
height = 1000;
//create new svg container for the map
var map = d3.select("body")
.append("svg")
.attr("class", "map")
.attr("width", width)
.attr("height", height);
//create Albers equal area conic projection centered on France
var projection = d3.geoOrthographic()
.scale(600)
.translate([width / 2, height / 2.7])
.clipAngle(85)
.precision(.1);
var path = d3.geoPath()
.projection(projection)
var graticule = d3.geoGraticule()
.step([5, 5]); //place graticule lines every 5 degrees of longitude and latitude
//create graticule background
var gratBackground = map.append("path")
.datum(graticule.outline()) //bind graticule background
.attr("class", "gratBackground") //assign class for styling
.attr("d", path) //project graticule
//Example 2.6 line 5...create graticule lines
var gratLines = map.selectAll(".gratLines")
.data(graticule.lines()) //bind graticule lines to each element to be created
.enter() //create an element for each datum
.append("path") //append each element to the svg as a path element
.attr("class", "gratLines") //assign class for styling
.attr("d", path); //project graticule lines
//use queue to parallelize asynchronous data loading
d3.queue()
.defer(d3.json, "https://raw.githubusercontent.com/Sharitau/website/main/Portfolio/GovernanceFinal/data/world.topojson") //load background spatial data
.defer(d3.json, "https://raw.githubusercontent.com/Sharitau/website/main/Portfolio/GovernanceFinal/data/Africa.TOPOJSON")
.await(callback);
function callback(error, world, africa) {
//translate europe TopoJSON
var basemapCountries = topojson.feature(world, world.objects.ne_10m_admin_0_countries),
choroplethCountries = topojson.feature(africa, africa.objects.ne_10m_admin_0_countries).features;
//select graticule elements that will be created
//add Europe countries to map
var countries = map.append("path")
.datum(basemapCountries)
.attr("class", "countries")
.attr("d", path);
//add France regions to map
var regions = map.selectAll(".regions")
.data(choroplethCountries)
.enter()
.append("path")
.attr("class", "regions")
.attr("data-country", function(d) {
return d.properties.ADMIN;
})
.attr("d", path);
var countryNames = choroplethCountries.map(function(d) {
return d.properties.ADMIN;
}).sort();
createDropdown(countryNames);
};
function createDropdown(countryNames) {
//add select element
var dropdown = d3.select("body")
.append("select")
.attr("class", "dropdown")
.on("change", function() {
// The value is the name of the country
var countryName = this.value;
highlight(countryName);
});
//add initial option
var titleOption = dropdown.append("option")
.attr("class", "titleOption")
.attr("disabled", "true")
.text("Select Country");
//add attribute name options
var attrOptions = dropdown.selectAll("attrOptions")
.data(countryNames)
.enter()
.append("option")
.attr("value", function(d) {
return d;
})
.text(function(d) {
return d;
});
};
//function to highlight enumeration units and bars
function highlight(countryName) {
//change stroke
var selected = d3.selectAll("[data-country='" countryName "']")
.style("stroke", "blue")
.style("stroke-width", "2")
console.log(countryName);
};
.countries {
fill: #0B1E38;
stroke: #fff;
stroke-width: 2px;
}
.map {
position: absolute;
right: 0;
}
.regions {
fill: #316331;
}
.gratLines {
fill: none;
stroke: #999;
stroke-width: 1px;
}
.gratBackground {
fill: #0B1E38;
}
.dropdown {
position: absolute;
top: 30px;
left: 500px;
z-index: 10;
font-family: sans-serif;
font-size: 1em;
font-weight: bold;
padding: 2px;
border: 1px solid #999;
box-shadow: 2px 2px 4px #999;
}
option {
font-weight: normal;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<script src="https://d3js.org/topojson.v3.min.js"></script>
最后,您的代碼中有一些不必要的復雜性。
- 沒有必要使用
c3圖書館; - 你給了
selectelement.attr('d', path),它沒有做任何事情。它僅適用path于 SVG 生態系統中的元素。
uj5u.com熱心網友回復:
在我看來,它更像是一個 JS 相關的問題,而不是一個 d3 相關的問題:
在這里,您的廣告變數似乎無處不在
function createDropdown(csvData) {
//add select element
var dropdown = d3.select("body")
.append("select")
.attr("class", "dropdown")
.attr("d", path) // I don't think a select can use this
.on("change", function() {
highlight(d.properties); // where does this d come from a actually ? It is not provided by the function itself so what it is ?
});
// rest of code
}
和這里 :
function highlight(props) {
//change stroke
var selected = d3.selectAll("." props.ADMIN) // <= here
.style("stroke", "blue")
.style("stroke-width", "2")
console.log(props.ADMIN);
};
您選擇具有與 props.ADMIN 匹配的類的所有元素,但您的代碼實際上從未在任何元素上使用此類。從 choroplethCountries 資料創建的路徑使用“regions” d.properties.ADMIN 類,因此如果要突出顯示這些,應使用“.regions” d.properties.ADMIN 選擇器。
您是否嘗試在除錯模式下運行您的代碼以檢查它的行為方式?另外,鑒于您是 JS 初學者,我建議您考慮不使用 d3 的可能性。這是一個非常通用的庫,這給了它很大的靈活性,但這也意味著在有效使用它之前你必須學習很多東西。如果您可以自由選擇技術,也許值得花一些時間研究更專注于您想要的可視化型別的替代解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/377327.html
標籤:javascript d3.js
