欧洲 map (此处使用方 block 而非国家进行了非常简化),其国家根据当年选择的死亡人数(由选择病引起)着色。
颜色越深,死亡人数越多(如图例中所述)。
用户可以使用 slider 选择喜欢的年份,也可以使用单选按钮选择疾病。 根据年份和选定的疾病,国家的颜色变化。
当用户将鼠标滚动到特定国家(例如法国)时,右侧会出现一些详细信息,例如:
- 国家
- 年份
- 总死亡人数
- 死亡人数除以男性和女性
我的数据集是这样完成的:
"","Country","Year","Sex","Death","Value"
"3","Austria","2012","Male","Tuberculosis",18
"4","Austria","2012","Male","Tetanus",1
"5","Austria","2012","Male","Diphtheria",0
"1641","Austria","2012","Female","Tuberculosis",7
"1642","Austria","2012","Female","Tetanus",0
"1643","Austria","2012","Female","Diphtheria",0
"3409","Austria","2011","Male","Tuberculosis",27
"3410","Austria","2011","Male","Tetanus",0
"3411","Austria","2011","Male","Diphtheria",0
"5047","Austria","2011","Female","Tuberculosis",14
"5048","Austria","2011","Female","Tetanus",0
"5049","Austria","2011","Female","Diphtheria",0
"46829","Austria","1998","Male","Tuberculosis",61
"46830","Austria","1998","Male","Tetanus",0
"46831","Austria","1998","Male","Diphtheria",0
"48341","Austria","1998","Female","Tuberculosis",30
"48342","Austria","1998","Female","Tetanus",0
"48343","Austria","1998","Female","Diphtheria",0
"59309","Belgium","2010","Male","Tuberculosis",13
"59310","Belgium","2010","Male","Tetanus",0
"59311","Belgium","2010","Male","Diphtheria",0
"60947","Belgium","2010","Female","Tuberculosis",13
"60948","Belgium","2010","Female","Tetanus",2
"60949","Belgium","2010","Female","Diphtheria",0
...
我搜索了是否有任何类似的图形可以使用,但我一无所获。
我试图创建一张欧洲 map ,这就是我得到的 https://plnkr.co/edit/Ny0lUkVoiKeP76R95eVn?p=preview .
图表不起作用,因为它缺少 europe.json 文件。 Plunker 不保存,因为文件太大。 这是 europe.json文件,这就是我所看到的(如果我将鼠标移到法国上方):
在 script.js 文件中有一段代码(已注释)不起作用。 这是我第一次用 map 做图形。
好吧,现在我不知道从哪里开始。 例如,我如何根据所选国家/地区关联国家/地区名称? 并过滤基准年和疾病的数据? 有人可以帮我吗?
我知道我问了很多,但我不想要所有的代码,而是想要能够继续开发图形的帮助。
非常感谢
我几乎完成了图表,只有两件事我无法修复:不随所选年份改变的国家/地区的图例和颜色。
这里是代码:PLUNKER
对于图例,我使用了 library of Susie Lu . 图例已创建但未着色。我尝试更改范围并使用我用来为国家/地区着色的相同方法,但不起作用。
// to color countries
var colors = d3.scale.linear()
.domain([0, 1, 2300])
.range(["#cccccc","#131313", "#ba3c28"]);
/**
* Legend.
*/
var quantize = d3.scale.quantize()
.domain([0, 1, 2300])
//.range(["#cccccc","#131313", "#ba3c28"]);
.range(d3.range(10).map(function(i) {
return "q" + i + "-10";
}));
var svg = d3.select("#leftDown")
.append("svg")
.attr("class", "legendQuantsvg");
svg.append("g")
.attr("class", "legendQuant")
.attr("transform", "translate(20, 20)");
var legend = d3.legend.color()
.labelFormat(d3.format(".0f"))
.useClass(true)
.scale(quantize);
svg.select(".legendQuant")
.call(legend);
第二个问题是,如果用户使用 slider 更改年份,国家/地区的颜色不会改变。 我不明白如何更新 slider 的值。 右边的数据是正确获取的。
有人可以帮我吗?
PS:不知道改这个问题对不对,还是得另开一个。 无论如何,谢谢。
最佳答案
这不是您答案的完整解决方案,但为您提供了我使用的一般模式。
- 设置初始值,准备界面场景
- 向服务器请求数据并等待数据到达
- 绘制 map 基础,添加事件监听与用户交互
- 根据用户操作过滤并选择合适的信息
设置初始值,准备界面场景
加载脚本
<script src="js/d3.js" charset="utf-8"></script> D3 base
<script src="js/topojson.v1.min.js"></script> TopoJSON
<script src="js/d3-queue.v2.min.js"></script> Queue
<script src="js/jquery-2.2.4.min.js"></script> jQuery
HTML
<div id="selector">
<form id="desses">
<input type="radio" name="desse" value="tuberculosis" checked>Tuberculosis<br>
<input type="radio" name="desse" value="tetanus">Tetanus<br>
<input type="radio" name="desse" value="diphtheria">Diphtheria
</form>
</div>
<input type="range" id="rango" value="2014" min=2004 max=2014>
<div id="container"></div>
<div id="info"></div>
JavaScript
// width and height
var w = 800, h = 600, dess;
// define map projection
var projection = d3.geo.mercator()
.center([13, 52])
.translate([w/2, h/2])
.scale([w/1.5]);
// define path generator
var path = d3.geo.path()
.projection(projection);
// create SVG
var svg = d3.select("#container")
.append("svg")
.attr("width", w)
.attr("height", h);
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
向服务器请求数据并等待它到达 您必须等待所有数据,否则用户可能会开始与其中一些数据交互并出现错误、未定义的值等。
建议:将 map 库与数据分开。您可以更改 map 和/或数据,而无需一遍又一遍地重新创建所有 json。易于维护
d3_queue.queue()
.defer(d3.json, 'data/europe.topojson') //<-- Topojson base map
.defer(d3.csv, 'data/dessease.csv') //<-- dessease csv data
.awaitAll(makemap); // <-- When data arrives call makemap function
必读:Queue
绘制 map 基础,添加事件监听与用户交互 绘制 map 。 在“mouseover”和“mouseout”上添加事件监听器:
function makemap(error, europe, dessease) {
dess = dessease.slice()
counties = topojson.feature(europe, europe.objects.collection);
vector = svg.selectAll("path")
.data(counties.features)
.enter()
.append("path")
.attr("class", "county")
.attr("id", function(d){
return "coun"+d.properties.indx})
.attr("d", path)
.on("mouseover", function(d) {
d3.select("#coun"+d.properties.indx).style('stroke', '777').style("stroke-width",2)
showInfo(d)
})
.on("mouseout", function(d) {
d3.select("#coun"+d.properties.indx).style('stroke', 'ddd').style("stroke-width",1)
$("#info").html("")
})
};
必读:TopoJSON
工具:TopoJSON Maps - Letfleat map tool
根据用户操作过滤并选择合适的信息 您有两种类型的互动:
- 一个国家的用户(showInfo 函数)
- 用户选择年份或年份(更新功能)
Javascript
var showInfo = function (d) { // Populate the tooltip
var infoNest = d3.nest()
.key(function(d) { return d.Year }) //<-- Filter selectors
.key(function(d) { return d.Sex; }) // Now you use
.map(dess); //<-- your csv data
$("#info").html($("#rango").val() + " - "+d.properties.name+" : "+JSON.stringify(infoNest['1998']['Male']) ) // sample
}
var update = function () { // change map color based on values
var des = $('input[name=desse]:checked', '#desses').val();
$("#info").html($("#rango").val()+ " : " + des)
}
$('#desses').on('change', update);
$("#rango").on("input", update);
d3.nest() 它是 D3 处理数据和数据子集最强大的函数之一。
必读:Groupin Data - Arrays API - D3 using nest on csv data - Reading in Data
附言:
我更改了您的 .csv,添加了一列以将 .topojson 国家/地区代码绑定(bind)到 .csv:
indx,id,Country,Year,Sex,Death,Value
4,3,Austria,2012,Male,Tuberculosis,18
4,4,Austria,2012,Male,Tetanus,1
4,5,Austria,2012,Male,Diphtheria,0
4,1641,Austria,2012,Female,Tuberculosis,7
4,1642,Austria,2012,Female,Tetanus,0
4,1643,Austria,2012,Female,Diphtheria,0
4,3409,Austria,2011,Male,Tuberculosis,27
4,3410,Austria,2011,Male,Tetanus,0
4,3411,Austria,2011,Male,Diphtheria,0
4,5047,Austria,2011,Female,Tuberculosis,14
4,5048,Austria,2011,Female,Tetanus,0
4,5049,Austria,2011,Female,Diphtheria,0
4,46829,Austria,1998,Male,Tuberculosis,61
4,46830,Austria,1998,Male,Tetanus,0
4,46831,Austria,1998,Male,Diphtheria,0
4,48341,Austria,1998,Female,Tuberculosis,30
4,48342,Austria,1998,Female,Tetanus,0
4,48343,Austria,1998,Female,Diphtheria,0
2,59309,Belgium,2010,Male,Tuberculosis,13
2,59310,Belgium,2010,Male,Tetanus,0
2,59311,Belgium,2010,Male,Diphtheria,0
2,60947,Belgium,2010,Female,Tuberculosis,13
2,60948,Belgium,2010,Female,Tetanus,2
2,60949,Belgium,2010,Female,Diphtheria,0
每个国家/地区都有一个代码 (indx),因此当您选择一个国家/地区时,传递代码以从 csv 中过滤数据。
关于javascript - 使用 D3 的欧洲交互式图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37635547/