我的JSON数据如下:
var IDData = JSON.stringify([
["node/105173", "node/38180995", "Agent", "Customer", "1379644.0", 1, 264, "1374903"],
["node/1061", "node/21373542", "Agent", "Customer", "530848.0", 1, 3000, "529502"],
["node/10750", "node/59648369", "Agent", "Customer", "1454228.0", 1, 120, "1454118"],
["node/10750", "node/78569210", "Agent", "Customer", "1425251.0", 1, 234, "1421416"],
["node/10750", "node/96726118", "Agent", "Customer", "1376239.0", 1, 434, "1376152"],
["node/10946829", "node/11190", "Customer", "Agent", "1409620.0", 20, 3380, "1406665"]...])
数组数组的长度是固定的,但格式保持不变。
以下是工作JSfiddle的链接:
https://jsfiddle.net/user/vishy1988/fiddles/
上面的代码在我的系统上正常运行。但出于某种原因,我不能让它在JSfiddle上运行。代码生成下图。
这是我迭代上面的数组并为图形制作数据的方法:
$(document).ready(function() {
console.log(IDData);
var galData = JSON.parse(IDData);
var startnodes = [];
var endnodes = [];
var startnodetype = [];
var endnodetype = [];
var PayTime = [];
var TXN_COUNT = [];
var Total_Amt = [];
var SendTime = [];
galData.map(function(e, i) {
startnodes.push(e[0]);
endnodes.push(e[1]);
startnodetype.push(e[2]);
endnodetype.push(e[3]);
PayTime.push(e[4]);
TXN_COUNT.push(e[5]);
Total_Amt.push(e[6]);
SendTime.push(e[7]);
});
var final_data = createNodes(startnodes, endnodes, startnodetype, endnodetype, PayTime, TXN_COUNT, Total_Amt, SendTime);
makeGraph("#Network_graph", final_data);
});
创建渲染图形所需数据的createnodes函数如下:
function createNodes(startnodes, endnodes, startnodetype, endnodetype, PayTime, TXN_COUNT, Total_Amt, SendTime) {
var node_set = d3.set();
var links = [];
var nodetype = d3.set();
startnodes.forEach(function(src, i) {
var tgt = endnodes[i];
node_set.add(src);
node_set.add(tgt);
links.push({
source: src,
target: tgt,
value: 1
});
});
var d3GraphData = {
nodes: node_set.values().map(function(d) {
return {
id: d,
group: 1
}
}),
links: links
}
return d3GraphData;
};
还需要计算以下元素并将它们添加到
d3graphdata
下面应该是悬停在节点上的节点文本:
startnodetype, //node text on hover
endndodetype, // node text on hover
下面的是悬停在链接上的链接文本块:
PayTime, //
TXN_COUNT, block of text when hovering over links
Total_Amt,
SendTime //
以下是我为makegraph使用的代码,并受到来自d3库的强制导向图的启发:
http://bl.ocks.org/mbostock/4062045
function makeGraph(selector, d3GraphData) {
var svg = d3.select(selector),
width = +svg.attr("width"),
height = +svg.attr("height");
var color = d3.scaleOrdinal(d3.schemeCategory20);
var simulation = d3.forceSimulation()
.force("link", d3.forceLink().id(function(d) {
return d.id;
}))
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter(width / 2, height / 2));
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(d3GraphData.links)
.enter().append("line")
.attr("stroke-width", function(d) {
return Math.sqrt(d.value);
});
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(d3GraphData.nodes)
.enter().append("circle")
.attr("r", 5)
.attr("fill", function(d) {
return color(d.group);
})
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
node.append("title")
.text(function(d) {
return d.id;
});
simulation
.nodes(d3GraphData.nodes)
.on("tick", ticked);
simulation.force("link")
.links(d3GraphData.links);
function ticked() {
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("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
});
}
function dragstarted(d) {
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function dragended(d) {
if (!d3.event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
}
以下是HTML:
<!doctype html>
<head>
<meta charset="UTF-8">
<title> Main Page </title>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://d3js.org/d3.v4.min.js"></script>
<script src="{{url_for('static',filename='graphlogic.js')}}"></script>
</head>
<form action = "{{url_for('enter_ID')}}" method = "POST">
<p>
Galactic_ID: <input type = "text" name = "Galactic_ID" />
<button type="submit" value="Submit">Submit</button>
Phone_ID: <input type = "text" name = "Phone_ID" />
<button type="submit" value="Submit">Submit</button>
ID_Card: <input type = "text" name = "ident_ID" />
<button type="submit" value="Submit">Submit</button>
</form>
</p>
<body>
<style>
.links line {
stroke: #999;
stroke-opacity: 0.6;
}
.nodes circle {
stroke: #fff;
stroke-width: 1.5px;
}
.nodes circle {
stroke: #fff;
stroke-width: 1.5px;
}
.tooltip {
position: absolute;
background-color: white;
max-width: 200px;
height: auto;
padding: 1px;
border-style: solid;
border-radius: 4px;
border-width: 1px;
box-shadow: 3px 3px 10px rgba(0, 0, 0, .5);
pointer-events: none;
}
</style>
<svg id="Network_graph" width="960" height="600"></svg>
<script type="text/javascript">
var IDData = JSON.stringify({{data|safe}});
</script>
<div id = "graph"></div>
</body>
</html>
在上面的makegraph代码中,我需要添加&#34; hover&#34;用于节点和链接的函数,它们将鼠标悬停在节点和链接上时显示必要的文本。
Javascript和d3.js中的全新。
答案 0 :(得分:1)
您必须将数据(节点类型)添加到节点对象中,以便以后使用。
以下是CreateNodes函数的示例。该对象具有属性类型。注意我使用的是ES6集而不是d3.set:
function createNodes(startnodes, endnodes, startnodetype, endnodetype, PayTime, TXN_COUNT, Total_Amt, SendTime) {
var node_set = new Set();
var links = [];
var nodetype = d3.set();
startnodes.forEach(function(src, i) {
var tgt = endnodes[i];
node_set.add({id:src, type:startnodetype[i]});
node_set.add({id:tgt, type:endnodetype[i]});
links.push({
source: src,
target: tgt,
paytime:PayTime[i],
value: 1
});
});
startnodetype.forEach(function(src, i) {
var tgt_type = endnodetype[i];
nodetype.add(src);
nodetype.add(tgt_type);
});
var d3GraphData = {
nodes: [...node_set.values()].map(function(d) {
return {
id: d.id,
type: d.type,
group: 1
}
}),
links: links,
nodetype: nodetype.values().map(function(d) {
return {
id: d.id,
group: 1
}
})
}
return d3GraphData;
};
然后您可以使用数据填充工具提示。我决定使用div作为工具提示。您可以通过这种方式更好地控制刀尖外观。我动态创建了工具提示div:
//$(document).ready(function() {
var tooltip = d3.select("body")
.append("div")
.attr("class","tooltip")
.style("opacity", 0);
console.log(IDData);
var galData = JSON.parse(IDData);
然后添加节点时。您可以为鼠标悬停添加事件并更新工具提示div:
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(d3GraphData.nodes)
.enter().append("circle")
.attr("r", 5)
.attr("fill", function(d) {
return color(d.group);
})
.on('mouseover', function(d) {
tooltip.transition()
.duration(300)
.style("opacity", .8);
tooltip.html(d.id +"<p/>type:" + d.type)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY + 10) + "px");
})
.on(...
工作JSFiffdle。
您可以对链接工具提示使用相同的方法。