npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@metabohub/mth-ui-viz

v1.4.0

Published

An open source project dedicated for graph visualisation.

Readme

mth-ui-viz

The mth-ui-viz project allows you to set up a network visualisation tool and to choose the features you want to add to the interface by means of ‘kits’.

Breaking Changes in version 1.0.0 !

v-model for network and networkStyle

Previous API:

<VizTool :network="network" :network-style="networkStyle" />

New API:

<VizTool v-model:network="network" v-model:network-style="networkStyle" />

Both network and networkStyle props have been changed from regular props to v-model bindings. This enables two-way data binding, allowing the component to update these objects directly and automatically synchronizing changes with the internal store. You must now use:

  • v-model:network instead of :network
  • v-model:network-style instead of :network-style

Pinia Store Integration

This project now uses Pinia for state management.

Prerequisites for parent projects: To use this component in your project, you must have Pinia installed and initialized:

npm install pinia
// main.ts in your parent project
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';

const app = createApp(App);
const pinia = createPinia();

app.use(pinia);  // ← Required: This Pinia instance will be shared with VizTool
app.mount('#app');

Zoom Store - Shared Instance: A Pinia store (useZoomStore) manages zoom functionality. The store instance is automatically shared between VizTool and your parent components when they use the same Pinia instance:

<template>
  <div>
    <VizTool v-model:network="network" v-model:network-style="style" />
    <!-- Parent can control zoom directly -->
    <button @click="zoomStore.rescaleNetwork()">Rescale from parent</button>
  </div>
</template>

<script setup>
import { VizTool, useZoomStore } from '@metabohub/mth-ui-viz';

// This returns the SAME store instance used internally by VizTool
const zoomStore = useZoomStore();

// Available methods:
// - zoomStore.rescaleNetwork()  → Fit network to viewport
// - zoomStore.graphZoomIn()     → Zoom in
// - zoomStore.graphZoomOut()    → Zoom out
// - zoomStore.svgProperties     → Access SVG zoom instance (read-only)
</script>

How it works: Pinia stores are singletons per Pinia instance. When VizTool calls useZoomStore() internally and your parent component calls useZoomStore(), they both get the same store instance because they share the same Pinia instance (the one you initialized with app.use(pinia)). This enables coordinated state management between the visualization component and your application logic.

Types

| Name | Value | | ---- | ----- | | Network | {id: string, nodes: {[key: string]: Node}, links: Array} | | GraphStyleProperties | {nodeStyle: NodeStyle, linkStyle: LinkStyle} |

For more specifications about Node, Link, NodeStyle and LinkStyle, see VizCore README.

VizTool

v-model

| Name | Description | Type | | ------------ | ---------------------------------------- | --------------------- | | network | Network object to visualise | Network | | networkStyle | Style object to apply to the network | GraphStyleProperties |

These props use Vue 3's v-model directive for two-way binding. This allows the component to both receive and update the network data and styles.

Props

| Name | Description | Type | Default | | ----------------- | --------------------------------------------- | ---------------------------------------- | ---------- | | mappingData | Mapping data for static mapping | {[key: string]: {conditions: Array, data: any}} | / | | mappingsDisplay | List of all mappings displayed in the graph | Array<{[key: string]: string}> | [] | | dynamicMapping | Mapping data for dynamic mapping | {conditions: Array, data: any} | / | | fluxMappings | Data for flux visualisation | {conditions: Array, data: {[key: string]: {[key: string]: {[key: string]: string}}}} | / | | cycleGroup | List of all cycles draw in the graph | Array | [] | | convexhulls | Information about convexhulls display or not | Convexhulls | {} | | linkClusters | Information about clusters display on links or not | Convexhulls | {} | | allowMappingInput | Enable / disable users to load mapping data | boolean | true | | allowLoadingMask | Enable / disable loading mask | boolean | true | | allowAutoAlgo | Enable / disable to start force layout at network load | boolean | false | | panelConfig | Configuration for menus and buttons | {listButtonMenu: Array, dropDownMenuLeft: {[key: string]: Array}, dropDownMenuRight: {[key: string]: Array}, switchTheme: boolean} | {listButtonMenu: [], dropDownMenuLeft: {}, dropDownMenuRight: {}, switchTheme: false} |

Events

