This AngularJS library allows you to easily produce a graph visualization for triples stored in MarkLogic, based on the VisJS Network library. It is specifically designed with applications generated by the MarkLogic SlushJS generator in mind.
Install this library:
bower install ml-visjs-graph-ng --save
If you want to use the default graphSearch and graphExpand functions, which return the node and link data powering the graph, you need to install the mlpm module (if you want to create your own, you could use this mlpm_module code as a starting point or roll your own):
npm install -g mlpm
mlpm install visjs-graph --save
mlpm deploy -H localhost -P 8040 -u admin -p admin
Since this library works based on SPARQL queries against triples stored in your MarkLogic database, you need to enable the triple index. Note that the triple index is enabled by default starting with MarkLogic 9.0.
You should do this in deploy/ml-config.xml
of your application.
Add the following line to the <database></database>
configuration for the
database with name <database-name>${content-db}</database-name>
(around line
179 at the time of this writing).
<triple-index>true</triple-index>
Update the src/main/ml-config/databases/content-database.json
file for your application
to include the following property:
"triple-index": true
Add the ml.visjsGraph
module as a dependency to your app.module. For
example, in a slush-generated
app, add this to
ui/app/app.js
:
angular.module('app', [
# ...
'ml.visjsGraph',
# ...
]);
You can add a VisJS graph for a document by adding the following HTML snippet
to a template, for example to ui/app/detail/detail.html
:
<ml-visjs-graph uris="[$ctrl.uri]"></ml-visjs-graph>
NOTE: Support for multiple uris is not yet provided, but that future extension is anticipated by this API. For now, it will only initialize the graph visualization with the first uri in the list provided to the directive.
VisJS provides a robust set of options to change how your graph is displayed. We have specified a default set of options in the visjsGraphCtrl. You can override these by passing an object to graph-options
in the ml-visjs-graph
directive. (Only the specific options you name will be changed. If you want to return to the VisJS default for an option that we have set in the visjsGraphCtrl, you will have to specify that explicitly.)
For example:
<ml-visjs-graph uris="[$ctrl.uri]" graph-options="{edges: {color: 'red'}, nodes: {color: {background: 'orange'}}}"></ml-visjs-graph>
The default event hooks for this library are:
/detail
page for that node,VisJS also provides many event hooks for you to add behavior or draw on the canvas. We have specified several in the visjsGraphCtrl. You can override these or add additional event hooks by passing an object to graph-events
in the ml-visjs-graph
directive. (If you want to remove one of the event hooks defined in this library, you will have to specify an empty, 'no-op' function.)
For example, create something like this in your controller:
$scope.myEvents = {
stabilized: function() {
console.log('overrode stabilized event to remove auto-fitting behavior');
},
hold: function(params) {
console.log('you are holding something: ', params);
}
};
Then, in your template:
<ml-visjs-graph uris="[$ctrl.uri]" graph-events="myEvents"></ml-visjs-graph>
With two steps, you can get access to the VisJS network object in your controller (which is useful for calling methods, often in VisJS graphEvents).
onload
event to your VisJS graphEvents).ctrl.myEvents = {
onload: function(network) {
ctrl.visjsNetwork = network;
}
};
network
:<ml-visjs-graph uris="[$ctrl.uri]" network="$ctrl.visjsNetwork" graph-events="$ctrl.myEvents"></ml-visjs-graph>
This can be useful if you want to add or delete nodes and edges. It can also be useful if you want to watch for changes in order to take some other action (such as clustering some set of nodes together).
To do this, simply bind an object in your controller to items
in the ml-visjs-graph
directive scope:
<ml-visjs-graph uris="[$ctrl.uri]" items="$ctrl.visjsItems"></ml-visjs-graph>
The ctrl.visjsItems
object is now an object containing nodes
and items
pointing to VisJS Data Sets.
You can specify which layout you want, by passing in layout="'hierarchyTop'"
. The default is 'standard'.
You can also specify a different physics for the 'standard' (default) layout: physics="'barnesHut'"
Or turn off physics initially with physics="false"
.
You can override the default graphSearch and/or graphExpand in order to provide custom data provider. functions Specify them in the directive:
<ml-visjs-graph uris="[$ctrl.uri]" graph-search="myGraphSearch" graph-expand="myGraphExpand"></ml-visjs-graph>
Both methods should return a promise that resolves to an object with two properties, nodes
and edges
, each containing an array. The expand
function does not need to provide a full picture of the graph nodes and edges. Each node/edge it does return will either be updated or added. Existing nodes and edges will not be removed. This is a canned example that would work as a replacement for either graphSearch or graphExpand:
function cannedSearch(uris) {
return $q.when({
nodes: [
{
id: '1',
label: 'The Number 1!',
group: 'number', // optional
linkCount: 8 // we look for this to add an small orb to the icon
},
{
id: '2',
label: 'The Only Even Prime!',
group: 'number', // optional
linkCount: 16 // we look for this to add an small orb to the icon
}
],
edges: [
{
id: 'more-2-1',
label: 'moreThan',
from: '2',
to: '1'
}
]
});
}
See the VisJS nodes and edges documentation for additional VisJS properties you can add. You may also add additional, non-VisJS properties if you wish (for example, to provide content to a summary pane when a node is clicked).
The default functions are provided by the visjsGraphService
, which simply calls a MarkLogic REST extension called visjs
. (This offers an additional way to override the built-in functionality, by creating a different 'visjs' REST extension.)
I recommend becoming familiar with the documentation for a VisJS network.
The original slush-generated app comes with 3000 JSON documents representing people. For the moment, those documents do not include triples.
This code repository has the same JSON documents, enriched with triples
representing foaf:knows relationships, an rdf:type, and an rdfs:label for each
document. One document also includes a rdfs:label for foaf:knows, so that it
displays on the graph as 'knows' rather than the more verbose 'foaf:knows'. To
use, you can replace the original sample-data.zip
file in the slush-generated
app with the sample-data.zip
file in this project. (Eventually, the
slush-generated app may use this project's version with triples.)
Then, you can load them with (MLCP)[https://docs.marklogic.com/guide/ingestion/content-pump] like this:
./ml local mlcp -options_file import-sample-data.options
Or on Windows:
ml.bat local mlcp -options_file import-sample-data.options
ml-visjs-graph
TODO