社区, 我想使用类似于found here的D3.js创建一个等值区域地图。
我的地图与此示例的不同之处在于,我想使用我创建的SVG并驻留在我的index.html中,而不是使用TopoJSON或GeoJson文件作为形状数据,因为我没有那个形状数据对于其他国家的地区。我的SVG使用带有id值的路径或多边形,用于我的地图中与my .tsv file's ID对应的每个区域。
我的my .tsv data set file带有id,范围等同于示例the example。
我考虑过使用this tool和that tool将SVG转换为GeoJSON然后转换为TopoJson,但我没有命令行经验。更多内容,在阅读the third answer to this question on Stackoverflow.之后说明:
"如果您正在创建一个等值区并且没有地理位置要求,那么您只需将SVG directy添加到您的页面并使用D3将数据映射到您的图像!一旦在页面中安装了SVG,您甚至可以手动编辑所有路径数据,以包含使您的D3工作更轻松的类和ID。 &#34 - Roberto Sterling
我尝试使用SVG,使用相应的id值来获取路径和polygon id属性的数据。
以下是来自the example的自定义D3代码:
<script>
var width = 960,
height = 600;
var rateById = d3.map();
var quantize = d3.scale.quantize()
.domain([0, .15])
.range(d3.range(9).map(function(i) { return "q" + i + "-9"; }));
var projection = d3.geo.albersUsa()
.scale(1280)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("body svg");
var constituencies = svg.selectAll("path, polygon");
queue()
//.defer(d3.json, "/mbostock/raw/4090846/us.json")
.defer(d3.tsv, "JM_election_results_2015.tsv", function(d) { rateById.set(d.id, +d.rate); })
.await(ready);
function ready(error, us) {
if (error) throw error;
constituencies.data(function(d){return d.id;})
.enter().append("path")
.attr("class", function(d) { return quantize(rateById.get(d.id)); })
.attr("d", path);
svg.append("path")
.datum(topojson.mesh(constituencies, constituencies.d.id, function(a, b) { return a !== b; }))
.attr("class", "constituency")
.attr("d", path);
}
d3.select(self.frameElement).style("height", height + "px");
</script>
是代码行:
.datum(topojson.mesh(constituencies, constituencies.d.id, function(a, b) { return a !== b; }))
导致以下错误:
未捕获的TypeError:无法读取属性&#39; id&#39;未定义的
我哪里出错了?和/或如何使用d3.js将数据从.tsv绑定到SVG的路径?
答案 0 :(得分:0)
这里有一个简短的描述和一个示例,说明在从hs页面中嵌入SVG并在从csv文件中读取数据时使其成为d3 cloropleth时需要做的事情:
首先将您的SVG添加到html页面。理想情况下,它将位于div中,如下例所示:
<div class="map">
<?xml version="1.0" enconding="UTF-8" standalone="no"?>
<svg ...your svg data...>
...
<path id="AngraDosReis"... class="fil3"...>
<path id="Aperibe"... class="fil3"...>
...
</svg>
</div>
在我的例子中,id并不重要,但“fil3”类和数据顺序很重要,因为我的数据与svg元素的顺序相同(换句话说,data.csv文件的第一行对应于与我svg上第一个path.fil3元素相关的数据。 稍后在代码中我将使用d3.selectAll(“svg.fil3”)将数据绑定到svg元素,因此每个路径元素上的类非常重要:如果路径不代表区域,那么它不会属于fil3类。 有了SVG,您只需要从csv文件中读取变量:
var ready = false; // Tells if file has been read and variables are ready
var dsv = d3.dsv(";", "text/plain");
dsv("./data.csv", function(dados) {
return {
indMed14: +dados.indMed14,
densidades: +dados.densidades,
gastos: +dados.gastos
}; }, function(dados) {
for ( i = 0; i < dados.length; i++) {
indMed14.push(dados[i].indMed14);
densidades.push(dados[i].densidades);
gastos.push(dados[i].gastos);
}
ready = true;
});
在这个例子中,我正在阅读一个csv并创建3个数组(indMed14,densidades和gastos),这些数组将在稍后的路上传递给绘画例程。 ready变量很重要,因为d3.dsv是异步的,所以只有在数据准备就绪时,cloropleth按钮才会处于活动状态。
稍后在html上你可以调用绘图程序:
<div class="col-md-4">
<button onclick="pintaMapa('linear', apaga, [0,1], ['#ffffff', '#ffffff'], 'Rio de Janeiro', 'região', textoOriginal)">
Limpa Mapa
</button>
</div>
<div class="col-md-4">
<button onclick="if (ready) pintaMapa( 'linear', indMed14, [d3.min(indMed14), d3.max(indMed14)], ['#a50f15', '#fee5d9'], 'Indicador de Saúde 2014', 'mapa', isaude)">
Indicador Saude 2014
</button>
<button onclick="if (ready) pintaMapa( 'log', gastos, [d3.min(gastos),d3.max(gastos)], ['#eff3ff', '#08519c'], 'Gastos dos Públicos Totais', 'mapa', gpub)">
Gastos Publicos
</button>
<button onclick="if (ready) pintaMapa( 'log', densidades, [d3.min(densidades), d3.max(densidades)], ['#feedde', '#a63603'], 'Densidade Demográfica', 'mapa', tdd)">
Densidade Demografica
</button>
在绘画例程结束时,在创建颜色函数(cor(d))之后,您只需将[.data(variavel)]的数据绑定到为绘制您的颜色而创建的“path.fil3”元素。 cloropleth。
// Binds data to the SVG map and paints the cloropleth
d3.selectAll("path.fil3").data(variavel)
.transition()
.duration(1000)
.ease("cubic-in-out")
.style("fill", function(d) {return cor(d)})
.text(function(d,i) { return(nMunicipio(i) + ": " + d)});
完整代码可在http://stelling.cc/svgExample找到 此示例中嵌入的SVG取自维基百科,并根据我的需要进行调整(添加ID和类以满足我的要求)。