D3.js 中的 Non-Contiguous Cartogram详解

Posted wan353694124

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了D3.js 中的 Non-Contiguous Cartogram详解相关的知识,希望对你有一定的参考价值。

Non-Contiguous Cartogram

今天来首次接触一下d3中的地图相关实现。这个地图非常简单,Non-Contiguous Cartogram,顾名思义,是一个不连续的示意性地图。
见图如下:

接下来解释地图的实现细节

index.html详解——[源码]

<!DOCTYPE html>
<meta charset="utf-8">
<title>Non-Contiguous Cartogram</title>
<style>

.land 
  fill: #fff;
  stroke: #ccc;


.state 
  fill: #ccc;
  stroke: #666;


</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>

// Ratio of Obese (BMI >= 30) in U.S. Adults, CDC 2008
// 美国各个州成年人的肥胖比例数据,NaN表示没有数据,接下来将要绘制的图形,会以洲之间的稀疏程度和州边缘线的粗细程度来直观地展示美国各个州的成年人肥胖比例情况。如果哪个区域的肥胖比例高,则这个区域的州之间的距离比较紧凑,州的边际线比较细,如果哪个区域的肥胖比例小,那么这个区域的各个州之间的距离比价稀疏,州的边际线较粗。
var valueById = [
   NaN, .187, .198,  NaN, .133, .175, .151,  NaN, .100, .125,
  .171,  NaN, .172, .133,  NaN, .108, .142, .167, .201, .175,
  .159, .169, .177, .141, .163, .117, .182, .153, .195, .189,
  .134, .163, .133, .151, .145, .130, .139, .169, .164, .175,
  .135, .152, .169,  NaN, .132, .167, .139, .184, .159, .140,
  .146, .157,  NaN, .139, .183, .160, .143
];

// 定义一个d3的地理数据处理函数path()
var path = d3.geo.path();

// 定义一个svg的画板,并设置其宽、高
var svg = d3.select("body").append("svg")
    .attr("width", 960)
    .attr("height", 500);

// 读取并处理地图数据
d3.json("/mbostock/raw/4090846/us.json", function(error, us) 
  if (error) throw error;

  // 这里绘制地图用的是topojson格式的地理信息数据,相当于简化版的geojson。
  // 第一步,绘制整个美国的轮廓线
  svg.append("path")
      // 获取地理数据中的land信息,绑定到元素上
      .datum(topojson.feature(us, us.objects.land))
      // 为path元素添加样式
      .attr("class", "land")
      // 为path元素的d属性绑定路径函数 path()函数,即前面定义的 var path = d3.geo.path();
      .attr("d", path);

  //第二步,绘制美国的各个州
  svg.selectAll(".state")
      // 绑定各个州的地理信息数据到 样式类为state的元素上
      .data(topojson.feature(us, us.objects.states).features)
    .enter().append("path")
      .attr("class", "state")
      // 为path元素的d属性绑定路径函数 path()函数,即前面定义的 var path = d3.geo.path();
      .attr("d", path)
      // 确定各个州的位置摆放问题
      .attr("transform", function(d) 
        // 获取州的中心坐标
        var centroid = path.centroid(d),
            x = centroid[0],
            y = centroid[1];
        // 将各个州的图形先向右向下分别移动x,y,然后按照肥胖比例算出的缩放比例进行缩放;之后又将缩放后的州的图形向左向上分别移动 x,y,即回到州的中心位置
        return "translate(" + x + "," + y + ")"
            + "scale(" + Math.sqrt(valueById[d.id] * 5 || 0) + ")"
            + "translate(" + -x + "," + -y + ")";
      )
      // 州的肥胖比例越高,那么州的边缘线越细
      .style("stroke-width", function(d) 
        return 1 / Math.sqrt(valueById[d.id] * 5 || 1);
      );
);

</script>

至此,这幅不连续的示意性地图的实现解析完毕,非常想说的是,这里展示各个地区的肥胖比例的方式很独特,不是通常的用颜色来区分不同的数据范围,而是用 各个州之间的稀疏程度来展示,肥胖比例较高的区域的州之间非常拥挤,肥胖比例较低的区域的州之间距离比较稀疏,非常形象地描述了肥胖比例这一数据的特性。我非常喜欢这个思路,打破了以往的用花花绿绿的颜色来展示数据特性的方式。

以上是关于D3.js 中的 Non-Contiguous Cartogram详解的主要内容,如果未能解决你的问题,请参考以下文章

如何通过D3.js中的JSON文件解析按键对对象进行排序[重复]

Javascript / D3.js - 绘制大型数据集 - 提高 d3.js 绘制的 svg 图表中的缩放和平移速度

如何暂时禁用 d3.js 中的缩放

D3.js 中的简单散点图示例?

D3.js使用过程中的常见问题(D3版本D3V4)

如何知道 D3.js 中的当前缩放级别