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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@marklogic-community/grove-vue-visjs-graph

v0.1.2

Published

Vue component to visualize RDF relationships and Timelines using Vis.js

Downloads

32

Readme

MarkLogic Grove Vue Visjs Graph

This library provides Vue components providing an interactive graph visualization of nodes and edges, as well an interactive timeline visualization of (grouped) items. It is a wrapper for the vanilla JS ml-visjs-graph library, which itself is based on the VisJS Network library and the VisJS Timeline library.

The library is part of the MarkLogic Grove project, but could work in any Vue application.

QuickStart

First, add the grove-vue-visjs-graph dependency via npm. (In a Grove Project, you will want to do this inside the ui directory.)

npm install --save @marklogic-community/grove-vue-visjs-graph

For now you also need to install ml-visjs-graph directly:

npm install --save ml-visjs-graph

The latter depends on the vis package, which will get installed as dependency.

Then, in your Vue application, import VisjsGraph and/or VisjsTimeline as well as necessary styling:

// Either add this to ui/src/main.js to add it globally:
import { VisjsGraph, VisjsTimeline } from 'grove-vue-visjs-graph';
import 'vis/dist/vis.css';
import 'ml-visjs-graph/less/ml-visjs-graph.js.less';
Vue.component(VisjsGraph.name, VisjsGraph);
Vue.component(VisjsTimeline.name, VisjsTimeline);

// Or do this in a Vue page/component to add it there only:
import { VisjsGraph, VisjsTimeline } from 'grove-vue-visjs-graph';
import 'vis/dist/vis.css';
import 'ml-visjs-graph/less/ml-visjs-graph.js.less';

export default {
  ...,
  components: {
    ...,
    VisjsGraph,
    VisjsTimeline
  },
  ...
};

After that you can start using the directly, which could look for example like this:

Graph:

            <visjs-graph :nodes="nodes" :edges="edges" :options="graphOptions" layout="standard" :events="graphEvents"></visjs-graph>

Timeline:

            <visjs-timeline :items="items" :groups="groups" :options="timelineOptions" :events="timelineEvents"></visjs-timeline>

Recommended setup for grove-vue-template for VisjsGraph and VisjsTimeline

It is easiest to import the component globally via main.js as described in previous section. Then add this to the template of the DetailPage (ui/src/views/DetailPage.vue) within the existing b-tabs, at last position:

          <b-tab title="Graph”>
            <visjs-graph v-if="tabIndex === 3" :nodes="nodes" :edges="edges" :options="graphOptions" layout="standard" :events="graphEvents"></visjs-graph>
          </b-tab>

Note: same might apply to Timeline, haven't tested yet.

Note that tabIndex === 3 to enforce that the graph is only painted when the tab is open. The graph won't show properly if painted while hidden, as it relies on panel sizes and such.

Graph:

At minimum, you need to initialize nodes, edges, graphOptions, and graphEvents. Though, it can be convenient to use nodesCache, and edgesCache, and use so-called computed nodes and edges. The cache object can be used to quickly check if a node or edge exists, and you can fetch its details very quickly from it. It would look like this:

  data() {
    return {
      ...,
      nodesCache: {},
      edgesCache: {},
      graphOptions: {},
      graphEvents: {}
    };
  },
  computed: {
    ...,
    nodes() {
      return Object.values(this.nodesCache);
    },
    edges() {
      return Object.values(this.edgesCache);
    }
  }

Timeline:

At minimum, you need to initialize items, groups, timelineOptions, and timelineEvents. Though, it can be convenient to use itemsCache, and groupsCache, and use so-called computed items and groups. The cache object can be used to quickly check if an item or a group exists, and you can fetch its details very quickly from it. It would look like this:

  data() {
    return {
      ...,
      itemsCache: {},
      groupsCache: {},
      timelineOptions: {},
      timelineEvents: {}
    };
  },
  computed: {
    ...,
    items() {
      return Object.values(this.itemsCache);
    },
    groups() {
      return Object.values(this.groupsCache);
    }
  }

