265 lines
10 KiB
TypeScript
265 lines
10 KiB
TypeScript
|
/**
|
||
|
* @author Martin Karkowski
|
||
|
* @email m.karkowski@zema.de
|
||
|
* @create date 2020-03-12 10:38:34
|
||
|
* @modify date 2020-08-11 10:03:20
|
||
|
* @desc [description]
|
||
|
*/
|
||
|
|
||
|
import { v4 as generateID } from 'uuid';
|
||
|
import { IBaseEdgeOptions } from '../interfaces/IBaseEdgeOptions';
|
||
|
import { IBaseNodeOptions } from '../interfaces/IBaseNodeOptions';
|
||
|
// import { generateNetworkAtLayout } from '../user-interface/helpers';
|
||
|
import { deepClone } from '../../../@zema/ZISS-TypeScript-Library/src/Object-Methods';
|
||
|
import { replaceAll } from '../../../@zema/ZISS-TypeScript-Library/src/String-Methods';
|
||
|
import { generateGraphOptions } from '../defaults/default.graph-options';
|
||
|
import { IUndoRedoGraph } from '../interfaces/IGraph';
|
||
|
import { generateNetworkAtLayout } from '../user-interface/helpers';
|
||
|
|
||
|
|
||
|
declare const $: any;
|
||
|
declare const w2ui: any;
|
||
|
|
||
|
/**
|
||
|
* Helper, to Display the Network in a W2UI-Popu
|
||
|
* @param title The Title of the Popup
|
||
|
* @param graph The Graph
|
||
|
* @param options Additional VISJS Options
|
||
|
*/
|
||
|
export function showHierarchicalNetworkInPopup(title: string, graph, options = {
|
||
|
autoResize: true,
|
||
|
height: '100%',
|
||
|
width: '100%',
|
||
|
physics: false,
|
||
|
edges: {
|
||
|
smooth: true,
|
||
|
arrows: 'to',
|
||
|
color: {
|
||
|
inherit: false
|
||
|
},
|
||
|
},
|
||
|
layout: {
|
||
|
hierarchical: {
|
||
|
enabled: true,
|
||
|
nodeSpacing: 100,
|
||
|
levelSeparation: 200,
|
||
|
}
|
||
|
}
|
||
|
}) {
|
||
|
|
||
|
const id = 'new_graph_prompt_' + replaceAll(generateID(), '-', '');
|
||
|
|
||
|
const speed = 0.3;
|
||
|
|
||
|
let res: {
|
||
|
network: IUndoRedoGraph<IBaseNodeOptions, IBaseEdgeOptions>,
|
||
|
resize: (width: number, height: number) => void
|
||
|
}
|
||
|
| null = null;
|
||
|
|
||
|
const resize = (event) => {
|
||
|
event.done((event) => {
|
||
|
if (res) {
|
||
|
res.resize(event.options.width, event.options.height);
|
||
|
res.network.fit({
|
||
|
animation: false
|
||
|
});
|
||
|
}
|
||
|
})
|
||
|
};
|
||
|
|
||
|
const optionsToUse = {
|
||
|
name: id,
|
||
|
label: 'Title',
|
||
|
title,
|
||
|
maximized: true,
|
||
|
width: 1200,
|
||
|
height: 1200,
|
||
|
body: '<div id="promptWindow" style="width:100%; height:100%"></div>',
|
||
|
showClose: true,
|
||
|
showMax: true,
|
||
|
onOpen(event) {
|
||
|
event.onComplete = () => {
|
||
|
/**
|
||
|
* Create a w2ui-Layout consisting of 2 Sidebars (left / right),
|
||
|
* a Top element and the Main-Frame in which the Network should
|
||
|
* be rendered
|
||
|
*/
|
||
|
const config = {
|
||
|
name: id,
|
||
|
panels: [
|
||
|
{
|
||
|
type: 'main', overflow: 'hidden', toolbar: {
|
||
|
items: [
|
||
|
{
|
||
|
type: 'button', id: 'fit', icon: 'fa fa-expand', text: 'Fit Graph',
|
||
|
onClick(event) {
|
||
|
if (res) {
|
||
|
res.network.fit();
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
{ type: 'break' },
|
||
|
{
|
||
|
type: 'html', id: 'nodeSpacing',
|
||
|
html: function (item) {
|
||
|
const width = options.layout.hierarchical.nodeSpacing;
|
||
|
const html =
|
||
|
'<input type="range" min="50" max="500" value="' + width.toString() + '" size="20" onchange="w2ui[\'' + id + '\'].get(\'main\').toolbar.set(\'nodeSpacing\', { value: this.value });"' +
|
||
|
' style="padding: 3px; border-radius: 2px; border: 1px solid silver" value="' + (item.value || '') + '"/>';
|
||
|
return html;
|
||
|
},
|
||
|
tooltip: 'Node Spacing',
|
||
|
onRefresh() {
|
||
|
let width = options.layout.hierarchical.nodeSpacing;
|
||
|
if (w2ui[id] && w2ui[id].get('main') && w2ui[id].get('main').toolbar && w2ui[id].get('main').toolbar.get('nodeSpacing')) {
|
||
|
width = w2ui[id].get('main').toolbar.get('nodeSpacing').value || width;
|
||
|
}
|
||
|
options.layout.hierarchical.nodeSpacing = parseFloat(width.toString());
|
||
|
if (res) {
|
||
|
res.network.network.setOptions(options);
|
||
|
res.network.fit({ animation: false });
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
{ type: 'break' },
|
||
|
{
|
||
|
type: 'html', id: 'levelSeparation',
|
||
|
html: function (item) {
|
||
|
const width = options.layout.hierarchical.levelSeparation;
|
||
|
const html =
|
||
|
'<input type="range" min="50" max="500" value="' + width.toString() + '" size="20" onchange="w2ui[\'' + id + '\'].get(\'main\').toolbar.set(\'levelSeparation\', { value: this.value });"' +
|
||
|
' style="padding: 3px; border-radius: 2px; border: 1px solid silver" value="' + (item.value || '') + '"/>';
|
||
|
return html;
|
||
|
},
|
||
|
tooltip: 'Tree Spacing',
|
||
|
onRefresh() {
|
||
|
let value = options.layout.hierarchical.levelSeparation;
|
||
|
if (w2ui[id] && w2ui[id].get('main') && w2ui[id].get('main').toolbar && w2ui[id].get('main').toolbar.get('levelSeparation')) {
|
||
|
value = w2ui[id].get('main').toolbar.get('levelSeparation').value || value;
|
||
|
}
|
||
|
options.layout.hierarchical.levelSeparation = parseFloat(value.toString());
|
||
|
if (res) {
|
||
|
res.network.network.setOptions(options);
|
||
|
res.network.fit({ animation: false });
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
}
|
||
|
],
|
||
|
};
|
||
|
|
||
|
/** Select the Element, in which the Layout should be rendered */
|
||
|
($('#promptWindow') as any).w2layout(config);
|
||
|
|
||
|
// Create the Newtork in here
|
||
|
res = generateNetworkAtLayout<IBaseNodeOptions, IBaseEdgeOptions>(w2ui[id], options, 'main');
|
||
|
|
||
|
if (res) {
|
||
|
res.network.disableStoringContent = true;
|
||
|
res.network.loadData(deepClone(graph));
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
onClose() {
|
||
|
// The Popup is closed
|
||
|
if (res) {
|
||
|
res.network.destroy();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
if (w2ui[id]) {
|
||
|
w2ui[id].destroy();
|
||
|
}
|
||
|
},
|
||
|
onMax: resize,
|
||
|
onMin: resize,
|
||
|
speed,
|
||
|
}
|
||
|
|
||
|
$().w2popup(optionsToUse);
|
||
|
}
|
||
|
|
||
|
export function showNetworkInPopup(title: string, graph, options = generateGraphOptions()) {
|
||
|
|
||
|
const id = 'new_graph_prompt_' + replaceAll(generateID(), '-', '');
|
||
|
|
||
|
const speed = 0.3;
|
||
|
|
||
|
let res: {
|
||
|
network: IUndoRedoGraph<IBaseNodeOptions, IBaseEdgeOptions>,
|
||
|
resize: (width: number, height: number) => void
|
||
|
}
|
||
|
| null = null;
|
||
|
|
||
|
const resize = (event) => {
|
||
|
event.done((event) => {
|
||
|
if (res) {
|
||
|
res.resize(event.options.width, event.options.height);
|
||
|
res.network.fit({
|
||
|
animation: false
|
||
|
});
|
||
|
}
|
||
|
})
|
||
|
};
|
||
|
|
||
|
const optionsToUse = {
|
||
|
name: id,
|
||
|
label: 'Title',
|
||
|
title,
|
||
|
maximized: true,
|
||
|
width: 1200,
|
||
|
height: 1200,
|
||
|
body: '<div id="promptWindow" style="width:100%; height:100%"></div>',
|
||
|
showClose: true,
|
||
|
showMax: true,
|
||
|
onOpen(event) {
|
||
|
event.onComplete = () => {
|
||
|
/**
|
||
|
* Create a w2ui-Layout consisting of 2 Sidebars (left / right),
|
||
|
* a Top element and the Main-Frame in which the Network should
|
||
|
* be rendered
|
||
|
*/
|
||
|
const config = {
|
||
|
name: id,
|
||
|
panels: [
|
||
|
{
|
||
|
type: 'main', overflow: 'hidden'
|
||
|
}
|
||
|
],
|
||
|
};
|
||
|
|
||
|
/** Select the Element, in which the Layout should be rendered */
|
||
|
($('#promptWindow') as any).w2layout(config);
|
||
|
|
||
|
// Create the Newtork in here
|
||
|
res = generateNetworkAtLayout<IBaseNodeOptions, IBaseEdgeOptions>(w2ui[id], options, 'main');
|
||
|
|
||
|
if (res) {
|
||
|
res.network.disableStoringContent = true;
|
||
|
res.network.loadData(deepClone(graph));
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
onClose() {
|
||
|
// The Popup is closed
|
||
|
if (res) {
|
||
|
res.network.destroy();
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
if (w2ui[id]) {
|
||
|
w2ui[id].destroy();
|
||
|
}
|
||
|
},
|
||
|
onMax: resize,
|
||
|
onMin: resize,
|
||
|
speed,
|
||
|
}
|
||
|
|
||
|
$().w2popup(optionsToUse);
|
||
|
}
|