Social relationship analysis-implemented with js

Preface

The effect of the program is as follows: you can initialize the number of nodes, search for users and display all relationships of users, and dynamically obtain data from the database.

Front-end code 

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <!-- 引入刚刚下载的 ECharts 文件 -->
  <script src="js/echarts.js"></script>
  <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
  <link rel="stylesheet" href="css/bootstrap.min.css">
  <!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
  <script src="js/bootstrap.min.js"></script>
</head>

<body>
  <nav class="navbar navbar-default">
    <div class="container-fluid">
      <!-- Brand and toggle get grouped for better mobile display -->
      <div class="navbar-header">
        <a class="navbar-brand" href="#">社交关系分析</a>
      </div>
      <!-- Collect the nav links, forms, and other content for toggling -->
      <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
        <ul class="nav navbar-nav">
          <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
              aria-expanded="false">初始化节点数(50个) <span class="caret"></span></a>
            <ul class="dropdown-menu">
              <li><a onclick="getRelationdataBycount(1)">页面初始化100节点</a></li>
              <li><a onclick="getRelationdataBycount(2)">页面初始化200节点</a></li>
              <li><a onclick="getRelationdataBycount(3)">页面初始化300节点</a></li>
            </ul>
          </li>
        </ul>
        <form class="navbar-form navbar-left">
          <div class="form-group">
            <input type="text" id="uname" name="uname" class="form-control" placeholder="请输入用户名">
          </div>
          <a  class="btn btn-default" onclick="getRelationdataByUsername()">搜索用户</a>
        </form>

      </div><!-- /.navbar-collapse -->
    </div><!-- /.container-fluid -->
  </nav>
  <!-- 为 ECharts 准备一个定义了宽高的 DOM -->
  <div id="main" style="width:100%;height:1000px;"></div>
  <script type="text/javascript">
    // 基于准备好的dom,初始化echarts实例
    var myChart = echarts.init(document.getElementById('main'));
    //设置只有当页面加载的时候才会执行的函数
    window.onload = function () {
      getRelationdata();
    }

    function getRelationdata() {

      //首先获取所有实体,也就是nodes数据
      var l_nodes = []
      $.ajax({
        type: "GET",
        url: "http://127.0.0.1:8080/getCountNodes?count=50",
        dataType: "json",
        async: false,
        success: function (e) {
          var data = e;
          var nodes = [];
          for (i = 0; i < e.length; i++) {
            var node = {};
            node.id = data[i].uid.toString();
            node.name = data[i].username
            node.symbolSize = 40
            node.symbol = 'circle'
            nodes.push(node)
          }
          l_nodes = nodes;
        }
      });

      //获取所有关系数据,也就是links数据
      var l_links = []
      $.ajax({
        type: "GET",
        url: "http://127.0.0.1:8080/getAllRelation",
        dataType: "json",
        async: false,
        success: function (e) {
          var data = e;
          var links = [];
          for (i = 0; i < e.length; i++) {
            var link = {}
            link.source = data[i].uid.toString();
            link.target = data[i].subscribeUid.toString();
            var relation = {}
            relation.name = data[i].relationType
            relation.id = "1"
            link.relation = relation
            links.push(link)
          }
          l_links = links;

        }
      });
      var option = {
        series: [{
          type: 'graph',
          layout: 'force',
          nodes: l_nodes, //节点数据
          links: l_links, //关系数据
          draggable: true,//实现节点可拖拽效果
          //节点的样式通过itemStyle设置
          itemStyle: {
            color: {
              type: "radial",
              x: 0.5,
              y: 0.5,
              r: 0.5,
              colorStops: [{
                  offset: 0,
                  color: "#3dd67a", // 0% 处的颜色
                },
                {
                  offset: 0.7,
                  color: "#465E76", // 0% 处的颜色
                },
                {
                  offset: 1,
                  color: "#764650", // 100% 处的颜色
                },
              ],
              global: false, // 缺省为 false
            },
          },
          //label设置标签样式
          label: {
            show: true,
            position: "bottom",
            distance: 5,
            fontSize: 18,
            align: "center",
          },
          autoCurveness: 0.01, //多条边的时候,自动计算曲率
          edgeLabel: { //边的设置
            show: true,
            position: "middle",
            fontSize: 12,
            formatter: (params) => {
              return params.data.relation.name;
            },
          },
          edgeSymbol: ["circle", "arrow"], //边两边的类型
          //只有设置了force节点之间才有排斥力
          force: {
            repulsion: 100,
            gravity: 0.01,
            edgeLength: 200
          }
        }],
      };
      // 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
    }

    function getRelationdataBycount(count) {

      //首先获取所有实体,也就是nodes数据
      var l_nodes = []
      $.ajax({
        type: "GET",
        url: "http://127.0.0.1:8080/getCountNodes" + '?' + 'count=' + count,
        dataType: "json",
        async: false,
        success: function (e) {
          var data = e;
          var nodes = [];
          for (i = 0; i < e.length; i++) {
            var node = {};
            node.id = data[i].uid.toString();
            node.name = data[i].username
            node.symbolSize = 40
            node.symbol = 'circle'
            nodes.push(node)
          }
          l_nodes = nodes;
        }
      });

      //获取所有关系数据,也就是links数据
      var l_links = []
      $.ajax({
        type: "GET",
        url: "http://127.0.0.1:8080/getAllRelation",
        dataType: "json",
        async: false,
        success: function (e) {
          var data = e;
          var links = [];
          for (i = 0; i < e.length; i++) {
            var link = {}
            link.source = data[i].uid.toString();
            link.target = data[i].subscribeUid.toString();
            var relation = {}
            relation.name = data[i].relationType
            relation.id = "1"
            link.relation = relation
            links.push(link)
          }
          l_links = links;

        }
      });
      var option = {
        series: [{
          type: 'graph',
          layout: 'force',
          nodes: l_nodes, //节点数据
          links: l_links, //关系数据
          draggable: true,//实现节点可拖拽效果
          //节点的样式通过itemStyle设置
          itemStyle: {
            color: {
              type: "radial",
              x: 0.5,
              y: 0.5,
              r: 0.5,
              colorStops: [{
                  offset: 0,
                  color: "#3dd67a", // 0% 处的颜色
                },
                {
                  offset: 0.7,
                  color: "#465E76", // 0% 处的颜色
                },
                {
                  offset: 1,
                  color: "#764650", // 100% 处的颜色
                },
              ],
              global: false, // 缺省为 false
            },
          },
          //label设置标签样式
          label: {
            show: true,
            position: "bottom",
            distance: 5,
            fontSize: 18,
            align: "center",
          },
          autoCurveness: 0.01, //多条边的时候,自动计算曲率
          edgeLabel: { //边的设置
            show: true,
            position: "middle",
            fontSize: 12,
            formatter: (params) => {
              return params.data.relation.name;
            },
          },
          edgeSymbol: ["circle", "arrow"], //边两边的类型
          //只有设置了force节点之间才有排斥力
          force: {
            repulsion: 100,
            gravity: 0.01,
            edgeLength: 200
          }
        }],
      };
      // 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
    }

    function getRelationdataByUsername() {

      var uname = $("#uname").val();
      if(uname==''){
        alert('用户名不能为空!')
        return;
      }
      //首先获取所有实体,也就是nodes数据
      var l_nodes = []
      $.ajax({
        type: "GET",
        url: "http://127.0.0.1:8080/getNodesByUsername"+'?'+'username='+ uname,
        dataType: "json",
        async: false,
        success: function (e) {
          var data = e;
          console.log(data)
          var nodes = [];
          for (i = 0; i < e.length; i++) {
            var node = {};
            node.id = data[i].uid.toString();
            node.name = data[i].username
            node.symbolSize = 40
            node.symbol = 'circle'
            nodes.push(node)
          }
          l_nodes = nodes;
        }
      });

      //获取所有关系数据,也就是links数据
      var l_links = []
      $.ajax({
        type: "GET",
        url: "http://127.0.0.1:8080/getRelationByUsername"+'?'+'username='+uname,
        dataType: "json",
        async: false,
        success: function (e) {
          var data = e;
          var links = [];
          for (i = 0; i < e.length; i++) {
            var link = {}
            link.source = data[i].uid.toString();
            link.target = data[i].subscribeUid.toString();
            var relation = {}
            relation.name = data[i].relationType
            relation.id = "1"
            link.relation = relation
            links.push(link)
          }
          l_links = links;

        }
      });
      var option = {
        series: [{
          type: 'graph',
          layout: 'force',
          nodes: l_nodes, //节点数据
          links: l_links, //关系数据
          draggable: true,//实现节点可拖拽效果
          //节点的样式通过itemStyle设置
          itemStyle: {
            color: {
              type: "radial",
              x: 0.5,
              y: 0.5,
              r: 0.5,
              colorStops: [{
                  offset: 0,
                  color: "#3dd67a", // 0% 处的颜色
                },
                {
                  offset: 0.7,
                  color: "#465E76", // 0% 处的颜色
                },
                {
                  offset: 1,
                  color: "#764650", // 100% 处的颜色
                },
              ],
              global: false, // 缺省为 false
            },
          },
          //label设置标签样式
          label: {
            show: true,
            position: "bottom",
            distance: 5,
            fontSize: 18,
            align: "center",
          },
          autoCurveness: 0.01, //多条边的时候,自动计算曲率
          edgeLabel: { //边的设置
            show: true,
            position: "middle",
            fontSize: 12,
            formatter: (params) => {
              return params.data.relation.name;
            },
          },
          edgeSymbol: ["circle", "arrow"], //边两边的类型
          //只有设置了force节点之间才有排斥力
          force: {
            repulsion: 100,
            gravity: 0.01,
            edgeLength: 200
          }
        }],
      };
      // 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
    }
  </script>
