如何使用d3.js将数据从.tsv绑定到SVG的路径以获取等值线图

时间:2016-02-15 11:34:20

标签: javascript d3.js svg data-visualization topojson

社区, 我想使用类似于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 toolthat 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的路径?

1 个答案:

答案 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和类以满足我的要求)。