javascript - 我如何使用 d3.js 将数据从 .tsv 绑定(bind)到 SVG 的路径以获得 Choropleth map

标签 javascript d3.js svg data-visualization topojson

社区, 我想使用类似于 found here 的 D3.js 创建一个 Choropleth map .

我的 map 与此示例不同,因为我想使用我创建并驻留在我的 index.html 中的 SVG,而不是使用 TopoJSON 或 GeoJson 文件作为形状数据,因为我没有该形状数据对于其他地方的国家地区。我的 SVG 使用具有 id 值的路径或多边形,用于 map 中与 my .tsv file's 相对应的每个区域编号。

我有my .tsv data set file使用 id,一个范围相当于示例 the example .

我考虑过使用 this tool 将 SVG 转换为 GeoJSON,然后再转换为 TopoJson和 that tool ,但是我没有命令行经验。更多结束,看完the third answer to this question on Stackoverflow.其中指出:

"If you're creating a choropleth and have no geolocation requirements then you can simply add the SVG directy to your page and use D3 to map data to your image! Once you have the SVG in your page then you can even manually edit all path data to include classes and ids that will make your D3 job easier. "-Roberto Sterling

我尝试使用 SVG,将相应的 id 值用于路径和多边形 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; }))

导致以下错误:

Uncaught TypeError: Cannot read property 'id' of undefined

我哪里做错了?和/或如何使用 d3.js 将数据从 .tsv 绑定(bind)到 SVG 的路径以生成 Choropleth map ?

最佳答案

这里有一个简短的描述和一个例子,说明你需要做什么来将 SVG 嵌入到 html 页面中,并在从 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") 将数据绑定(bind)到 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)] 绑定(bind)到为绘制您的作品而创建的“path.fil3”元素叶绿素。

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

关于javascript - 我如何使用 d3.js 将数据从 .tsv 绑定(bind)到 SVG 的路径以获得 Choropleth map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35408303/

相关文章:

javascript - D3js 按钮 onclick 函数可缩放特定时间范围内的图表

javascript - 每次访问选项卡时都会生成 D3 图表

html - maskUnits 和 maskContentUnits 属性如何影响蒙版定位?

animation - 在D3 js中将SVG坐标转换为页面坐标

JavaScript 窗口打开选项

javascript - Socket.io 聊天服务器不提供 SSL 证书

javascript - 如何使用 D3.js 将两个按钮添加到一个 div?

javascript - 有时会嵌入错误的 svg。在React/Redux/Webpack项目中使用react-inlinesvg

Javascript计算浮点值错误

javascript - 在 Javascript 中循环访问三重嵌套对象