</body>

</html>

Database Design 

DROP TABLE IF EXISTS `relation_info`;
CREATE TABLE `relation_info` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) DEFAULT NULL,
  `username` varchar(100) DEFAULT NULL,
  `subscribe_uid` int(11) DEFAULT NULL,
  `subscribe_name` varchar(100) DEFAULT NULL,
  `strong_value` int(11) DEFAULT NULL,
  `relation_type` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of relation_info
-- ----------------------------
INSERT INTO `relation_info` VALUES ('1', '1', '姚明', '2', '叶莉', null, '夫妻');
INSERT INTO `relation_info` VALUES ('2', '1', '姚明', '3', '姚沁蕾', null, '女儿');
INSERT INTO `relation_info` VALUES ('3', '1', '姚明', '4', '姚志源', null, '父亲');
INSERT INTO `relation_info` VALUES ('4', '1', '姚明', '5', '方凤娣', null, '母亲');
INSERT INTO `relation_info` VALUES ('5', '1', '姚明', '6', '迈克尔.哈里斯', null, '前队友');
INSERT INTO `relation_info` VALUES ('6', '6', '迈克尔.哈里斯', '7', '易建联', null, '好友');
INSERT INTO `relation_info` VALUES ('7', '7', '易建联', '4', '姚志源', null, '好友');
INSERT INTO `relation_info` VALUES ('8', '8', '奥尼尔', '1', '姚明', null, '好友');
INSERT INTO `relation_info` VALUES ('9', '1', '姚明', '8', '奥尼尔', null, '好友');
INSERT INTO `relation_info` VALUES ('10', '9', '刘伟华', '10', '刘洋', null, '好友');
INSERT INTO `relation_info` VALUES ('11', '10', '刘洋', '1', '姚明', null, '粉丝');
INSERT INTO `relation_info` VALUES ('12', '11', '马云', '9', '刘伟华', null, '好友');

