nope/resources/ui/graph/addons/minimap.extension.ts

180 lines
6.1 KiB
TypeScript
Raw Normal View History

2020-10-25 20:14:51 +00:00
/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2019-04-29 11:30:22
* @modify date 2019-04-29 11:30:22
* @desc [description]
*/
import { generateNetworkAtElement } from '../helpers/generateNetworkAtElement';
import { defaultStaticOptions } from '../defaults/default.graph-options';
import { IUndoRedoGraph } from '../interfaces/IGraph';
import { IBaseNodeOptions } from '../interfaces/IBaseNodeOptions';
import { IBaseEdgeOptions } from '../interfaces/IBaseEdgeOptions';
declare const $: any;
/**
* Function to create the HTML-Code, which is capable of creating a Minimap as overlay
* @param networkID An Id, which is used for the div of the Network
* @param miniMapID An Id, which is used for the div Minimap
* @param initialOpacity The Initial Opacity of the Overview. Defaults to 0.95
*/
export function miniMapHTML(networkID: string, miniMapID: string, initialOpacity = '0.95'){
const html =
`
<div style="width:100%;height:100%;display:flex">
<div id="` + networkID + `"></div>
<div id="` + miniMapID + `Wrapper" style="position: absolute; margin: 5px; border: 1px solid #ddd; overflow: hidden; background-color: #FFF; z-index: 9; opacity: ` + initialOpacity + `; transition: opacity 0.5s;">
<div id="` + miniMapID + `Image" style="position: absolute" />
<div id="` + miniMapID + `Radar" style="position: absolute; background-color: rgba(16, 84, 154, 0.26);"></div>
</div>
</div>
`;
return html;
}
/**
* Function, to create a Minimap
* @param network The Network, which is used to render the Minimap
* @param miniMapID The MinimapID of the corresponding DIV
* @param ratio The Ratio between the realNetwork and the Minimap. Defaults to 5
* @param enableFading Enable or disabling Fading effects. Defaults to ture
*/
export function addMinimap(network: IUndoRedoGraph<IBaseNodeOptions,IBaseEdgeOptions>, miniMapID, ratio = 5, enableFading = true) {
/** Define a Network for the Minimap */
const miniMapNetwork = generateNetworkAtElement(document.getElementById(miniMapID + 'Image'), defaultStaticOptions());
/** Function to Update the Wrapper element */
const drawMinimapWrapper = () => {
/** Extrat the Size of the Element */
const {
clientWidth,
clientHeight
} = network.network.body.container;
/** Get the Wrapper */
const minimapWrapper = document.getElementById(miniMapID + 'Wrapper');
/** Adapt its Size, based on the Ratio and the Dimensions of the Net */
const width = Math.round(clientWidth / ratio);
const height = Math.round(clientHeight / ratio);
/** Updat the Size */
minimapWrapper.style.width = `${width}px`;
minimapWrapper.style.height = `${height}px`;
/** Move the Element to the bottom right Position */
minimapWrapper.style.right = '0';
minimapWrapper.style.bottom = '0';
};
const updateNetwork = () => {
setTimeout(() => {
miniMapNetwork.network.clear();
miniMapNetwork.network.loadData(network.getData())
miniMapNetwork.network.network.fit({
animation: false
});
}, 10);
};
/**
* Function to draw the current Positon of the View.
*/
const drawRadar = () => {
/**
* Extract the Widht and Height
*/
const {
clientWidth,
clientHeight
} = network.network.body.container;
/** Extract the Radar-Element */
const minimapRadar = document.getElementById(miniMapID + 'Radar');
const {
targetScale
} = network.network.view;
const scale = network.network.getScale();
const translate = network.network.getViewPosition();
minimapRadar.style.transform = `translate(${(translate.x / ratio) *
targetScale}px, ${(translate.y / ratio) * targetScale}px) scale(${targetScale / scale})`;
minimapRadar.style.width = `${clientWidth / ratio}px`;
minimapRadar.style.height = `${clientHeight / ratio}px`;
};
/** Subscribe to different updates of the Graph. */
const update = () => {
const {
clientWidth,
clientHeight
} = network.network.body.container;
const width = Math.round(clientWidth / ratio);
const height = Math.round(clientHeight / ratio);
const minimapWrapper = document.getElementById(miniMapID + 'Wrapper');
/**
* If there are some Changes,
* Update the Wrapper and resize the Network
*/
if (
minimapWrapper.style.width !== `${width}px` ||
minimapWrapper.style.height !== `${height}px`
) {
drawMinimapWrapper();
miniMapNetwork.resize(width,height);
}
/** Update the Radar */
drawRadar();
};
/** Perform an Update of the Minimap after Drawing and after resizing */
network.network.on('afterDrawing', () => update())
network.network.on('resize', () => update());
network.on('dataUpdate', updateNetwork);
if (enableFading) {
let timer = null;
const fade = (opacity: string) => {
const minimapWrapper = document.getElementById(miniMapID + 'Wrapper');
minimapWrapper.style.opacity = opacity;
minimapWrapper.style.transition = 'opacity 0.5s';
}
/** Switch the Opacity of the Graph on Dragging and Zooming. */
network.on('dragStart', () => {
fade('0.95');
})
network.on('dragEnd', () => {
fade('0.25');
})
network.on('zoom', () => {
fade('0.95');
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => fade('0.25'), 500)
})
}
/**
* Toggles the Minimap
* @param visible Flag indicating, whether the element is visible or not
*/
const toggleVisibility = (visible: boolean) => {
document.getElementById(miniMapID + 'Wrapper').hidden = !visible;
}
return toggleVisibility
}