四、 事件监听:visjs事件监听

let container = document.getElementById("mynetwork");
    let data = {
        nodes: this.nodes,
        edges: this.edges,
    };
    let options = {interaction: { hover: true }};

    network = new vis.Network(container, data, options);
    // 事件监听
    this.networkEvent();
},

// 拓扑网络监听事件
networkEvent() {
    //单击
    network.on("click", (e) => {});

    // 双击
    network.on("doubleClick", (e) => {});

    // 单击鼠标右键
    network.on("oncontext", (e) => {});

    // 节点悬停
    network.on("hoverNode", (e) => {});

    // 节点失焦
    network.on("blurNode", (e) => {});

    // 边悬停
    network.on("hoverEdge", (e) => {});

    // 边失焦
    network.on("blurEdge", (e) => {});

    //  鼠标拖动开始事件
    network.on("dragStart", (e) => {});
    
    //  鼠标拖动结束事件
    network.on("dragEnd", (e) => {});
    
    //  鼠标缩放事件
    network.on("zoom", (e) => {});
    //...
}

例:展开&收缩节点

需求:展开节点,收缩节点,收缩展开过的节点光晕颜色改变(区别未展开过的节点)

DataSet Methods
新增节点/边:nodes.add({…}),edges.add({…})
删除节点/边:nodes.remove({…}),edges.remove({…})


<template>
  <div id="mynetwork" class="mynetwork2"></div>
</template>

<script>
const vis = require("vis-network/dist/vis-network.min.js");
import _ from "lodash";

var network = null;
export default {
  data() {
    return {
      //创建节点对象
      nodes: new vis.DataSet([
        {
          id: "node-1",
          label: "Node 1",
          title: "1111",
          image: {
            selected: require("@/assets/people-opened.png"),
            unselected: require("@/assets/people-def.png"),
          },
        },
      ]),
      //创建连线对象
      edges: new vis.DataSet([
        // { id: "edge-1", from: "node-1", to: "node-2" },
      ]),
      removeNodes: [],
      removeEdges: [],
    };
  },
  mounted() {
    this.initNetwork();
  },
  methods: {
    // 初始化网络拓扑
    initNetwork() {
      let container = document.getElementById("mynetwork");
      let data = {
        nodes: this.nodes,
        edges: this.edges,
      };
      let options = {
        interaction: {
          hover: true,
        },
        layout: {
          randomSeed: 2, //配置每次生成的节点位置都一样,参数为数字1、2等
        },
        nodes: {
          // shape: "dot",
          // shape: "circularImage",
          // borderWidth: 2,
          shape: "image",
          size: 23,
          color: {
            // border: "rgba(255, 255, 255, 1)",
            background: "rgba(102, 51, 255, 1)",
          },
          font: {
            // color: "#fff",
          },
          shadow: {
            enabled: true,
            // color: "rgba(153, 102, 204, 1)",
            color: "rgba(153, 0, 204, 1)",
            size: 40,
            x: 0,
            y: 0,
          },
          chosen: {
            label: false,
            // node: function(values, id, selected, hovering) {
            node: function(values) {
              values.shadowColor = "rgba(255, 215, 0, 0.8)";
            },
          },
          // shapeProperties: {
          //     borderDashes: [5, 15],
          // },
        },
        edges: {
          hoverWidth: 0,
          shadow: true,
          arrows: {
            to: {
              enabled: true,
              type: "arrow",
            },
          },
          color: {
            color: "#525A81",
            highlight: "#FFBA30",
            hover: "#FFBA30",
            // inherit: "from",
            opacity: 1.0,
          },
          font: {
            // color: "#fff",
            size: 12, // px
            strokeWidth: 0, // px
          },
        },
        physics: {
          enabled: true,
          // minVelocity: 1 //(default: 1)一旦达到所有节点的最小速度,我们假设网络已经稳定,布局停止。
          timestep: 0.2,
          // wind: {
          //   x: 10,
          //   y: 10
          // }
        },
      };
      network = new vis.Network(container, data, options);
      // 事件监听
      this.networkEvent();
    },
    // 拓扑网络监听事件
    networkEvent() {
      // 单击
      network.on("click", (e) => {
        console.log("单击:", e);
        console.log(this.edges.get(e.edges[0]));
        // 只有在点击节点时才进行节点的增删
        if (!e.nodes.length) {
          return false;
        }
        var clickNodeList = this.nodes.get(e.nodes[0]);
        console.log(clickNodeList);
        if (!clickNodeList.open) {
          // 恢复过滤数据
          // this.recoverFilterData();
          this.generateData(e.nodes[0], e.edges[0], e.nodes[0]);
          // 判断是否有子节点
          let haschildState = network.getConnectedNodes(e.nodes[0], "to").length ? true : false;
          this.nodes.update({
            id: e.nodes[0],
            open: true,
            haschildren: haschildState,
            changEdge: e.edges[0],
          });
          if (e.edges[0]) {
            this.edges.update({
              id: e.edges[0],
              open: true,
              haschildren: haschildState,
              // length: 600,
            });
          }
          // 移动焦点到视图中心
          // 双击某一节点,画布放大至1:1比例,当前节点处于画布中心位置
          var option = {
            scale: 1.0,
            offset: { x: 0, y: 0 },
            animation: {
              duration: 1000,
              easingFunction: "easeInOutQuad",
            },
          };
          network.focus(e.nodes[0], option);
        } else {
          // 获取该节点下 未展开的节点的集合 和 从该节点发出的到未展开节点线的集合
          let nodeItems = this.nodes.get({
            filter: function(item) {
              return item.parentId === e.nodes[0] && !item.open && !item.haschildren;
            },
          });
          // console.log("nodeItems", nodeItems);
          let edgesItem = this.edges.get({
            filter: function(item) {
              return (
                !item.open && item.from == e.nodes[0] && !item.haschildren
                // (item.to == e.nodes[0] || item.from == e.nodes[0])
              );
            },
          });
          console.log("edgesItem", edgesItem);
          // 需求: 只缩进当前节点一度关系中未展开的节点,一度关系点已展开关系的不缩进
          // 缩进( 删除未展开子节点和子节点连线)
          // this.addNew(this.removeNodes, nodeItems);
          // this.addNew(this.removeEdges, edgesItem);
          this.nodes.remove(nodeItems);
          this.edges.remove(edgesItem);
          // 判断是否有子节点
          let haschildState = network.getConnectedNodes(e.nodes[0], "to").length ? true : false;
          this.nodes.update({
            id: e.nodes[0],
            open: false,
            shadow: {
              // color: "rgba(166, 26, 120, 1)",
              color: "rgba(81, 0, 255, 1)",
            },
            image: {
              selected: require("@/assets/people-opened.png"),
              unselected: require("@/assets/people-def.png"),
            },
            // clickNodeList.image.selected || clickNodeList.image, //已修改后的字段为image
            haschildren: haschildState,
          });
          if (clickNodeList.changEdge) {
            // 初始中心节点无changEdge
            this.edges.update({
              id: clickNodeList.changEdge,
              open: false,
              haschildren: haschildState,
              // length: 280,
            });
          }
        }
      });
    },
    generateData(nodename, edgename, orgnode) {
      var len = 2;
      let nodes = [];
      let edges = [];
      let nodeName = nodename || "node";
      let edgeName = edgename || "edge";
      const relation = ["诈骗","父亲","母亲","哥哥","姐姐","同事","定向扩展","妻子","弟弟",];
      const labelType = ["people", "car", "phone", "qq", "wx", "email"];
      for (var i = 1; i <= len; i++) {
        const randomIndex = Math.floor(Math.random() * 6);
        nodes.push({
          parentId: orgnode,
          id: nodeName + "-" + i,
          label: labelType[randomIndex],
          shape: "image",
          image: {
            selected: require("@/assets/people-opened.png"),
            unselected: require("@/assets/people-def.png"),
          },
          haschildren: false,
        });
        edges.push({
          id: edgeName + "-" + i,
          from: orgnode || "node-1",
          to: nodeName + "-" + i,
          label: relation[Math.floor(Math.random() * 10)],
          haschildren: false,
        });
      }
      // 避免添加重复数据导致错误
      this.buildData(nodes, edges);
    },
    // 构建数据
    buildNode(nodes) {
      nodes.forEach((item) => {
        // var node = {
        // ...
        //};
        this.nodes.add(item);
      });
      // console.log("---------", this.nodes.get());
    },
    buildEdge(edges) {
      edges.forEach((item) => {
        // var edge = {
        //  ...
        // };
        this.edges.add(item);
      });
    },
    buildData(n, e) {
      // 去重
      // console.log(this.nodes.get());
      // 删除n中与第二个数组对象id相同的值
      let differenceN = _.differenceBy(n, this.nodes.get(), "id");
      let differenceE = _.differenceBy(e, this.edges.get(), "id");
      // console.log("differenceN:", differenceN, differenceE);
      this.buildNode(differenceN);
      this.buildEdge(differenceE);
    },
    addNew(arr, newarr) {
      for (const item of newarr) {
        arr.push(item);
      }
    },
    recoverFilterData() {
      // console.log("reset:", this.removeNodes);
      // console.log("reset:", this.removeEdges);
    },
  },
};
</script>

