JS-如何删除重复的JSON节点并为所有合并的节点添加一个链接 [英] JS- how to remove duplicate JSON nodes and add one link for all nodes that get merged

查看:159
本文介绍了JS-如何删除重复的JSON节点并为所有合并的节点添加一个链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在此处输入代码我有一个JSON文件,我想从中创建一个带有箭头的d3定向
图形,影响得分较高

  {nodes:[{Name:GJA,influenceScore:81.0,type:10.0},
{Name:JJZ,influenceScore:82.6,type:30.0},
{Name:SAG,influenceScore:89.0,type:30.0} ,
{Name:JJZ,influenceScore:82.6,type:30.0}],links:
[{source:0,target type:SA,value:1},
{source:0,target:1,type:SA,value:1},
{source:0,target:2,type:SA,value:1},
{source:0,target:3,type SA,value:1}]}

我是一个d3novice,所以想要一些
我的d3代码在这里:

  .link {
stroke:#ccc;
}

.node text {
pointer-events:none;
字体:12px sans-serif;
}

< / style>


< body>
< script src =// d3js.org/d3.v3.min.js\">< t; / script>
< script>
var width = 1200,
height = 900;

var color = d3.scale.category10();
var fill = d3.scale.category10();
var svg = d3.select(body)。append(svg)
.attr(width,width)
.attr(height,height);

var force = d3.layout.force()
.gravity(0.052)
.distance(350)
.charge(-20)
.size([width,height]);

d3.json(\\abc.json,function(error,json){
if(error)throw error;

force
.nodes(json.nodes)
.links(json.links)
.start();

var link = svg.selectAll(。link)
.data(json.links)
.enter()。append(line)
.attr(class,link)。style(stroke-width,函数(d){return
Math.sqrt(d.value);})。style(stroke,function(d){return $ b $ fill(d.value);});

var node = svg.selectAll(。node)
.data(json.nodes)
.enter()。append(g)
.attr (class,node)
.call(force.drag);

node.append(circle)
.attr(class,node )
.attr(r,function(d){return(d.influenceScore / 10)+ 10;
})。style(fill,function(d){return color( d.type);});

node.append(text)
.attr(dx,-35)
.attr(dy, text(function(d){return d.Name});


node.append(title)。text(function(d){return d。娜);


force.on(tick,function(){
link.attr(x1,function(d){return d.source 。X; })
.attr(y1,function(d){return d.source.y;})
.attr(x2,function(d){return d.target.x; })
.attr(y2,function(d){return d.target.y;});

node.attr(transform,function(d){returntranslate(+ d.x +,+ d.y +
);});
});
});

我收到以下图片



我希望目标节点(例如JJZ)只出现一次(目前它发生的次数与在JSON中重复的次数相同,即在给定示例中为2次)连接两个节点的线应根据节点重复的次数增加厚度。所以连接JJZ和GJA的蓝线应该比GJA和SAG厚,如果另一个节点出现5倍,应该比JJZ和GJA厚。另外我该如何在影响力较高的方向上插入指示箭头

解决方案

您的问题与D3无关:你可以用普通的JavaScript操作你的数组。



这个函数根据 json.nodes 查找对象。属性名称。如果它不存在,它会将该对象推入一个名为 filtered 的数组中。如果它已经存在,它将增加该对象中 count 的值:

  var filtered = [] 

json.nodes.forEach(function(d){
if(!this [d.Name]){
d.count = 0 ;
this [d.Name] = d;
filtered.push(this [d.Name])
}
this [d.Name] .count + = 1
},Object.create(null))

以下是演示:



var json = {nodes:[{Name: GJA, influenceScore:81.0, 类型:10.0},{ 名称: JJZ, influenceScore:82.6, 类型:30.0},{ 名称: SAG,influenceScore :89.0, 类型 :30.0},{ 名称 : JJZ, influenceScore:82.6, 类型:30.0}], 链接:[{ 源:0, 目标: 0, 类型: SA, 值:1},{ 源:0, 目标:1, 类型: SA, 值:1},{ 源: 0, 目标:2, 类型: SA, 值:1},{S我们可以通过下面的例子来说明如何使用这个函数来创建一个函数:this(0),target:3,type:SA,value:1}]}; var filtered = [] json.nodes.forEach .Name]){d.count = 0;这[d.Name] = d; filtered.push(this [d.Name])} this [d.Name] .count + = 1},Object.create(null))console.log(已过滤) count 来设置 笔画宽度您的链接。