| Name | Description | Return | | ----------- | ---------------------------------------------- | ------------------------------------ | | removeNode | Event emit when a node is removed from graph | node id as string | | loadingEnd | Event emit at end of network load | / |

Slots

contextual-panel-content

The contextual-panel-content slot allows you to customize the content displayed in the metadata panel when a user right-clicks on a node and selects "Show node information".

Slot Props:

| Name | Description | Type | | ---------- | ------------------------ | ---------------------------------------- | | nodeId | The node's ID | string | | nodeLabel | The node's label | string | | metadata | The node's metadata | {[key: string]: string | number | Array<string | number> | {[key: string]: string | number } | boolean} |

Use Case:

This slot is particularly useful when you need to:

  • Display external data from an API based on the selected node
  • Add custom interactions (buttons, forms) for the selected node
  • Combine default metadata with additional information
  • Apply custom styling or layout to the metadata display

Example:

<template>
  <VizTool 
    v-model:network="network" 
    v-model:network-style="networkStyle"
    :panel-config="config"
  >
    <template #contextual-panel-content="{ nodeId, nodeLabel, metadata }">
      <!-- Custom API data section -->
      <div style="padding: 16px; background-color: #f5f5f5;">
        <h3>📡 External Data</h3>
        <div v-if="loading">Loading...</div>
        <div v-else>
          <p><strong>External ID:</strong> {{ apiData.externalId }}</p>
          <p><strong>Database:</strong> {{ apiData.database }}</p>
        </div>
        <button @click="fetchNodeData(nodeId)">
          🔄 Refresh data
        </button>
      </div>
      
      <!-- Default metadata section -->
      <div v-if="Object.keys(metadata).length > 0" style="padding: 16px;">
        <h3>📋 Local Metadata</h3>
        <table>
          <tr v-for="(value, key) in metadata" :key="key">
            <td><strong>{{ key }}</strong></td>
            <td>{{ value }}</td>
          </tr>
        </table>
      </div>
    </template>
  </VizTool>
</template>

<script setup>
import { ref } from 'vue';
import { VizTool } from '@metabohub/mth-ui-viz';

const network = ref({ id: '', nodes: {}, links: [] });
const networkStyle = ref({ nodeStyles: {}, linkStyles: {} });
const apiData = ref({});
const loading = ref(false);

const fetchNodeData = async (nodeId) => {
  loading.value = true;
  // Fetch data from your API
  const response = await fetch(`/api/nodes/${nodeId}`);
  apiData.value = await response.json();
  loading.value = false;
};
</script>

Note: If this slot is not provided, the component will display the node's metadata in a default table format.

MultiVizTool

The MultiVizTool component is a variant of the VizTool component to display multi networks. It takes as a main input a multi (meta) network, a base network style (on top of which the multi network style will be added), a multi network report (a map which contains information on the given multi network), and an array containing the ids of the networks in the multinetwork. It also takes the panel configuration as an input. The rest of the input of the original VizTool component is planned to be added at some point.

Exported Functions

These functions are exported from the package and can be imported for use:

| Name | Description | Argument(s) | Return | | ---- | ----------- | ----------- | ------ | | saveNetworkAsJSON | Save and download network as JSONGraph or return JSON string of the object | network: Network, networkStyle: GraphStyleProperties, mappings: {[key: string]: {[key: string]: string | Array}}, mappingsDisplay: Array<{[key: string]: string}>, dynamicMapping: any, fluxMapping: any, convexhulls: Convexhulls, linkClusters: Convexhulls, cycleGroup: any, download: boolean = true | void or string | | getNetworkData | Return all network, styles and mappings in an object | / | {network: Network, networkStyle: GraphStyleProperties, mappings: {[key: string]: {[key: string]: string | Array}}, mappingsDisplay: Array<{[key: string]: string}>, dynamicMapping: any, fluxMappings: any, convexhulls: Convexhulls, linkClusters: Convexhulls, cycleGroup: any} | | importGraphFromFile | Import a network, styles and mappings object from a file (from @metabohub/mth-viz-core) | file: File | Promise<{network: Network, networkStyle: GraphStyleProperties, mappings: any, dynamicMapping: any, fluxMappings: any, convexhulls: Convexhulls, linkClusters: Convexhulls, cycleGroup: any, metadata: {[key: string]: string}}> | | importGraphFromURL | Import a network, styles and mappings object from an URL (from @metabohub/mth-viz-core) | path: string | Promise<{network: Network, networkStyle: GraphStyleProperties, mappings: any, dynamicMapping: any, fluxMappings: any, convexhulls: Convexhulls, linkClusters: Convexhulls, cycleGroup: any, metadata: {[key: string]: string}}> | | importGraphsFromFile | Import multiple networks from a file (from @metabohub/mth-viz-core) | file: File | Promise<Array<{network: Network, networkStyle: GraphStyleProperties, mappings: any, dynamicMapping: any, fluxMappings: any, convexhulls: Convexhulls, linkClusters: Convexhulls, cycleGroup: any, metadata: {[key: string]: string}}>> | | importGraphsFromURL | Import multiple networks from an URL (from @metabohub/mth-viz-core) | path: string | Promise<Array<{network: Network, networkStyle: GraphStyleProperties, mappings: any, dynamicMapping: any, fluxMappings: any, convexhulls: Convexhulls, linkClusters: Convexhulls, cycleGroup: any, metadata: {[key: string]: string}}>> |