All component properties are automatically monitored for changes via the Observer pattern. Computed properties are automatically recalculated when a depending property gets changed, but really only when it changes!

Adding interaction with MarkLogic for VisjsGraph

The component includes a library that can make appropriate MarkLogic calls to /v1/graphs/sparql. Eventually, we would like to replace this library with a default Grove middle-tier endpoint. For now, you'll need to enable the legacy proxy (the whitelistProxyRoute from the legacy-routes package) in Grove. You can find the config in middle-tier/routes/index.js:

const enableLegacyProxy = true;

In that same file, you configure that legacy proxy. Add or uncomment at least the following:

        {
          endpoint: '/graphs/sparql',
          methods: ['post'], // no need for 'get'
          authed: true
        }

And make sure commas between other endpoint rules are applied correctly.

When you have the middle-tier running in development mode (with a straight npm start), it will restart automatically. If not, restart it manually to enable the change.

Next, you can start using it in the DetailPage. Start with importing the GraphApi, near the top of the script tag inside ui/src/views/DetailPage.vue:

import GraphApi from 'grove-vue-visjs-graph/src/api/GraphApi.js';

Next, you add a method to update the nodes and edges, just for convenience:

  methods: {
    ...,
    updateGraph(response) {
      const self = this;
      self.nodesCache = response.nodes;
      self.edgesCache = response.edges;
    }
  }

And then you use it to first initialize the graph by feeding it the result of GraphApi.expand:

  created() {
    const self = this;
    this.$store
      .dispatch('crud/' + self.type + '/view', {
        id: self.id,
        view: 'metadata'
      })
      .then(function(response) {
        if (!response.isError) {
          var metadata = JSON.parse(response.response);

          ...

          GraphApi.expand([metadata.uri]).then(self.updateGraph);
        }
      });
  },

Next, do the same in graphEvents to intercept double-click:

      graphEvents: {
        doubleClick(params) {
          if (params.nodes[0]) {
            GraphApi.expand(params.nodes, self.nodesCache, self.edgesCache).then(self.updateGraph);
          }
        }
      }

Note that nodesCache and edgesCache are passed in here, which is needed to prevent edges from being added multiple times, and getting miscounted.

VisJS provides many event hooks for you to add behavior or draw on the canvas, doubleClick is just one of them. See the VisJS documentation for other events. click and onContext are useful ones as well, and you can inspect the event argument to look for modifier keys.

Styling your VisjsGraph

To give some pointers about polishing how the graph looks, and feels: you can do a lot of tweaking with graphOptions. Most interesting is setting a different default, and leveraging groups. The GraphApi by default looks for rdf:type links, and uses the object iri as group name for the nodes. Something like the following gives you nice fancy fontawesome icons when running this against the sample-data that comes with the grove ui templates:

      graphOptions: {
        nodes: {
          shape: 'dot'
        },
        groups: {
          'http://xmlns.com/foaf/0.1/Person': {
            shape: 'icon',
            icon: {
              face: 'FontAwesome',
              code: '\uf007', // fa-user icon
              color: 'green'
            }
          }
        }
      },

For more detail on available options, see: http://visjs.org/docs/network/#options

Directive options

Out of the box, grove-vue-visjs-graph does not add any defaults on top of visjs, but ml-visjs-graph does. It tries to bundle some experience with bigger graphs, and large updates. You can override however, and you can also influence how the graph is displayed initially. ml-visjs-graph provides a ui toolbar that allows enabling/disabling physics, and picking a different layout for instance, but you can also influence them with directive options. One for layout is given above. A full list of available layouts include:

  • "standard" (force-directed)
  • "hierarchyTop"
  • "hierarchyBottom"
  • "hierarchyLeft"
  • "hierarchyRight"

Next to that you can specify physics, or just turn it off by passing in physics="false".

Further Reading

It is recommended to becoming familiar with the documentation for a VisJS network and VisJS timeline to take full benefit of these components.