<style scoped>
.mynetwork2 {
  height: 100%;
  /* background-color: #2a004a; */
}
</style>

效果如下
在这里插入图片描述

功能点:

右键展开菜单,点击请求节点数据,或展开下级菜单

拖动节点或画布,菜单跟随节点

缩放画布,菜单同步缩放

对其它或者空白区域进行操作时,关闭菜单

一、visjs的安装及简单使用

二、 配置项

三、 公共API

四、 事件监听+例子

五、自定义右键菜单

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
按钮事件监听是指在用户点击按钮时,程序能够捕捉到该事件,并执行相应的操作。在开发界面交互性较强的应用程序时,通常需要使用按钮事件监听来实现用户与程序之间的交互。具体实现方式有多种,例如在按钮上添加点击事件监听器,或者使用响应式编程框架中的观察者模式等。 在Java Swing中,可以使用ActionListener接口来实现按钮事件监听。下面是一个简单的示例代码: ``` import javax.swing.*; import java.awt.event.*; public class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(null, "Button clicked!"); } } public class Main { public static void main(String[] args) { JFrame frame = new JFrame("Button Listener Example"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JButton button = new JButton("Click me!"); button.addActionListener(new ButtonListener()); frame.getContentPane().add(button); frame.pack(); frame.setVisible(true); } } ``` 在上面的代码中,我们创建了一个JButton和一个实现了ActionListener接口的ButtonListener类。当用户点击按钮时,程序会调用ButtonListener类的actionPerformed方法,并在对话框中显示一个消息。最后,我们将按钮添加到窗口中,并显示窗口。 除了Java Swing之外,其他GUI框架也都提供了类似的事件监听机制,开发人员可以根据具体需要选择相应的实现方式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值