Exported Stores

The following Pinia stores are exported and can be used in parent projects:

| Name | Description | Available Methods | | ---- | ----------- | ----------------- | | useZoomStore | Manages zoom functionality for the network visualization | storeZoomObject(instance), rescaleNetwork(), graphZoomIn(), graphZoomOut() |

Example usage:

import { useZoomStore } from '@metabohub/mth-ui-viz';

const zoomStore = useZoomStore();
zoomStore.rescaleNetwork(); // Fit network to viewport

Kits

The kits are used to define the buttons and menus that will be present in the interface. These elements must be passed in the VizTool configuration props.

Example

const config = {
  "listButtonMenu": [
    "undo",
    ...
  ],
  "dropDownMenuLeft": {
    "File": [
      "loadFile",
      "saveJson"
    ],
    "Edit": [
      "undo",
      "redo",
      "removeSC",
      "removeAll",
      "duplicateSC",
      "verticalAlign",
      "horizontalAlign"
    ]
  },
  "dropDownMenuRight": {
    "Style": [
      "styleManager",
      "convexhulls"
    ],
    "Mappings": [
      "staticMapping",
      "dynamicMapping",
      "fluxMapping"
    ],
    "Layouts": [
      "forceLayout",
      "hierarchicalLayout"
    ],
    "Exploration": [
      "gir"
    ]
  },
  "switchTheme": true,
}

Buttons

These items must be included in the listButtonMenu argument to the configuration.

| Name | Description | | ---- | ----------- | | undo | Make an undo on graph modification | | redo | Make a redo on graph modification | | playForce | Start force layout and switch to stopForce if present in configuration | | stopForce | Stop force layout and switch to playForce if present in configuration | | rescale | Fit network to visualisation area | | curveEdge | Switch between line and curve edge(s) | | toggleLabels | Toggle display of all node labels on/off | | nodeList | Open node list panel | | zoomIn | Zoom in | | zoomOut | Zoom out |

Menu options

To define the menus present in the interface, two options are available dropDownMenuLeft and dropDownMenuRight, which define whether the menus will be on the right or left of the header. In these objects, the key will correspond to the name of the menu and the items in the list to the options available in this menu.

You can also create nested menus by grouping list options within an object.

const config = {
  // List of buttons
  "listButtonMenu": [
    "undo",
    "redo",
    "playForce",
    "rescale"
  ],
  // List of menus displayed on the left
  "dropDownMenuLeft": {
    "File": [
      "saveJson"
    ],
    "Edit": [
      "undo",
      "redo",
      // Nested menu example
      {"subGroup": "Remove node(s)", "list": ["removeSC", "removeAll"]},
    ],
  },
  // Display toggle switch for dark / light theme
  "switchTheme": false,

  // Manage convexhulls panel tabs
  "convexhulls": {
    "attribut": {
      "pathways": "reaction",
      "compartments": ""
    }
  }
}

