[英]How do I Bind Data from a .tsv to an SVG's paths using d3.js for a Choropleth Map
[英]d3.js choropleth map --How do I map more than one property from CSV to JSON, so I can use it in a tooltip?
我有一個用d3.js構建的Choropleth映射。 我正在將data.csv中的'Total_Score'屬性映射到JSON文件中的'id'屬性,並且使用該分數為狀態着色。 我還將在鼠標懸停時使用工具提示顯示它。
但是,我也希望能夠顯示CSV文件中的其他屬性。 還有其他四個-“等級”,“第一”,“第二”和“第三”。 我也必須為每個地圖創建地圖嗎? 我從來沒有映射過多個地圖,因此任何指導或示例都將不勝感激。
謝謝!
這是代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Worst Drivers</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="d3.tip.js"></script>
<style type="text/css">
body{
background:#333;
font-family:Helvetica, Arial, sans-serif;
font-size:13px;
color:#fff;
padding:0px;
margin:0px;
}
h1{
margin:50px 0px 0px;
text-align:center;
font-size:30px;
font-weight:normal;
}
h2{
margin:0px;
padding:0px;
}
h4{
font-size:16px;
}
a{
text-decoration: none;
color: #2bbe8c;
}
#panel{
background:#fff;
color:#111;
width:27%;
height:100%;
float:right;
padding:3%;
}
#map{
width:66%;
float:left;
}
.sources{
font-size:12px;
}
.d3-tip{
background:#000;
opacity:.7;
padding:20px;
border-radius:3px;
}
.statename{
font-size:16px;
}
.mainno{
font-size:14px;
}
#legend{
position:absolute;
width:66%;
height:20px;
}
#legendinner{
margin:0 auto;
position:relative;
width:245px;
}
.legendleft{
width:50px;
float:left;
margin:0px;
}
.legendright{
width:50px;
float:right;
text-align:right;
margin:0px;
}
</style>
</head>
<body>
<div id="container">
<div id="map">
<div id="legend">
<div id="legendinner">
<svg width="250" height="15">
<rect x="0" y="0" width="50" height="10" fill="#041e47"></rect>
<rect x="50" y="0" width="50" height="10" fill="#063685"></rect>
<rect x="100" y="0" width="50" height="10" fill="#0449bb"></rect>
<rect x="150" y="0" width="50" height="10" fill="#055ced"></rect>
<rect x="200" y="0" width="50" height="10" fill="#5092ff"></rect>
</svg>
<p class="legendleft">Most</p>
<p class="legendright">Least</p>
</div>
</div>
</div>
</div>
<script type="text/javascript">
//Width and height
var w = Math.max(window.innerWidth) / 3 *2;
var h = Math.max(window.innerHeight) - 100;
//Create SVG element
map = d3.select("#map")
.append("svg")
.attr("id", "usstates")
.attr("width", w)
.attr("height", h);
var maph = document.getElementById('usstates').clientHeight;
d3.select("#legend")
.style("top", maph + 150 + "px");
//Define map projection
var p = d3.geo.albersUsa()
.translate([w/2, h/2])
.scale([1000]);
//Define path generator
var path = d3.geo.path()
.projection(p);
//load the geoJSON file for drawing the map
d3.json("states.json", function(error, states) {
var newDict = {}; //mapping for choropleth
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([40, 0])
.html(function(d,i) {
return "<span class='statename'>" + d.properties.name + "</span>" +
"<hr/>" +
"<span class='mainno'>Total Score: " + newDict[d.id] +
"<br/>rank: </span>" +
"<hr/>" +
"First: " +
"<br/>Second: " +
"<br/>Third: " ;
})
var mapstates = map.append("svg:g")
.attr("id", "states")
.style("fill", "#dedee0")
.style("stroke", "#aaa")
.style("stroke-width", .5);
mapstates.call(tip);
mapstates
.selectAll("path")
.data(states.features)
.enter().append("path")
.attr("d", path);
d3.csv("data.csv", function(error, data) {
data.forEach(function(d){
d.rank = + d.rank;
d.Total_Score = +d.Total_Score;
newDict[d.id] = +d.Total_Score;
});
var minValue = d3.min(data, function(d,data) { return d.Total_Score; });
var maxValue = d3.max(data, function(d,data) { return d.Total_Score; });
//Quantize scale for map
var color = d3.scale.quantize()
.domain([minValue, maxValue])
.range(["#041e47", "#063685", "#0449bb", "#055ced", "#5092ff"]);
mapstates
.selectAll("path")
.attr("d", path)
.on('mouseover', function(d) {
d3.select(this).style('fill-opacity', .75);
})
.on('mouseout', function(d){
d3.select(this).style("fill-opacity", 1);
})
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
.attr("class", function(d){return newDict[d.id];})
.attr("fill", function(d) { return color(newDict[d.id]); })
.text("heyo");
mapstates.selectAll("text")
.data(states.features)
.enter()
.append("text")
.html(function(d){
return d.properties.abbr + ": " + newDict[d.id] ;
})
.attr("x", function(d){
return path.centroid(d)[0];
})
.attr("y", function(d){
return path.centroid(d)[1];
})
.attr("text-anchor","middle")
.attr('font-size',11)
.attr('font-weight', 'normal');
}); //close csv
}); // close json
</script>
</body>
</html>
data.csv文件:
"State","id","first","second","third","TotalScore","rank"
"Alabama",1,15,24,29,113,18
"Alaska",2,22,51,50,195,49
"Arizona",4,14,28,41,109,14
"Arkansas",5,5,21,43,141,28
"California",6,42,26,39,146,33
"Colorado",8,33,4,24,101,11
"Connecticut",9,48,44,9,185,47
"Delaware",10,21,31,12,74,7
"District of Columbia",11,51,8,32,139,27
"Florida",12,19,29,30,131,24
"Georgia",13,28,11,46,147,34
"Hawaii",15,20,33,6,70,5
"Idaho",16,27,20,36,152,38
"Illinois",17,39,39,10,125,22
"Indiana",18,36,19,34,165,42
"Iowa",19,25,38,48,205,50
"Kansas",20,17,15,47,151,37
"Kentucky",21,6,2,49,131,24
"Louisiana",22,7,5,19,71,6
"Maine",23,26,10,17,103,12
"Maryland",24,41,50,18,141,28
"Massachusetts",25,50,37,8,156,39
"Michigan",26,37,42,37,179,45
"Minnesota",27,49,34,35,205,50
"Mississippi",28,8,12,26,111,17
"Missouri",29,24,18,13,91,10
"Montana",30,3,6,1,59,2
"Nebraska",31,29,16,7,141,28
"Nevada",32,30,14,14,79,8
"New Hampshire",33,43,46,33,190,48
"New Jersey",34,46,43,21,160,40
"New Mexico",35,11,27,42,109,14
"New York",36,40,36,20,143,31
"North Carolina",37,23,35,23,109,14
"North Dakota",38,4,3,2,66,4
"Ohio",39,35,22,15,135,26
"Oklahoma",40,9,1,31,87,9
"Oregon",41,34,49,45,184,46
"Pennsylvania",42,18,32,25,105,13
"Rhode Island",44,44,48,4,147,34
"South Carolina",45,1,30,3,54,1
"South Dakota",46,10,7,11,114,20
"Tennessee",47,13,25,27,143,31
"Texas",48,12,23,5,63,3
"Utah",49,45,9,51,169,44
"Vermont",50,31,13,40,113,18
"Virginia",51,38,40,38,163,41
"Washington",53,47,47,22,165,42
"West Virginia",54,2,45,44,116,21
"Wisconsin",55,32,17,16,130,23
"Wyoming",56,16,41,28,149,36
(我無法在此處粘貼states.json文件,因為它超出了帖子允許的正文大小,但是如果您進入了Plunker ,則可以看到它。)
您可以創建對象並將其放在newDict中。 任何其他集合也將起作用。
以下是添加具有rank和score屬性的新對象的代碼。
data.forEach(function(d){
d.rank = d.rank;
d.Total_Score = d.Total_Score;
newDict[d.id] = {rank:d.rank, score:d.Total_Score};
});
然后可以像普通對象一樣使用它們。
mapstates
.selectAll("path")
.attr("d", path)
.on('mouseover', function(d) {
d3.select(this).style('fill-opacity', .75);
})
.on('mouseout', function(d){
d3.select(this).style("fill-opacity", 1);
})
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
.attr("class", function(d){return newDict[d.id];})
attr("fill", function(d) { return color(newDict[d.id].score); });
添加任意數量的值是對data.forEach閉包的簡單添加。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.