Interactive Network Graph Visualization Component For Vue 3

An interactive, draggable, SVG based network graph visualization component for Vue 3.

Basic Usage:

1. Import and register the component.

import VNetworkGraph from "v-network-graph"
import "v-network-graph/style.css"
Vue.use(VNetworkGraph);

2. Add the v-network-graph component to the template.

<template>
  <v-network-graph
    :nodes="nodes"
    :edges="edges"
  />
</template>

3. Prepare your node & edge data as follows:

import { defineComponent } from "vue"
export default defineComponent({
  setup() {
    const nodes = {
      node1: { name: "Node 1" },
      node2: { name: "Node 2" },
      node3: { name: "Node 3" },
      // ...
    }
    const edges = {
      edge1: { source: "node1", target: "node2" },
      edge2: { source: "node2", target: "node3" },
      // ...
    }
    return { nodes, edges }
  },
})

4. Default component props.

nodes: {
  type: Object as PropType<Nodes>,
  default: () => ({}),
},
edges: {
  type: Object as PropType<Edges>,
  default: () => ({}),
},
layouts: {
  type: Object as PropType<UserLayouts>,
  default: () => ({}),
},
zoomLevel: {
  type: Number,
  default: 1,
},
selectedNodes: {
  type: Array as PropType<string[]>,
  default: () => [],
},
selectedEdges: {
  type: Array as PropType<string[]>,
  default: () => [],
},
configs: {
  type: Object as PropType<UserConfigs>,
  default: () => ({}),
},
paths: {
  type: Array as PropType<Paths>,
  default: () => [],
},
layers: {
  type: Object as PropType<Layers>,
  default: () => ({}),
},
eventHandlers: {
  // Since a large number of events will be issued, to avoid
  // contaminating the event log of the development tools,
  // events are designed to be notified to a handler function
  // specified by the user.
  type: Object as PropType<EventHandlers>,
  default: () => ({}),
},

5. Default configurations.

