【问题标题】:consume nested data in d3/javascript使用 d3/javascript 中的嵌套数据
【发布时间】:2018-01-04 12:00:04
【问题描述】:

我目前正在 d3 中处理一个项目,其中我从 csv 文件创建了一个嵌套的 json 对象(参见代码 sn-p)它有多个键和一组值,我想在地图上绘制它们。

0:
   key: "Islamic State of Iraq and the Levant (ISIL)"
      values:
         kills: 30889
         map_data:
            Array(4287)
               [0 … 99]
                  0: {longitude: "44.290423", latitude: "33.297678", nkill: "28", nwound: "50", city: "Baghdad", …}
                  1: {longitude: "44.356585", latitude: "32.985052", nkill: "0", nwound: "4", city: "Latifiyah", …}
1:
   key: "Taliban"
      values:
         kills: 24482
         map_data: 
            Array(6575)
               [0 … 99]
                  0: {longitude: "", latitude: "", nkill: "0", nwound: "0", city: "Unknown", …}
                  1: {longitude: "65.675942", latitude: "31.617667", nkill: "0", nwound: "0", city: "Kandahar", …}

[编辑] 我想为 map_data 数组中的每个项目投影一个圆圈,但圆圈属性只取一个值,正如 Shashank 的评论中所说。还有其他方法可以在属性中获取我的正确数据吗?

g.selectAll("circle")
.data(topgroups)
.enter()
.append("a")
.attr("xlink:href", function(d) {
    return "https://www.google.com/search?q="+d.key;}
)
.append("circle")
.attr("cx", function(d) {
    d.values.map_data.map(function (t) {
        return projection([t.Longitude, t.Latitude])[0];
    })
})
.attr("cy", function(d) {
    d.values.map_data.map(function (t) {
        return projection([t.Longitude, t.Latitude])[1];
    })
})
.attr("r", function(d) {
    d.values.map_data.map(function (t) {
        return t.nkill/500;
    })
})
.style("fill", "red");

【问题讨论】:

  • 感谢您回复编辑。所以here 是如何为圆定义属性的。在您的情况下,cx, cy and r 通过执行 d.values.map_data.map() 被分配了一个数组,这是行不通的。您能否澄清一下:由于屏幕截图中的 map_data4287 元素的 Array,您是否尝试添加位于 projection([longitude, latitude)[0]4287 圈子?
  • 我正在尝试为 map_data 数组中的每个项目投影一个圆圈

标签: javascript json d3.js


【解决方案1】:

感谢您返回确切的要求和更多代码。事情是这样的:

您正在尝试绑定一个对象,而您总是必须将一个数组绑定到 D3 中的选择。

由于map_data 数组中的每个项目都需要圆圈,因此您必须将此数组绑定到d3.selectAll('circle')

查看this link 以了解有关 D3 中数据绑定的更多信息。

这是一个代码 sn-p,它执行上述操作并将圆圈与属性 cxcyr 一起根据您的初始要求分配到 SVG,即调用 projection 等。

它包含一个类似于您的示例数组,但请确保您提供数据的代码 sn-p 而不是屏幕截图

var topgroups = {
	key: 'ISIL',
  values: {
  	kills: 30899,
    map_data: [
    	{
	    	city: "A",
  	    latitude: '20',
    	  longitude: '40',
        nkill: 100
       },
       {
       	city: "B",
        latitude: '90',
        longitude: '50',
        nkill: 200
       },
       {
       	city: "C",
        latitude: '120',
        longitude: '140',
        nkill: 300
       },
       {
       	city: "D",
        latitude: '120',
        longitude: '250',
        nkill: 400
       }
    ]
  }
};

function projection(lt, long) {
	return [lt, long];
}

d3.select('body').append('svg')
	.attr('width', 400).attr('height', 350)
  .append('g').attr('class', 'circles');
  
  
var circles = d3.select('svg g.circles').selectAll('circle')  
								.data(topgroups.values.map_data);
                
   circles.enter().append('circle')
   	.attr('cx', function(d) {
 			return projection(+d.latitude, +d.longitude)[0];   
    }).attr('cy', function(d) {
    	return projection(+d.latitude, +d.longitude)[1];
    })
   	.attr('r', function(d) {
    	return d.nkill/40;
    });
    
    
  
<script src="https://d3js.org/d3.v4.min.js"></script>

希望这会有所帮助。

编辑: 最初在图像中,它显示为一个对象,因此是上面的代码。无论如何,如果它是一个数组,我想你会从那里拿走它。这是简单的 进入/更新/退出 模式。

这是一个 sn-p 这样做的:

var topgroups = [
{
	key: 'ISIL',
  values: {
  	kills: 30899,
    map_data: [
    	{
	    	city: "A",
  	    latitude: '20',
    	  longitude: '40',
        nkill: 100
       },
       {
       	city: "B",
        latitude: '90',
        longitude: '50',
        nkill: 200
       },
       {
       	city: "C",
        latitude: '120',
        longitude: '140',
        nkill: 300
       },
       {
       	city: "D",
        latitude: '120',
        longitude: '250',
        nkill: 400
       }
    ]
  }
},
{
	key: 'ISIL2',
  values: {
  	kills: 308990,
    map_data: [
    	{
	    	city: "E",
  	    latitude: '100',
    	  longitude: '40',
        nkill: 100
       },
       {
       	city: "F",
        latitude: '10',
        longitude: '120',
        nkill: 200
       }
    ]
  }
}
];

function projection(lt, long) {
	return [lt, long];
}

var svg = d3.select('body').append('svg')
	.attr('width', 400).attr('height', 350);
  
  var g = svg.selectAll('g.circles').data(topgroups);
  	g.enter().append('g').attr('class', 'circles').attr('data-key', function(d) { return d.key; });
  
  
var circles = d3.selectAll('svg g.circles').selectAll('circle')  
                .data(function(d) { 
                	return d.values.map_data; 
                });
                
   circles.enter().append('circle')
     .attr('cx', function(d) {
       return projection(+d.latitude, +d.longitude)[0];   
    }).attr('cy', function(d) {
      return projection(+d.latitude, +d.longitude)[1];
    })
     .attr('r', function(d) {
      return d.nkill/40;
    });
    
    
  
<script src="https://d3js.org/d3.v4.min.js"></script>

希望这会有所帮助。 :)

【讨论】:

  • 好吧,我可以通过这种方式访问​​数据,但属性不想显示数据
  • 哦,我也很糟糕!我没有查属性。 cx 属性只需要 1 个值,但在这种情况下,您将返回一个绝对行不通的数组。如果您能提供更多的代码、数据,那就太好了。
  • 我根据您的回答编辑了我的问题我希望这可以为您提供足够的信息来帮助我
  • 您提供的答案并不完全有效,因为我有不止一个键,因此它还需要遍历所有键,然后需要遍历每个键的 map_data 数组。我还向您提出的问题添加了截取我的数据的代码。我希望这足以让它现在工作
  • 抱歉这么晚才回来。查看最新编辑和新代码 sn-p。
猜你喜欢
  • 2015-12-06
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-17
  • 1970-01-01
相关资源
最近更新 更多