当前位置:首页 > VUE

vue实现网状关系图

2026-02-22 08:55:34VUE

使用 Vue 和 D3.js 实现网状关系图

D3.js 是一个强大的数据可视化库,结合 Vue 可以高效实现网状关系图。以下是一个基于 Force-Directed Graph(力导向图)的实现方法。

安装依赖:

npm install d3

组件代码示例:

<template>
  <div ref="networkChart" class="network-container"></div>
</template>

<script>
import * as d3 from 'd3';

export default {
  props: {
    nodes: { type: Array, default: () => [] },
    links: { type: Array, default: () => [] }
  },
  mounted() {
    this.drawNetwork();
  },
  methods: {
    drawNetwork() {
      const container = this.$refs.networkChart;
      const width = container.clientWidth;
      const height = 600;

      const simulation = d3.forceSimulation(this.nodes)
        .force("link", d3.forceLink(this.links).id(d => d.id).distance(100))
        .force("charge", d3.forceManyBody().strength(-300))
        .force("center", d3.forceCenter(width / 2, height / 2));

      const svg = d3.select(container)
        .append("svg")
        .attr("width", width)
        .attr("height", height);

      const link = svg.append("g")
        .selectAll("line")
        .data(this.links)
        .enter().append("line")
        .attr("stroke", "#999")
        .attr("stroke-width", 2);

      const node = svg.append("g")
        .selectAll("circle")
        .data(this.nodes)
        .enter().append("circle")
        .attr("r", 10)
        .attr("fill", "#69b3a2")
        .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

      node.append("title").text(d => d.id);

      simulation.on("tick", () => {
        link
          .attr("x1", d => d.source.x)
          .attr("y1", d => d.source.y)
          .attr("x2", d => d.target.x)
          .attr("y2", d => d.target.y);

        node
          .attr("cx", d => d.x)
          .attr("cy", d => d.y);
      });

      function dragstarted(event) {
        if (!event.active) simulation.alphaTarget(0.3).restart();
        event.subject.fx = event.subject.x;
        event.subject.fy = event.subject.y;
      }

      function dragged(event) {
        event.subject.fx = event.x;
        event.subject.fy = event.y;
      }

      function dragended(event) {
        if (!event.active) simulation.alphaTarget(0);
        event.subject.fx = null;
        event.subject.fy = null;
      }
    }
  }
};
</script>

<style>
.network-container {
  width: 100%;
  border: 1px solid #eee;
}
</style>

使用 Vue 和 vis-network 实现

vis-network 是专门用于网络图可视化的库,使用更简单:

安装依赖:

npm install vis-network

组件实现:

<template>
  <div ref="network" class="network-container"></div>
</template>

<script>
import { Network } from "vis-network";

export default {
  props: {
    nodes: { type: Array, default: () => [] },
    edges: { type: Array, default: () => [] }
  },
  mounted() {
    this.initNetwork();
  },
  methods: {
    initNetwork() {
      const container = this.$refs.network;
      const data = {
        nodes: this.nodes,
        edges: this.edges
      };
      const options = {
        nodes: {
          shape: "dot",
          size: 16,
          font: {
            size: 14
          }
        },
        edges: {
          width: 2,
          smooth: true
        },
        physics: {
          enabled: true,
          stabilization: {
            iterations: 100
          }
        }
      };
      new Network(container, data, options);
    }
  }
};
</script>

<style>
.network-container {
  width: 100%;
  height: 600px;
  border: 1px solid #eee;
}
</style>

数据结构示例

两种实现方式都需要特定的数据结构:

// D3.js 格式数据
{
  nodes: [
    { id: "Node 1" },
    { id: "Node 2" },
    { id: "Node 3" }
  ],
  links: [
    { source: "Node 1", target: "Node 2" },
    { source: "Node 2", target: "Node 3" }
  ]
}

// vis-network 格式数据
{
  nodes: [
    { id: 1, label: "Node 1" },
    { id: 2, label: "Node 2" },
    { id: 3, label: "Node 3" }
  ],
  edges: [
    { from: 1, to: 2 },
    { from: 2, to: 3 }
  ]
}

交互功能增强

可以添加以下交互功能:

  • 节点点击事件处理
  • 鼠标悬停显示详细信息
  • 缩放和平移控制
  • 动态添加/删除节点
  • 分组和颜色编码

对于大型数据集,建议:

  • 使用Web Worker进行数据处理
  • 实现虚拟渲染(只渲染可见区域)
  • 添加加载状态指示器

性能优化建议

当节点数量超过500时:

  • 减少物理模拟的迭代次数
  • 简化节点渲染(使用简单形状)
  • 禁用阴影等视觉效果
  • 分批次渲染数据

这两种方案各有优势:D3.js更灵活适合定制化需求,vis-network更简单适合快速实现标准网络图。根据项目复杂度选择合适方案。

vue实现网状关系图

标签: 网状关系
分享给朋友:

相关文章

react实现人物关系图

react实现人物关系图

实现人物关系图的方法 使用React实现人物关系图通常需要结合可视化库来处理节点和边的渲染。以下是几种常见的方法: 使用D3.js与React结合 D3.js是一个强大的数据可视化库,适合处理复杂的…

js和jquery的关系

js和jquery的关系

JavaScript 与 jQuery 的关系 JavaScript 是一种脚本编程语言,主要用于网页开发,实现动态交互功能。jQuery 是一个基于 JavaScript 的库,封装了常见的 DOM…

vue实现关系分配页面

vue实现关系分配页面

Vue 实现关系分配页面的方法 数据结构设计 使用树形结构或扁平化数据结构存储关系层级,例如: data() { return { relations: [ { id: 1,…

php分销关系实现

php分销关系实现

分销关系实现方法 在PHP中实现分销关系通常涉及用户层级管理、佣金计算和数据存储。以下是几种常见的实现方式: 数据库设计 创建用户表时添加推荐关系字段: CREATE TABLE users…

php实现人物关系

php实现人物关系

PHP 实现人物关系的方法 在PHP中实现人物关系可以通过多种方式,常见的有数据库建模、图数据库、或者使用数组和对象来模拟关系。以下是几种常见的方法: 使用关系型数据库 关系型数据库如MySQL可…

vue实现关系图

vue实现关系图

Vue 实现关系图的方法 使用 Vue 实现关系图可以通过多种方式完成,常见的方法是借助第三方库或手动绘制。以下是几种常用的实现方案: 使用第三方库(如 D3.js 或 ECharts) 安装 D…