我有一个D3 api,我必须显示一些关系,我使用json作为数据但是在两个不同的时间我从json的相同结构得到两个不同的api输出。我发布了两个jsons。
{
"nodes" : [ {
"name" : "Jeet123",
"type" : 1,
"slug" : "",
"entity" : "company"
}, {
"name" : "9804500485",
"type" : 2,
"slug" : "",
"entity" : "number"
}, {
"name" : "9804086391",
"type" : 2,
"slug" : "",
"entity" : "number"
}, {
"name": "offnet",
"type" : 3,
"slug" : "",
"entity" : "employee"
},{
"name" : "onnet",
"type" : 3,
"slug" : "",
"entity" : "employee"
},{
"name" : "offsms",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "offvoice",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "onsms",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "onvoice",
"type" : 4,
"slug" : "",
"entity" : "description"
}, {
"name": "offnet1",
"type" : 3,
"slug" : "",
"entity" : "employee"
},{
"name" : "onnet1",
"type" : 3,
"slug" : "",
"entity" : "employee"
},{
"name" : "offsms1",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "offvoice1",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "onsms1",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "onvoice1",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "Subho",
"type" : 1,
"slug" : "",
"entity" : "company"
}, {
"name" : "9804125689",
"type" : 2,
"slug" : "",
"entity" : "number"
}, {
"name" : "9854789651",
"type" : 2,
"slug" : "",
"entity" : "number"
}, {
"name": "offnet",
"type" : 3,
"slug" : "",
"entity" : "employee"
},{
"name" : "onnet",
"type" : 3,
"slug" : "",
"entity" : "employee"
},{
"name" : "offsms",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "offvoice",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "onsms",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "onvoice",
"type" : 4,
"slug" : "",
"entity" : "description"
}, {
"name": "offnet1",
"type" : 3,
"slug" : "",
"entity" : "employee"
},{
"name" : "onnet1",
"type" : 3,
"slug" : "",
"entity" : "employee"
},{
"name" : "offsms1",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "offvoice1",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "onsms1",
"type" : 4,
"slug" : "",
"entity" : "description"
},{
"name" : "onvoice1",
"type" : 4,
"slug" : "",
"entity" : "description"
}
],
"links" : [ {
"source" : 0,
"target" : 1,
"value" : 1,
"distance" : 5
}, {
"source" : 0,
"target" : 2,
"value" : 1,
"distance" : 5
}, {
"source" : 1,
"target" : 3,
"value" : 1,
"distance" : 5
},{
"source" : 1,
"target" : 4,
"value" : 1,
"distance" : 5
},{
"source" : 3,
"target" : 5,
"value" : 2,
"distance" : 5
},{
"source" : 3,
"target" : 6,
"value" : 1,
"distance" : 5
},{
"source" : 4,
"target" : 7,
"value" : 2,
"distance" : 5
},{
"source" : 4,
"target" : 8,
"value" : 1,
"distance" : 5
},{
"source" : 2,
"target" : 9,
"value" : 1,
"distance" : 5
},{
"source" : 2,
"target" : 10,
"value" : 1,
"distance" : 5
},{
"source" : 9,
"target" : 11,
"value" : 2,
"distance" : 5
},{
"source" : 9,
"target" : 12,
"value" : 1,
"distance" : 5
},{
"source" : 10,
"target" : 13,
"value" : 2,
"distance" : 5
},{
"source" : 10,
"target" : 14,
"value" : 1,
"distance" : 5
},{
"source" : 15,
"target" : 16,
"value" : 1,
"distance" : 5
},{
"source" : 15,
"target" : 17,
"value" : 1,
"distance" : 5
},{
"source" : 16,
"target" : 18,
"value" : 2,
"distance" : 5
},{
"source" : 16,
"target" : 19,
"value" : 1,
"distance" : 5
},{
"source" : 18,
"target" : 20,
"value" : 2,
"distance" : 5
},{
"source" : 18,
"target" : 21,
"value" : 1,
"distance" : 5
},{
"source" : 19,
"target" : 22,
"value" : 2,
"distance" : 5
},{
"source" : 19,
"target" : 23,
"value" : 1,
"distance" : 5
},{
"source" : 17,
"target" : 24,
"value" : 1,
"distance" : 5
},{
"source" : 17,
"target" : 25,
"value" : 1,
"distance" : 5
},{
"source" : 24,
"target" : 26,
"value" : 2,
"distance" : 5
},{
"source" : 24,
"target" : 27,
"value" : 1,
"distance" : 5
},{
"source" : 25,
"target" : 28,
"value" : 2,
"distance" : 5
},{
"source" : 25,
"target" : 29,
"value" : 1,
"distance" : 5
}
]
}
这是正常工作的json
这是json无法正常工作。
{
"nodes":[{
"name":"9748108991",
"type":1,
"slug":"",
"entity":"company"
},{
"name":"offnet",
"type":1,
"slug":"",
"entity":"employee"
},{
"name":"onnet",
"type":1,
"slug":"",
"entity":"employee"
},{
"name":"8749258125",
"type":4,
"slug":"",
"entity":"description"
},{
"name":"9748697490",
"type":4,
"slug":"",
"entity":"description"
}],
"links":[{
"source":0,
"target":1,
"value":1,
"distance":5
},{
"source":0,
"target":2,
"value":1,
"distance":5
},{
"source":1,
"target":3,
"value":4,
"distance":5
},{
"source":1,
"target":4,
"value":4,
"distance":5
}]
}
这就是我正在使用的API ..
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<style>
/* CSS Document */
.link2 {
stroke: #000;
stroke-width: 2px;
stroke-dasharray:3,3;
}
.link1 {
stroke: #000;
stroke-width: 2px;
}
.nodetext {
pointer-events: none;
}
.node.type4 {
fill: #800000;
}
.node.type1 {
fill: #BF00426;
}
.node.type3 {
fill: #0000A0;
size: 20px;
}
.node.type2 {
fill: #008000;
size: 40px;
}
.node.type4 {
fill: #65000b;
size: 40px;
}
image.circle {
cursor: pointer;
}
.fadein {
display: none;
font-size: 20px;
}
.rectD {
background-color: #000000;
width: 70px;
height: 30px
}
.rectL {
background-color: #000000;
width: 90px;
height: 30px
}
</style>
<script src="http://d3js.org/d3.v2.js?2.9.1"></script>
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
</head>
<body>
<script>
var w = 1200, h = 900, radius = d3.scale.log().domain([0,312000 ])
.range([ "10", "50" ]);
var vis = d3.select("body").append("svg:svg").attr("width", w).attr(
"height", h);
vis.append("marker")
.attr("id", "arrowhead")
.attr("refX", 6 + 6) /*must be smarter way to calculate shift*/
.attr("refY", 2)
.attr("markerWidth", 6)
.attr("markerHeight", 4)
.attr("orient", "auto")
.append("path")
.attr("d", "M 0,0 V 4 L6,2 Z"); //this is actual shape for arrowhead
d3.json("myjson.json", function(data,error) {
var force = self.force = d3.layout.force().nodes(data.nodes).links(
data.links).linkDistance(function(d) {
return (d.distance * 10);
})
//.friction(0.5)
.charge(-250).size([ w, h ]).start();
var link = vis.selectAll("line.link").data(data.links).enter().append(
"svg:line").attr("class", function(d) {
return "link" + d.value + "";
}).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;
}).attr("marker-end", function(d) {
if (d.value == 10 || d.value==1) {
return "url(#arrowhead)"
} else {
return " "
}
;
});
function openLink() {
return function(d) {
var url = "";
if (d.slug != "") {
url = d.slug
} else if(d.type == 2) {
url = "clients/" + d.slug
} else if(d.type == 3) {
url = "agencies/" + d.slug
}
window.open("//" + url)
}
}
var node = vis.selectAll("g.node").data(data.nodes).enter().append(
"svg:g").attr("class", "node").call(force.drag);
// size of the nodes are given here
node.append("circle").attr("class", function(d) {
return "node type" + d.type
}).attr("r", function(d) {
if (d.entity == "description") {
return 16
} else if(d.entity=="company"){
return 14
}else if(d.entity=="number"){
return 25
}else{
return 18
}
})
node.append("text").attr("class", function(d) {
return "nodetext title_" + d.name
}).attr("dx", 0).attr("dy", ".35em").style("font-size", "10px").attr(
"text-anchor", "middle").style("fill", "white").text(
function(d) {
return d.name
});
node.on("mouseover", function(d) {
if (d.entity == "description") {
d3.select(this).select('text').transition().duration(300).text(
function(d) {
return d.name;
}).style("font-size", "15px")
} else if (d.entity == "employee") {
var asdf = d3.select(this);
asdf.select('text').remove();
asdf.append("text").text(function(d) {
return d.prefix + ' ' + d.fst_name
}).attr("class", "nodetext").attr("dx", 0).attr("dy", ".35em")
.style("font-size", "5px")
.attr("text-anchor", "middle").style("fill", "white")
.transition().duration(300).style("font-size", "12px");
asdf.append("text").text(function(d) {
return d.snd_name
}).attr("class", "nodetext").attr("transform",
"translate(0, 12)").attr("dx", 0).attr("dy", ".35em")
.style("font-size", "5px")
.attr("text-anchor", "middle").style("fill", "white")
.transition().duration(300).style("font-size", "12px");
} else {
d3.select(this).select('text').transition().duration(300)
.style("font-size", "15px")
}
if (d.entity == "company") {
d3.select(this).select('image').attr("width", "100px").attr("x",
"-46px").attr("y", "-36.5px").attr("xlink:href",
function(d) {
return d.name
});
}
if (d.entity == "company") {
d3.select(this).select('circle').transition().duration(300)
.attr("r", 28)
} else if (d.entity == "employee") {
d3.select(this).select('circle').transition().duration(300)
.attr("r", 15)
}
});
node.on("mouseout", function(d) {
if (d.entity == "company") {
d3.select(this).select('text').transition().duration(300).text(
function(d) {
return d.name;
}).style("font-size", "10px")
} else if (d.entity == "employee") {
///////////////////////////
// CHANGE
///////////////////////////
d3.select(this).selectAll('text').remove();
//d3.select(this).select('text')
d3.select(this).append('text').text(function(d) {
return d.name;
}).style("font-size", "14px").attr("dx", 0).attr("dy", ".35em")
.attr("text-anchor", "middle").style("fill", "white")
.attr("class", "nodetext").transition().duration(300)
.style("font-size", "10px")
} else {
d3.select(this).select('text').transition().duration(300)
.style("font-size", "10px")
}
if (d.entity == "company") {
d3.select(this).select('image').attr("width", "70px").attr("x",
"-36px").attr("y", "-36px").attr("xlink:href",
function(d) {
return d.img_hrefD
});
}
if (d.entity == "company" || d.entity == "employee") {
d3.select(this).select('circle').transition().duration(300)
.attr("r", 18)
}
});
node.on("mouseover", fade(.4, "red")).on("mouseout", fade(1));
var linkedByIndex = {};
data.links.forEach(function(d) {
linkedByIndex[d.source.index + "," + d.target.index] = 1;
});
function isConnected(a, b) {
return linkedByIndex[a.index + "," + b.index]
|| linkedByIndex[b.index + "," + a.index]
|| a.index == b.index;
}
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 + ")";
});
});
function getConnected(cn, d, level) {
node.each(function(o) {
if(isConnected(d, o) && cn.indexOf(o) == -1) {
cn.push(o);
if(level > 0) getConnected(cn, o, level-1);
};
});
return cn;
}
function fade(opacity,color) {
return function(d) {
node.style("stroke-opacity", function(o) {
thisOpacity = isConnected(d, o) ? 1 : opacity;
this.setAttribute('fill-opacity', thisOpacity);
return thisOpacity;
});
link.style("stroke-opacity", function(o) {
return o.source === d || o.target === d ? 1 : opacity;
})
.style("stroke", function(o) {
return o.source === d || o.target === d ? color : "#000" ;
});
};
}
});
</script>
</body>
这是有时会显示两个未连接的节点的图片....但是当我使用第一个json时,它会很好地工作
答案 0 :(得分:0)
它似乎不起作用的原因是第二个JSON中的链接具有其他JSON中不会出现的值。这意味着它们将被分配一个不定义CSS的不同类。链接在那里,它们只是没有样式,所以你可以看到它们。
添加此CSS可修复它。
.link4 {
stroke: #000;
stroke-width: 2px;
}
完整示例here。