Backend implementation 

Relation class

package com.atguigu.admin.bean;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("relation_info")
public class Relation {

    private Long id;
    private Long uid;
    private String username;
    private Long subscribeUid;
    private String subscribeName;
    private int strongValue;
    private String relationType;

}

 RelationMapper.xml file

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.admin.mapper.RelationMapper">
    <!--    public Account getAcct(Long id); -->
    <select id="getAllRelation" resultType="com.atguigu.admin.bean.Relation">
        select * from  relation_info
    </select>
    <select id="getAllNodes" resultType="com.atguigu.admin.bean.Relation">
        SELECT DISTINCT username,uid from relation_info UNION SELECT DISTINCT subscribe_name,subscribe_uid from relation_info
    </select>
    <select id="getCountNodes" resultType="com.atguigu.admin.bean.Relation">
        SELECT DISTINCT username,uid from relation_info UNION SELECT DISTINCT subscribe_name,subscribe_uid from relation_info ORDER BY uid ASC LIMIT #{count}
    </select>
    <select id="getRelationByUserName" resultType="com.atguigu.admin.bean.Relation">
        select * from relation_info WHERE username=#{username} OR subscribe_name=#{username}
    </select>
    <select id="getNodesByUserName" resultType="com.atguigu.admin.bean.Relation">
        select  DISTINCT uid,username from relation_info WHERE username=#{username} OR subscribe_name=#{username} UNION select  DISTINCT subscribe_uid,subscribe_name from relation_info WHERE username=#{username} OR subscribe_name=#{username} ORDER BY uid ASC
    </select>