{
  view: {
    scalingObjects: boolean, // whether to expand the entire object.    default: false
    panEnabled: boolean,     // whether the pan is enabled or not.      default: true
    zoomEnabled: boolean,    // whether the zoom is enabled or not.     default: true
    minZoomLevel: number,    // minimum zoom level.                     default: 0.1
    maxZoomLevel: number,    // maximum zoom level.                     default: 64
    fit: boolean,            // whether to fit the content when loaded. default: false
    layoutHandler: LayoutHandler, // class to control node layout.   default: new SimpleLayout()
    onSvgPanZoomInitialized: undefined | (instance) => void, // callback on init svg-pan-zoom. default: undefined
    grid: {
      visible: boolean,         // whether to show the grid in the background. default: false
      interval: number,         // grid line spacing.                          default: 10
      thickIncrements: number,  // increments of ticks to draw thick lines.    default: 5
      line: {                   // normal line style
        color: string,          //   default: "#e0e0e0",
        width: number,          //   default: 1
        dasharray: number       //   default: 1
      },
      thick: {                  // thick line style
        color: string,          //   default: "#cccccc",
        width: number,          //   default: 1
        dasharray: number       //   default: 0
      }
    }
  },
  node: {
    normal: {
      // * These fields can also be specified with the function as `(node) => value`.
      type: "circle" | "rect",  // shape type.            default: "circle"
      radius: number,           // radius of circle.      default: 16
      width: number,            // width of rect.         default: (not specified)
      height: number,           // height of rect.        default: (not specified)
      borderRadius: number,     // border radius of rect. default: (not specified)
      color: string,            // fill color.            default: "#4466cc"
      strokeWidth: number,      // stroke width.          default: 0
      strokeColor: string | undefined,              // stroke color.      default: "#000000"
      strokeDasharray: number | string | undefined  // stroke dash array. default: 0
    },
    hover: { /* same structure as `node.normal`. */ } | undefined,
        // default: {
        //   color: "#3355bb",
        //   ... all other values are same as `normal`
        // }
    selected: { /* same structure as `node.normal`. */ } | undefined,
        // default: undefined
    draggable: boolean,         // whether the node is draggable or not.  default: true
    selectable: boolean,        // whether the node is selectable or not. default: false
    label: {
      // * These fields can also be specified with the function as `(node) => value`.
      visible: boolean,         // whether the node's label is visible or not. default: true
      fontFamily: string | undefined,  // font family.       default: undefined
      fontSize: number,                // font size.         default: 11
      lineHeight: number,              // line height (multiplier for font size). default: 1.1
      color: string,                   // font color.        default: "#000000"
      background: {                    // background config. default: undefined
        visible: boolean,          // whether the background is visible or not.
        color: string,             // background color.
        padding: number | {        // padding.
          vertical: number,        // vertical padding.
          horizontal: number,      // horizontal padding.
        },
        borderRadius: number       // border radius.
      } | undefined,
      margin: number,                  // margin from node. default: 4
      direction: NodeLabelDirection,   // node label display direction. default: SOUTH
      text: string    // field name in the node object to use as the label. default: "name"
                      // if function is specified, the return value is string of label.
    },
    focusring: {
      visible: boolean, // whether the focus ring is visible or not.     default: true
      width: number,    // line width of the focus ring.                 default: 4
      padding: number,  // distance between the focus ring and the node. default: 3
      color: string     // fill color.                                   default: "#eebb00"
    }
  },
  edge: {
    normal: {
      // * These fields can also be specified with the function as `(edge) => value`.
      width: number,           // width of edge.                           default: 2
      color: string,           // line color.                              default: "#4466cc"
      dasharray: number | string | undefined,        // stroke dash array. default: 0
      linecap: "butt" | "round" | "square" | undefined, // stroke linecap. default: "butt"
      animate: boolean,        // whether to animate or not.               default: false
      animationSpeed: number   // animation speed.                         default: 100
    },
    hover: { /* same structure as `normal`. */ } | undefined,
        // default: {
        //   color: "#3355bb",
        //   ... all other values are same as `edge.normal`
        // },
    selected: { /* same structure as `normal`. */ } | undefined,
        // default: {
        //   color: "#dd8800",
        //   dasharray: (wider than `normal`),
        //   ... all other values are same as `edge.normal`
        // }
    selectable: boolean,   // whether the edge is selectable or not. default: false
    gap: number | ((edges: Edges, configs: Configs) => number),
        // number: distance between edges.
        // func : function to calculate gap from edge list between nodes.
        // default: 3
    marker: {
      source: {
        type:  "none" | "array" | "angle" | "circle" | "custom",
                              // type of marker.                          default: "none"
        width: number,        // width of marker.                         default: 5
        height: number,       // height of marker.                        default: 5
        margin: number,       // distance between marker and end of edge. default: -1
        units: "strokeWidth" | "userSpaceOnUse",
                              // units of width, height and margin.            default: "strokeWidth"
        color: string | null, // color of marker. null: same as edge color.    default: null
        customId: string | undefined
                              // custom marker ID for marker type is "custom". default: undefined
      },
      target: { /* same structure as `source`. */ }
    },
    summarize: boolean | ((edges: Edges, configs: Configs) => boolean),
        // true : summarize when the width of the edge becomes larger than the node.
        // false: do not summarize.
        // func : function to determine whether to summarize from edge list between nodes.
        // default: true
    summarized: { // configs for summarized edge
      label: {
        fontSize: number,  // font size.  default: 10
        color: string      // font color. default: "#4466cc"
      },
      shape: { /* same structure as `node.normal`. */ },
        // default: {
        //   type: "rect",
        //   width: 12,
        //   height: 12,
        //   borderRadius: 3,
        //   color: "#ffffff",
        //   strokeWidth: 1,
        //   strokeColor: "#4466cc",
        //   strokeDasharray: undefined
        // }
      stroke: { /* same structure as `edge.normal`. */ }
        // default: {
        //   width: 5,
        //   color: "#4466cc",
        //   dasharray: undefined,
        //   linecap: undefined,
        //   animate: false,
        //   animationSpeed: 50
        // }
      }
    },
    label: {
      fontFamily: string | undefined,  // font family.       default: undefined
      fontSize: number,                // font size.         default: 11
      lineHeight: number,              // line height (multiplier for font size). default: 1.1
      color: string,                   // font color.        default: "#000000"
      background: {                    // background config. default: undefined
        visible: boolean,          // whether the background is visible or not.
        color: string,             // background color.
        padding: number | {        // padding.
          vertical: number,        // vertical padding.
          horizontal: number,      // horizontal padding.
        },
        borderRadius: number       // border radius.
      } | undefined,
      margin: number,              // distance from edge stroke. default: 4
      padding: number              // distance from end node. default: 4
    }
  },
  path: {
    visible: boolean,     // whether the paths are visible or not. default: false
    clickable: boolean,   // whether paths are clickable or not.   default: false
    curveInNode: boolean, // whether to curve paths within nodes.  default: false
    path: {
      // * These fields can also be specified with the function as `(path) => value`.
      width: number,      // width of path. default: 6
      color: string,      // path color. default: (Func to select a color from a hash of edges.)
      dasharray: number | string | undefined,         // stroke dash array. default: undefined
      linecap: "butt" | "round" | "square" | undefined,  // stroke linecap. default: "round"
      linejoin: "miter" | "round" | "bevel",            // stroke linejoin. default: "round"
      animate: boolean,                       // whether to animate or not. default: false
      animationSpeed: number                  // animation speed.           default: 50
    },
  }
}

