人物关系图采用ZoomCharts 来实现
ZoomCharts 是一个 JavaScript/HTML 库,可以帮助您向应用程序添加视觉丰富的交互式图表。只需要最少量的代码,您就可以将数据可视化,并让用户发现新的见解。可以将 ZoomCharts 与任何服务器端编程语言一起使用(包括。NET、 PHP、 Java、 Ruby 等)和任何客户端框架(包括 AngularJS、 jQuery 等)。
获取 ZoomCharts 的最简单方法是直接从 CDN 服务器使用该库:
<script src=”https://cdn.zoomcharts-cloud.com/1/stable/zoomcharts.js”></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<meta charset="utf-8"/>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
<title>人物关系图</title>
<!--<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>-->
<script src="./jquery.min.js"></script>
<link rel="apple-touch-icon" href=""/>
<style type="text/css">
.icon-bar {
display: flex;/*设置弹性盒子*/
justify-content: space-around;/*水平对齐,两边间距是中间间距的一半*/
align-items: center;/* 垂直居中对齐 */
position: fixed;
bottom:0;
left:50%;
transform: translateX(-50%);
width: 100%;
height: 70px;
max-width: 760px;
font-size: 12px;
text-align: center;
}
.icon-bar span {
width: 80px;
}
.icon-bar a{
color:#696969;
}
.role{
display:none;
}
.relation{
display:none;
}
#chartContainer{
height:650px;
}
.icon-bar span i{
font-family: iconfont;/*设置资自定义图标字体*/
font-size: 18px;
font-style: normal;
display: block;
}
.icon-bar span i img{
width:25px;
}
</style>
<script src="https://cdn.zoomcharts-cloud.com/1/latest/zoomcharts.js"></script>
<!-- <script>-->
<!-- var ZoomChartsLicense = "ZCP-w4sm9lg0n: Production licence for *.zoomcharts.com";-->
<!-- var ZoomChartsLicenseKey = "577dc0aa9e80ab25c83df5607bfb23369d8c5566347c7"+-->
<!--"b54a64a4fbc45ccf4a1e7dbaf0827249c6676c19c918ed548f67ae225e813c5f57dfdc0709137"+-->
<!--"7b72c6c3883f1ae343abf2ef77d3470ee58a8d62781eac016e311d12122256184e9b3efed"+-->
<!--"8b7e38d326e1fc10efc599803e7a173d128115eb57dabc5f4bf7ae520a50c6963e2ab8c56"+-->
<!--"2fa24fa46d246e57afb5bb1b4507e738251b644f0bd9235665138f043cbce5acfa8197f934"+-->
<!--"c58e805963693344ff5240ad98ba8ed583f5990cd79e109ab23daaf8cba9ac5c3fee0471b2"+-->
<!--"f8f5abff432bff536d8980d582411724f60e01244c8ae94e3e31a4afe4e3322dc9aa5567eabc9";-->
<!-- </script>-->
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
</head>
<body>
<div id="chartContainer"></div>
<div class="icon-bar">
<input type="hidden" id="changeId" value=""/>
<span class="main"><i><img src="./assets/add.png"/></i><a href='javascript:android.addRole()'><font>添加角色</font></a ></span>
<span class="main"><i><img src="./assets/add.png"/></i><a href='javascript:android.addRelation()'><font>添加关系</font></a ></span>
<span class="role"><i><img src="./assets/add.png"/></i><a href='javascript:android.addRole()'><font>添加角色</font></a ></span>
<span class="role"><i><img src="./assets/edit.png"/></i><a href='javascript:android.editRole()'><font>编辑角色</font></a ></span>
<span class="role"><i><img src="./assets/delete.png"/></i><a href='javascript:android.delRole()'><font>删除角色</font></a ></span>
<span class="relation"><i><img src="./assets/add.png"/></i><a href='javascript:android.addRelation()'><font>添加关系</font></a ></span>
<span class="relation"><i><img src="./assets/edit.png"/></i><a href='javascript:android.editRelation()'><font>编辑关系</font></a ></span>
<span class="relation"><i><img src="./assets/delete.png"/></i><a href='javascript:android.delRelation()'><font>删除关系</font></a ></span>
</div>
<script>
var init = {
"nodes": [
{
"id": "n1",
"name":"角色1",
"info":"角色1的简介",
"image":""
},
{
"id": "n2",
"name":"角色2",
"info":"角色2的简介",
"image":""
},
{
"id": "n3",
"name":"角色3",
"info":"角色3的简介",
"image":""
}
],
"links": [
{
"id": "l1",
"from": "n1",
"to": "n2",
"type":"关系1"
},
{
"id": "l2",
"from": "n2",
"to": "n3",
"type":"关系2"
},
{
"id": "l3",
"from": "n3",
"to": "n1",
"type":"关系3"
}
]
};
var t = new NetChart({
container: document.getElementById("chartContainer"),
//area: { height: 780 },
data: {preloaded:init},//{ url: "https://yjm.kuanjv.com/people/people"},//"https://yjm.kuanjv.com/test/a.json" },
// events:{
// onClick: graphClick
// },
events: {
onClick: function (event, args) {
// if (args.clickNode) alert("You clicked on " + args.clickNode.data.id + ".");
// if (args.clickLink) alert("You clicked on a link.");
if(args.clickNode){
$('#changeId').val(args.clickNode.data.id);
$('.main').hide();
$('.relation').hide();
$('.role').show();
$('.role:eq(1) > a').attr('onclick','javascript:alert(1)');//attr('href','javascript:android.editRole("'+args.clickNode.data.id+'")');
$('.role:eq(2) > a').attr('href','javascript:android.delRole("'+args.clickNode.data.id+'")');
}else if (args.clickLink){
$('#changeId').val(args.clickLink.id);
$('.main').hide();
$('.relation').show();
$('.role').hide();
$('.relation:eq(1) > a').attr('href','javascript:android.editRelation("'+args.clickLink.id+'")');
$('.relation:eq(2) > a').attr('href','javascript:android.delRelation("'+args.clickLink.id+'")');
}else if(event.y < 650){
$('.main').show();
$('.relation').hide();
$('.role').hide();
}
event.preventDefault();
}
},
navigation: {
focusNodeExpansionRadius: 1,
numberOfFocusNodes: 169,
expandOnClick:true,//点击是否展示节点
initialNodes: ["n1"],//初始化节点
//mode: "focusnodes"//设置后会导致无关系节点不显示
},
focusnodes: {
relevance: "Expanded flag",
focusAtutoFadeout: true,
},
layout: {
mode: "dynamic",
nodeSpacing: 10
},
//展示中心点
// "layout": {
// "mode": "radial",
// "nodeSpacing": 45
// },
style: {
linkLabel:{
padding: 3,
borderRadius: 999, //make as round as possible
//textStyle:{font:"12px Arial", fillColor: "#878785"},
//backgroundStyle:{fillColor:"rgba(86,185,247,0.8)", lineColor:"rgba(28,124,213,0.9)"}
},
node: {
display:"roundtext",
lineWidth: 0,
lineColor: "#EDEDED",
fillColor: "#e3a143"
},
link: {
fillColor: "#878785"
},
"nodeStyleFunction": function (node) {
console.log(node.data);
node.label = node.data.image ? "" : "角";
//node.fillColor = node.data.fillColor;
//node.lineColor = node.data.lineColor;
if(node.data.image){
node.image = node.data.image;
node.display = "image";
node.imageCropping = "crop";
//node.imageSlicing = [0,0,239,239];
}else{
node.imageCropping = "letterbox";
}
node.items = [
{
text: node.data.name,
aspectRatio: 0, //force single line
px: 0, py: -1, x: 0, y: 80,
textStyle:{fillColor: "#696969", font:"16px Arial"},
},{
text: node.data.info,
aspectRatio: 0, //force single line
px: 0, py: -1, x: 0, y: 100,
textStyle:{fillColor: "#696969", font:"12px Arial"},
// backgroundStyle: {
// lineWidth: 0
// }
}];
},
"linkStyleFunction":function(link){
link.toDecoration = "arrow";
link.length = 2;
link.label = link.data.type;
//link.fillColor = link.data.fillColor;
}
},
toolbar: {
fullscreen: true,
enabled: false
},
interaction: {
resizing: {
enabled: false
}
}
});
//chart.updateSettings({area: { height:250, width:400 }});
//chart.addData, chart.replaceData
//替换
//t.replaceData({"nodes":[{"id":"n1", "loaded": true,"name":"角色5 角色5的简介","fillColor": "#e3a143","lineColor": "#e3a143"}]});
//删除
//zoomcharts文档 https://zoomcharts.com/developers/en/net-chart/api-reference/api.html
function getDataList(){
return init;
}
//添加角色,关系
function addData(nodes = '',links = []){
if(nodes !==''){
t.addData({
nodes:[nodes]//{"id":"n6", "loaded": true,"name":"角色6 角色6的简介"}
});
}
if(links.length > 0){
t.addData({
links:links //[{"id": "l6","from": "n6","to": "n5","type":"关系6"}]
});
}
}
//修改角色,关系
function replace(nodes = '', links = []){
var node = init.nodes;
var link = init.links;
if(nodes !== ''){
nodes.push(node);//{"id":"n1", "loaded": true, "name":"橘色", "image":""}
t.replaceData({ "nodes": nodes});//, "links": links
}
if(links.length > 0){
link.push(links);
t.replaceData({ "links": links});//, "links": links
}
}
//删除角色,关系
function remove(nodes = '', links = []){
if(nodes !== ''){
t.removeData({nodes:[nodes]});//{id:"n2"}
}
if(links.length > 0){
t.removeData({links:links});//{id:"n2"}
}
}
//导出数据
function exportData(){
return t.exportData();
}
function getRole(id){
return t.getNode(id).data;
}
function getRelation(id){
return t.getLink(id).data;
}
function setData(store){
return t.replaceData(store);
}
// var menuElement = document.createElement("div");
// menuElement.id = "test";
// menuElement.style.zIndex = 9999;
// menuElement.style.display = "none";
// menuElement.style.position = "absolute";
// menuElement.style.background = "#eee";
// menuElement.style.border = "1px solid #09c";
// menuElement.style.padding = "10px";
// // the context menu element has to be the direct descendant of the document.body
// document.body.appendChild(menuElement);
</script>
</body>
</html>