2.0.64 • Published 9 months ago

vue-safe-force-graph v2.0.64

Weekly downloads
-
License
MIT
Repository
-
Last release
9 months ago

vue-safe-force-graph

vue-safe-force-graph 是一个使用 Vue3、d3.js 、 canvas 开发的可视化溯源关系图。

安装

npm install vue-safe-force-graph

使用方式

可以在组件中引入 或者可以在全局引入注册组件。

方式一:组件中引入

在vue组件中引入Graph组件和样式:

import { Graph } from 'vue-safe-force-graph'
import 'vue-safe-force-graph/lib/style.css'

完整index.vue示例如下:

<template>
  <div class="graph-container">
    <Graph
      :graph-api="graphApi"
      :module="module"
      :start-node="startNode"
      :enter-start-node="true"
      :has-level="true"
      :snapshot_id="snapshotId"
      :vcode="vcode"
      :handle-select-node-event="handleSelectNode"
      :custom-context-menu-event="handleEvent"
      :singles-node-max-num="500"
      @handle-data-loaded="handleDataLoaded"
    />
  </div>
</template>
<script setup>

import {
  getGraphConfig, getGraphRequest, getNodesDetail, getSnapshotDetail,
} from 'src/api/graph'
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import request from '@/utils/request'
import { Graph } from 'vue-safe-force-graph'
import 'vue-safe-force-graph/lib/style.css'

const module = ref('graph')
const startNode = ref([])
const vcode = ref(null)
const snapshotId = ref(null)
const forceGraph = ref(null)

function addSnapshot(params) {
  return request({
    url: `/graph/v1/snapshot/add?module=${module.value}`,
    method: 'post',
    data: params
  })
}

const graphApi = {
  getGraphConfig: getGraphConfig,
  getGraphRequest: getGraphRequest,
  getNodesDetail: getNodesDetail,
  addSnapshot1: addSnapshot,
  getSnapshotDetail: getSnapshotDetail,
}

const route = useRoute()

snapshotId.value = route.query.snapshot_id
vcode.value = route.query.vcode

if (route.query.type && route.query.id) {
  startNode.value = [
    {
      type: route.query.type,
      id: route.query.id
    }
  ]
}

const handleHighLight = (type, prop, value) => {
  console.log('forceGraph', forceGraph.value)
  forceGraph.value.handleCustomSelect(type, prop, value)
}

const handleEvent = (data) => {
  console.log('监听菜单事件', data)
}
const handleSelectNode = (data) => {
  console.log('handleSelectNode', data)
}
function handleDataLoaded(data) {
  console.log('handleDataLoaded', data)
}
</script>
<style lang="scss">
.graph-container {
  height: calc(100vh - 66px);
}
</style>

方式二:全局引入

在main.js中引入并注册。

// main.js
import { createApp } from 'vue'
import Graph from 'vue-safe-force-graph'
import 'vue-safe-force-graph/lib/style.css'
const app = createApp(App)
app.use(Graph)

在自己的业务组件中使用,全局注册的组件名为ForceGraphByCanvas,示例如下 :

<template>
  <ForceGraphByCanvas
      :graph-api="graphApi"
      module="md5graph"
      :start-node="startNode"
      :enter-start-node="true"
      :has-level="true"
      :snapshot_id="snapshotId"
      :vcode="vcode"
      :handle-select-node-event="handleSelectNode"
      :custom-context-menu-event="handleEvent"
      @handle-data-loaded="handleDataLoaded"
    />
</template>

<script setup>
// 此处js代码参考上面组件引入的实例
</script>

组件属性

