D3:序数尺度,测距带和纽约地铁

时间:2013-04-09 02:13:24

标签: d3.js

我有一个可视化显示纽约地铁经过的人口普查区域的收入水平中位数(图片在这里 - https://dl.dropbox.com/u/17156665/Screen%20Shot%202013-04-08%20at%209.56.20%20PM.png)。希望清楚地显示哪个站点在哪个区域。将此文件用于数据(https://docs.google.com/spreadsheet/pub?key=0ApL2ZVhpOmONdFdTUWhxV252elNORVNqT0g5Y0NzV1E&output=html)。认为最好的方法是在县切换时绘制一条垂直线,然后在底部附加自治市镇的名称。

现在我在背景中有一系列rects,每个都有一个if语句,但它非常笨重。玩过有序音阶和测距带无济于事。任何更好的解决方案非常感

1 个答案:

答案 0 :(得分:1)

(这是一个非常有趣的数据并置!)

IMO的序数规模对此来说过于笨重,但更重要的是,在一条线路经过同一个区域不止一次的情况下会出现问题(如 M 线,在皇后区开始和结束);因为序数量表需要唯一值。

可能最好的解决方案是首先建立一个数据数组,代表每个行政区的起始位置和跨越的停靠点数。例如。对于 M 行,它看起来像这样:

[
  {
    "county": "81",
    "countyName": "Queens"
    "start": 1,
    "span": 14
  },
  {
    "county": "61",
    "countyName": "Manhattan"
    "start": 15,
    "span": 10
  },
  {
    "county": "47",
    "countyName": "Brooklyn"
    "start": 25,
    "span": 7
  },
  {
    "county": "81",
    "countyName": "Queens"
    "start": 32,
    "span": 5
  }
]

创建此数据数组的一种(有点神秘但非常简洁)方法是在过滤后的数据上调用reduce()方法。像这样:

    boroughs = filtered_data.reduce(
      function(memo, stop, i) {
        var len = memo.length;
        if(len == 0 || (memo[len - 1].county != stop.county)) {
          memo.push({
            county: stop.county,
            start: i+1,
            span: 1
            countyName: "foo"// This needs a dictionary mapping county code to name 
          });
        }
        else {
          memo[len - 1].span++;
        }
        return memo;
      },
      []
    )

构建此数据后,您将其绑定到d3选择并为每个条目创建一个组。即,如果一条线穿过3个区域,你将创建3个组。在每个组中,您可以为行政区的名称附加text,并为rectline附加描述。像这样:

  // note the use of your `stop_scale` for calculating positions/widths
  d3.selectAll('g.borough').data(boroughs)
    gCounties.enter()
      .append('g')// Create a group
      .attr('class', 'borough'
      .attr('transform', function(d) {// move the group to its appropriate x position
        return 'translate(' + stop_scale(d.start+1) + ')';
      })
      .each(function(d, i) {// inside each group:
        // append a rect (this is just an example)
        d3.select(this)
          .append('rect')
          .style('stroke', '#000')
          .attr('x', 0)
          .attr('width', stop_scale(d.span))
          .attr('height', 50);// This height should be changed to match your chart
        // append a text
        d3.select(this)
          .append('text')
          .text(d.countyName);
      });

顺便说一下,您的代码可以使用重构。您不必在draw_first_lineupdate_chart函数之间重复代码。有关详细信息,请查看d3 tutorials page上的常规更新模式(第I,II和III部分)。