</mapper>

RelationMapper interface file

package com.atguigu.admin.mapper;

import com.atguigu.admin.bean.Relation;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface RelationMapper {
    public List<Relation> getAllRelation();
    public List<Relation> getAllNodes();

    public List<Relation> getCountNodes(Integer count);
    public List<Relation> getRelationByUserName(String username);

    public List<Relation> getNodesByUserName(String username);
}

RelationService implementation class

package com.atguigu.admin.service.imp;

import com.atguigu.admin.bean.Relation;
import com.atguigu.admin.mapper.RelationMapper;
import com.atguigu.admin.service.RelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class RelationServiceImpl implements RelationService {
    @Autowired
    RelationMapper relationMapper;
    @Override
    public List<Relation> getAllRelation() {
        return relationMapper.getAllRelation();
    }

    @Override
    public List<Relation> getAllNodes() {
        return relationMapper.getAllNodes();
    }

    @Override
    public List<Relation> getCountNodes(Integer count) {
        return relationMapper.getCountNodes(count);
    }


}

 SocialController class implementation

package com.atguigu.admin.controller;

import com.atguigu.admin.bean.Relation;
import com.atguigu.admin.mapper.RelationMapper;
import com.atguigu.admin.service.RelationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

@Controller
public class SocialController {

    @Autowired
    RelationService relationService;

    @ResponseBody
    @GetMapping("/getAllRelation")
    public List<Relation> getAllRelation(){


        return relationService.getAllRelation();
    }

    @ResponseBody
    @GetMapping("/getAllNodes")
    public List<Relation> getAllNodes(){
        return relationService.getAllNodes();
    }

    @ResponseBody
    @GetMapping("/getCountNodes")
    public List<Relation> getAllNodes(@RequestParam("count") Integer count){
        if (count==null){
            List<Relation> strings=new ArrayList<>();
            return strings;
        }else {
            return relationService.getCountNodes(count);
        }
    }
    @Autowired
    RelationMapper relationMapper;

    @ResponseBody
    @GetMapping("/getRelationByUsername")
    public List<Relation> getRelationByUsername(@RequestParam("username") String username){
        if (username==null){
            List<Relation> strings=new ArrayList<>();
            return strings;
        }else {
            return relationMapper.getRelationByUserName(username);
        }
    }

    @ResponseBody
    @GetMapping("/getNodesByUsername")
    public List<Relation> getNodesByUsername(@RequestParam("username") String username){
        if (username==null){
            List<Relation> strings=new ArrayList<>();
            return strings;
        }else {
            return relationMapper.getNodesByUserName(username);
        }
    }

}

Guess you like

Origin blog.csdn.net/weixin_41477928/article/details/123598390