763 lines
36 KiB
TypeScript
763 lines
36 KiB
TypeScript
/**
|
|
* @author Martin Karkowski
|
|
* @email m.karkowski@zema.de
|
|
* @create date 2019-04-29 11:30:22
|
|
* @modify date 2020-07-22 21:57:09
|
|
* @desc [description]
|
|
*/
|
|
|
|
import { callImmediate } from '../../../@zema/ZISS-TypeScript-Library/src/Function-Call';
|
|
import { rsetattr, rgetattr } from '../../../@zema/ZISS-TypeScript-Library/src/Object-Methods';
|
|
import { generateGraphOptions } from './default.graph-options';
|
|
import { clusterSelected } from '../addons/cluster.selected';
|
|
import { IBaseNodeOptions } from '../../../@zema/ZISS-Network/type/IBaseNodeOptions';
|
|
import { IBaseEdgeOptions } from '../../../@zema/ZISS-Network/type/IBaseEdgeOptions';
|
|
import { stringify, stringifyWithFunctions } from '../../../@zema/ZISS-TypeScript-Library/src/JSON';
|
|
import { IVisjsOptions } from '../interfaces/IVisjsOptions';
|
|
import { IToolbarConfig } from '../../gui-components-basic-layout/types/interfaces';
|
|
import { createUploadPrompt } from '../../gui-components-basic-layout/helpers/upload.file';
|
|
import { ICallbackData } from '../interfaces/IGraphTool';
|
|
import { HelpComponent } from '../help/help';
|
|
import { writeToClipboard } from '../../../@zema/ZISS-Browser-Library/src/clipboard';
|
|
|
|
|
|
declare const $: any;
|
|
declare const w2prompt: any;
|
|
declare const w2popup: any;
|
|
declare const jsPDF: any;
|
|
|
|
declare const JSONEditor: any;
|
|
|
|
/**
|
|
* Function to extract the Default Toolbar Menu
|
|
*/
|
|
export function defaultToolbar<N extends IBaseNodeOptions, E extends IBaseEdgeOptions, D extends ICallbackData<N,E>>(graphOptions: IVisjsOptions = generateGraphOptions(), additionalOptions: {[index: string]: any} = {}) {
|
|
|
|
/**
|
|
* Function to Determine the Graph-Layout, based on the Hierarchical Layout
|
|
*/
|
|
const getCurrentLayout = () => {
|
|
let initalLayout = 'normal';
|
|
|
|
if (rgetattr(graphOptions, 'layout.hierarchical', false) === true || rgetattr(graphOptions, 'layout.hierarchical.enabled', false) === true) {
|
|
initalLayout = 'h_' + (rgetattr(graphOptions, 'layout.hierarchical.direction', 'ud') as string).toLowerCase()
|
|
}
|
|
|
|
return initalLayout;
|
|
}
|
|
|
|
const config: IToolbarConfig<D> = {
|
|
/** Set the File-Menu as initally active */
|
|
activeTab: 'fileMenu',
|
|
/** Define the Tabs of the Toolbar */
|
|
tabs: {
|
|
fileMenu: {
|
|
text: 'File',
|
|
menu: {
|
|
items: [
|
|
{
|
|
type: 'button',
|
|
text: 'new',
|
|
icon: 'fa fa-sticky-note',
|
|
onClick: (data) => {
|
|
/** Clearout the Graph and Delete the History */
|
|
data.network.clear();
|
|
data.network.resetHistory();
|
|
}
|
|
},
|
|
{
|
|
type: 'break',
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: 'load',
|
|
icon: 'fa fa-upload',
|
|
onClick: (data) => {
|
|
createUploadPrompt({
|
|
callback(content){
|
|
/** Read In the JSON File */
|
|
data.component.loadJSON(content, true);
|
|
},
|
|
title:'Load Network File'
|
|
})
|
|
}
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: 'import',
|
|
icon: 'fa fa-upload',
|
|
onClick: (data) => {
|
|
createUploadPrompt({
|
|
callback(content){
|
|
/** Read In the JSON File */
|
|
data.component.loadJSON(content, false);
|
|
},
|
|
title:'Import Network File'
|
|
})
|
|
}
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: 'save',
|
|
icon: 'fa fa-download',
|
|
onClick: (data) => {
|
|
w2prompt({
|
|
label: 'Filename',
|
|
value: 'graph.json',
|
|
attrs: 'style="width: 200px"',
|
|
title: 'Enter File Name',
|
|
ok_text: 'save',
|
|
cancel_text: 'cancel',
|
|
width: 300,
|
|
height: 200
|
|
}).ok((filename) => {
|
|
data.zemaService.saveFile(filename, stringify(data.network.getData(), data.component.parseFunctions));
|
|
});
|
|
}
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: 'print',
|
|
icon: 'fa fa-print',
|
|
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');
|
|
}
|
|
}
|
|
]
|
|
}
|
|
},
|
|
edit: {
|
|
text: 'Edit',
|
|
tooltip: 'Edit Actions for the Network',
|
|
menu: {
|
|
items: [
|
|
{
|
|
id: 'undo',
|
|
type: 'button',
|
|
tooltip: 'Undo',
|
|
icon: 'fa fa-arrow-left',
|
|
onClick: (data) => {
|
|
/** Undo the Last Action if Possible */
|
|
data.network.undo();
|
|
}
|
|
},
|
|
{
|
|
type: 'button',
|
|
tooltip: 'Redo',
|
|
icon: 'fa fa-arrow-right',
|
|
onClick: (data) => {
|
|
/** Redo the Last Action if Possible */
|
|
data.network.redo();
|
|
}
|
|
},
|
|
{
|
|
type: 'break'
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: 'add node',
|
|
tooltip: 'Add a new Node Element in the Center of the current View',
|
|
icon: 'fa fa-plus-square',
|
|
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.
|
|
*/
|
|
|
|
// 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: 'button',
|
|
text: 'add edge',
|
|
tooltip: 'Add a new Node Element',
|
|
icon: 'fa fa-arrow-right',
|
|
onClick: (data) => {
|
|
/**
|
|
* Set the graph in the Add-Edge Mode
|
|
*/
|
|
// 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: 'break',
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: 'export to clipboard',
|
|
tooltip: 'Copy the selected elements to the Clipboard',
|
|
icon: 'fa fa-clone',
|
|
onClick: (data) => {
|
|
// writeToClipboard(data.component.genCopyData());
|
|
}
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: 'import from clipboard',
|
|
tooltip: 'Imports elements from the Clipboard. They can be pasted by pressing "ctrl+v" later on.',
|
|
icon: 'fa fa-clone',
|
|
onClick: (data) => {
|
|
data.component.pasteFromClipboard();
|
|
}
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: 'upload project-file',
|
|
tooltip: 'Opens ',
|
|
icon: 'fa fa-clone',
|
|
onClick: (data) => {
|
|
// Iterate over the selected
|
|
|
|
data.component.disableHotkeys();
|
|
|
|
w2prompt({
|
|
label: 'name',
|
|
value: 'default',
|
|
attrs: 'style="width: 200px"',
|
|
title: 'Paste the Template below',
|
|
ok_text: 'save',
|
|
cancel_text: 'cancel',
|
|
width: 300,
|
|
height: 200,
|
|
onClose(){
|
|
data.component.enableHotkeys();
|
|
}
|
|
}).ok((content) => {
|
|
// data.component.copyTemplate = content;
|
|
});
|
|
|
|
}
|
|
},
|
|
{
|
|
type: 'break',
|
|
},
|
|
{
|
|
// id: 'color1',
|
|
type: 'color',
|
|
onRefresh: (data) => {
|
|
if (data.event && data.event.item && typeof data.event.item.color === 'string') {
|
|
|
|
data.network.disableStoringContent = true;
|
|
|
|
// Extract the Base Color
|
|
const color = data.event.item.color.startsWith('#') ? data.event.item.color : '#' + data.event.item.color;
|
|
|
|
let mustUpdate = false;
|
|
|
|
// Update the New Color
|
|
for (const id of data.selectedNodes) {
|
|
const node = data.network.getNode(id);
|
|
if (node.color !== color) {
|
|
node.color = color;
|
|
data.network.updateNode(node);
|
|
mustUpdate = true;
|
|
}
|
|
}
|
|
|
|
data.network.disableStoringContent = false;
|
|
|
|
callImmediate(() => {
|
|
if (mustUpdate) {
|
|
data.network.save();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}, {
|
|
type: 'break'
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: 'hide selected',
|
|
tooltip: 'Hide the Selected Element',
|
|
icon: 'fa fa-eye-slash',
|
|
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();
|
|
}
|
|
},
|
|
]
|
|
}
|
|
},
|
|
view: {
|
|
text: 'View',
|
|
tooltip: 'Manipulates the View of the Graph',
|
|
menu: {
|
|
items: [
|
|
{
|
|
type: 'button',
|
|
text: 'fit',
|
|
tooltip: 'Fits the Graph',
|
|
icon: 'fa fa-expand',
|
|
onClick: (data) => {
|
|
data.network.network.fit({
|
|
animation: true
|
|
});
|
|
}
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: '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: 'button',
|
|
text: '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: 'break'
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: '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: {
|
|
text: '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', text: 'Hierarchical: UD', icon: 'fa fa-arrow-down' },
|
|
{ id: 'h_du', text: 'Hierarchical: DU', icon: 'fa fa-arrow-up' },
|
|
{ id: 'h_lr', text: 'Hierarchical: LR', icon: 'fa fa-arrow-right' },
|
|
{ id: 'h_rl', text: 'Hierarchical: RL', icon: 'fa fa-arrow-left' },
|
|
{ id: 'normal', text: '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: {
|
|
text: 'Clusters',
|
|
tooltip: 'Add Clusters to the Node',
|
|
// disabled: true,
|
|
menu: {
|
|
items: [
|
|
{
|
|
type: 'button',
|
|
text: 'cluster selected',
|
|
tooltip: 'Clusterize the Selected Elements',
|
|
icon: 'fa fa-cog',
|
|
onClick: (data) => {
|
|
clusterSelected(data.component, false)
|
|
}
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: 'cluster outliners',
|
|
tooltip: 'Clusterize the Selected Elements',
|
|
icon: 'fa fa-cog',
|
|
onClick: (data) => {
|
|
data.network.network.clusterOutliers();
|
|
data.network.save();
|
|
}
|
|
},
|
|
{
|
|
type: 'break'
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: '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: 'button',
|
|
text: '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: {
|
|
text: 'Settings',
|
|
tooltip: 'User Settings',
|
|
// disabled: true,
|
|
menu: {
|
|
items: [
|
|
{
|
|
type: 'check',
|
|
text: '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: 'break'
|
|
},
|
|
{
|
|
type: 'check',
|
|
text: '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: 'break'
|
|
},
|
|
{
|
|
id: 'physics',
|
|
type: 'check',
|
|
text: '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: 'break'
|
|
},
|
|
{
|
|
id: 'shadows',
|
|
type: 'check',
|
|
text: '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: 'break'
|
|
},
|
|
{
|
|
type: 'check',
|
|
text: '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',
|
|
text: '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: {
|
|
text: 'Developer',
|
|
tooltip: 'Extra Tools for a Developer',
|
|
// disabled: true,
|
|
menu: {
|
|
items: [
|
|
{
|
|
type: 'button',
|
|
text: '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: 'button',
|
|
text: 'generate Template',
|
|
tooltip: 'Creates a Template Structure',
|
|
icon: 'fa fa-code',
|
|
onClick: (data) => {
|
|
writeToClipboard(stringifyWithFunctions(data.component.generateTemplateData()));
|
|
}
|
|
},
|
|
{
|
|
type: 'break'
|
|
},
|
|
{
|
|
type: 'check',
|
|
text: '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: {
|
|
text: 'Help',
|
|
menu: {
|
|
items: [
|
|
{
|
|
type: 'button',
|
|
text: '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 config;
|
|
} |