UNPKG

francy-renderer-vis

Version:

Francy - An Interactive Discrete Mathematics Framework for GAP - A Vis.js Renderer

113 lines (95 loc) 3.56 kB
import { Callback, ContextMenu, Decorators, Graph, Tooltip, Utilities } from 'francy-core'; /* global vis */ export default class GraphGeneric extends Graph { constructor({ appendTo, callbackHandler }, context) { super({ appendTo: appendTo, callbackHandler: callbackHandler }, context); this.callback = new Callback(this.options, this.context); this.tooltip = new Tooltip(this.options, this.context); this.contextMenu = new ContextMenu(this.options, this.context); } @Decorators.Data.requires('canvas.graph') @Decorators.Initializer.initialize() async render() { let self = this, loader = Decorators.Loader.withContext(this).show(), canvasNodes = this.data.canvas.graph.nodes ? JSON.parse(JSON.stringify(Object.values(this.data.canvas.graph.nodes))) : [], canvasLinks = this.data.canvas.graph.links ? JSON.parse(JSON.stringify(Object.values(this.data.canvas.graph.links))) : []; canvasLinks.forEach(function(link){ if (self.data.canvas.graph.type === 'directed') { link['arrows'] = 'to'; } link['label'] = link.title; link['from'] = link.source; link['to'] = link.target; }); canvasNodes.forEach(function(node){ node['label'] = node.title; node['group'] = node.conjugate || node.layer; node['borderWidth'] = node.invisible ? 0 : Math.sqrt(node.weight || 0.2); node['chosen'] = node.selected; node['shape'] = node.type; if (self.data.canvas.graph.type === 'tree') { // safe as there are no links on trees - yeah, it's an hack canvasLinks.push({id: Utilities.generateId(), from: node.parent, to: node.id}); } }); var network = new vis.Network(this.parent.node(), { nodes: new vis.DataSet(canvasNodes), edges: new vis.DataSet(canvasLinks) }, { nodes: { borderWidth: 2, size: 10 }, interaction: { hover: true, dragNodes: self.data.canvas.graph.type !== 'tree' }, layout: { hierarchical: { direction: self.context.configuration.object.visLayoutDirection, sortMethod: self.context.configuration.object.visLayoutSortMethod } }, height: self.data.canvas.height + '' }); // update the 'zoom to fit' function self.parentClass.zoomToFit = () => network.fit(); network.on('stabilized', function() { loader.hide(); }); network.on('animationFinished', function() { loader.hide(); }); network.on('click', function(params) { params.event.preventDefault(); let data = resolveNode.call(this, params); self.OnEvent.click(data); }); network.on('oncontext', function (params) { params.event.preventDefault(); let data = resolveNode.call(this, params); self.OnEvent.contextMenu(data); }); network.on('doubleClick', function (params) { params.event.preventDefault(); let data = resolveNode.call(this, params); self.OnEvent.doubleClick(data); }); network.on('hoverNode', function (params) { params.event.preventDefault(); let data = resolveNode.call(this, params); self.OnEvent.mouseIn(data); }); network.on('blurNode', function () { self.OnEvent.mouseOut(); }); function resolveNode(params) { let nodeIndex = this.getNodeAt(params.pointer.DOM); if (nodeIndex) { let node = this.body.nodes[nodeIndex]; return node.options; } } } }