影视人物关系图实现方案


人物关系图采用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>

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注