【问题标题】:Dynamically project a Single County动态投影单个县
【发布时间】:2017-01-22 17:09:23
【问题描述】:

这是一个简单但鼓舞人心的单一状态 topojson:

https://bl.ocks.org/mbostock/7061976

它是由仅包含该状态的 json 中的数据绘制的,如下所示:

d3.json("va-counties.json", function(error, topo) {
  if (error) throw error;

我想做的是动态规划一个县。假设有一个键盘事件或其他运行函数的东西:读入解析的数据,找到县 id,并返回仅该县的 topojson 特征。上述块与我的案例之间的区别在于,我的 json 文件将包含美国的所有县,但我一次只需要 1 个县。有没有办法在 D3 中实现这一点?

作为一个简单的试金石,我尝试了县 id=1000:

  var current_county = topojson.feature(topo, topo.objects.counties).filter(function(d) { return d.id=1000;})),
      bounds = path.bounds(county);

然而,无论我多么辛苦地处理它,我都会不断地遇到错误。或者它会停止抛出错误,但仍然不能“工作”。也许.filter() 不是这项工作的最佳工具?还有什么意见?

感谢您的阅读

【问题讨论】:

    标签: javascript d3.js topojson


    【解决方案1】:

    首先你的filter 语法是错误的,我认为你的意思是比较而不是赋值:

    d.id === 1000
    

    其次,topojson.feature 返回一个对象中的 GeoJSON,它不会像那样过滤。最好的办法是在进入的过程中对其进行过滤:

    // filter the geometries of the topojson the structure you want
    var geoCounty = topo.objects.counties.geometries.filter(function(d){
      return d.id === "51750";
    });
    
    // assign it back to the topojson object
    topo.objects.counties.geometries = geoCounty;
    
    // and off you go...
    var county = topojson.feature(topo, topo.objects.counties),
        bounds = path.bounds(county);
    

    完整运行代码:

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
    
    .county {
      fill: #ccc;
    }
    
    </style>
    <body>
    <script src="//d3js.org/d3.v3.min.js"></script>
    <script src="//d3js.org/d3.geo.projection.v0.min.js"></script>
    <script src="//d3js.org/topojson.v1.min.js"></script>
    <script>
    
    var width = 500,
        height = 300;
    
    var projection = d3.geo.conicConformal()
        .parallels([38 + 02 / 60, 39 + 12 / 60])
        .rotate([78 + 30 / 60, 0])
        .scale(200000)
        .translate([0, 0]);
    
    var path = d3.geo.path()
        .projection(projection);
    
    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
    
    d3.json("https://jsonblob.com/api/ce96ca06-e1ce-11e6-90ab-03e5986c4e20", function(error, topo) {
      if (error) throw error;
    
      var geoCounty = topo.objects.counties.geometries.filter(function(d){
        return d.id === "51750";
      });
    
      topo.objects.counties.geometries = geoCounty;
    
      var county = topojson.feature(topo, topo.objects.counties),
          bounds = path.bounds(county);
    
      projection
          .translate([width / 2 - (bounds[0][0] + bounds[1][0]) / 2, height / 2 - (bounds[0][1] + bounds[1][1]) / 2]);
    
      svg.append("path")
          .datum(county)
          .attr("class", "county")
          .attr("d", path);
    
    });
    
    </script>

    【讨论】:

    • 这很有意义。感谢您向我展示了正确的约定。你是对的,我应该使用比较===。我正在尝试测试您的示例,但是在指向库时遇到了问题。我不断收到“错误:无效或意外的令牌”。来自 d3.projection.js 文件。我知道 D3.js 是 utf-8,那有什么不同吗?我该怎么办??
    • @ArashHowaida,该错误消息应该将您指向一行代码。当你检查它时,它看起来有什么不对吗?错误真的来自d3.projection.js 还是您的代码?如果不复制它,我几乎不可能为您调试它。
    • 它说d3js.org/d3.geo.projection.v0.min.js 第 1 行,而不是来自主 html。让我运行一些测试,看看它是什么编码。
    • 我真的很困惑。如果我们省略d3.geo.projection.v0.min.js,你的方法会奏效吗?赞成标准投影方式?我猜角度会有所不同,但不会那么明显。我尝试只更改投影函数,但除了投影变量之外,似乎还有其他一些对 geo.projection 脚本的调用。在我弄清楚我对库的引用有什么问题之前,我们可以将其用作解决方案。
    • @ArashHowaida,当然。 Here is it 与标准 d3.geo.albersUsa 一起运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多