enter code here I have a JSON File from which I want to create a d3 directed graph with arrows in the direction of higher influence score

{"nodes":[{"Name":"GJA","influenceScore":81.0,"type":10.0},
{"Name":"JJZ","influenceScore":82.6,"type":30.0},
{"Name":"SAG","influenceScore":89.0,"type":30.0},
{"Name":"JJZ","influenceScore":82.6,"type":30.0}],"links":
[{"source":0,"target":0,"type":"SA","value":1},
{"source":0,"target":1,"type":"SA","value":1},
{"source":0,"target":2,"type":"SA","value":1},
{"source":0,"target":3,"type":"SA","value":1}]}

I am a d3novice, so would like some help from experts here My d3 code is here:

.link {
 stroke: #ccc;
 }

.node text {
 pointer-events: none;
 font: 12px sans-serif;
 }

</style>


<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var width = 1200,
    height = 900;

var color = d3.scale.category10();
var fill = d3.scale.category10();
var svg = d3.select("body").append("svg")
   .attr("width", width)
   .attr("height", height);

var force = d3.layout.force()
   .gravity(0.052)
   .distance(350)
   .charge(-20)
   .size([width, height]);

d3.json("\\abc.json", function(error, json) {
 if (error) throw error;

 force
  .nodes(json.nodes)
  .links(json.links)
  .start();

var link = svg.selectAll(".link")
   .data(json.links)
   .enter().append("line")
   .attr("class", "link").style("stroke-width", function(d) { return 
    Math.sqrt(d.value); }).style("stroke", function(d) {return 
    fill(d.value);});

var node = svg.selectAll(".node")
  .data(json.nodes)
 .enter().append("g")
  .attr("class", "node")
  .call(force.drag);

  node.append("circle")
  .attr("class", "node")
  .attr("r", function(d) { return (d.influenceScore/10) + 10; 
  }).style("fill", function(d) { return color(d.type); });

  node.append("text")
  .attr("dx", -35)
  .attr("dy", "4.5em").text(function(d) { return d.Name });


  node.append("title").text(function(d) { return d.Name ;});


 force.on("tick", function() {
  link.attr("x1", function(d) { return d.source.x; })
    .attr("y1", function(d) { return d.source.y; })
    .attr("x2", function(d) { return d.target.x; })
    .attr("y2", function(d) { return d.target.y; });

node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + 
 ")"; });
   });
  });

I am getting the following image

I would like the target node e.g JJZ here just to occur once ( currently it's occurring as many number of times as it is repeated in the JSON i.e 2 times in the given example) however the line joining the two nodes should increase in thickness depending on the number of times the nodes repeat. so the blue line linking JJZ with GJA should be thicker than GJA and SAG and if another node occurs 5 times that should be thicker than JJZ and GJA. Also how do I insert directed arrows in the direction of a higher influence score

解决方案

Your question here has little to do with D3: you can manipulate your array with plain JavaScript.

This function looks for the objects on json.nodes based on the property Name. If it doesn't exist, it pushes the object into an array that I named filtered. If it already exists, it increases the value of count in that object:

var filtered = []

json.nodes.forEach(function(d) {
  if (!this[d.Name]) {
    d.count = 0;
    this[d.Name] = d;
    filtered.push(this[d.Name])
  }
  this[d.Name].count += 1
}, Object.create(null))

Here is the demo:

var json = {"nodes":[{"Name":"GJA","influenceScore":81.0,"type":10.0},
{"Name":"JJZ","influenceScore":82.6,"type":30.0},
{"Name":"SAG","influenceScore":89.0,"type":30.0},
{"Name":"JJZ","influenceScore":82.6,"type":30.0}],"links":
[{"source":0,"target":0,"type":"SA","value":1},
{"source":0,"target":1,"type":"SA","value":1},
{"source":0,"target":2,"type":"SA","value":1},
{"source":0,"target":3,"type":"SA","value":1}]};

var filtered = []

json.nodes.forEach(function(d){
	if(!this[d.Name]){
  	d.count = 0;
  	this[d.Name] = d;
    filtered.push(this[d.Name])
  }
  this[d.Name].count += 1
}, Object.create(null))

console.log(filtered)

Then, you just need to use the property count to set the stroke-width of your links.

这篇关于JS-如何删除重复的JSON节点并为所有合并的节点添加一个链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