788 lines
37 KiB
TypeScript
788 lines
37 KiB
TypeScript
|
/**
|
||
|
* @author Martin Karkowski
|
||
|
* @email m.karkowski@zema.de
|
||
|
* @create date 2019-04-29 11:30:22
|
||
|
* @modify date 2020-10-29 12:44:40
|
||
|
* @desc [description]
|
||
|
*/
|
||
|
|
||
|
import { faArrowLeft, faArrowRight, faClone, faDownload, faEyeSlash, faFile, faPlusSquare, faPrint, faUpload } from '@fortawesome/free-solid-svg-icons';
|
||
|
import React from 'react';
|
||
|
import { Button, Form } from 'react-bootstrap';
|
||
|
import { IToolbar } from '../../layout/toolbar';
|
||
|
|
||
|
|
||
|
async function openFile(data){
|
||
|
return await data.layout.getDialogData({
|
||
|
content: {
|
||
|
props: {},
|
||
|
component(props: {
|
||
|
onSubmit: (data: string) => void;
|
||
|
onCancel: (error: any) => void
|
||
|
}) {
|
||
|
const showFile = (e) => {
|
||
|
e.preventDefault()
|
||
|
const reader = new FileReader()
|
||
|
reader.onload = async (event) => {
|
||
|
const text = ((event.target).result as string);
|
||
|
// Use the Submit Function
|
||
|
props.onSubmit(text);
|
||
|
};
|
||
|
|
||
|
// Tell the Reader to load the File.
|
||
|
reader.readAsText(e.target.files[0])
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<>
|
||
|
<p>
|
||
|
Select the File:
|
||
|
</p>
|
||
|
<Form>
|
||
|
<Form.File
|
||
|
id="file"
|
||
|
label="Custom file input"
|
||
|
custom
|
||
|
onChange={(e) => showFile(e)}
|
||
|
/>
|
||
|
</Form>
|
||
|
</>
|
||
|
)
|
||
|
},
|
||
|
},
|
||
|
header: 'Do you want to discard all unstored changes?',
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function to extract the Default Toolbar Menu
|
||
|
*/
|
||
|
export function defaultToolbar() {
|
||
|
|
||
|
const toolbar: IToolbar<any> = {
|
||
|
items: [
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: '',
|
||
|
icon: faPlusSquare,
|
||
|
onClick: (data) => {
|
||
|
/**
|
||
|
* Add a new Node in the Center of the Screen.
|
||
|
* Therefore extract the Center-Position of the
|
||
|
* Graph and call the addNode Function.
|
||
|
*
|
||
|
* This will result in opening up the corresponding
|
||
|
* Editor.
|
||
|
*/
|
||
|
|
||
|
data.network.network.addNodeMode();
|
||
|
|
||
|
// if (( data.component.template as ITemplate<N,E>).nodes && (data.component.template as ITemplate<N,E>).nodes.length > 0){
|
||
|
// const pos = data.network.network.getViewPosition();
|
||
|
// data.component.addNode(pos);
|
||
|
// } else {
|
||
|
// data.network.showMessage('info', 'No Template Selected!', 'Please select a template for a Node in the Sidebar!', 5000);
|
||
|
// }
|
||
|
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: '',
|
||
|
icon: faArrowRight,
|
||
|
onClick: (data) => {
|
||
|
/**
|
||
|
* Set the graph in the Add-Edge Mode
|
||
|
*/
|
||
|
|
||
|
data.network.network.addEdgeMode();
|
||
|
|
||
|
// if ((data.eid as ITemplate<N,E>).nodes && (data.component.template as ITemplate<N,E>).nodes.length === 0 && (data.component.template as ITemplate<N,E>).edges.length === 1){
|
||
|
// data.network.network.addEdgeMode();
|
||
|
// } else {
|
||
|
// data.network.showMessage('info', 'No Template Selected!', 'Please select a template for an Edge in the Sidebar!', 5000);
|
||
|
// }
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'menu',
|
||
|
id: 'fileMenu',
|
||
|
items: [
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'New File',
|
||
|
icon: faFile,
|
||
|
onClick: async (data) => {
|
||
|
/** Clearout the Graph and Delete the History */
|
||
|
data.network.clear();
|
||
|
data.network.resetHistory();
|
||
|
|
||
|
if (data.layout.tabs.length > 0) {
|
||
|
const clearAll = await data.layout.getDialogData({
|
||
|
content: {
|
||
|
props: {},
|
||
|
component(props: {
|
||
|
onSubmit: (data: boolean) => void;
|
||
|
onCancel: (error: any) => void
|
||
|
}) {
|
||
|
return (
|
||
|
<>
|
||
|
<Button variant="danger" onClick={e => props.onSubmit(true)}>Yes</Button> {' '}
|
||
|
<Button variant="success" onClick={e => props.onSubmit(false)}>No </Button>
|
||
|
</>
|
||
|
)
|
||
|
},
|
||
|
},
|
||
|
header: 'Do you want to discard all unstored changes?',
|
||
|
});
|
||
|
|
||
|
// Iterate over the Tabs and delete every.
|
||
|
for (const tab of data.layout.props.tabs.items){
|
||
|
// Force to delete the Tabs.
|
||
|
await data.layout.delteTab(tab,clearAll);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
await data.layout.requestTab();
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'divider',
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'Open File',
|
||
|
icon: faUpload,
|
||
|
onClick: async (data) => {
|
||
|
const file = await openFile(data);
|
||
|
}
|
||
|
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'Import File',
|
||
|
icon: faUpload,
|
||
|
onClick: async (data) => {
|
||
|
const file = await openFile(data);
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'Save File',
|
||
|
icon: faDownload,
|
||
|
onClick: async (data) => {
|
||
|
// Get the Name
|
||
|
const name = await data.layout.getDialogData({
|
||
|
header: 'Enter File-Name',
|
||
|
content: {
|
||
|
component: 'DynamicForm',
|
||
|
props: {
|
||
|
schema: {
|
||
|
type: "string",
|
||
|
description: "Name of the File"
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Store the content
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'print',
|
||
|
icon: faPrint,
|
||
|
onClick: (data) => {
|
||
|
/** Function, which should render the CANVAS as PDF */
|
||
|
/** Therefore extract the real Canvas-Object */
|
||
|
const canvas = data.network.network.body.container.getElementsByTagName('canvas')[0];
|
||
|
const imgData = canvas.toDataURL('image/jpeg', 1.0);
|
||
|
// // const pdf = new jsPDF();
|
||
|
// pdf.addImage(imgData, 'JPEG', 0, 0);
|
||
|
// pdf.save('download.pdf');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
],
|
||
|
label: 'File'
|
||
|
},
|
||
|
{
|
||
|
type: 'menu',
|
||
|
id: 'editMenu',
|
||
|
label: 'edit',
|
||
|
items: [
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'Undo',
|
||
|
icon: faArrowLeft,
|
||
|
onClick: (data) => {
|
||
|
/** Undo the Last Action if Possible */
|
||
|
data.network.undo();
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'Redo',
|
||
|
icon: faArrowRight,
|
||
|
onClick: (data) => {
|
||
|
/** Redo the Last Action if Possible */
|
||
|
data.network.redo();
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'divider'
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'add node',
|
||
|
icon: faPlusSquare,
|
||
|
onClick: (data) => {
|
||
|
/**
|
||
|
* Add a new Node in the Center of the Screen.
|
||
|
* Therefore extract the Center-Position of the
|
||
|
* Graph and call the addNode Function.
|
||
|
*
|
||
|
* This will result in opening up the corresponding
|
||
|
* Editor.
|
||
|
*/
|
||
|
|
||
|
data.network.network.addNodeMode();
|
||
|
|
||
|
// if (( data.component.template as ITemplate<N,E>).nodes && (data.component.template as ITemplate<N,E>).nodes.length > 0){
|
||
|
// const pos = data.network.network.getViewPosition();
|
||
|
// data.component.addNode(pos);
|
||
|
// } else {
|
||
|
// data.network.showMessage('info', 'No Template Selected!', 'Please select a template for a Node in the Sidebar!', 5000);
|
||
|
// }
|
||
|
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'add edge',
|
||
|
icon: faArrowRight,
|
||
|
onClick: (data) => {
|
||
|
/**
|
||
|
* Set the graph in the Add-Edge Mode
|
||
|
*/
|
||
|
|
||
|
data.network.network.addEdgeMode();
|
||
|
|
||
|
// if ((data.eid as ITemplate<N,E>).nodes && (data.component.template as ITemplate<N,E>).nodes.length === 0 && (data.component.template as ITemplate<N,E>).edges.length === 1){
|
||
|
// data.network.network.addEdgeMode();
|
||
|
// } else {
|
||
|
// data.network.showMessage('info', 'No Template Selected!', 'Please select a template for an Edge in the Sidebar!', 5000);
|
||
|
// }
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'divider',
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'export to clipboard',
|
||
|
icon: faClone,
|
||
|
onClick: (data) => {
|
||
|
// writeToClipboard(data.component.genCopyData());
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'import from clipboard',
|
||
|
icon: faClone,
|
||
|
onClick: (data) => {
|
||
|
data.component.pasteFromClipboard();
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'upload project-file',
|
||
|
icon: faClone,
|
||
|
onClick: (data) => {
|
||
|
|
||
|
}
|
||
|
},
|
||
|
{
|
||
|
type: 'divider',
|
||
|
},
|
||
|
{
|
||
|
type: 'action',
|
||
|
label: 'hide selected',
|
||
|
icon: faEyeSlash,
|
||
|
onClick: (data) => {
|
||
|
/**
|
||
|
* Callback which whill hide the selected Elements.
|
||
|
* Therefore disable storingContent on Updates, cause
|
||
|
* every data.options of the Selected Elements are updated.
|
||
|
*/
|
||
|
|
||
|
data.network.disableStoringContent = true;
|
||
|
|
||
|
data.network.network.setVisibilityOfNodes(data.selectedNodes, false);
|
||
|
data.network.network.storePositions();
|
||
|
|
||
|
/** Iterate over the selected Elements and hide the Node */
|
||
|
for (const id of data.selectedNodes) {
|
||
|
const node = data.network.getNode(id);
|
||
|
node.hidden = true;
|
||
|
/** Update the data.options */
|
||
|
data.network.updateNode(node);
|
||
|
}
|
||
|
|
||
|
/** Iterate over the selected Elements and hide the Edge */
|
||
|
for (const id of data.selectedEdges) {
|
||
|
const edge = data.network.getEdge(id);
|
||
|
edge.hidden = true;
|
||
|
/** Update the data.options */
|
||
|
data.network.updateEdge(edge);
|
||
|
}
|
||
|
|
||
|
/** Activate Redo/Undo Tracking again */
|
||
|
data.network.disableStoringContent = false;
|
||
|
/** Store the current state */
|
||
|
data.network.save();
|
||
|
}
|
||
|
},
|
||
|
]
|
||
|
}
|
||
|
]
|
||
|
}
|
||
|
|
||
|
// const config: IToolbar<D> = {
|
||
|
// /** Set the File-Menu as initally active */
|
||
|
// activeTab: 'fileMenu',
|
||
|
// /** Define the Tabs of the Toolbar */
|
||
|
// tabs: {
|
||
|
// view: {
|
||
|
// label: 'View',
|
||
|
// tooltip: 'Manipulates the View of the Graph',
|
||
|
// menu: {
|
||
|
// items: [
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'fit',
|
||
|
// tooltip: 'Fits the Graph',
|
||
|
// icon: 'fa fa-expand',
|
||
|
// onClick: (data) => {
|
||
|
// data.network.network.fit({
|
||
|
// animation: true
|
||
|
// });
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'zoom in',
|
||
|
// tooltip: 'Zoom in the Graph',
|
||
|
// icon: 'fa fa-search-plus',
|
||
|
// onClick: (data) => {
|
||
|
// const position = data.network.network.getViewPosition();
|
||
|
// const currentScale = data.network.network.getScale();
|
||
|
// data.network.network.moveTo({
|
||
|
// position,
|
||
|
// scale: currentScale + 0.1,
|
||
|
// animation: {
|
||
|
// duration: 100,
|
||
|
// }
|
||
|
// });
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'zoom out',
|
||
|
// tooltip: 'Zooms out the Graph',
|
||
|
// icon: 'fa fa-search-minus',
|
||
|
// onClick: (data) => {
|
||
|
// const position = data.network.network.getViewPosition();
|
||
|
// const currentScale = data.network.network.getScale();
|
||
|
// data.network.network.moveTo({
|
||
|
// position,
|
||
|
// scale: currentScale - 0.1,
|
||
|
// animation: {
|
||
|
// duration: 100,
|
||
|
// }
|
||
|
// });
|
||
|
// }
|
||
|
// }, {
|
||
|
// type: 'divider'
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'view all',
|
||
|
// tooltip: 'Show all hidden Elements',
|
||
|
// icon: 'fa fa-eye',
|
||
|
// onClick: (data) => {
|
||
|
// const nodes = data.network.nodes;
|
||
|
// const edges = data.network.edges;
|
||
|
|
||
|
// for (const node of nodes){
|
||
|
// node.hidden = false;
|
||
|
// }
|
||
|
|
||
|
// for (const edge of edges){
|
||
|
// edge.hidden = false;
|
||
|
// }
|
||
|
|
||
|
// data.network.updateNode(nodes);
|
||
|
// data.network.updateEdge(edges);
|
||
|
// }
|
||
|
// },
|
||
|
// ]
|
||
|
// }
|
||
|
// },
|
||
|
// layout: {
|
||
|
// label: 'Layout',
|
||
|
// tooltip: 'Options to Manipulate the Layout of the Graph',
|
||
|
// // disabled: true,
|
||
|
// menu: {
|
||
|
// items: [
|
||
|
// {
|
||
|
// id: 'item2',
|
||
|
// type: 'menu-radio',
|
||
|
// text(item) {
|
||
|
// const text = item.selected;
|
||
|
// const el = this.get('item2:' + item.selected);
|
||
|
// return el.text;
|
||
|
// },
|
||
|
// selected: getCurrentLayout(),
|
||
|
// items: [
|
||
|
// { id: 'h_ud', label: 'Hierarchical: UD', icon: 'fa fa-arrow-down' },
|
||
|
// { id: 'h_du', label: 'Hierarchical: DU', icon: 'fa fa-arrow-up' },
|
||
|
// { id: 'h_lr', label: 'Hierarchical: LR', icon: 'fa fa-arrow-right' },
|
||
|
// { id: 'h_rl', label: 'Hierarchical: RL', icon: 'fa fa-arrow-left' },
|
||
|
// { id: 'normal', label: 'Normal View-Mode' }
|
||
|
// ],
|
||
|
// onRefresh(data) {
|
||
|
// data.event.done(() => {
|
||
|
// const before = getCurrentLayout();
|
||
|
|
||
|
// if (data.event.item.selected != before) {
|
||
|
// // Update the data.options object
|
||
|
// if (typeof rgetattr(data.options, 'layout.hierarchical', {}) === 'boolean') {
|
||
|
// rsetattr(data.options, 'layout.hierarchical', {})
|
||
|
// }
|
||
|
|
||
|
// // Based on the Selection, update the Elements
|
||
|
// switch (data.event.item.selected) {
|
||
|
// case 'normal':
|
||
|
// rsetattr(data.options, 'layout.hierarchical.enabled', false)
|
||
|
// break;
|
||
|
|
||
|
// default:
|
||
|
// const direction = (data.event.item.selected as string).slice(2).toUpperCase();
|
||
|
// rsetattr(data.options, 'layout.hierarchical.enabled', true);
|
||
|
// rsetattr(data.options, 'layout.hierarchical.direction', direction);
|
||
|
// break;
|
||
|
// }
|
||
|
|
||
|
// data.component.visjsOptions = data.options;
|
||
|
|
||
|
// // Store the New data.options
|
||
|
// data.network.network.storePositions();
|
||
|
// const nodes = data.network.nodes;
|
||
|
// const edges = data.network.edges;
|
||
|
// const clusters = data.network.getClusters();
|
||
|
|
||
|
// data.network.clear();
|
||
|
// data.network.network.setOptions(data.options);
|
||
|
// data.network.addNode(nodes);
|
||
|
// data.network.addEdge(edges);
|
||
|
// data.network.readinClusters(clusters);
|
||
|
// }
|
||
|
// });
|
||
|
// }
|
||
|
// },
|
||
|
// ]
|
||
|
// }
|
||
|
// },
|
||
|
// cluster: {
|
||
|
// label: 'Clusters',
|
||
|
// tooltip: 'Add Clusters to the Node',
|
||
|
// // disabled: true,
|
||
|
// menu: {
|
||
|
// items: [
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'cluster selected',
|
||
|
// tooltip: 'Clusterize the Selected Elements',
|
||
|
// icon: 'fa fa-cog',
|
||
|
// onClick: (data) => {
|
||
|
// clusterSelected(data.component, false)
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'cluster outliners',
|
||
|
// tooltip: 'Clusterize the Selected Elements',
|
||
|
// icon: 'fa fa-cog',
|
||
|
// onClick: (data) => {
|
||
|
// data.network.network.clusterOutliers();
|
||
|
// data.network.save();
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'divider'
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'uncluster selected',
|
||
|
// tooltip: '',
|
||
|
// icon: 'fa fa-cog',
|
||
|
// onClick: (data) => {
|
||
|
// for (const node of data.selectedNodes) {
|
||
|
// if (data.network.network.isCluster(node)) {
|
||
|
// data.network.network.openCluster(node)
|
||
|
// }
|
||
|
// }
|
||
|
// data.network.save();
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'view all',
|
||
|
// tooltip: 'Show all hidden Elements',
|
||
|
// icon: 'fa fa-eye',
|
||
|
// onClick: (data) => {
|
||
|
// const nodesToUpdate = data.network.nodes;
|
||
|
// for (const node of nodesToUpdate){
|
||
|
// node.hidden = false;
|
||
|
// }
|
||
|
// data.network.updateNode(nodesToUpdate);
|
||
|
// }
|
||
|
// },
|
||
|
// ]
|
||
|
// }
|
||
|
// },
|
||
|
// settings: {
|
||
|
// label: 'Settings',
|
||
|
// tooltip: 'User Settings',
|
||
|
// // disabled: true,
|
||
|
// menu: {
|
||
|
// items: [
|
||
|
// {
|
||
|
// type: 'check',
|
||
|
// label: 'Multiselect',
|
||
|
// icon: 'fa fa-check-square',
|
||
|
// checked: rgetattr(graphOptions, 'interaction.multiselect', false),
|
||
|
// onClick: (data) => {
|
||
|
// data.event.done(() => {
|
||
|
// rsetattr(data.options, 'interaction.multiselect', data.event.item.checked);
|
||
|
// data.component.visjsOptions = data.options;
|
||
|
// data.network.network.setOptions(data.options);
|
||
|
// })
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'divider'
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'check',
|
||
|
// label: 'Navigation Buttons',
|
||
|
// icon: 'fa fa-check-square',
|
||
|
// checked: rgetattr(graphOptions, 'interaction.navigationButtons', false),
|
||
|
// onClick: (data) => {
|
||
|
// data.event.done(() => {
|
||
|
// rsetattr(data.options, 'interaction.navigationButtons', data.event.item.checked);
|
||
|
// data.component.visjsOptions = data.options;
|
||
|
// data.network.network.setOptions(data.options);
|
||
|
// })
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'divider'
|
||
|
// },
|
||
|
// {
|
||
|
// id: 'physics',
|
||
|
// type: 'check',
|
||
|
// label: 'physics',
|
||
|
// icon: 'fa fa-check-square',
|
||
|
// checked: rgetattr(graphOptions, 'physics', false) === true || rgetattr(graphOptions, 'physics.enabled', false) === true,
|
||
|
// onClick: (data) => {
|
||
|
// data.event.done(() => {
|
||
|
// if (typeof data.options.physics == 'boolean') {
|
||
|
// data.options.physics = data.event.item.checked;
|
||
|
// rsetattr(data.options, 'physics', data.event.item.checked);
|
||
|
// data.component.visjsOptions = data.options;
|
||
|
// data.network.network.setOptions(data.options);
|
||
|
// } else {
|
||
|
// rsetattr(data.options, 'physics.enabled', data.event.item.checked);
|
||
|
// data.component.visjsOptions = data.options;
|
||
|
// data.network.network.setOptions(data.options);
|
||
|
// }
|
||
|
// })
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'divider'
|
||
|
// },
|
||
|
// {
|
||
|
// id: 'shadows',
|
||
|
// type: 'check',
|
||
|
// label: 'shadows',
|
||
|
// icon: 'fa fa-check-square',
|
||
|
// checked: rgetattr(graphOptions, 'nodes.shadow', false) === true || rgetattr(graphOptions, 'nodes.shadow.enabled', false) === true,
|
||
|
// onClick: (data) => {
|
||
|
// data.event.done(() => {
|
||
|
// if (data.options.nodes && typeof data.options.nodes.shadow == 'boolean') {
|
||
|
// data.options.nodes.shadow = data.event.item.checked;
|
||
|
// rsetattr(data.options, 'nodes.shadow', data.event.item.checked);
|
||
|
// } else {
|
||
|
// rsetattr(data.options, 'nodes.shadow.enabled', data.event.item.checked);
|
||
|
// }
|
||
|
|
||
|
// if (data.options.edges && typeof data.options.edges.shadow == 'boolean') {
|
||
|
// data.options.edges.shadow = data.event.item.checked;
|
||
|
// rsetattr(data.options, 'edges.shadow', data.event.item.checked);
|
||
|
// } else {
|
||
|
// rsetattr(data.options, 'edges.shadow.enabled', data.event.item.checked);
|
||
|
// }
|
||
|
|
||
|
// data.component.visjsOptions = data.options;
|
||
|
// data.network.network.setOptions(data.options);
|
||
|
// })
|
||
|
// }
|
||
|
// },{
|
||
|
// type: 'divider'
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'check',
|
||
|
// label: 'Edit on Select',
|
||
|
// icon: 'fa fa-check-square',
|
||
|
// checked: additionalOptions.editOnSelect || false,
|
||
|
// onClick: (data) => {
|
||
|
// data.event.done(() => {
|
||
|
// data.component.options.editOnSelect = data.event.item.checked;
|
||
|
// })
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'check',
|
||
|
// label: 'Hide Panel on Deselect',
|
||
|
// icon: 'fa fa-check-square',
|
||
|
// checked: additionalOptions.hidePanelOnDeselect || false,
|
||
|
// onClick: (data) => {
|
||
|
// data.event.done(() => {
|
||
|
// data.component.options.hidePanelOnDeselect = data.event.item.checked;
|
||
|
// })
|
||
|
// }
|
||
|
// },
|
||
|
// ]
|
||
|
// }
|
||
|
// },
|
||
|
// developer: {
|
||
|
// label: 'Developer',
|
||
|
// tooltip: 'Extra Tools for a Developer',
|
||
|
// // disabled: true,
|
||
|
// menu: {
|
||
|
// items: [
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'json',
|
||
|
// tooltip: 'Shows the current data as JSON',
|
||
|
// icon: 'fa fa-code',
|
||
|
// onClick: (data) => {
|
||
|
|
||
|
// let editor: any = null;
|
||
|
|
||
|
// const speed = 0.3;
|
||
|
|
||
|
// w2popup.open({
|
||
|
// id: 'test',
|
||
|
// title: 'Debug window',
|
||
|
// maximized: true,
|
||
|
// body: '<div id="jsonviewer" style="width:100%;height:100%"></div>',
|
||
|
// showMax: true,
|
||
|
// speed,
|
||
|
// width: 500,
|
||
|
// height: 500,
|
||
|
// onOpen(event) {
|
||
|
|
||
|
// setTimeout(() => {
|
||
|
// // Generate the Editor
|
||
|
// const editorOptions = {
|
||
|
// // modes: ['tree', 'view', 'code', 'text']
|
||
|
// mode: 'view',
|
||
|
// search: 'true',
|
||
|
// mainMenuBar: false
|
||
|
// };
|
||
|
// editor = new JSONEditor(document.getElementById('jsonviewer'), editorOptions, {
|
||
|
// nodes: data.network.nodes,
|
||
|
// edges: data.network.edges
|
||
|
// });
|
||
|
// }, speed * 1000 + 0.050)
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// },
|
||
|
// onClose(event) {
|
||
|
// if (editor) {
|
||
|
// editor.destroy();
|
||
|
// }
|
||
|
// }
|
||
|
// });
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'generate Template',
|
||
|
// tooltip: 'Creates a Template Structure',
|
||
|
// icon: 'fa fa-code',
|
||
|
// onClick: (data) => {
|
||
|
// writeToClipboard(stringifyWithFunctions(data.component.generateTemplateData()));
|
||
|
// }
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'divider'
|
||
|
// },
|
||
|
// {
|
||
|
// type: 'check',
|
||
|
// label: 'Use Version Control',
|
||
|
// icon: 'fa fa-check-square',
|
||
|
// checked: rgetattr(additionalOptions, 'useVersionControl', true),
|
||
|
// onClick: (data) => {
|
||
|
// data.event.done(() => {
|
||
|
// data.component.network.useVersionControl = data.event.item.checked;
|
||
|
// })
|
||
|
// }
|
||
|
// },
|
||
|
// ]
|
||
|
// }
|
||
|
// },
|
||
|
// help: {
|
||
|
// label: 'Help',
|
||
|
// menu: {
|
||
|
// items: [
|
||
|
// {
|
||
|
// type: 'action',
|
||
|
// label: 'Show Help',
|
||
|
// tooltip: 'Clusterize the Selected Elements',
|
||
|
// icon: 'fa fa-info',
|
||
|
// onClick: (data) => {
|
||
|
// // Load the Help Component.
|
||
|
// data.component.layout.openDialogComponent<HelpComponent>({
|
||
|
// title: 'help',
|
||
|
// component: {
|
||
|
// component: HelpComponent
|
||
|
// },
|
||
|
// buttons: [
|
||
|
// {
|
||
|
// label: 'Close',
|
||
|
// callback(instance, close){
|
||
|
// close();
|
||
|
// },
|
||
|
// status: 'danger'
|
||
|
// }
|
||
|
// ],
|
||
|
// closeOnBackdropClick: true,
|
||
|
// closeOnEsc: true,
|
||
|
// });
|
||
|
// }
|
||
|
// },
|
||
|
// ]
|
||
|
// }
|
||
|
// }
|
||
|
// }
|
||
|
// };
|
||
|
|
||
|
return toolbar;
|
||
|
}
|