| Name | Description | Option title | | ---- | ----------- | ------------ | | loadFile | Allows you to load a network at JSONGraph format | Load File | | loadPositionsFile | Allows you to load node positions at JSON format | Load node positions | | saveJson | Save and download network at JSONGraph format | Save as Json | | saveNodePositions | Save and download node positions at JSON format | Save node positions | | saveAsPng | Save graph and caption as PNG | Save as PNG | | saveAsSvg | Save graph and caption as SVG | Save as SVG | | undo | Make an undo on graph modification | Undo | | redo | Make a redo on graph modification | Redo | | removeSC | Remove all side compounds present in graph, if there are set | Remove side compounds | | removeAll | Remove all selected nodes | Remove All selected nodes | | duplicateSC | Duplicate all side compounds present in graph, if there are set | Duplicate side compounds | | duplicateAll | Duplicate all selected nodes | Duplicate all selected nodes | | verticalAlign | Align selected nodes vertically | Vertical align | | horizontalAlign | Align selected nodes horizontally | Horizontal align | | fixNodes | Fix positions of all selected nodes | Fix all selected nodes | | unfixNodes | Unfix positions of all selected nodes | Unfix all selected nodes | | unfixAllNodes | Unfix positions of all network nodes | Unfix all nodes | | styleManager | Open style manager panel | Style manager | | convexhulls | Open convexhulls manager panel | Display pathways / compartments | | staticMapping | Open static mapping panel manager | Static mapping | | fluxMapping | Open flux visualisation panel manager | Flux visualisation | | dynamicMapping | Open dynamic mapping panel manager | Dynamic mapping | | forceLayout | Open force layout panel manager | Force layout manager | | hierarchicalLayout | Open hierarchical layout panel manager | Hierarchical layout manager | | cycleLayout | Open cycle panel manager | Cycle layout manager | | gir | Open GIR panel manager | Guided Iterative Reconstruction (GIR) | | nodeList | Open node list panel | Display nodes list | | curveEdge | Switch between line and curve edge(s) | Curve edge |

Use example

This web component requires Vuetify.

<template>
	<VizTool
		v-model:network="network" 
		v-model:network-style="networkStyle" 
		:mapping-data="mappingData" 
		:mappings-display="mappingsDisplay"
		:allow-mapping-input="false" 
		:allow-auto-algo="true"
		:panel-config="config"
		@remove-node="emitNodeID"
		@loading-end="handleLoadingEnd"
	/>
</template>

<script setup lang="ts">
import { VizTool } from '@metabohub/mth-ui-viz';
import type { Network, GraphStyleProperties } from '@metabohub/mth-ui-viz';
import { ref } from 'vue';

const network = ref<Network | undefined>(undefined);
const networkStyle = ref<GraphStyleProperties | undefined>(undefined);
const mappingData = ref(undefined);
const mappingsDisplay = ref([]);

function emitNodeID(nodeID: string): void {
	console.log('Node removed:', nodeID);
}

function handleLoadingEnd(): void {
	console.log('Network loading completed');
}

const config = {
  "listButtonMenu": [
    "undo",
    "redo",
    "playForce",
    "rescale"
  ],
  "dropDownMenuLeft": {
    "File": [
      "saveJson"
    ],
    "Edit": [
      "undo",
      "redo",
      "removeAll",
      "nodeList"
    ],
    "Layouts": [
      "verticalAlign",
      "horizontalAlign",
      "forceLayout",
      "hierarchicalLayout"
    ],
    "Styles": [
      "styleManager",
      "curveEdge",
      "convexhulls"
    ],
    "Mappings": [
      "staticMapping",
      "dynamicMapping",
      "fluxMapping"
    ]
  },
  "switchTheme": false,
  "convexhulls": {
    "attribut": {
      "pathways": "reaction",
      "compartments": ""
    }
  }
}

</script>

<style>
@import '@metabohub/mth-ui-viz/dist/style.css';
</style>

Project Setup

npm install

Compile and Hot-Reload for Development

npm run dev

Type-Check, Compile and Minify for Production

npm run build

Run Unit Tests with Vitest

npm run test:unit

Check the coverage of the unit tests :

npm run coverage

Lint with ESLint

npm run lint

View documentation

npm run storybook

CICD pipeline

Tests

test:
  image: node:latest
  stage: test
  before_script:
    - npm install
  script:
    - npm run test:unit

This runs the unit tests defined in src/components/__tests__/

Deploy

.publish:
  stage: deploy
  before_script:
    - apt-get update && apt-get install -y git default-jre
    - npm install
    - npm run build

This builds the component as an npm package.