属性名说明类型默认值是否必填
graph-api图数据相关接口,包含config、节点数据、节点详情接口Object
module当前图模块 用于 获取config接口时的传参。 this.graphApi?.getGraphConfig({name: this.module}).then(() => {})String
start-node开始节点,如 startNode = {type: "ip",id: "193.36.119.50"}Array
enter-start-node起始节点时是否出现查询添加接口Booleanfalse
has-level是否有level等级概念Booleantrue
snapshot_id快照idString
vcode快照密码String
dark-mode是否为深色模式Booleanfalse
showPoint图左侧的legend图例部分,是否需要收藏 备注 标签Booleantrue
isShowRightMenu是否展示右侧详情 部分Booleantrue
hideButtonList需要隐藏的顶部按钮, 如 hideButtonList = "新增节点"。全部可选项为[ "新增节点", "删除", "保存快照", "保存图片", "数据导出", "数据导入", "撤销", "恢复", "自动布局", "全局固定", "全局解除固定", "树型布局", "斥力布局","展开折叠", "功能介绍", ]Array
isRenderStartNode是否渲染startNode。Booleantrue
isDefaultSelectStartNode是否默认选中开始节点startNodeBooleantrue
graphUrlPath用于生成快照后的图页面的地址路径。 例如当生成快照成功后,会生成一个链接,https://xxx.b.net/${graphUrlPath}?snapshot_id=xxxString'/graph'
levelListlevel危险级别Array { level: '未知', // 级别。必传 levelName: '未知', // 必传。级别的名称 用于展示文案 className: 'unknown', // class样式名。必传 iconType: '', // 默认使用图标,传dot使用圆点样式 normalColor: '#666', // 颜色色值。必传 darkColor: '#c6cdd5', // 暗黑模式颜色色值,非必传。不传使用normalColor dangerNumber: 0, // 是否是 危险的局别。 用于统计危险数,对危险的节点增加样式等。和危险数的排序 }, { level: '危险', levelName: '危险', className: 'warn', iconType: '', // 默认使用图标,传dot使用圆点样式 normalColor: '#CF1322', darkColor: '#fb2400', dangerNumber: 1, }, { level: '普通', levelName: '普通', className: 'normal', iconType: '', // 默认使用图标,传dot使用圆点样式 normalColor: '#007EE2', darkColor: '#0094ff', dangerNumber: -1, }, { level: '安全', levelName: '安全', className: 'safe', iconType: '', // 默认使用图标,传dot使用圆点样式 normalColor: '#009A75', darkColor: '#00da90', dangerNumber: -2, },
showLevelCount是否在左侧图例legend的leve图标l旁边展示相关节点的数量。Booleanfalse
title在图的左上角设置标题,默认无String | Html
isShowNodeMessage是否展示 渲染多少个节点的 message提示Booleantrue
nodeTypeScale图中关系节点图标大小的缩放比例。如缩小0.5倍则传数字0.5Number1
singlesNodeMaxNum单个关系类型下的最大节点数量。如果节点数量超过此值,默认聚合隐藏起来Number100
handleSelectNodeEvent选择节点事件的props(兼容angular调用,vue可以使用事件方式)Function
customContextMenuEvent自定义右键菜单的点击事件,相关配置参考下面的自定义右键菜单。会返回数据 { eventName: 'api.name', customConfig: 'api.customConfig', nodes: 'nodes', allNodes: 'this.history.dataNow.nodes', }(兼容angular调用,vue可以使用事件方式)Function
handleDataLoaded图加载数据完成后 的事件通知。会返回图中所有的节点数据。(兼容angular调用,vue可以使用事件方式)Function
nodeWidth节点的宽度Number24
startNodeWidth起始节点的宽度Number24
linkDistance用于调整d3.forceLink 的距离:以确保link长度,值越大距离越长。d3文档 (当配置nodeWidth后可能会用到,比如nodewidth太大时,需要增加link距离)Number120
strengthd3js的manyBody.strength属性。调整 d3.forceManyBody 的强度:增加或减少节点之间的排斥力,值为负值,负数越大斥力越大,如0表示无斥力,-600中等斥力。d3文档(当配置nodeWidth后可能会用到,比如nodewidth太大时,需要增加节点之间的斥力)Number-600
customTooltip自定义tooltip内容,传入一个函数,函数中能拿到节点数据,函数需返回html模板Function
edgeLabelMaxLength边上文字的最大长度,超过则省略展示,鼠标悬浮展示全部Number10

自定义右键菜单

在config接口中配置节点的右键菜单项,图组件拿到数据后渲染到页面上, 并绑定点击事件。点击后emit出去相关的数据。使用者监听该事件,然后自行处理后续流程。

菜单项配置在下面详情接口中,data => records => info => extraNodeContextMenus字段,如

{
    'code': '0',
    'msg': 'ok',
    'data': {
      'records': [
        {
          'summary': '',
          'tags': [],
          'info': {
            // 额外右键菜单项
            'extraNodeContextMenus': [
              {
                name: 'dealwith1', // 菜单唯一标识,用于点击事件传出去
                namec: '菜单1 无children', // 菜单展示的文案
                icon: 'button_edit_label', // 右键菜单的图标,不传的话默认一个图标
                customConfig: { // 透传自定义配置
                  input: 'xxxxx',
                  a: 'ceshi'
                }
              },
              {
                name: 'dealwith2',
                namec: '菜单2 无children',
                customConfig: {
                  input: 'xxxxx',
                  a: 'ceshi'
                },
                // children 二级菜单
                children: [
                  {
                    name: 'xxx',
                    namec: 'xxx',
                    customConfig: {
                      input: '333',
                      a: 'ces3333hi'
                    }
                  }
                ]
              },
              {
                name: 'dealwxxith3',
                namec: 'xxx',
                children: [
                  {
                    name: 'xxx',
                    namec: 'xxx',
                    children: [
                      {
                        name: 'threelevel',
                        namec: '三级菜单'
                      }
                    ]
                  }
                ]
              }
            ],
            'id': '1234',
            'name': '123',
            'type': 'url',
            'basic': {
              'level': '未知',
              'check_time': '',
              'desc': ''
            },
            'extends': null
          },
          'brief': []
        },
        {
          'summary': '',
          'tags': [],
          'info': {
            'id': '234234',
            'name': '234234',
            'type': 'url',
            'basic': {
              'level': '未知',
              'check_time': '',
              'desc': ''
            },
            'extends': null
          },
          'brief': []
        }
      ]
    }
  }

事件

事件名说明示例
handle-data-loaded图加载数据完成后 的事件通知。会返回图中所有的节点数据<ForceGraphByCanvas :graph-api="graphApi" :module="module" :start-node="startNode" @handle-data-loaded="handleDataLoaded" @custom-contextmenu-click="handleContextmenu" @handle-select-node="handleSelectNode" />
custom-contextmenu-click自定义右键菜单的点击事件。返回 eventName 事件名 、customConfig当前点击的nodes 节点的整个数据, 所有节点allNodes如上
handle-select-node选择节点事件如上

方法

方法名说明参数
controlOperation操作控制,传入node数据和对应api操作。如显示隐藏按钮,示例如下
handleCustomSelect选择节点
controlOperation示例
<ForceGraphByCanvas
  ref="forceGraph"
  graph-url-path="/hmGraphByCanvas"
  :graph-api="graphApi"
  :module="module"
  :start-node="startNode"
  @handle-data-loaded="handleDataLoaded"
/>

/*
* 参数格式 { nodes: [{ id: '8c5c0cda7d0f3ec28e818b441037cf2d' }], api: { name: 'show_node' }}
*  */
function showNode() {
  forceGraph.value.controlOperation({ nodes: [{ id: '8c5c0cda7d0f3ec28e818b441037cf2d' }], api: { name: 'show_node' }})
}
function hideNode() {
  forceGraph.value.controlOperation({ nodes: [{ id: '8c5c0cda7d0f3ec28e818b441037cf2d' }], api: { name: 'hide_node' }})
}

// 全部展示数据节点边的label
function allShowEdgeLabel() {
  forceGraph.value.controlOperation({ api: { name: 'all_show_edges_label' }})
}
// 全部隐藏数据节点边的label
function allHideEdgeLabel() {
  forceGraph.value.controlOperation({ api: { name: 'all_hide_edges_label' }})
}
controlOperation其他api name
  • edit_label修改label
  • single_edge_select 单边顶点选择
  • hold_aggregation单边顶点聚合
  • release_aggregation聚合顶点释放
  • node_star收藏
  • un_node_star取消收藏
  • show_label show_names 显示节点名称
  • un_show_names un_show_label 隐藏节点名称
  • fix_nodes固定节点
  • un_fix_nodes取消固定节点
  • delete_node删除节点
handleCustomSelect
const handleHighLight = () => {
  forceGraph.value.handleCustomSelect('include', 'id', ['xxxs0'])
}

图标加载方式

图标icon图片有2中加载方式:1从cdn中加载,2打包为base64到npm包中加载。

图谱中的图标icon默认是从cdn链接中加载的。如果您存在私有化部署不能访问公网的场景,可以联系作者打包base64版本。

其他配置项

1.关系节点增加统计数字

在config配置中的的plugs对应的新增一个 show_total 字段,布尔值 true 或者 false。

2.icon自定义图标的图片

数据节点的图标。 节点详情detail接口的 info下 新增 icon_img字段 存在,则使用此 icon_img 图片。 可以是图片链接或者是base64。

关系节点的图标。 在config接口的plugs字段下对应的位置,加一个icon_img字段,用于关系节点的图标。

3.节点线上 增加描述文案

在获取节点和link的接口中,在links字段下面,新增一个字段 edge_label,字符串,如果有值则展示此文案,没有则不展示。

config配置
// config配置
{
    "code": "0",
    "msg": "ok",
    "request_id": "QJDysikHdHqtwhMRQFek",
    "data": {
        "plugs": {
            "md5": [
                {
                    "show_total": true, // 是否展示增加统计数字
                    "icon_img": "https://files.codelife.cc/icons/google.svg", // 自定义关系节点图标的图片
                    "canloop": true,
                    "icon": "file",
                    "name": "xxx",
                    "namec": "释放文件",
                    "path": "xxxx",
                    "relay_name": "释放文件"
                },
            ]
        }
    }
}
detail配置
{
    "code": "0",
    "msg": "ok",
    "data": {
        "records": [
            {
                "summary": "",
                "tags": null,
                "info": {
                    "id": "sfdsdfsf",
                    "name": "“xxx",
                    "type": "report",
                    "icon_img": "自定义节点图片", // 自定义图片
                    "basic": {
                        "title": "“黑球”行动再升级,SMBGhost漏洞攻击进入实战",
                        "url": "xxxx",
                        "update_time": "2021-04-29 05:11:53"
                    },
                    "extends": null
                },
                "brief": []
            }
        ]
    }
}
获取节点数据接口示例
{
  "code": "0",
  "msg": "ok",
  "data": {
    "nodes": [
      {
        "id": "a",
        "name": "a",
        "type": "md5",
        "origin": [],
        "feature": {}
      },
      {
        "id": "b",
        "name": "b",
        "type": "md5",
        "origin": [],
        "feature": {}
      }
    ],
    "links": [
      {
        "source": "a",
        "target": "b",
        "type": "domain-md5",
        "desc": "",
        "feature": {},
        "edge_label": "边的描述文案" // 新增:边的描述文案
      }
    ]
  }
}

开发相关

To run the development server

npm run dev

To build the library

npm run lib

To publish a new version

npm run patch npm run lib npm publish

开发人员手册

开发请看这里

如有问题请联系 jiangzhenxiang

2.0.64

9 months ago

2.0.62

10 months ago

2.0.63

10 months ago

2.0.48

1 year ago

2.0.49

1 year ago

2.0.46

1 year ago

2.0.47

1 year ago

2.0.59

12 months ago

2.0.57

12 months ago

2.0.58

12 months ago

2.0.55

1 year ago

2.0.56

1 year ago

2.0.53

1 year ago

2.0.54

1 year ago

2.0.51

1 year ago

2.0.52

1 year ago

2.0.50

1 year ago

2.0.60

12 months ago

2.0.45

1 year ago

2.0.44

1 year ago

2.0.42

1 year ago

2.0.43

1 year ago

2.0.40

1 year ago

2.0.41

1 year ago

2.0.38

1 year ago

2.0.39

1 year ago

2.0.37

1 year ago

2.0.36

1 year ago

2.0.35

1 year ago

2.0.34

1 year ago

2.0.33

1 year ago

2.0.32

1 year ago

2.0.31

1 year ago

2.0.30

1 year ago

2.0.27

1 year ago

2.0.28

1 year ago

2.0.29

1 year ago

2.0.26

1 year ago

2.0.24

1 year ago

2.0.25

1 year ago

2.0.23

1 year ago

2.0.22

1 year ago

2.0.21

1 year ago

2.0.20

2 years ago

2.0.19

2 years ago

2.0.18

2 years ago

1.0.32

2 years ago

2.0.17

2 years ago

0.0.216

2 years ago

0.0.217

2 years ago

2.0.15

2 years ago

2.0.16

2 years ago

2.0.14

2 years ago

2.0.13

2 years ago

2.0.11

2 years ago

2.0.12

2 years ago

2.0.10

2 years ago

2.0.9

2 years ago

0.0.215

2 years ago

0.0.214

2 years ago

0.0.213

2 years ago

2.0.5

2 years ago

2.0.7

2 years ago

2.0.6

2 years ago

2.0.8

2 years ago

1.0.31

2 years ago

1.0.30

2 years ago

2.0.3

2 years ago

2.0.2

2 years ago

2.0.4

2 years ago

1.0.29

2 years ago

2.0.2-beta.3

2 years ago

0.0.212

2 years ago

0.0.210

2 years ago

2.0.2-beta.0

2 years ago

2.0.2-beta.1

2 years ago

2.0.2-beta.2

2 years ago

2.0.1-beta.8

2 years ago

2.0.1-beta.9

2 years ago

2.0.1-beta.2

2 years ago

2.0.1-beta.3

2 years ago

2.0.1-beta.0

2 years ago

2.0.1-beta.1

2 years ago

2.0.1-beta.6

2 years ago

2.0.1-beta.7

2 years ago

2.0.1-beta.4

2 years ago

2.0.1-beta.5

2 years ago

2.0.1-beta.11

2 years ago

2.0.1-beta.10

2 years ago

2.0.1

2 years ago

0.0.208

2 years ago

0.0.205

2 years ago

0.0.204

2 years ago

0.0.203

2 years ago

0.0.202

2 years ago

0.0.207

2 years ago

0.0.206

2 years ago

0.0.201

2 years ago

0.0.200

2 years ago

0.0.203-alpha.0

2 years ago

0.0.197

2 years ago

0.0.196

2 years ago

0.0.195

2 years ago

0.0.194

2 years ago

0.0.199

2 years ago

0.0.198

2 years ago

0.0.193

2 years ago

1.0.19

2 years ago

1.0.2

2 years ago

1.0.18

2 years ago

1.0.1

2 years ago

1.0.17

2 years ago

1.0.0

2 years ago

1.0.16

2 years ago

1.0.9

2 years ago

1.0.8

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.0.21

2 years ago

1.0.20

2 years ago

1.0.26

2 years ago

1.0.25

2 years ago

1.0.24

2 years ago

1.0.23

2 years ago

1.0.28

2 years ago

1.0.27

2 years ago

1.0.0-beta.2

2 years ago

1.0.0-beta.3

2 years ago

1.0.0-beta.4

2 years ago

1.0.0-beta.5

2 years ago

1.0.0-beta.0

2 years ago

1.0.0-beta.1

2 years ago

1.0.0-beta.6

2 years ago

1.0.11

2 years ago

1.0.10

2 years ago

1.0.15

2 years ago

1.0.14

2 years ago

1.0.13

2 years ago

1.0.12

2 years ago

0.0.188

3 years ago

0.0.187

3 years ago

0.0.192

3 years ago

0.0.191

3 years ago

0.0.190

3 years ago

0.0.186

3 years ago

0.0.185

3 years ago

0.0.184

3 years ago

0.0.183

3 years ago

0.0.182

3 years ago

0.0.181

3 years ago

0.0.169

3 years ago

0.0.168

3 years ago

0.0.167

3 years ago

0.0.166

3 years ago

0.0.165

3 years ago

0.0.175

3 years ago

0.0.174

3 years ago

0.0.173

3 years ago

0.0.172

3 years ago

0.0.179

3 years ago

0.0.178

3 years ago

0.0.177

3 years ago

0.0.176

3 years ago

0.0.171

3 years ago

0.0.170

3 years ago

0.0.180

3 years ago

0.0.164

3 years ago

0.0.163

3 years ago

0.0.159

3 years ago

0.0.158

3 years ago

0.0.153

3 years ago

0.0.152

4 years ago

0.0.151

4 years ago

0.0.150

4 years ago

0.0.157

3 years ago

0.0.156

3 years ago

0.0.155

3 years ago

0.0.154

3 years ago

0.0.162

3 years ago

0.0.161

3 years ago

0.0.160

3 years ago

0.0.128

4 years ago

0.0.127

4 years ago

0.0.126

4 years ago

0.0.125

4 years ago

0.0.129

4 years ago

0.0.124

4 years ago

0.0.123

4 years ago

0.0.122

4 years ago

0.0.139

4 years ago

0.0.138

4 years ago

0.0.137

4 years ago

0.0.136

4 years ago

0.0.131

4 years ago

0.0.130

4 years ago

0.0.135

4 years ago

0.0.134

4 years ago

0.0.133

4 years ago

0.0.132

4 years ago

0.0.149

4 years ago

0.0.148

4 years ago

0.0.147

4 years ago

0.0.142

4 years ago

0.0.141

4 years ago

0.0.140

4 years ago

0.0.146

4 years ago

0.0.145

4 years ago

0.0.144

4 years ago

0.0.143

4 years ago

0.0.119

4 years ago

0.0.118

4 years ago

0.0.120

4 years ago

0.0.121

4 years ago

0.0.109

4 years ago

0.0.108

4 years ago

0.0.117

4 years ago

0.0.116

4 years ago

0.0.115

4 years ago

0.0.114

4 years ago

0.0.113

4 years ago

0.0.112

4 years ago

0.0.111

4 years ago

0.0.110

4 years ago

0.0.107

4 years ago

0.0.106

4 years ago

0.0.105

4 years ago

0.0.104

4 years ago

0.0.103

4 years ago

0.0.101

4 years ago

0.0.100

4 years ago

0.0.95

4 years ago

0.0.96

4 years ago

0.0.97

4 years ago

0.0.98

4 years ago

0.0.99

4 years ago

0.0.94

4 years ago

0.0.91

4 years ago

0.0.92

4 years ago

0.0.93

4 years ago

0.0.90

4 years ago

0.0.87

4 years ago

0.0.88

4 years ago

0.0.89

4 years ago

0.0.85

4 years ago

0.0.86

4 years ago

0.0.84

4 years ago

0.0.83

4 years ago

0.0.81

4 years ago

0.0.82

4 years ago

0.0.80

4 years ago

0.0.74

4 years ago

0.0.75

4 years ago

0.0.76

4 years ago

0.0.77

4 years ago

0.0.78

4 years ago

0.0.79

4 years ago

0.0.73

4 years ago

0.0.72

4 years ago

0.0.70

4 years ago

0.0.71

4 years ago

0.0.68

4 years ago

0.0.69

4 years ago

0.0.67

4 years ago

0.0.66

4 years ago

0.0.64

4 years ago

0.0.65

4 years ago

0.0.62

4 years ago

0.0.63

4 years ago

0.0.60

4 years ago

0.0.61

4 years ago

0.0.59

4 years ago

0.0.58

4 years ago

0.0.57

4 years ago

0.0.55

4 years ago

0.0.56

4 years ago

0.0.54

4 years ago

0.0.51

4 years ago

0.0.52

4 years ago

0.0.53

4 years ago

0.0.47

4 years ago

0.0.50

4 years ago

0.0.48

4 years ago

0.0.49

4 years ago

0.0.44

4 years ago

0.0.45

4 years ago

0.0.46

4 years ago

0.0.40

4 years ago

0.0.41

4 years ago

0.0.42

4 years ago

0.0.43

4 years ago

0.0.37

4 years ago

0.0.38

4 years ago

0.0.39

4 years ago

0.0.30

4 years ago

0.0.31

4 years ago

0.0.32

4 years ago

0.0.33

4 years ago

0.0.34

4 years ago

0.0.35

4 years ago

0.0.36

4 years ago

0.0.29

4 years ago

0.0.28

4 years ago

0.0.27

4 years ago

0.0.26

4 years ago

0.0.25

4 years ago

0.0.24

4 years ago

0.0.23

4 years ago

0.0.22

4 years ago

0.0.21

4 years ago

0.0.20

4 years ago

0.0.19

4 years ago

0.0.18

4 years ago

0.0.17

4 years ago

0.0.15

4 years ago

0.0.14

4 years ago

0.0.13

4 years ago

0.0.12

4 years ago

0.0.11

4 years ago

0.0.10

4 years ago

0.0.9

4 years ago

0.0.8

4 years ago

0.0.7

4 years ago

0.0.6

4 years ago

0.0.4

4 years ago

0.0.3

4 years ago

0.0.2

4 years ago

0.0.1

4 years ago