5. Event handlers.

  • @update:zoomLevel: update zoom level
  • @update:selectedNodes: update selected nodes
  • @update:selectedEdges: update selected edges
  • @update:layouts: update layouts

6. API methods.

  • fitToContents(): void Perform zooming/panning according to the graph size.
  • getAsSvg(): string Get the network-graph contents as SVG text data.
  • getPan(): {x, y} Get pan vector.
  • getSizes(): Sizes Get all calculate svg dimensions.
  • Sizes: {width, height, viewBox:{x, y, width, height}}
  • panTo(point: {x, y}): void Pan to a rendered position.
  • panBy(point: {x, y}): void Relatively pan the graph by a specified rendered position vector.
  • panToCenter(): void Perform a pan to center the contents of the network graph.
  • zoomIn(): void Perform zoom-in.
  • zoomOut(): void Perform zoom-out.

Preview:

Interactive Network Graph Visualization Component For Vue 3

Changelog:

v0.6.3 (07/01/2022)

  • Fix to not raise an error even if the node pointed to by the edge does not exist, in ForceLayout.

v0.6.2 (06/28/2022)

  • Fix a bug in box-selection that the box remains when the cmd key is released before the mouse.

v0.6.1 (06/26/2022)

  • Add a slot edge-overlay for drawing objects on edges.
  • Add a config to start box selection mode with ctrl/cmd key (configs.view.boxSelectionEnabled).
  • Bug Fix

v0.6.0 (06/20/2022)

  • Add a feature to select nodes with a rectangle.

v0.5.19 (06/13/2022)

  • Change to not block wheel event when zoom by mouse wheel is disabled.
  • Change to not block touch operation when pan/zoom/draggable are all disabled.

v0.5.18 (06/07/2022)

  • Add transitionWhile() method to <v-network-graph> instance.

v0.5.17 (05/26/2022)

  • The width and height of a css can now be specified directly for <v-network-graph> component.

v0.5.16 (05/19/2022)

  • Fixed an issue where, in a situation with multiple v-network-graph instances, if there is an edge marker with the same parameters and the forward instance is hidden with display:none, the edge marker of the back instance will disappear.

v0.5.15 (05/15/2022)

  • Fix incorrect gap calculation between rectangular nodes and arrow-headed edges.
  • Add getViewBox and setViewBox functions to get and set view area.

v0.5.14 (05/10/2022)

  • Fix a problem where ForceLayout would detect any property change of the edge and recalculate force simulation.

v0.5.13 (04/24/2022)

  • Change that dbl-click and wheel zoom are also disabled if view.zoomEnabled config is set to false.

v0.5.13 (04/24/2022)

  • Fix an exception when deleting a node to which an edge is connected when edge type is “curve”.

v0.5.11 (04/17/2022)

  • Fix: the focus ring was not shown when modifying selected-nodes
  • Fix: double-clicking on a node would unexpectedly zoom in. (update @dash14/svg-pan-zoom library)

v0.5.10 (04/16/2022)

  • Expose <v-shape /> components for the use case that specify raw event handlers to the nodes.
  • Remove unnecessary event.preventDefault().

v0.5.9 (04/07/2022)

  • Fix wheel events being propagated outside the graph area.

v0.5.8 (04/04/2022)

  • Fix an issue where the view:click event would not work after view:contextmenu

v0.5.7 (03/22/2022)

  • Fix an issue where right-clicking on node/edge/path would also trigger “view:contextmenu” event.

v0.5.5 (03/17/2022)

  • Fix problem with multiple edge selection by touch

v0.5.4 (03/12/2022)

  • Change to relax the movement detection threshold with touch

v0.5.3 (03/08/2022)

  • Fix issue with onclick events not firing in mobile browsers

v0.5.2 (03/06/2022)

  • Fix a bug that edge selected from the beginning did not become selected

v0.5.0 (02/22/2022)

  • Add the ability to select paths.
  • Add support for dynamically changing the appearance of a path when its hover/selection state changes.
  • Add support for z-order control of paths as well as nodes and edges.
  • Add support for catching new path-related events with event-handlers. “path:pointerover”, “path:pointerout”, “path:pointerdown”, “path:pointerup”, “path:select”
  • Purge the dependency on victor (2D vector maths library).

Download Details:

Author: dash14

Live Demo: https://dash14.github.io/v-network-graph/examples/basic.html

Download Link: https://github.com/dash14/v-network-graph/archive/refs/heads/main.zip

Official Website: https://github.com/dash14/v-network-graph

Install & Download:

# NPM
$ npm i v-network-graph --save

Add Comment