0

我有一个可视化显示纽约地铁穿过的人口普查区中收入水平的中位数(图片在这里 - 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)。认为最好的方法是在县切换时只画一条垂直线,然后在底部附加自治市镇的名称。

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

4

1 回答 1

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_lineandupdate_chart函数之间重复代码。有关这方面的更多信息,请查看d3 教程页面上的通用更新模式(第 I、II 和 III 部分)。

于 2013-04-09T07:23:27.950 回答