run clean, update gitignore
This commit is contained in:
Родитель
0134cdc7c6
Коммит
f166fdf3ee
|
@ -1,10 +1,10 @@
|
|||
# NodeJS Outputs
|
||||
node_modules
|
||||
packages/*/*/lib/
|
||||
packages/*/*/dist/
|
||||
packages/*/*/build/
|
||||
packages/*/*/storybook-static/
|
||||
packages/*/*/site/
|
||||
node_modules/
|
||||
lib/
|
||||
dist/
|
||||
build/
|
||||
storybook-static/
|
||||
site/
|
||||
|
||||
# Misc
|
||||
*.log
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Layout Sandbox</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"></head>
|
||||
<body>
|
||||
<script src="main.%5Bfullhash%5D.js"></script></body>
|
||||
</html>
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,12 +0,0 @@
|
|||
/*!
|
||||
* OverlayScrollbars
|
||||
* https://github.com/KingSora/OverlayScrollbars
|
||||
*
|
||||
* Version: 1.13.0
|
||||
*
|
||||
* Copyright KingSora | Rene Haas.
|
||||
* https://github.com/KingSora
|
||||
*
|
||||
* Released under the MIT license.
|
||||
* Date: 02.08.2020
|
||||
*/
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1 +0,0 @@
|
|||
(window.webpackJsonp=window.webpackJsonp||[]).push([[12],{1487:function(module,exports){module.exports=function(e,n){return n=n||{},new Promise((function(t,r){var s=new XMLHttpRequest,o=[],u=[],i={},a=function(){return{ok:2==(s.status/100|0),statusText:s.statusText,status:s.status,url:s.responseURL,text:function(){return Promise.resolve(s.responseText)},json:function(){return Promise.resolve(s.responseText).then(JSON.parse)},blob:function(){return Promise.resolve(new Blob([s.response]))},clone:a,headers:{keys:function(){return o},entries:function(){return u},get:function(e){return i[e.toLowerCase()]},has:function(e){return e.toLowerCase()in i}}}};for(var l in s.open(n.method||"get",e,!0),s.onload=function(){s.getAllResponseHeaders().replace(/^(.*?):[^\S\n]*([\s\S]*?)$/gm,(function(e,n,t){o.push(n=n.toLowerCase()),u.push([n,t]),i[n]=i[n]?i[n]+","+t:t})),t(a())},s.onerror=r,s.withCredentials="include"==n.credentials,n.headers)s.setRequestHeader(l,n.headers[l]);s.send(n.body||null)}))}}}]);
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,8 +0,0 @@
|
|||
/**
|
||||
* Prism: Lightweight, robust, elegant syntax highlighting
|
||||
*
|
||||
* @license MIT <https://opensource.org/licenses/MIT>
|
||||
* @author Lea Verou <https://lea.verou.me>
|
||||
* @namespace
|
||||
* @public
|
||||
*/
|
Двоичные данные
packages/docs-stories/storybook-static/favicon.ico
Двоичные данные
packages/docs-stories/storybook-static/favicon.ico
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 32 KiB |
|
@ -1,138 +0,0 @@
|
|||
<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Storybook</title><meta name="viewport" content="width=device-width,initial-scale=1"><base target="_parent"><style>:not(.sb-show-main) > .sb-main,
|
||||
:not(.sb-show-nopreview) > .sb-nopreview,
|
||||
:not(.sb-show-errordisplay) > .sb-errordisplay {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sb-show-main.sb-main-centered {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.sb-show-main.sb-main-centered #root {
|
||||
box-sizing: border-box;
|
||||
margin: auto;
|
||||
padding: 1rem;
|
||||
max-height: 100%; /* Hack for centering correctly in IE11 */
|
||||
}
|
||||
|
||||
/* Vertical centering fix for IE11 */
|
||||
@media screen and (-ms-high-contrast: none), (-ms-high-contrast: active) {
|
||||
.sb-show-main.sb-main-centered:after {
|
||||
content: '';
|
||||
min-height: inherit;
|
||||
font-size: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sb-show-main.sb-main-fullscreen {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sb-show-main.sb-main-padded {
|
||||
margin: 0;
|
||||
padding: 1rem;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.sb-wrapper {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 20px;
|
||||
font-family: "Nunito Sans", -apple-system, ".SFNSText-Regular", "San Francisco", BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.sb-heading {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.2px;
|
||||
margin: 10px 0;
|
||||
padding-right: 25px;
|
||||
}
|
||||
|
||||
.sb-nopreview {
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.sb-nopreview_main {
|
||||
margin: auto;
|
||||
padding: 30px;
|
||||
border-radius: 10px;
|
||||
background: rgba(0,0,0,0.03);
|
||||
}
|
||||
|
||||
.sb-nopreview_heading {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.sb-errordisplay {
|
||||
border: 20px solid rgb(187, 49, 49);
|
||||
background: #222;
|
||||
color: #fff;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
.sb-errordisplay_code {
|
||||
padding: 10px;
|
||||
background: #000;
|
||||
color: #eee;
|
||||
font-family: "Operator Mono", "Fira Code Retina", "Fira Code", "FiraCode-Retina", "Andale Mono", "Lucida Console", Consolas, Monaco, monospace;
|
||||
}
|
||||
|
||||
.sb-errordisplay pre {
|
||||
white-space: pre-wrap;
|
||||
}</style><script>/* globals window */
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
try {
|
||||
if (window.top !== window) {
|
||||
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = window.top.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
window.__VUE_DEVTOOLS_GLOBAL_HOOK__ = window.top.__VUE_DEVTOOLS_GLOBAL_HOOK__;
|
||||
window.top.__VUE_DEVTOOLS_CONTEXT__ = window.document;
|
||||
}
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('unable to connect to top frame for connecting dev tools');
|
||||
}
|
||||
|
||||
window.onerror = function onerror(message, source, line, column, err) {
|
||||
if (window.CONFIG_TYPE !== 'DEVELOPMENT') return;
|
||||
// eslint-disable-next-line no-var, vars-on-top
|
||||
var xhr = new window.XMLHttpRequest();
|
||||
xhr.open('POST', '/runtime-error');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
|
||||
xhr.send(
|
||||
JSON.stringify({
|
||||
/* eslint-disable object-shorthand */
|
||||
message: message,
|
||||
source: source,
|
||||
line: line,
|
||||
column: column,
|
||||
error: err && { message: err.message, name: err.name, stack: err.stack },
|
||||
origin: 'preview',
|
||||
/* eslint-enable object-shorthand */
|
||||
})
|
||||
);
|
||||
};</script><style>#root[hidden],
|
||||
#docs-root[hidden] {
|
||||
display: none !important;
|
||||
}</style></head><body><div class="sb-nopreview sb-wrapper"><div class="sb-nopreview_main"><h1 class="sb-nopreview_heading sb-heading">No Preview</h1><p>Sorry, but you either have no stories or none are selected somehow.</p><ul><li>Please check the Storybook config.</li><li>Try reloading the page.</li></ul><p>If the problem persists, check the browser console, or the terminal you've run Storybook from.</p></div></div><div class="sb-errordisplay sb-wrapper"><pre id="error-message" class="sb-heading"></pre><pre class="sb-errordisplay_code"><code id="error-stack"></code></pre></div><div id="root"></div><div id="docs-root"></div><script>window['LOGLEVEL'] = "info";
|
||||
|
||||
|
||||
|
||||
window['FRAMEWORK_OPTIONS'] = {};
|
||||
|
||||
|
||||
|
||||
window['FEATURES'] = {"postcss":true};</script><script src="runtime~main.857ba510.iframe.bundle.js"></script><script src="vendors~main.f0b7b8ab.iframe.bundle.js"></script><script src="main.d9189b32.iframe.bundle.js"></script></body></html>
|
|
@ -1,55 +0,0 @@
|
|||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><title>Storybook</title><meta name="viewport" content="width=device-width,initial-scale=1"/><style>html, body {
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}</style><script>/* globals window */
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
try {
|
||||
if (window.top !== window) {
|
||||
window.__REACT_DEVTOOLS_GLOBAL_HOOK__ = window.top.__REACT_DEVTOOLS_GLOBAL_HOOK__;
|
||||
}
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('unable to connect to top frame for connecting dev tools');
|
||||
}
|
||||
|
||||
window.onerror = function onerror(message, source, line, column, err) {
|
||||
if (window.CONFIG_TYPE !== 'DEVELOPMENT') return;
|
||||
// eslint-disable-next-line no-var, vars-on-top
|
||||
var xhr = new window.XMLHttpRequest();
|
||||
xhr.open('POST', '/runtime-error');
|
||||
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
|
||||
xhr.send(
|
||||
JSON.stringify({
|
||||
/* eslint-disable object-shorthand */
|
||||
message: message,
|
||||
source: source,
|
||||
line: line,
|
||||
column: column,
|
||||
error: err && { message: err.message, name: err.name, stack: err.stack },
|
||||
origin: 'manager',
|
||||
/* eslint-enable object-shorthand */
|
||||
})
|
||||
);
|
||||
};</script><style>#root[hidden],
|
||||
#docs-root[hidden] {
|
||||
display: none !important;
|
||||
}</style></head><body><div id="root"></div><div id="docs-root"></div><script>window['CONFIG_TYPE'] = "PRODUCTION";
|
||||
|
||||
|
||||
|
||||
window['LOGLEVEL'] = "info";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
window['DOCS_MODE'] = false;</script><script src="runtime~main.54547d39ceaccb9b188f.manager.bundle.js"></script><script src="vendors~main.2a25695e2168441db276.manager.bundle.js"></script><script src="main.463cf6b6e4372b623802.manager.bundle.js"></script></body></html>
|
|
@ -1 +0,0 @@
|
|||
(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{607:function(module,exports){},809:function(module,exports,__webpack_require__){__webpack_require__(810),module.exports=__webpack_require__(974)},943:function(module,exports){}},[[809,1,2]]]);
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,4 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"main.d9189b32.iframe.bundle.js","sources":[],"mappings":";A","sourceRoot":""}
|
|
@ -1 +0,0 @@
|
|||
!function(modules){function webpackJsonpCallback(data){for(var moduleId,chunkId,chunkIds=data[0],moreModules=data[1],executeModules=data[2],i=0,resolves=[];i<chunkIds.length;i++)chunkId=chunkIds[i],Object.prototype.hasOwnProperty.call(installedChunks,chunkId)&&installedChunks[chunkId]&&resolves.push(installedChunks[chunkId][0]),installedChunks[chunkId]=0;for(moduleId in moreModules)Object.prototype.hasOwnProperty.call(moreModules,moduleId)&&(modules[moduleId]=moreModules[moduleId]);for(parentJsonpFunction&&parentJsonpFunction(data);resolves.length;)resolves.shift()();return deferredModules.push.apply(deferredModules,executeModules||[]),checkDeferredModules()}function checkDeferredModules(){for(var result,i=0;i<deferredModules.length;i++){for(var deferredModule=deferredModules[i],fulfilled=!0,j=1;j<deferredModule.length;j++){var depId=deferredModule[j];0!==installedChunks[depId]&&(fulfilled=!1)}fulfilled&&(deferredModules.splice(i--,1),result=__webpack_require__(__webpack_require__.s=deferredModule[0]))}return result}var installedModules={},installedChunks={1:0},deferredModules=[];function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}__webpack_require__.e=function requireEnsure(chunkId){var promises=[],installedChunkData=installedChunks[chunkId];if(0!==installedChunkData)if(installedChunkData)promises.push(installedChunkData[2]);else{var promise=new Promise((function(resolve,reject){installedChunkData=installedChunks[chunkId]=[resolve,reject]}));promises.push(installedChunkData[2]=promise);var onScriptComplete,script=document.createElement("script");script.charset="utf-8",script.timeout=120,__webpack_require__.nc&&script.setAttribute("nonce",__webpack_require__.nc),script.src=function jsonpScriptSrc(chunkId){return __webpack_require__.p+""+({}[chunkId]||chunkId)+"."+{8:"1df334e88b2854fa0c86",9:"03e63c837c620878f2d7",10:"83e44dee997931b1f201",11:"dc5d39b0a906f39d702d",12:"c725a3b2cf53a549103d"}[chunkId]+".manager.bundle.js"}(chunkId);var error=new Error;onScriptComplete=function(event){script.onerror=script.onload=null,clearTimeout(timeout);var chunk=installedChunks[chunkId];if(0!==chunk){if(chunk){var errorType=event&&("load"===event.type?"missing":event.type),realSrc=event&&event.target&&event.target.src;error.message="Loading chunk "+chunkId+" failed.\n("+errorType+": "+realSrc+")",error.name="ChunkLoadError",error.type=errorType,error.request=realSrc,chunk[1](error)}installedChunks[chunkId]=void 0}};var timeout=setTimeout((function(){onScriptComplete({type:"timeout",target:script})}),12e4);script.onerror=script.onload=onScriptComplete,document.head.appendChild(script)}return Promise.all(promises)},__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{enumerable:!0,get:getter})},__webpack_require__.r=function(exports){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.t=function(value,mode){if(1&mode&&(value=__webpack_require__(value)),8&mode)return value;if(4&mode&&"object"==typeof value&&value&&value.__esModule)return value;var ns=Object.create(null);if(__webpack_require__.r(ns),Object.defineProperty(ns,"default",{enumerable:!0,value:value}),2&mode&&"string"!=typeof value)for(var key in value)__webpack_require__.d(ns,key,function(key){return value[key]}.bind(null,key));return ns},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function getDefault(){return module.default}:function getModuleExports(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="",__webpack_require__.oe=function(err){throw console.error(err),err};var jsonpArray=window.webpackJsonp=window.webpackJsonp||[],oldJsonpFunction=jsonpArray.push.bind(jsonpArray);jsonpArray.push=webpackJsonpCallback,jsonpArray=jsonpArray.slice();for(var i=0;i<jsonpArray.length;i++)webpackJsonpCallback(jsonpArray[i]);var parentJsonpFunction=oldJsonpFunction;checkDeferredModules()}([]);
|
|
@ -1 +0,0 @@
|
|||
!function(modules){function webpackJsonpCallback(data){for(var moduleId,chunkId,chunkIds=data[0],moreModules=data[1],executeModules=data[2],i=0,resolves=[];i<chunkIds.length;i++)chunkId=chunkIds[i],Object.prototype.hasOwnProperty.call(installedChunks,chunkId)&&installedChunks[chunkId]&&resolves.push(installedChunks[chunkId][0]),installedChunks[chunkId]=0;for(moduleId in moreModules)Object.prototype.hasOwnProperty.call(moreModules,moduleId)&&(modules[moduleId]=moreModules[moduleId]);for(parentJsonpFunction&&parentJsonpFunction(data);resolves.length;)resolves.shift()();return deferredModules.push.apply(deferredModules,executeModules||[]),checkDeferredModules()}function checkDeferredModules(){for(var result,i=0;i<deferredModules.length;i++){for(var deferredModule=deferredModules[i],fulfilled=!0,j=1;j<deferredModule.length;j++){var depId=deferredModule[j];0!==installedChunks[depId]&&(fulfilled=!1)}fulfilled&&(deferredModules.splice(i--,1),result=__webpack_require__(__webpack_require__.s=deferredModule[0]))}return result}var installedModules={},installedChunks={1:0},deferredModules=[];function __webpack_require__(moduleId){if(installedModules[moduleId])return installedModules[moduleId].exports;var module=installedModules[moduleId]={i:moduleId,l:!1,exports:{}};return modules[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.l=!0,module.exports}__webpack_require__.m=modules,__webpack_require__.c=installedModules,__webpack_require__.d=function(exports,name,getter){__webpack_require__.o(exports,name)||Object.defineProperty(exports,name,{enumerable:!0,get:getter})},__webpack_require__.r=function(exports){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(exports,"__esModule",{value:!0})},__webpack_require__.t=function(value,mode){if(1&mode&&(value=__webpack_require__(value)),8&mode)return value;if(4&mode&&"object"==typeof value&&value&&value.__esModule)return value;var ns=Object.create(null);if(__webpack_require__.r(ns),Object.defineProperty(ns,"default",{enumerable:!0,value:value}),2&mode&&"string"!=typeof value)for(var key in value)__webpack_require__.d(ns,key,function(key){return value[key]}.bind(null,key));return ns},__webpack_require__.n=function(module){var getter=module&&module.__esModule?function getDefault(){return module.default}:function getModuleExports(){return module};return __webpack_require__.d(getter,"a",getter),getter},__webpack_require__.o=function(object,property){return Object.prototype.hasOwnProperty.call(object,property)},__webpack_require__.p="";var jsonpArray=window.webpackJsonp=window.webpackJsonp||[],oldJsonpFunction=jsonpArray.push.bind(jsonpArray);jsonpArray.push=webpackJsonpCallback,jsonpArray=jsonpArray.slice();for(var i=0;i<jsonpArray.length;i++)webpackJsonpCallback(jsonpArray[i]);var parentJsonpFunction=oldJsonpFunction;checkDeferredModules()}([]);
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
object-assign
|
||||
(c) Sindre Sorhus
|
||||
@license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Fuse.js v3.6.1 - Lightweight fuzzy-search (http://fusejs.io)
|
||||
*
|
||||
* Copyright (c) 2012-2017 Kirollos Risk (http://kiro.me)
|
||||
* All Rights Reserved. Apache Software License 2.0
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
/*!
|
||||
* https://github.com/es-shims/es5-shim
|
||||
* @license es5-shim Copyright 2009-2020 by contributors, MIT License
|
||||
* see https://github.com/es-shims/es5-shim/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
/*!
|
||||
* https://github.com/paulmillr/es6-shim
|
||||
* @license es6-shim Copyright 2013-2016 by Paul Miller (http://paulmillr.com)
|
||||
* and contributors, MIT License
|
||||
* es6-shim: v0.35.4
|
||||
* see https://github.com/paulmillr/es6-shim/blob/0.35.3/LICENSE
|
||||
* Details and documentation:
|
||||
* https://github.com/paulmillr/es6-shim/
|
||||
*/
|
||||
|
||||
/*!
|
||||
* isobject <https://github.com/jonschlinkert/isobject>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/** @license React v0.19.1
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v16.13.1
|
||||
* react-is.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v16.14.0
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v16.14.0
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
object-assign
|
||||
(c) Sindre Sorhus
|
||||
@license MIT
|
||||
*/
|
||||
|
||||
/*!
|
||||
* https://github.com/es-shims/es5-shim
|
||||
* @license es5-shim Copyright 2009-2020 by contributors, MIT License
|
||||
* see https://github.com/es-shims/es5-shim/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
/*!
|
||||
* https://github.com/paulmillr/es6-shim
|
||||
* @license es6-shim Copyright 2013-2016 by Paul Miller (http://paulmillr.com)
|
||||
* and contributors, MIT License
|
||||
* es6-shim: v0.35.4
|
||||
* see https://github.com/paulmillr/es6-shim/blob/0.35.3/LICENSE
|
||||
* Details and documentation:
|
||||
* https://github.com/paulmillr/es6-shim/
|
||||
*/
|
||||
|
||||
/*!
|
||||
* isobject <https://github.com/jonschlinkert/isobject>
|
||||
*
|
||||
* Copyright (c) 2014-2017, Jon Schlinkert.
|
||||
* Released under the MIT License.
|
||||
*/
|
||||
|
||||
/** @license React v0.19.1
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v16.14.0
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/** @license React v16.14.0
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
//! stable.js 0.1.8, https://github.com/Two-Screen/stable
|
||||
|
||||
//! © 2018 Angry Bytes and contributors. MIT licensed.
|
|
@ -1 +0,0 @@
|
|||
{"version":3,"file":"vendors~main.f0b7b8ab.iframe.bundle.js","sources":[],"mappings":";A","sourceRoot":""}
|
|
@ -1 +0,0 @@
|
|||
{"version":"4.5.2"}
|
|
@ -1,55 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.CountdownClock = void 0;
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* An implementation of a clock which will tick until it reaches a target tick count
|
||||
*/
|
||||
class CountdownClock {
|
||||
/**
|
||||
* Constructor for the countdown clock
|
||||
* @param targetTicks The target number of ticks to run
|
||||
*/
|
||||
constructor(targetTicks) {
|
||||
_defineProperty(this, "_targetTicks", void 0);
|
||||
|
||||
_defineProperty(this, "_ticks", 0);
|
||||
|
||||
this._targetTicks = targetTicks;
|
||||
}
|
||||
/**
|
||||
* Gets the current ticks
|
||||
*/
|
||||
|
||||
|
||||
get currentTicks() {
|
||||
return this._ticks;
|
||||
}
|
||||
/**
|
||||
* Gets the target ticks
|
||||
*/
|
||||
|
||||
|
||||
get targetTicks() {
|
||||
return this._targetTicks;
|
||||
}
|
||||
/**
|
||||
* Ticks the current clock
|
||||
*/
|
||||
|
||||
|
||||
tick() {
|
||||
this._ticks++;
|
||||
return this._ticks < this._targetTicks;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.CountdownClock = CountdownClock;
|
|
@ -1,31 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _CountdownClock = require("./CountdownClock");
|
||||
|
||||
Object.keys(_CountdownClock).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (key in exports && exports[key] === _CountdownClock[key]) return;
|
||||
Object.defineProperty(exports, key, {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _CountdownClock[key];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var _types = require("./types");
|
||||
|
||||
Object.keys(_types).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (key in exports && exports[key] === _types[key]) return;
|
||||
Object.defineProperty(exports, key, {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _types[key];
|
||||
}
|
||||
});
|
||||
});
|
|
@ -1,5 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
|
@ -1,44 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _workers = require("./workers");
|
||||
|
||||
Object.keys(_workers).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (key in exports && exports[key] === _workers[key]) return;
|
||||
Object.defineProperty(exports, key, {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _workers[key];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var _layout = require("./layout");
|
||||
|
||||
Object.keys(_layout).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (key in exports && exports[key] === _layout[key]) return;
|
||||
Object.defineProperty(exports, key, {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _layout[key];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var _clock = require("./clock");
|
||||
|
||||
Object.keys(_clock).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (key in exports && exports[key] === _clock[key]) return;
|
||||
Object.defineProperty(exports, key, {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _clock[key];
|
||||
}
|
||||
});
|
||||
});
|
|
@ -1,176 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.BaseExecutor = void 0;
|
||||
|
||||
var _common = require("@graspologic/common");
|
||||
|
||||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Base class for layout executors
|
||||
*/
|
||||
class BaseExecutor extends _common.EventEmitter {
|
||||
/**
|
||||
* Constructor for the base executor
|
||||
* @param graph The graph to run the layout on
|
||||
* @param config The configuration for the layout
|
||||
* @param clock The clock which is used to indicate when a layout cycle has occurred
|
||||
* @param globalObject The "global" object environment
|
||||
*/
|
||||
constructor(graph, config, clock, globalObject) {
|
||||
super();
|
||||
|
||||
_defineProperty(this, "_graph", void 0);
|
||||
|
||||
_defineProperty(this, "_halted", false);
|
||||
|
||||
_defineProperty(this, "_complete", false);
|
||||
|
||||
_defineProperty(this, "_global", void 0);
|
||||
|
||||
_defineProperty(this, "_configuration", void 0);
|
||||
|
||||
_defineProperty(this, "_tickListener", void 0);
|
||||
|
||||
_defineProperty(this, "_clock", void 0);
|
||||
|
||||
this._clock = clock;
|
||||
this._graph = graph;
|
||||
this._global = globalObject;
|
||||
this._configuration = config;
|
||||
this.executeStep = this.executeStep.bind(this);
|
||||
globalObject.console.log(`create new ${this.getName()} instance`, this._configuration);
|
||||
}
|
||||
/**
|
||||
* Halts the layout process
|
||||
*/
|
||||
|
||||
|
||||
halt() {
|
||||
this._halted = true;
|
||||
}
|
||||
/**
|
||||
* Returns true if the layout is halted
|
||||
*/
|
||||
|
||||
|
||||
get isHalted() {
|
||||
return this._halted;
|
||||
}
|
||||
/**
|
||||
* Returns true if the layout is completed
|
||||
*/
|
||||
|
||||
|
||||
get isComplete() {
|
||||
return this._complete;
|
||||
}
|
||||
/**
|
||||
* Gets the current clock
|
||||
*/
|
||||
|
||||
|
||||
get clock() {
|
||||
return this._clock;
|
||||
}
|
||||
/**
|
||||
* Gets the current graph
|
||||
*/
|
||||
|
||||
|
||||
get graph() {
|
||||
return this._graph;
|
||||
}
|
||||
/**
|
||||
* Gets the current global object
|
||||
*/
|
||||
|
||||
|
||||
get globalObject() {
|
||||
return this._global;
|
||||
}
|
||||
/**
|
||||
* Gets the current configuration
|
||||
*/
|
||||
|
||||
|
||||
get configuration() {
|
||||
return this._configuration;
|
||||
}
|
||||
/**
|
||||
* Configures the executor
|
||||
* @param config The layout config
|
||||
*/
|
||||
|
||||
|
||||
configure(config) {
|
||||
this._configuration = _objectSpread(_objectSpread({}, this.defaultConfiguration), config);
|
||||
}
|
||||
/**
|
||||
* Executes the layout process
|
||||
*/
|
||||
|
||||
|
||||
execute() {
|
||||
this._global.console.log(`execute ${this.getName()}, %s nodes, %s edges`, this.graph.nodes.count, this.graph.edges.count);
|
||||
|
||||
this._halted = false;
|
||||
this._complete = false;
|
||||
this.clearTickListener();
|
||||
return new Promise(resolve => {
|
||||
this.executeStep();
|
||||
this._tickListener = this.on('tick', () => {
|
||||
if (this._complete) {
|
||||
resolve(this.getProgress());
|
||||
this.clearTickListener();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Clears the tick listener
|
||||
*/
|
||||
|
||||
|
||||
clearTickListener() {
|
||||
if (this._tickListener) {
|
||||
this._tickListener();
|
||||
|
||||
this._tickListener = undefined;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Executes one step of the layout algorithm
|
||||
*/
|
||||
|
||||
|
||||
executeStep() {
|
||||
this.performUnitOfWork(); // Advance the annealing clock
|
||||
|
||||
const ticking = this._clock.tick();
|
||||
|
||||
if (!ticking) {
|
||||
this._complete = true;
|
||||
} // Perform the next layout step on the event queue
|
||||
|
||||
|
||||
if (ticking && !this._halted) {
|
||||
this._global.setTimeout(this.executeStep, 0);
|
||||
} // Emit the tick event
|
||||
|
||||
|
||||
this.emit('tick', this.getProgress());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.BaseExecutor = BaseExecutor;
|
|
@ -1,18 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _BaseExecutor = require("./BaseExecutor");
|
||||
|
||||
Object.keys(_BaseExecutor).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (key in exports && exports[key] === _BaseExecutor[key]) return;
|
||||
Object.defineProperty(exports, key, {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _BaseExecutor[key];
|
||||
}
|
||||
});
|
||||
});
|
|
@ -1,124 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.LayoutWorkerManager = void 0;
|
||||
|
||||
var _types = require("./types");
|
||||
|
||||
var _common = require("@graspologic/common");
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/**
|
||||
* A manager class for using webworker-based layout execution
|
||||
*/
|
||||
class LayoutWorkerManager extends _common.EventEmitter {
|
||||
/**
|
||||
* Constructor for the LayoutWorkerManager
|
||||
* @param createWorker A callback for instantiating the worker
|
||||
*/
|
||||
constructor(createWorker) {
|
||||
super();
|
||||
|
||||
_defineProperty(this, "_createWorker", void 0);
|
||||
|
||||
_defineProperty(this, "_worker", void 0);
|
||||
|
||||
_defineProperty(this, "_configuration", {});
|
||||
|
||||
this._createWorker = createWorker;
|
||||
}
|
||||
/**
|
||||
* Configures the layout worker
|
||||
* @param configuration The configuration options for the layout worker
|
||||
*/
|
||||
|
||||
|
||||
configure(configuration) {
|
||||
this._configuration = configuration;
|
||||
}
|
||||
/**
|
||||
* Performs the layout on the given graph
|
||||
* @param graph The graph to perform the layout on
|
||||
* @returns A promise for when the layout is completed
|
||||
*/
|
||||
|
||||
|
||||
layout(graph) {
|
||||
this._worker = this._createWorker(); // Listen for completion
|
||||
|
||||
const result = new Promise((resolve, reject) => {
|
||||
this._worker.onmessage = ev => {
|
||||
const {
|
||||
type,
|
||||
payload
|
||||
} = ev.data;
|
||||
|
||||
if (type === _types.WorkerMessageType.Progress) {
|
||||
this.emit('progress', payload);
|
||||
} else if (type === _types.WorkerMessageType.Complete) {
|
||||
this.reset();
|
||||
resolve(payload);
|
||||
} else if (type === _types.WorkerMessageType.Error) {
|
||||
this.reset();
|
||||
reject(payload);
|
||||
}
|
||||
};
|
||||
}); // kick off the layout
|
||||
|
||||
this.sendMessage(_types.WorkerMessageType.Execute, {
|
||||
graph: graph.serialize(),
|
||||
configuration: this._configuration
|
||||
});
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Resets the layout worker to it's initial state
|
||||
*/
|
||||
|
||||
|
||||
reset() {
|
||||
if (this._worker) {
|
||||
this._worker.terminate();
|
||||
|
||||
this._worker = undefined;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Stops the current layout process
|
||||
*/
|
||||
|
||||
|
||||
halt() {
|
||||
this.sendMessage(_types.WorkerMessageType.Halt);
|
||||
}
|
||||
/**
|
||||
* Resumes the current layout process
|
||||
*/
|
||||
|
||||
|
||||
resume() {
|
||||
this.sendMessage(_types.WorkerMessageType.Resume);
|
||||
}
|
||||
/**
|
||||
* Sends a message to the layout worker
|
||||
* @param type The message type
|
||||
* @param payload The payload
|
||||
* @param share The data to share
|
||||
*/
|
||||
|
||||
|
||||
sendMessage(type, payload, share) {
|
||||
if (this._worker) {
|
||||
this._worker.postMessage({
|
||||
type,
|
||||
payload
|
||||
}, share || []);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.LayoutWorkerManager = LayoutWorkerManager;
|
|
@ -1,44 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _LayoutWorkerManager = require("./LayoutWorkerManager");
|
||||
|
||||
Object.keys(_LayoutWorkerManager).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (key in exports && exports[key] === _LayoutWorkerManager[key]) return;
|
||||
Object.defineProperty(exports, key, {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _LayoutWorkerManager[key];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var _workerFactory = require("./workerFactory");
|
||||
|
||||
Object.keys(_workerFactory).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (key in exports && exports[key] === _workerFactory[key]) return;
|
||||
Object.defineProperty(exports, key, {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _workerFactory[key];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var _types = require("./types");
|
||||
|
||||
Object.keys(_types).forEach(function (key) {
|
||||
if (key === "default" || key === "__esModule") return;
|
||||
if (key in exports && exports[key] === _types[key]) return;
|
||||
Object.defineProperty(exports, key, {
|
||||
enumerable: true,
|
||||
get: function () {
|
||||
return _types[key];
|
||||
}
|
||||
});
|
||||
});
|
|
@ -1,59 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.WorkerMessageType = void 0;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The type of message for Manager <-> Worker communication
|
||||
*/
|
||||
var WorkerMessageType;
|
||||
exports.WorkerMessageType = WorkerMessageType;
|
||||
|
||||
(function (WorkerMessageType) {
|
||||
// Manager -> Worker
|
||||
|
||||
/**
|
||||
* Tells the worker to configure itself
|
||||
*/
|
||||
WorkerMessageType["Configure"] = "CONFIGURE";
|
||||
/**
|
||||
* Tells the worker to execute the layout
|
||||
*/
|
||||
|
||||
WorkerMessageType["Execute"] = "EXECUTE";
|
||||
/**
|
||||
* Tells the worker to halt layout
|
||||
*/
|
||||
|
||||
WorkerMessageType["Halt"] = "HALT";
|
||||
/**
|
||||
* Tells the worker to resume layout
|
||||
*/
|
||||
|
||||
WorkerMessageType["Resume"] = "RESUME";
|
||||
/**
|
||||
* Tells the worker to reset it's to the initial state
|
||||
*/
|
||||
|
||||
WorkerMessageType["Reset"] = "RESET"; // Worker -> Manager
|
||||
|
||||
/**
|
||||
* Tells the manager that the worker experienced an error
|
||||
*/
|
||||
|
||||
WorkerMessageType["Error"] = "ERROR";
|
||||
/**
|
||||
* Tells the manager that progress has occurred on the graph layout
|
||||
*/
|
||||
|
||||
WorkerMessageType["Progress"] = "PROGRESS";
|
||||
/**
|
||||
* Tells the manager that the worker has completed layout of the graph
|
||||
*/
|
||||
|
||||
WorkerMessageType["Complete"] = "COMPLETE";
|
||||
})(WorkerMessageType || (exports.WorkerMessageType = WorkerMessageType = {}));
|
|
@ -1,18 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.workerFactoryFromScript = workerFactoryFromScript;
|
||||
|
||||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
function workerFactoryFromScript(workerScript) {
|
||||
const blob = new Blob([workerScript], {
|
||||
type: 'text/javascript'
|
||||
});
|
||||
const blobUrl = window.URL.createObjectURL(blob);
|
||||
return () => new Worker(blobUrl);
|
||||
}
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 9.4 KiB |
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 28 KiB |
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 480 B |
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 855 B |
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -1 +0,0 @@
|
|||
{"kinds":{"1":"Module"},"rows":[{"id":0,"kind":1,"name":"\"index\"","url":"modules/_index_.html","classes":"tsd-kind-module"}],"index":{"version":"2.3.9","fields":["name","parent"],"fieldVectors":[["name/0",[0,2.877]],["parent/0",[]]],"invertedIndex":[["index",{"_index":0,"name":{"0":{}},"parent":{}}]],"pipeline":[]}}
|
|
@ -1,104 +0,0 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>@graspologic/layout-core</title>
|
||||
<meta name="description" content="Documentation for @graspologic/layout-core">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="assets/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="tsd-page-toolbar">
|
||||
<div class="container">
|
||||
<div class="table-wrap">
|
||||
<div class="table-cell" id="tsd-search" data-index="assets/js/search.json" data-base=".">
|
||||
<div class="field">
|
||||
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||
<input id="tsd-search-field" type="text" />
|
||||
</div>
|
||||
<ul class="results">
|
||||
<li class="state loading">Preparing search index...</li>
|
||||
<li class="state failure">The search index is not available</li>
|
||||
</ul>
|
||||
<a href="index.html" class="title">@graspologic/layout-core</a>
|
||||
</div>
|
||||
<div class="table-cell" id="tsd-widgets">
|
||||
<div id="tsd-filter">
|
||||
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||
<div class="tsd-filter-group">
|
||||
<div class="tsd-select" id="tsd-filter-visibility">
|
||||
<span class="tsd-select-label">All</span>
|
||||
<ul class="tsd-select-list">
|
||||
<li data-value="public">Public</li>
|
||||
<li data-value="protected">Public/Protected</li>
|
||||
<li data-value="private" class="selected">All</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tsd-page-title">
|
||||
<div class="container">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="globals.html">Globals</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1>@graspologic/layout-core</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<section class="tsd-panel-group tsd-index-group">
|
||||
<h2>Index</h2>
|
||||
<section class="tsd-panel tsd-index-panel">
|
||||
<div class="tsd-index-content">
|
||||
<section class="tsd-index-section ">
|
||||
<h3>Modules</h3>
|
||||
<ul class="tsd-index-list">
|
||||
<li class="tsd-kind-module"><a href="modules/_index_.html" class="tsd-kind-icon">"index"</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals current ">
|
||||
<a href="globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="with-border-bottom">
|
||||
<div class="container">
|
||||
<h2>Legend</h2>
|
||||
<div class="tsd-legend-group">
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div class="container tsd-generator">
|
||||
<p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="assets/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,193 +0,0 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>@graspologic/layout-core</title>
|
||||
<meta name="description" content="Documentation for @graspologic/layout-core">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="assets/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="tsd-page-toolbar">
|
||||
<div class="container">
|
||||
<div class="table-wrap">
|
||||
<div class="table-cell" id="tsd-search" data-index="assets/js/search.json" data-base=".">
|
||||
<div class="field">
|
||||
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||
<input id="tsd-search-field" type="text" />
|
||||
</div>
|
||||
<ul class="results">
|
||||
<li class="state loading">Preparing search index...</li>
|
||||
<li class="state failure">The search index is not available</li>
|
||||
</ul>
|
||||
<a href="index.html" class="title">@graspologic/layout-core</a>
|
||||
</div>
|
||||
<div class="table-cell" id="tsd-widgets">
|
||||
<div id="tsd-filter">
|
||||
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||
<div class="tsd-filter-group">
|
||||
<div class="tsd-select" id="tsd-filter-visibility">
|
||||
<span class="tsd-select-label">All</span>
|
||||
<ul class="tsd-select-list">
|
||||
<li data-value="public">Public</li>
|
||||
<li data-value="protected">Public/Protected</li>
|
||||
<li data-value="private" class="selected">All</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tsd-page-title">
|
||||
<div class="container">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="globals.html">Globals</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1>@graspologic/layout-core</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
<div class="tsd-panel tsd-typography">
|
||||
<a href="#graspologiclayout-core" id="graspologiclayout-core" style="color: inherit; text-decoration: none;">
|
||||
<h1>@graspologic/layout-core</h1>
|
||||
</a>
|
||||
<p>This library contains all the core logic for executing graph layout algorithms using Web Workers.</p>
|
||||
<a href="#basic-usage" id="basic-usage" style="color: inherit; text-decoration: none;">
|
||||
<h2>Basic Usage</h2>
|
||||
</a>
|
||||
<pre><code class="language-js"><span class="hljs-comment">// See below for other implementations of createWorker</span>
|
||||
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createWorker</span>(<span class="hljs-params">type</span>) </span>{
|
||||
<span class="hljs-comment">// A url to either</span>
|
||||
<span class="hljs-comment">//</span>
|
||||
<span class="hljs-comment">// OpenOrd:</span>
|
||||
<span class="hljs-comment">// @graspologic/layout-openord/dist/openord_worker.js</span>
|
||||
<span class="hljs-comment">//</span>
|
||||
<span class="hljs-comment">// or</span>
|
||||
<span class="hljs-comment">//</span>
|
||||
<span class="hljs-comment">// ForceAtlas2:</span>
|
||||
<span class="hljs-comment">// @graspologic/layout-fa2/dist/fa2_worker.js</span>
|
||||
<span class="hljs-comment">//</span>
|
||||
<span class="hljs-keyword">const</span> workerUrl =
|
||||
type === <span class="hljs-string">'fa2'</span>
|
||||
? <span class="hljs-string">'https://path-to-fa2.worker.js'</span>
|
||||
: <span class="hljs-string">'https://path-to-open-ord.worker.js'</span>
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Worker(workerUrl)
|
||||
}
|
||||
|
||||
<span class="hljs-comment">// Construct the layout manager which manages the layout worker scripts</span>
|
||||
<span class="hljs-keyword">const</span> layoutManager = <span class="hljs-keyword">new</span> LayoutWorkerManager(<span class="hljs-function">() =></span> createWorker(<span class="hljs-string">'fa2'</span>))
|
||||
|
||||
<span class="hljs-comment">// A layout tick was performed</span>
|
||||
layoutManager.on(<span class="hljs-string">'progress'</span>, <span class="hljs-function">() =></span> {
|
||||
<span class="hljs-comment">// As the layout progresses, tell the graph renderer to rebind to the underlying data</span>
|
||||
renderer.rebind()
|
||||
|
||||
<span class="hljs-comment">// Tell the renderer to re-fit to the graph</span>
|
||||
renderer.zoomToGraph()
|
||||
})
|
||||
|
||||
layoutManager.layout(renderer.graph)</code></pre>
|
||||
<a href="#webpack-createworker-using-worker-loader" id="webpack-createworker-using-worker-loader" style="color: inherit; text-decoration: none;">
|
||||
<h3>Webpack createWorker using worker-loader</h3>
|
||||
</a>
|
||||
<p>Below is a basic implementation of creating workers for the LayoutWorkerManager.</p>
|
||||
<blockquote>
|
||||
<p>Note: This requires Webpack's <a href="https://webpack.js.org/loaders/worker-loader/">worker-loader</a> to be installed.</p>
|
||||
</blockquote>
|
||||
<pre><code class="language-js"><span class="hljs-keyword">import</span> FA2Worker <span class="hljs-keyword">from</span> <span class="hljs-string">'worker-loader!./@graspologic/layout-fa2/dist/fa2_worker.js'</span>
|
||||
<span class="hljs-keyword">import</span> OpenOrdWorker <span class="hljs-keyword">from</span> <span class="hljs-string">'worker-loader!./@graspologic/layout-openord/dist/openord_worker.js'</span>
|
||||
|
||||
<span class="hljs-comment">/**
|
||||
* Creates a worker for the given type
|
||||
*/</span>
|
||||
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createWorker</span>(<span class="hljs-params">type</span>) </span>{
|
||||
<span class="hljs-keyword">if</span> (type === <span class="hljs-string">'fa2'</span>) {
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> FA2Worker()
|
||||
}
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> OpenOrdWorker()
|
||||
}</code></pre>
|
||||
<a href="#webpack-createworker-using-raw-loader" id="webpack-createworker-using-raw-loader" style="color: inherit; text-decoration: none;">
|
||||
<h3>Webpack createWorker using raw-loader</h3>
|
||||
</a>
|
||||
<p>Below is a basic implementation of creating workers for the LayoutWorkerManager.</p>
|
||||
<blockquote>
|
||||
<p>Note: This requires Webpack's <a href="https://webpack.js.org/loaders/raw-loader/">raw-loader</a> to be installed.</p>
|
||||
</blockquote>
|
||||
<pre><code class="language-js"><span class="hljs-comment">// Loads the FA2 script as a raw string</span>
|
||||
<span class="hljs-keyword">const</span> FA2_WORKER_SCRIPT = <span class="hljs-built_in">require</span>(<span class="hljs-string">'!raw-loader!@graspologic/layout-fa2/dist/fa2_worker.js'</span>)
|
||||
.default
|
||||
|
||||
<span class="hljs-comment">// Create a blob for the worker script</span>
|
||||
<span class="hljs-keyword">const</span> FA2_WORKER_BLOB = <span class="hljs-keyword">new</span> Blob([FA2_WORKER_SCRIPT], {
|
||||
<span class="hljs-attr">type</span>: <span class="hljs-string">'text/javascript'</span>,
|
||||
})
|
||||
|
||||
<span class="hljs-comment">// Create a blob url for the fa2 worker script</span>
|
||||
<span class="hljs-keyword">const</span> FA2_WORKER_URL = <span class="hljs-built_in">window</span>.URL.createObjectURL(FA2_WORKER_BLOB)
|
||||
|
||||
<span class="hljs-comment">// Loads the OpenOrd script as a raw string</span>
|
||||
<span class="hljs-keyword">const</span> OPEN_ORD_WORKER_SCRIPT = <span class="hljs-built_in">require</span>(<span class="hljs-string">'!raw-loader!@graspologic/layout-openord/dist/openord_worker.js'</span>)
|
||||
.default
|
||||
|
||||
<span class="hljs-comment">// Create a blob for the worker script</span>
|
||||
<span class="hljs-keyword">const</span> OPEN_ORD_WORKER_BLOB = <span class="hljs-keyword">new</span> Blob([OPEN_ORD_WORKER_SCRIPT], {
|
||||
<span class="hljs-attr">type</span>: <span class="hljs-string">'text/javascript'</span>,
|
||||
})
|
||||
|
||||
<span class="hljs-comment">// Create a blob url for the openORD worker script</span>
|
||||
<span class="hljs-keyword">const</span> OPEN_ORD_WORKER_URL = <span class="hljs-built_in">window</span>.URL.createObjectURL(OPEN_ORD_WORKER_BLOB)
|
||||
|
||||
<span class="hljs-comment">/**
|
||||
* Creates a worker for the given type
|
||||
*/</span>
|
||||
<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createWorker</span>(<span class="hljs-params">type</span>) </span>{
|
||||
<span class="hljs-keyword">let</span> url = OPEN_ORD_WORKER_URL
|
||||
<span class="hljs-keyword">if</span> (type === <span class="hljs-string">'fa2'</span>) {
|
||||
url = FA2_WORKER_URL
|
||||
}
|
||||
<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Worker(url)
|
||||
}</code></pre>
|
||||
<p>See the <a href="./dist/docs/globals.md">API documentation</a> or <a href="../../../examples">examples</a> for additional examples.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="with-border-bottom">
|
||||
<div class="container">
|
||||
<h2>Legend</h2>
|
||||
<div class="tsd-legend-group">
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div class="container tsd-generator">
|
||||
<p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="assets/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,94 +0,0 @@
|
|||
<!doctype html>
|
||||
<html class="default no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>"index" | @graspologic/layout-core</title>
|
||||
<meta name="description" content="Documentation for @graspologic/layout-core">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="../assets/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<div class="tsd-page-toolbar">
|
||||
<div class="container">
|
||||
<div class="table-wrap">
|
||||
<div class="table-cell" id="tsd-search" data-index="../assets/js/search.json" data-base="..">
|
||||
<div class="field">
|
||||
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||
<input id="tsd-search-field" type="text" />
|
||||
</div>
|
||||
<ul class="results">
|
||||
<li class="state loading">Preparing search index...</li>
|
||||
<li class="state failure">The search index is not available</li>
|
||||
</ul>
|
||||
<a href="../index.html" class="title">@graspologic/layout-core</a>
|
||||
</div>
|
||||
<div class="table-cell" id="tsd-widgets">
|
||||
<div id="tsd-filter">
|
||||
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||
<div class="tsd-filter-group">
|
||||
<div class="tsd-select" id="tsd-filter-visibility">
|
||||
<span class="tsd-select-label">All</span>
|
||||
<ul class="tsd-select-list">
|
||||
<li data-value="public">Public</li>
|
||||
<li data-value="protected">Public/Protected</li>
|
||||
<li data-value="private" class="selected">All</li>
|
||||
</ul>
|
||||
</div>
|
||||
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||
</div>
|
||||
</div>
|
||||
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tsd-page-title">
|
||||
<div class="container">
|
||||
<ul class="tsd-breadcrumb">
|
||||
<li>
|
||||
<a href="../globals.html">Globals</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="_index_.html">"index"</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h1>Module "index"</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="container container-main">
|
||||
<div class="row">
|
||||
<div class="col-8 col-content">
|
||||
</div>
|
||||
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||
<nav class="tsd-navigation primary">
|
||||
<ul>
|
||||
<li class="globals ">
|
||||
<a href="../globals.html"><em>Globals</em></a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<nav class="tsd-navigation secondary menu-sticky">
|
||||
<ul class="before-current">
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<footer class="with-border-bottom">
|
||||
<div class="container">
|
||||
<h2>Legend</h2>
|
||||
<div class="tsd-legend-group">
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<div class="container tsd-generator">
|
||||
<p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||
</div>
|
||||
<div class="overlay"></div>
|
||||
<script src="../assets/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,46 +0,0 @@
|
|||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* An implementation of a clock which will tick until it reaches a target tick count
|
||||
*/
|
||||
export class CountdownClock {
|
||||
/**
|
||||
* Constructor for the countdown clock
|
||||
* @param targetTicks The target number of ticks to run
|
||||
*/
|
||||
constructor(targetTicks) {
|
||||
_defineProperty(this, "_targetTicks", void 0);
|
||||
|
||||
_defineProperty(this, "_ticks", 0);
|
||||
|
||||
this._targetTicks = targetTicks;
|
||||
}
|
||||
/**
|
||||
* Gets the current ticks
|
||||
*/
|
||||
|
||||
|
||||
get currentTicks() {
|
||||
return this._ticks;
|
||||
}
|
||||
/**
|
||||
* Gets the target ticks
|
||||
*/
|
||||
|
||||
|
||||
get targetTicks() {
|
||||
return this._targetTicks;
|
||||
}
|
||||
/**
|
||||
* Ticks the current clock
|
||||
*/
|
||||
|
||||
|
||||
tick() {
|
||||
this._ticks++;
|
||||
return this._ticks < this._targetTicks;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './CountdownClock';
|
||||
export * from './types';
|
|
@ -1 +0,0 @@
|
|||
export {};
|
|
@ -1,7 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './workers';
|
||||
export * from './layout';
|
||||
export * from './clock';
|
|
@ -1,167 +0,0 @@
|
|||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
import { EventEmitter } from '@graspologic/common';
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Base class for layout executors
|
||||
*/
|
||||
|
||||
export class BaseExecutor extends EventEmitter {
|
||||
/**
|
||||
* Constructor for the base executor
|
||||
* @param graph The graph to run the layout on
|
||||
* @param config The configuration for the layout
|
||||
* @param clock The clock which is used to indicate when a layout cycle has occurred
|
||||
* @param globalObject The "global" object environment
|
||||
*/
|
||||
constructor(graph, config, clock, globalObject) {
|
||||
super();
|
||||
|
||||
_defineProperty(this, "_graph", void 0);
|
||||
|
||||
_defineProperty(this, "_halted", false);
|
||||
|
||||
_defineProperty(this, "_complete", false);
|
||||
|
||||
_defineProperty(this, "_global", void 0);
|
||||
|
||||
_defineProperty(this, "_configuration", void 0);
|
||||
|
||||
_defineProperty(this, "_tickListener", void 0);
|
||||
|
||||
_defineProperty(this, "_clock", void 0);
|
||||
|
||||
this._clock = clock;
|
||||
this._graph = graph;
|
||||
this._global = globalObject;
|
||||
this._configuration = config;
|
||||
this.executeStep = this.executeStep.bind(this);
|
||||
globalObject.console.log(`create new ${this.getName()} instance`, this._configuration);
|
||||
}
|
||||
/**
|
||||
* Halts the layout process
|
||||
*/
|
||||
|
||||
|
||||
halt() {
|
||||
this._halted = true;
|
||||
}
|
||||
/**
|
||||
* Returns true if the layout is halted
|
||||
*/
|
||||
|
||||
|
||||
get isHalted() {
|
||||
return this._halted;
|
||||
}
|
||||
/**
|
||||
* Returns true if the layout is completed
|
||||
*/
|
||||
|
||||
|
||||
get isComplete() {
|
||||
return this._complete;
|
||||
}
|
||||
/**
|
||||
* Gets the current clock
|
||||
*/
|
||||
|
||||
|
||||
get clock() {
|
||||
return this._clock;
|
||||
}
|
||||
/**
|
||||
* Gets the current graph
|
||||
*/
|
||||
|
||||
|
||||
get graph() {
|
||||
return this._graph;
|
||||
}
|
||||
/**
|
||||
* Gets the current global object
|
||||
*/
|
||||
|
||||
|
||||
get globalObject() {
|
||||
return this._global;
|
||||
}
|
||||
/**
|
||||
* Gets the current configuration
|
||||
*/
|
||||
|
||||
|
||||
get configuration() {
|
||||
return this._configuration;
|
||||
}
|
||||
/**
|
||||
* Configures the executor
|
||||
* @param config The layout config
|
||||
*/
|
||||
|
||||
|
||||
configure(config) {
|
||||
this._configuration = _objectSpread(_objectSpread({}, this.defaultConfiguration), config);
|
||||
}
|
||||
/**
|
||||
* Executes the layout process
|
||||
*/
|
||||
|
||||
|
||||
execute() {
|
||||
this._global.console.log(`execute ${this.getName()}, %s nodes, %s edges`, this.graph.nodes.count, this.graph.edges.count);
|
||||
|
||||
this._halted = false;
|
||||
this._complete = false;
|
||||
this.clearTickListener();
|
||||
return new Promise(resolve => {
|
||||
this.executeStep();
|
||||
this._tickListener = this.on('tick', () => {
|
||||
if (this._complete) {
|
||||
resolve(this.getProgress());
|
||||
this.clearTickListener();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Clears the tick listener
|
||||
*/
|
||||
|
||||
|
||||
clearTickListener() {
|
||||
if (this._tickListener) {
|
||||
this._tickListener();
|
||||
|
||||
this._tickListener = undefined;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Executes one step of the layout algorithm
|
||||
*/
|
||||
|
||||
|
||||
executeStep() {
|
||||
this.performUnitOfWork(); // Advance the annealing clock
|
||||
|
||||
const ticking = this._clock.tick();
|
||||
|
||||
if (!ticking) {
|
||||
this._complete = true;
|
||||
} // Perform the next layout step on the event queue
|
||||
|
||||
|
||||
if (ticking && !this._halted) {
|
||||
this._global.setTimeout(this.executeStep, 0);
|
||||
} // Emit the tick event
|
||||
|
||||
|
||||
this.emit('tick', this.getProgress());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './BaseExecutor';
|
|
@ -1,118 +0,0 @@
|
|||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { WorkerMessageType } from './types';
|
||||
import { EventEmitter } from '@graspologic/common';
|
||||
/**
|
||||
* A manager class for using webworker-based layout execution
|
||||
*/
|
||||
|
||||
export class LayoutWorkerManager extends EventEmitter {
|
||||
/**
|
||||
* Constructor for the LayoutWorkerManager
|
||||
* @param createWorker A callback for instantiating the worker
|
||||
*/
|
||||
constructor(createWorker) {
|
||||
super();
|
||||
|
||||
_defineProperty(this, "_createWorker", void 0);
|
||||
|
||||
_defineProperty(this, "_worker", void 0);
|
||||
|
||||
_defineProperty(this, "_configuration", {});
|
||||
|
||||
this._createWorker = createWorker;
|
||||
}
|
||||
/**
|
||||
* Configures the layout worker
|
||||
* @param configuration The configuration options for the layout worker
|
||||
*/
|
||||
|
||||
|
||||
configure(configuration) {
|
||||
this._configuration = configuration;
|
||||
}
|
||||
/**
|
||||
* Performs the layout on the given graph
|
||||
* @param graph The graph to perform the layout on
|
||||
* @returns A promise for when the layout is completed
|
||||
*/
|
||||
|
||||
|
||||
layout(graph) {
|
||||
this._worker = this._createWorker(); // Listen for completion
|
||||
|
||||
const result = new Promise((resolve, reject) => {
|
||||
this._worker.onmessage = ev => {
|
||||
const {
|
||||
type,
|
||||
payload
|
||||
} = ev.data;
|
||||
|
||||
if (type === WorkerMessageType.Progress) {
|
||||
this.emit('progress', payload);
|
||||
} else if (type === WorkerMessageType.Complete) {
|
||||
this.reset();
|
||||
resolve(payload);
|
||||
} else if (type === WorkerMessageType.Error) {
|
||||
this.reset();
|
||||
reject(payload);
|
||||
}
|
||||
};
|
||||
}); // kick off the layout
|
||||
|
||||
this.sendMessage(WorkerMessageType.Execute, {
|
||||
graph: graph.serialize(),
|
||||
configuration: this._configuration
|
||||
});
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Resets the layout worker to it's initial state
|
||||
*/
|
||||
|
||||
|
||||
reset() {
|
||||
if (this._worker) {
|
||||
this._worker.terminate();
|
||||
|
||||
this._worker = undefined;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Stops the current layout process
|
||||
*/
|
||||
|
||||
|
||||
halt() {
|
||||
this.sendMessage(WorkerMessageType.Halt);
|
||||
}
|
||||
/**
|
||||
* Resumes the current layout process
|
||||
*/
|
||||
|
||||
|
||||
resume() {
|
||||
this.sendMessage(WorkerMessageType.Resume);
|
||||
}
|
||||
/**
|
||||
* Sends a message to the layout worker
|
||||
* @param type The message type
|
||||
* @param payload The payload
|
||||
* @param share The data to share
|
||||
*/
|
||||
|
||||
|
||||
sendMessage(type, payload, share) {
|
||||
if (this._worker) {
|
||||
this._worker.postMessage({
|
||||
type,
|
||||
payload
|
||||
}, share || []);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './LayoutWorkerManager';
|
||||
export * from './workerFactory';
|
||||
export * from './types';
|
|
@ -1,51 +0,0 @@
|
|||
/**
|
||||
* @internal
|
||||
*
|
||||
* The type of message for Manager <-> Worker communication
|
||||
*/
|
||||
export var WorkerMessageType;
|
||||
|
||||
(function (WorkerMessageType) {
|
||||
// Manager -> Worker
|
||||
|
||||
/**
|
||||
* Tells the worker to configure itself
|
||||
*/
|
||||
WorkerMessageType["Configure"] = "CONFIGURE";
|
||||
/**
|
||||
* Tells the worker to execute the layout
|
||||
*/
|
||||
|
||||
WorkerMessageType["Execute"] = "EXECUTE";
|
||||
/**
|
||||
* Tells the worker to halt layout
|
||||
*/
|
||||
|
||||
WorkerMessageType["Halt"] = "HALT";
|
||||
/**
|
||||
* Tells the worker to resume layout
|
||||
*/
|
||||
|
||||
WorkerMessageType["Resume"] = "RESUME";
|
||||
/**
|
||||
* Tells the worker to reset it's to the initial state
|
||||
*/
|
||||
|
||||
WorkerMessageType["Reset"] = "RESET"; // Worker -> Manager
|
||||
|
||||
/**
|
||||
* Tells the manager that the worker experienced an error
|
||||
*/
|
||||
|
||||
WorkerMessageType["Error"] = "ERROR";
|
||||
/**
|
||||
* Tells the manager that progress has occurred on the graph layout
|
||||
*/
|
||||
|
||||
WorkerMessageType["Progress"] = "PROGRESS";
|
||||
/**
|
||||
* Tells the manager that the worker has completed layout of the graph
|
||||
*/
|
||||
|
||||
WorkerMessageType["Complete"] = "COMPLETE";
|
||||
})(WorkerMessageType || (WorkerMessageType = {}));
|
|
@ -1,11 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export function workerFactoryFromScript(workerScript) {
|
||||
const blob = new Blob([workerScript], {
|
||||
type: 'text/javascript'
|
||||
});
|
||||
const blobUrl = window.URL.createObjectURL(blob);
|
||||
return () => new Worker(blobUrl);
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { TickingClock } from './types';
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* An implementation of a clock which will tick until it reaches a target tick count
|
||||
*/
|
||||
export declare class CountdownClock implements TickingClock {
|
||||
private _targetTicks;
|
||||
private _ticks;
|
||||
/**
|
||||
* Constructor for the countdown clock
|
||||
* @param targetTicks The target number of ticks to run
|
||||
*/
|
||||
constructor(targetTicks: number);
|
||||
/**
|
||||
* Gets the current ticks
|
||||
*/
|
||||
get currentTicks(): number;
|
||||
/**
|
||||
* Gets the target ticks
|
||||
*/
|
||||
get targetTicks(): number;
|
||||
/**
|
||||
* Ticks the current clock
|
||||
*/
|
||||
tick(): boolean;
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './CountdownClock';
|
||||
export * from './types';
|
|
@ -1,17 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export declare type OnTickHandler<T> = (arg: T) => void;
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Shape of a clock that can be ticked
|
||||
*/
|
||||
export interface TickingClock {
|
||||
/**
|
||||
* Ticks the clock
|
||||
* @returns True if the clock was ticked
|
||||
*/
|
||||
tick(): boolean;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './workers';
|
||||
export * from './layout';
|
||||
export * from './clock';
|
|
@ -1,98 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { TickingClock } from '../clock';
|
||||
import { EventEmitter } from '@graspologic/common';
|
||||
import { GraphContainer } from '@graspologic/graph';
|
||||
export interface BaseExecutorEvents<Progress> {
|
||||
/**
|
||||
* A layout tick has occurred occurred
|
||||
*/
|
||||
tick: (progress: Progress) => void;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Base class for layout executors
|
||||
*/
|
||||
export declare abstract class BaseExecutor<Config, Clock extends TickingClock, Progress> extends EventEmitter<BaseExecutorEvents<Progress>> {
|
||||
private _graph;
|
||||
private _halted;
|
||||
private _complete;
|
||||
private _global;
|
||||
private _configuration;
|
||||
private _tickListener;
|
||||
private _clock;
|
||||
/**
|
||||
* Constructor for the base executor
|
||||
* @param graph The graph to run the layout on
|
||||
* @param config The configuration for the layout
|
||||
* @param clock The clock which is used to indicate when a layout cycle has occurred
|
||||
* @param globalObject The "global" object environment
|
||||
*/
|
||||
constructor(graph: GraphContainer, config: Config, clock: Clock, globalObject: any);
|
||||
/**
|
||||
* Halts the layout process
|
||||
*/
|
||||
halt(): void;
|
||||
/**
|
||||
* Returns true if the layout is halted
|
||||
*/
|
||||
get isHalted(): boolean;
|
||||
/**
|
||||
* Returns true if the layout is completed
|
||||
*/
|
||||
get isComplete(): boolean;
|
||||
/**
|
||||
* Gets the current clock
|
||||
*/
|
||||
get clock(): Clock;
|
||||
/**
|
||||
* Gets the current graph
|
||||
*/
|
||||
get graph(): GraphContainer;
|
||||
/**
|
||||
* Gets the current global object
|
||||
*/
|
||||
get globalObject(): any;
|
||||
/**
|
||||
* Gets the current configuration
|
||||
*/
|
||||
get configuration(): Config;
|
||||
/**
|
||||
* Configures the executor
|
||||
* @param config The layout config
|
||||
*/
|
||||
configure(config: Partial<Config>): void;
|
||||
/**
|
||||
* The default configuration for the executor
|
||||
*/
|
||||
protected abstract defaultConfiguration: Config;
|
||||
/**
|
||||
* Executes the layout process
|
||||
*/
|
||||
execute(): Promise<Progress>;
|
||||
/**
|
||||
* Clears the tick listener
|
||||
*/
|
||||
private clearTickListener;
|
||||
/**
|
||||
* Executes one step of the layout algorithm
|
||||
*/
|
||||
private executeStep;
|
||||
/**
|
||||
* Gets the name of the layout algorithm
|
||||
* @returns The name
|
||||
*/
|
||||
protected abstract getName(): string;
|
||||
/**
|
||||
* Gets the the current progress of the layout algorithm
|
||||
* @returns The current progress
|
||||
*/
|
||||
protected abstract getProgress(): Progress;
|
||||
/**
|
||||
* Performs a unit of work on the layout
|
||||
*/
|
||||
protected abstract performUnitOfWork(): void;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './BaseExecutor';
|
|
@ -1,51 +0,0 @@
|
|||
import { EventEmitter } from '@graspologic/common';
|
||||
import { GraphContainer } from '@graspologic/graph';
|
||||
export interface LayoutWorkerManagerEvents<TickProgress> {
|
||||
/**
|
||||
* An even for when the layout progresses
|
||||
*/
|
||||
progress: (progress: TickProgress) => void;
|
||||
}
|
||||
/**
|
||||
* A manager class for using webworker-based layout execution
|
||||
*/
|
||||
export declare class LayoutWorkerManager<Configuration, TickProgress> extends EventEmitter<LayoutWorkerManagerEvents<TickProgress>> {
|
||||
private _createWorker;
|
||||
private _worker?;
|
||||
private _configuration;
|
||||
/**
|
||||
* Constructor for the LayoutWorkerManager
|
||||
* @param createWorker A callback for instantiating the worker
|
||||
*/
|
||||
constructor(createWorker: () => Worker);
|
||||
/**
|
||||
* Configures the layout worker
|
||||
* @param configuration The configuration options for the layout worker
|
||||
*/
|
||||
configure(configuration: Partial<Configuration>): void;
|
||||
/**
|
||||
* Performs the layout on the given graph
|
||||
* @param graph The graph to perform the layout on
|
||||
* @returns A promise for when the layout is completed
|
||||
*/
|
||||
layout(graph: GraphContainer): Promise<TickProgress>;
|
||||
/**
|
||||
* Resets the layout worker to it's initial state
|
||||
*/
|
||||
reset(): void;
|
||||
/**
|
||||
* Stops the current layout process
|
||||
*/
|
||||
halt(): void;
|
||||
/**
|
||||
* Resumes the current layout process
|
||||
*/
|
||||
resume(): void;
|
||||
/**
|
||||
* Sends a message to the layout worker
|
||||
* @param type The message type
|
||||
* @param payload The payload
|
||||
* @param share The data to share
|
||||
*/
|
||||
private sendMessage;
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './LayoutWorkerManager';
|
||||
export * from './workerFactory';
|
||||
export * from './types';
|
|
@ -1,74 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { TransportGraph } from '@graspologic/graph';
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The type of message for Manager <-> Worker communication
|
||||
*/
|
||||
export declare enum WorkerMessageType {
|
||||
/**
|
||||
* Tells the worker to configure itself
|
||||
*/
|
||||
Configure = "CONFIGURE",
|
||||
/**
|
||||
* Tells the worker to execute the layout
|
||||
*/
|
||||
Execute = "EXECUTE",
|
||||
/**
|
||||
* Tells the worker to halt layout
|
||||
*/
|
||||
Halt = "HALT",
|
||||
/**
|
||||
* Tells the worker to resume layout
|
||||
*/
|
||||
Resume = "RESUME",
|
||||
/**
|
||||
* Tells the worker to reset it's to the initial state
|
||||
*/
|
||||
Reset = "RESET",
|
||||
/**
|
||||
* Tells the manager that the worker experienced an error
|
||||
*/
|
||||
Error = "ERROR",
|
||||
/**
|
||||
* Tells the manager that progress has occurred on the graph layout
|
||||
*/
|
||||
Progress = "PROGRESS",
|
||||
/**
|
||||
* Tells the manager that the worker has completed layout of the graph
|
||||
*/
|
||||
Complete = "COMPLETE"
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The shape of the messages send to the worker
|
||||
*/
|
||||
export interface WorkerMessage<T> {
|
||||
/**
|
||||
* The type of message
|
||||
*/
|
||||
type: WorkerMessageType;
|
||||
/**
|
||||
* The payload of the message
|
||||
*/
|
||||
payload?: T;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The shape of the "Execute" message type payload
|
||||
*/
|
||||
export interface ExecuteMessagePayload<Configuration> {
|
||||
/**
|
||||
* The graph to execute layout on
|
||||
*/
|
||||
graph: TransportGraph;
|
||||
/**
|
||||
* The configuration for the layout
|
||||
*/
|
||||
configuration?: Partial<Configuration>;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export declare function workerFactoryFromScript(workerScript: string): () => Worker;
|
|
@ -1,273 +0,0 @@
|
|||
// Generated by dts-bundle v0.7.3
|
||||
// Dependencies for this module:
|
||||
// ../@graspologic/common
|
||||
// ../@graspologic/graph
|
||||
|
||||
declare module '@graspologic/layout-core' {
|
||||
export * from '@graspologic/layout-core/workers';
|
||||
export * from '@graspologic/layout-core/layout';
|
||||
export * from '@graspologic/layout-core/clock';
|
||||
}
|
||||
|
||||
declare module '@graspologic/layout-core/workers' {
|
||||
export * from '@graspologic/layout-core/workers/LayoutWorkerManager';
|
||||
export * from '@graspologic/layout-core/workers/workerFactory';
|
||||
export * from '@graspologic/layout-core/workers/types';
|
||||
}
|
||||
|
||||
declare module '@graspologic/layout-core/layout' {
|
||||
export * from '@graspologic/layout-core/layout/BaseExecutor';
|
||||
}
|
||||
|
||||
declare module '@graspologic/layout-core/clock' {
|
||||
export * from '@graspologic/layout-core/clock/CountdownClock';
|
||||
export * from '@graspologic/layout-core/clock/types';
|
||||
}
|
||||
|
||||
declare module '@graspologic/layout-core/workers/LayoutWorkerManager' {
|
||||
import { EventEmitter } from '@graspologic/common';
|
||||
import { GraphContainer } from '@graspologic/graph';
|
||||
export interface LayoutWorkerManagerEvents<TickProgress> {
|
||||
/**
|
||||
* An even for when the layout progresses
|
||||
*/
|
||||
progress: (progress: TickProgress) => void;
|
||||
}
|
||||
/**
|
||||
* A manager class for using webworker-based layout execution
|
||||
*/
|
||||
export class LayoutWorkerManager<Configuration, TickProgress> extends EventEmitter<LayoutWorkerManagerEvents<TickProgress>> {
|
||||
/**
|
||||
* Constructor for the LayoutWorkerManager
|
||||
* @param createWorker A callback for instantiating the worker
|
||||
*/
|
||||
constructor(createWorker: () => Worker);
|
||||
/**
|
||||
* Configures the layout worker
|
||||
* @param configuration The configuration options for the layout worker
|
||||
*/
|
||||
configure(configuration: Partial<Configuration>): void;
|
||||
/**
|
||||
* Performs the layout on the given graph
|
||||
* @param graph The graph to perform the layout on
|
||||
* @returns A promise for when the layout is completed
|
||||
*/
|
||||
layout(graph: GraphContainer): Promise<TickProgress>;
|
||||
/**
|
||||
* Resets the layout worker to it's initial state
|
||||
*/
|
||||
reset(): void;
|
||||
/**
|
||||
* Stops the current layout process
|
||||
*/
|
||||
halt(): void;
|
||||
/**
|
||||
* Resumes the current layout process
|
||||
*/
|
||||
resume(): void;
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@graspologic/layout-core/workers/workerFactory' {
|
||||
export function workerFactoryFromScript(workerScript: string): () => Worker;
|
||||
}
|
||||
|
||||
declare module '@graspologic/layout-core/workers/types' {
|
||||
import { TransportGraph } from '@graspologic/graph';
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The type of message for Manager <-> Worker communication
|
||||
*/
|
||||
export enum WorkerMessageType {
|
||||
/**
|
||||
* Tells the worker to configure itself
|
||||
*/
|
||||
Configure = "CONFIGURE",
|
||||
/**
|
||||
* Tells the worker to execute the layout
|
||||
*/
|
||||
Execute = "EXECUTE",
|
||||
/**
|
||||
* Tells the worker to halt layout
|
||||
*/
|
||||
Halt = "HALT",
|
||||
/**
|
||||
* Tells the worker to resume layout
|
||||
*/
|
||||
Resume = "RESUME",
|
||||
/**
|
||||
* Tells the worker to reset it's to the initial state
|
||||
*/
|
||||
Reset = "RESET",
|
||||
/**
|
||||
* Tells the manager that the worker experienced an error
|
||||
*/
|
||||
Error = "ERROR",
|
||||
/**
|
||||
* Tells the manager that progress has occurred on the graph layout
|
||||
*/
|
||||
Progress = "PROGRESS",
|
||||
/**
|
||||
* Tells the manager that the worker has completed layout of the graph
|
||||
*/
|
||||
Complete = "COMPLETE"
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The shape of the messages send to the worker
|
||||
*/
|
||||
export interface WorkerMessage<T> {
|
||||
/**
|
||||
* The type of message
|
||||
*/
|
||||
type: WorkerMessageType;
|
||||
/**
|
||||
* The payload of the message
|
||||
*/
|
||||
payload?: T;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The shape of the "Execute" message type payload
|
||||
*/
|
||||
export interface ExecuteMessagePayload<Configuration> {
|
||||
/**
|
||||
* The graph to execute layout on
|
||||
*/
|
||||
graph: TransportGraph;
|
||||
/**
|
||||
* The configuration for the layout
|
||||
*/
|
||||
configuration?: Partial<Configuration>;
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@graspologic/layout-core/layout/BaseExecutor' {
|
||||
import { TickingClock } from '@graspologic/layout-core/clock';
|
||||
import { EventEmitter } from '@graspologic/common';
|
||||
import { GraphContainer } from '@graspologic/graph';
|
||||
export interface BaseExecutorEvents<Progress> {
|
||||
/**
|
||||
* A layout tick has occurred occurred
|
||||
*/
|
||||
tick: (progress: Progress) => void;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Base class for layout executors
|
||||
*/
|
||||
export abstract class BaseExecutor<Config, Clock extends TickingClock, Progress> extends EventEmitter<BaseExecutorEvents<Progress>> {
|
||||
/**
|
||||
* Constructor for the base executor
|
||||
* @param graph The graph to run the layout on
|
||||
* @param config The configuration for the layout
|
||||
* @param clock The clock which is used to indicate when a layout cycle has occurred
|
||||
* @param globalObject The "global" object environment
|
||||
*/
|
||||
constructor(graph: GraphContainer, config: Config, clock: Clock, globalObject: any);
|
||||
/**
|
||||
* Halts the layout process
|
||||
*/
|
||||
halt(): void;
|
||||
/**
|
||||
* Returns true if the layout is halted
|
||||
*/
|
||||
get isHalted(): boolean;
|
||||
/**
|
||||
* Returns true if the layout is completed
|
||||
*/
|
||||
get isComplete(): boolean;
|
||||
/**
|
||||
* Gets the current clock
|
||||
*/
|
||||
get clock(): Clock;
|
||||
/**
|
||||
* Gets the current graph
|
||||
*/
|
||||
get graph(): GraphContainer;
|
||||
/**
|
||||
* Gets the current global object
|
||||
*/
|
||||
get globalObject(): any;
|
||||
/**
|
||||
* Gets the current configuration
|
||||
*/
|
||||
get configuration(): Config;
|
||||
/**
|
||||
* Configures the executor
|
||||
* @param config The layout config
|
||||
*/
|
||||
configure(config: Partial<Config>): void;
|
||||
/**
|
||||
* The default configuration for the executor
|
||||
*/
|
||||
protected abstract defaultConfiguration: Config;
|
||||
/**
|
||||
* Executes the layout process
|
||||
*/
|
||||
execute(): Promise<Progress>;
|
||||
/**
|
||||
* Gets the name of the layout algorithm
|
||||
* @returns The name
|
||||
*/
|
||||
protected abstract getName(): string;
|
||||
/**
|
||||
* Gets the the current progress of the layout algorithm
|
||||
* @returns The current progress
|
||||
*/
|
||||
protected abstract getProgress(): Progress;
|
||||
/**
|
||||
* Performs a unit of work on the layout
|
||||
*/
|
||||
protected abstract performUnitOfWork(): void;
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@graspologic/layout-core/clock/CountdownClock' {
|
||||
import { TickingClock } from '@graspologic/layout-core/clock/types';
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* An implementation of a clock which will tick until it reaches a target tick count
|
||||
*/
|
||||
export class CountdownClock implements TickingClock {
|
||||
/**
|
||||
* Constructor for the countdown clock
|
||||
* @param targetTicks The target number of ticks to run
|
||||
*/
|
||||
constructor(targetTicks: number);
|
||||
/**
|
||||
* Gets the current ticks
|
||||
*/
|
||||
get currentTicks(): number;
|
||||
/**
|
||||
* Gets the target ticks
|
||||
*/
|
||||
get targetTicks(): number;
|
||||
/**
|
||||
* Ticks the current clock
|
||||
*/
|
||||
tick(): boolean;
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@graspologic/layout-core/clock/types' {
|
||||
export type OnTickHandler<T> = (arg: T) => void;
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Shape of a clock that can be ticked
|
||||
*/
|
||||
export interface TickingClock {
|
||||
/**
|
||||
* Ticks the clock
|
||||
* @returns True if the clock was ticked
|
||||
*/
|
||||
tick(): boolean;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { TickingClock } from './types';
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* An implementation of a clock which will tick until it reaches a target tick count
|
||||
*/
|
||||
export declare class CountdownClock implements TickingClock {
|
||||
private _targetTicks;
|
||||
private _ticks;
|
||||
/**
|
||||
* Constructor for the countdown clock
|
||||
* @param targetTicks The target number of ticks to run
|
||||
*/
|
||||
constructor(targetTicks: number);
|
||||
/**
|
||||
* Gets the current ticks
|
||||
*/
|
||||
get currentTicks(): number;
|
||||
/**
|
||||
* Gets the target ticks
|
||||
*/
|
||||
get targetTicks(): number;
|
||||
/**
|
||||
* Ticks the current clock
|
||||
*/
|
||||
tick(): boolean;
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/**
|
||||
* @internal
|
||||
*
|
||||
* An implementation of a clock which will tick until it reaches a target tick count
|
||||
*/
|
||||
export class CountdownClock {
|
||||
_targetTicks;
|
||||
_ticks = 0;
|
||||
/**
|
||||
* Constructor for the countdown clock
|
||||
* @param targetTicks The target number of ticks to run
|
||||
*/
|
||||
constructor(targetTicks) {
|
||||
this._targetTicks = targetTicks;
|
||||
}
|
||||
/**
|
||||
* Gets the current ticks
|
||||
*/
|
||||
get currentTicks() {
|
||||
return this._ticks;
|
||||
}
|
||||
/**
|
||||
* Gets the target ticks
|
||||
*/
|
||||
get targetTicks() {
|
||||
return this._targetTicks;
|
||||
}
|
||||
/**
|
||||
* Ticks the current clock
|
||||
*/
|
||||
tick() {
|
||||
this._ticks++;
|
||||
return this._ticks < this._targetTicks;
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './CountdownClock';
|
||||
export * from './types';
|
|
@ -1,6 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './CountdownClock';
|
||||
export * from './types';
|
|
@ -1,17 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export declare type OnTickHandler<T> = (arg: T) => void;
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Shape of a clock that can be ticked
|
||||
*/
|
||||
export interface TickingClock {
|
||||
/**
|
||||
* Ticks the clock
|
||||
* @returns True if the clock was ticked
|
||||
*/
|
||||
tick(): boolean;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export {};
|
|
@ -1,7 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './workers';
|
||||
export * from './layout';
|
||||
export * from './clock';
|
|
@ -1,7 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './workers';
|
||||
export * from './layout';
|
||||
export * from './clock';
|
|
@ -1,98 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { TickingClock } from '../clock';
|
||||
import { EventEmitter } from '@graspologic/common';
|
||||
import { GraphContainer } from '@graspologic/graph';
|
||||
export interface BaseExecutorEvents<Progress> {
|
||||
/**
|
||||
* A layout tick has occurred occurred
|
||||
*/
|
||||
tick: (progress: Progress) => void;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Base class for layout executors
|
||||
*/
|
||||
export declare abstract class BaseExecutor<Config, Clock extends TickingClock, Progress> extends EventEmitter<BaseExecutorEvents<Progress>> {
|
||||
private _graph;
|
||||
private _halted;
|
||||
private _complete;
|
||||
private _global;
|
||||
private _configuration;
|
||||
private _tickListener;
|
||||
private _clock;
|
||||
/**
|
||||
* Constructor for the base executor
|
||||
* @param graph The graph to run the layout on
|
||||
* @param config The configuration for the layout
|
||||
* @param clock The clock which is used to indicate when a layout cycle has occurred
|
||||
* @param globalObject The "global" object environment
|
||||
*/
|
||||
constructor(graph: GraphContainer, config: Config, clock: Clock, globalObject: any);
|
||||
/**
|
||||
* Halts the layout process
|
||||
*/
|
||||
halt(): void;
|
||||
/**
|
||||
* Returns true if the layout is halted
|
||||
*/
|
||||
get isHalted(): boolean;
|
||||
/**
|
||||
* Returns true if the layout is completed
|
||||
*/
|
||||
get isComplete(): boolean;
|
||||
/**
|
||||
* Gets the current clock
|
||||
*/
|
||||
get clock(): Clock;
|
||||
/**
|
||||
* Gets the current graph
|
||||
*/
|
||||
get graph(): GraphContainer;
|
||||
/**
|
||||
* Gets the current global object
|
||||
*/
|
||||
get globalObject(): any;
|
||||
/**
|
||||
* Gets the current configuration
|
||||
*/
|
||||
get configuration(): Config;
|
||||
/**
|
||||
* Configures the executor
|
||||
* @param config The layout config
|
||||
*/
|
||||
configure(config: Partial<Config>): void;
|
||||
/**
|
||||
* The default configuration for the executor
|
||||
*/
|
||||
protected abstract defaultConfiguration: Config;
|
||||
/**
|
||||
* Executes the layout process
|
||||
*/
|
||||
execute(): Promise<Progress>;
|
||||
/**
|
||||
* Clears the tick listener
|
||||
*/
|
||||
private clearTickListener;
|
||||
/**
|
||||
* Executes one step of the layout algorithm
|
||||
*/
|
||||
private executeStep;
|
||||
/**
|
||||
* Gets the name of the layout algorithm
|
||||
* @returns The name
|
||||
*/
|
||||
protected abstract getName(): string;
|
||||
/**
|
||||
* Gets the the current progress of the layout algorithm
|
||||
* @returns The current progress
|
||||
*/
|
||||
protected abstract getProgress(): Progress;
|
||||
/**
|
||||
* Performs a unit of work on the layout
|
||||
*/
|
||||
protected abstract performUnitOfWork(): void;
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
import { EventEmitter } from '@graspologic/common';
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Base class for layout executors
|
||||
*/
|
||||
export class BaseExecutor extends EventEmitter {
|
||||
_graph;
|
||||
_halted = false;
|
||||
_complete = false;
|
||||
_global;
|
||||
_configuration;
|
||||
_tickListener;
|
||||
_clock;
|
||||
/**
|
||||
* Constructor for the base executor
|
||||
* @param graph The graph to run the layout on
|
||||
* @param config The configuration for the layout
|
||||
* @param clock The clock which is used to indicate when a layout cycle has occurred
|
||||
* @param globalObject The "global" object environment
|
||||
*/
|
||||
constructor(graph, config, clock, globalObject) {
|
||||
super();
|
||||
this._clock = clock;
|
||||
this._graph = graph;
|
||||
this._global = globalObject;
|
||||
this._configuration = config;
|
||||
this.executeStep = this.executeStep.bind(this);
|
||||
globalObject.console.log(`create new ${this.getName()} instance`, this._configuration);
|
||||
}
|
||||
/**
|
||||
* Halts the layout process
|
||||
*/
|
||||
halt() {
|
||||
this._halted = true;
|
||||
}
|
||||
/**
|
||||
* Returns true if the layout is halted
|
||||
*/
|
||||
get isHalted() {
|
||||
return this._halted;
|
||||
}
|
||||
/**
|
||||
* Returns true if the layout is completed
|
||||
*/
|
||||
get isComplete() {
|
||||
return this._complete;
|
||||
}
|
||||
/**
|
||||
* Gets the current clock
|
||||
*/
|
||||
get clock() {
|
||||
return this._clock;
|
||||
}
|
||||
/**
|
||||
* Gets the current graph
|
||||
*/
|
||||
get graph() {
|
||||
return this._graph;
|
||||
}
|
||||
/**
|
||||
* Gets the current global object
|
||||
*/
|
||||
get globalObject() {
|
||||
return this._global;
|
||||
}
|
||||
/**
|
||||
* Gets the current configuration
|
||||
*/
|
||||
get configuration() {
|
||||
return this._configuration;
|
||||
}
|
||||
/**
|
||||
* Configures the executor
|
||||
* @param config The layout config
|
||||
*/
|
||||
configure(config) {
|
||||
this._configuration = { ...this.defaultConfiguration, ...config };
|
||||
}
|
||||
/**
|
||||
* Executes the layout process
|
||||
*/
|
||||
execute() {
|
||||
this._global.console.log(`execute ${this.getName()}, %s nodes, %s edges`, this.graph.nodes.count, this.graph.edges.count);
|
||||
this._halted = false;
|
||||
this._complete = false;
|
||||
this.clearTickListener();
|
||||
return new Promise(resolve => {
|
||||
this.executeStep();
|
||||
this._tickListener = this.on('tick', () => {
|
||||
if (this._complete) {
|
||||
resolve(this.getProgress());
|
||||
this.clearTickListener();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Clears the tick listener
|
||||
*/
|
||||
clearTickListener() {
|
||||
if (this._tickListener) {
|
||||
this._tickListener();
|
||||
this._tickListener = undefined;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Executes one step of the layout algorithm
|
||||
*/
|
||||
executeStep() {
|
||||
this.performUnitOfWork();
|
||||
// Advance the annealing clock
|
||||
const ticking = this._clock.tick();
|
||||
if (!ticking) {
|
||||
this._complete = true;
|
||||
}
|
||||
// Perform the next layout step on the event queue
|
||||
if (ticking && !this._halted) {
|
||||
this._global.setTimeout(this.executeStep, 0);
|
||||
}
|
||||
// Emit the tick event
|
||||
this.emit('tick', this.getProgress());
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './BaseExecutor';
|
|
@ -1,5 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './BaseExecutor';
|
|
@ -1,51 +0,0 @@
|
|||
import { EventEmitter } from '@graspologic/common';
|
||||
import { GraphContainer } from '@graspologic/graph';
|
||||
export interface LayoutWorkerManagerEvents<TickProgress> {
|
||||
/**
|
||||
* An even for when the layout progresses
|
||||
*/
|
||||
progress: (progress: TickProgress) => void;
|
||||
}
|
||||
/**
|
||||
* A manager class for using webworker-based layout execution
|
||||
*/
|
||||
export declare class LayoutWorkerManager<Configuration, TickProgress> extends EventEmitter<LayoutWorkerManagerEvents<TickProgress>> {
|
||||
private _createWorker;
|
||||
private _worker?;
|
||||
private _configuration;
|
||||
/**
|
||||
* Constructor for the LayoutWorkerManager
|
||||
* @param createWorker A callback for instantiating the worker
|
||||
*/
|
||||
constructor(createWorker: () => Worker);
|
||||
/**
|
||||
* Configures the layout worker
|
||||
* @param configuration The configuration options for the layout worker
|
||||
*/
|
||||
configure(configuration: Partial<Configuration>): void;
|
||||
/**
|
||||
* Performs the layout on the given graph
|
||||
* @param graph The graph to perform the layout on
|
||||
* @returns A promise for when the layout is completed
|
||||
*/
|
||||
layout(graph: GraphContainer): Promise<TickProgress>;
|
||||
/**
|
||||
* Resets the layout worker to it's initial state
|
||||
*/
|
||||
reset(): void;
|
||||
/**
|
||||
* Stops the current layout process
|
||||
*/
|
||||
halt(): void;
|
||||
/**
|
||||
* Resumes the current layout process
|
||||
*/
|
||||
resume(): void;
|
||||
/**
|
||||
* Sends a message to the layout worker
|
||||
* @param type The message type
|
||||
* @param payload The payload
|
||||
* @param share The data to share
|
||||
*/
|
||||
private sendMessage;
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { WorkerMessageType, } from './types';
|
||||
import { EventEmitter } from '@graspologic/common';
|
||||
/**
|
||||
* A manager class for using webworker-based layout execution
|
||||
*/
|
||||
export class LayoutWorkerManager extends EventEmitter {
|
||||
_createWorker;
|
||||
_worker;
|
||||
_configuration = {};
|
||||
/**
|
||||
* Constructor for the LayoutWorkerManager
|
||||
* @param createWorker A callback for instantiating the worker
|
||||
*/
|
||||
constructor(createWorker) {
|
||||
super();
|
||||
this._createWorker = createWorker;
|
||||
}
|
||||
/**
|
||||
* Configures the layout worker
|
||||
* @param configuration The configuration options for the layout worker
|
||||
*/
|
||||
configure(configuration) {
|
||||
this._configuration = configuration;
|
||||
}
|
||||
/**
|
||||
* Performs the layout on the given graph
|
||||
* @param graph The graph to perform the layout on
|
||||
* @returns A promise for when the layout is completed
|
||||
*/
|
||||
layout(graph) {
|
||||
this._worker = this._createWorker();
|
||||
// Listen for completion
|
||||
const result = new Promise((resolve, reject) => {
|
||||
this._worker.onmessage = ev => {
|
||||
const { type, payload } = ev.data;
|
||||
if (type === WorkerMessageType.Progress) {
|
||||
this.emit('progress', payload);
|
||||
}
|
||||
else if (type === WorkerMessageType.Complete) {
|
||||
this.reset();
|
||||
resolve(payload);
|
||||
}
|
||||
else if (type === WorkerMessageType.Error) {
|
||||
this.reset();
|
||||
reject(payload);
|
||||
}
|
||||
};
|
||||
});
|
||||
// kick off the layout
|
||||
this.sendMessage(WorkerMessageType.Execute, {
|
||||
graph: graph.serialize(),
|
||||
configuration: this._configuration,
|
||||
});
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Resets the layout worker to it's initial state
|
||||
*/
|
||||
reset() {
|
||||
if (this._worker) {
|
||||
this._worker.terminate();
|
||||
this._worker = undefined;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Stops the current layout process
|
||||
*/
|
||||
halt() {
|
||||
this.sendMessage(WorkerMessageType.Halt);
|
||||
}
|
||||
/**
|
||||
* Resumes the current layout process
|
||||
*/
|
||||
resume() {
|
||||
this.sendMessage(WorkerMessageType.Resume);
|
||||
}
|
||||
/**
|
||||
* Sends a message to the layout worker
|
||||
* @param type The message type
|
||||
* @param payload The payload
|
||||
* @param share The data to share
|
||||
*/
|
||||
sendMessage(type, payload, share) {
|
||||
if (this._worker) {
|
||||
this._worker.postMessage({
|
||||
type,
|
||||
payload,
|
||||
}, share || []);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './LayoutWorkerManager';
|
||||
export * from './workerFactory';
|
||||
export * from './types';
|
|
@ -1,7 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export * from './LayoutWorkerManager';
|
||||
export * from './workerFactory';
|
||||
export * from './types';
|
|
@ -1,74 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
import { TransportGraph } from '@graspologic/graph';
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The type of message for Manager <-> Worker communication
|
||||
*/
|
||||
export declare enum WorkerMessageType {
|
||||
/**
|
||||
* Tells the worker to configure itself
|
||||
*/
|
||||
Configure = "CONFIGURE",
|
||||
/**
|
||||
* Tells the worker to execute the layout
|
||||
*/
|
||||
Execute = "EXECUTE",
|
||||
/**
|
||||
* Tells the worker to halt layout
|
||||
*/
|
||||
Halt = "HALT",
|
||||
/**
|
||||
* Tells the worker to resume layout
|
||||
*/
|
||||
Resume = "RESUME",
|
||||
/**
|
||||
* Tells the worker to reset it's to the initial state
|
||||
*/
|
||||
Reset = "RESET",
|
||||
/**
|
||||
* Tells the manager that the worker experienced an error
|
||||
*/
|
||||
Error = "ERROR",
|
||||
/**
|
||||
* Tells the manager that progress has occurred on the graph layout
|
||||
*/
|
||||
Progress = "PROGRESS",
|
||||
/**
|
||||
* Tells the manager that the worker has completed layout of the graph
|
||||
*/
|
||||
Complete = "COMPLETE"
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The shape of the messages send to the worker
|
||||
*/
|
||||
export interface WorkerMessage<T> {
|
||||
/**
|
||||
* The type of message
|
||||
*/
|
||||
type: WorkerMessageType;
|
||||
/**
|
||||
* The payload of the message
|
||||
*/
|
||||
payload?: T;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The shape of the "Execute" message type payload
|
||||
*/
|
||||
export interface ExecuteMessagePayload<Configuration> {
|
||||
/**
|
||||
* The graph to execute layout on
|
||||
*/
|
||||
graph: TransportGraph;
|
||||
/**
|
||||
* The configuration for the layout
|
||||
*/
|
||||
configuration?: Partial<Configuration>;
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/**
|
||||
* @internal
|
||||
*
|
||||
* The type of message for Manager <-> Worker communication
|
||||
*/
|
||||
export var WorkerMessageType;
|
||||
(function (WorkerMessageType) {
|
||||
// Manager -> Worker
|
||||
/**
|
||||
* Tells the worker to configure itself
|
||||
*/
|
||||
WorkerMessageType["Configure"] = "CONFIGURE";
|
||||
/**
|
||||
* Tells the worker to execute the layout
|
||||
*/
|
||||
WorkerMessageType["Execute"] = "EXECUTE";
|
||||
/**
|
||||
* Tells the worker to halt layout
|
||||
*/
|
||||
WorkerMessageType["Halt"] = "HALT";
|
||||
/**
|
||||
* Tells the worker to resume layout
|
||||
*/
|
||||
WorkerMessageType["Resume"] = "RESUME";
|
||||
/**
|
||||
* Tells the worker to reset it's to the initial state
|
||||
*/
|
||||
WorkerMessageType["Reset"] = "RESET";
|
||||
// Worker -> Manager
|
||||
/**
|
||||
* Tells the manager that the worker experienced an error
|
||||
*/
|
||||
WorkerMessageType["Error"] = "ERROR";
|
||||
/**
|
||||
* Tells the manager that progress has occurred on the graph layout
|
||||
*/
|
||||
WorkerMessageType["Progress"] = "PROGRESS";
|
||||
/**
|
||||
* Tells the manager that the worker has completed layout of the graph
|
||||
*/
|
||||
WorkerMessageType["Complete"] = "COMPLETE";
|
||||
})(WorkerMessageType || (WorkerMessageType = {}));
|
|
@ -1,5 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export declare function workerFactoryFromScript(workerScript: string): () => Worker;
|
|
@ -1,9 +0,0 @@
|
|||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
export function workerFactoryFromScript(workerScript) {
|
||||
const blob = new Blob([workerScript], { type: 'text/javascript' });
|
||||
const blobUrl = window.URL.createObjectURL(blob);
|
||||
return () => new Worker(blobUrl);
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
"David Tittsworth (datittsw@microsoft.com)"
|
||||
],
|
||||
"scripts": {
|
||||
"bundle_types": "node ../../../scripts/bundleTypes",
|
||||
"bundle_types": "node ../../scripts/bundleTypes",
|
||||
"build_lib": "essex build",
|
||||
"build": "run-s build_lib bundle_types",
|
||||
"clean": "essex clean lib dist",
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
{"version":"4.5.2"}
|
|
@ -1,133 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.FA2LayoutExecutor = void 0;
|
||||
|
||||
var _forces = require("./forces");
|
||||
|
||||
var _types = require("./types");
|
||||
|
||||
var _graph = require("@graspologic/graph");
|
||||
|
||||
var _layoutCore = require("@graspologic/layout-core");
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* The layout executor which applies the ForceAtlas2 layout algorithm
|
||||
*/
|
||||
class FA2LayoutExecutor extends _layoutCore.BaseExecutor {
|
||||
/**
|
||||
* Constructor for the fa2 layout executor
|
||||
* @param graph The graph to run the layout on
|
||||
* @param config The configuration for the layout
|
||||
* @param clock The clock which is used to indicate when a layout cycle has occurred
|
||||
* @param globalObject The "global" object environment
|
||||
*/
|
||||
constructor(graph, configuration, clock, globalObject) {
|
||||
super(graph, configuration, clock, globalObject);
|
||||
|
||||
_defineProperty(this, "_metrics", [0, 0, 0, 0, 0, 0]);
|
||||
|
||||
this.checkforRandomization();
|
||||
this.computeMass();
|
||||
}
|
||||
/**
|
||||
* Gets the name of the layout
|
||||
*/
|
||||
|
||||
|
||||
getName() {
|
||||
return 'ForceAtlas2';
|
||||
}
|
||||
/**
|
||||
* Gets the default layout configuration
|
||||
*/
|
||||
|
||||
|
||||
get defaultConfiguration() {
|
||||
return _types.DEFAULT_CONFIGURATION;
|
||||
}
|
||||
/**
|
||||
* Performs one iteration of the ForceAtlas2 algorithm
|
||||
*/
|
||||
|
||||
|
||||
performUnitOfWork() {
|
||||
try {
|
||||
this._metrics = (0, _forces.iterate)(this.graph.nodes, this.graph.edges, this.configuration);
|
||||
} catch (err) {
|
||||
this.globalObject.console.log('caught error', err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns the current progress of the layout algorithm
|
||||
*/
|
||||
|
||||
|
||||
getProgress() {
|
||||
return {
|
||||
clock: {
|
||||
iteration: this.clock.currentTicks,
|
||||
targetIterations: this.clock.targetTicks
|
||||
},
|
||||
metrics: {
|
||||
tension: this._metrics[0],
|
||||
swing: this._metrics[1],
|
||||
traction: this._metrics[2]
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Checks if the graph is setup for randomization
|
||||
*/
|
||||
|
||||
|
||||
checkforRandomization() {
|
||||
let node;
|
||||
let isZeroed = true; // Randomize the graph layout if it's zeroed out
|
||||
|
||||
for (node of this.graph.nodes) {
|
||||
if (node.x !== 0 || node.y !== 0) {
|
||||
isZeroed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isZeroed) {
|
||||
this.globalObject.console.log('randomizing layouts');
|
||||
|
||||
for (node of this.graph.nodes) {
|
||||
node.x = (0, _graph.randBetween)(0, 1024);
|
||||
node.y = (0, _graph.randBetween)(0, 1024);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Computes the mass of the graph
|
||||
*/
|
||||
|
||||
|
||||
computeMass() {
|
||||
let node;
|
||||
|
||||
for (node of this.graph.nodes) {
|
||||
node.mass = 1;
|
||||
}
|
||||
|
||||
let edge;
|
||||
|
||||
for (edge of this.graph.edges) {
|
||||
this.graph.nodes.itemAt(edge.sourceIndex).mass += 1;
|
||||
this.graph.nodes.itemAt(edge.targetIndex).mass += 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exports.FA2LayoutExecutor = FA2LayoutExecutor;
|
|
@ -1,29 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.executeFa2 = executeFa2;
|
||||
|
||||
var _factory = require("./factory");
|
||||
|
||||
/*!
|
||||
* Copyright (c) Microsoft. All rights reserved.
|
||||
* Licensed under the MIT license. See LICENSE file in the project.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Executes the FA2 algorithm
|
||||
* @param graph The graph to layout
|
||||
* @param configuration The configuration for the layout
|
||||
* @param onTick The callback for when an iteration of the layout was performed
|
||||
* @returns A promise that resolves when the layout is completed
|
||||
*/
|
||||
function executeFa2(graph, configuration = {}, onTick = () => null) {
|
||||
const executor = (0, _factory.createInstance)(graph, configuration, window);
|
||||
const subscription = executor.on('tick', onTick); // Execute the Layout
|
||||
|
||||
return executor.execute().then(() => subscription());
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.createInstance = createInstance;
|
||||
|
||||
var _FA2LayoutExecutor = require("./FA2LayoutExecutor");
|
||||
|
||||
var _types = require("./types");
|
||||
|
||||
var _layoutCore = require("@graspologic/layout-core");
|
||||
|
||||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Creates a new instance of the ForceAtlas2 layout executor
|
||||
* @param graph The graph to layout
|
||||
* @param configuration The FA2 configuration
|
||||
* @param globalObject The global object
|
||||
*/
|
||||
function createInstance(graph, configuration = {}, globalObject = window) {
|
||||
const finalConfig = _objectSpread(_objectSpread({}, _types.DEFAULT_CONFIGURATION), configuration);
|
||||
|
||||
return new _FA2LayoutExecutor.FA2LayoutExecutor(graph, finalConfig, new _layoutCore.CountdownClock(configuration.targetIterations || 100), globalObject);
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.applyForces = applyForces;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Applies the forces to the nodes to move them
|
||||
* @param nodes The node data
|
||||
* @param config The layout configuration
|
||||
* @param repulsion The repulsion amount
|
||||
* @param gravity The gravity amount
|
||||
* @param attraction
|
||||
* @returns The force metrics
|
||||
*/
|
||||
function applyForces(nodes, config, // Force Metrics
|
||||
repulsion, gravity, attraction) {
|
||||
let force, swinging, traction, nodespeed;
|
||||
let totalTension = 0;
|
||||
let totalSwing = 0;
|
||||
let totalTraction = 0;
|
||||
let node;
|
||||
let forceScale; // MATH: sqrt and square distances
|
||||
|
||||
for (node of nodes) {
|
||||
if (!node.fixed) {
|
||||
force = getForce(node);
|
||||
swinging = getSwing(node);
|
||||
traction = getTraction(node); // track global metrics
|
||||
|
||||
totalTension += force;
|
||||
totalSwing += swinging;
|
||||
totalTraction += traction;
|
||||
|
||||
if (config.adjustSizes) {
|
||||
if (force > config.maxForce) {
|
||||
forceScale = config.maxForce / force;
|
||||
node.dx *= forceScale;
|
||||
node.dy *= forceScale;
|
||||
}
|
||||
|
||||
nodespeed = getNodeSpeed(0.1, traction, swinging);
|
||||
} else {
|
||||
nodespeed = getNodeSpeed(node.convergence, traction, swinging); // Updating node convergence
|
||||
|
||||
node.convergence = getNodeConvergence(node, swinging, nodespeed);
|
||||
}
|
||||
|
||||
moveNode(node, nodespeed / config.slowDown);
|
||||
}
|
||||
}
|
||||
|
||||
return [totalTension, totalSwing, totalTraction, repulsion, gravity, attraction];
|
||||
}
|
||||
|
||||
function getNodeConvergence(node, swinging, speed) {
|
||||
return Math.min(1, Math.sqrt(speed * (node.dx ** 2 + node.dy ** 2) / (1 + Math.sqrt(swinging))));
|
||||
}
|
||||
|
||||
function getNodeSpeed(convergence, traction, swinging) {
|
||||
return convergence * Math.log(1 + traction) / (1 + Math.sqrt(swinging));
|
||||
}
|
||||
|
||||
function moveNode(node, factor) {
|
||||
node.x += node.dx * factor;
|
||||
node.y += node.dy * factor;
|
||||
}
|
||||
|
||||
function getSwing(node) {
|
||||
return node.mass * Math.sqrt((node.old_dx - node.dx) ** 2 + (node.old_dy - node.dy) ** 2);
|
||||
}
|
||||
|
||||
function getTraction(node) {
|
||||
return Math.sqrt((node.old_dx + node.dx) ** 2 + (node.old_dy + node.dy) ** 2) / 2;
|
||||
}
|
||||
|
||||
function getForce(node) {
|
||||
return Math.sqrt(node.dx ** 2 + node.dy ** 2);
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.computeAttraction = computeAttraction;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Computes the attraction component of the FA2 algorithm
|
||||
* @param nodes The set of node data
|
||||
* @param edges The set of edge data
|
||||
* @param config The layout configuration
|
||||
* @returns The total scaled distance in the graph
|
||||
*/
|
||||
function computeAttraction(nodes, edges, config) {
|
||||
const coefficient = 1 * (config.outboundAttractionDistribution ? getOutboundAttCompensation(nodes, config) : 1); // TODO: simplify distance
|
||||
// TODO: coefficient is always used as -c --> optimize?
|
||||
|
||||
let edge;
|
||||
let source;
|
||||
let target; // edge weight
|
||||
|
||||
let w; // edge weight influence
|
||||
|
||||
let ewc;
|
||||
let xDist;
|
||||
let yDist;
|
||||
let distance;
|
||||
let factor = 0;
|
||||
let result = 0;
|
||||
|
||||
for (edge of edges) {
|
||||
// Get the edge and nodes on the edge
|
||||
source = nodes.itemAt(edge.sourceIndex);
|
||||
target = nodes.itemAt(edge.targetIndex); // Compute necessary values
|
||||
|
||||
w = edge.weight;
|
||||
ewc = Math.pow(w, config.edgeWeightInfluence);
|
||||
xDist = source.x - target.x;
|
||||
yDist = source.y - target.y; // Applying attraction to nodes
|
||||
|
||||
if (config.adjustSizes) {
|
||||
distance = Math.sqrt(xDist ** 2 + yDist ** 2 - source.size - target.size);
|
||||
|
||||
if (config.linLogMode) {
|
||||
if (config.outboundAttractionDistribution) {
|
||||
//-- LinLog Degree Distributed Anti-collision Attraction
|
||||
if (distance > 0) {
|
||||
factor = -coefficient * ewc * Math.log(1 + distance) / distance / source.mass;
|
||||
}
|
||||
} else {
|
||||
//-- LinLog Anti-collision Attraction
|
||||
if (distance > 0) {
|
||||
factor = -coefficient * ewc * Math.log(1 + distance) / distance;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (config.outboundAttractionDistribution) {
|
||||
//-- Linear Degree Distributed Anti-collision Attraction
|
||||
if (distance > 0) {
|
||||
factor = -coefficient * ewc / source.mass;
|
||||
}
|
||||
} else {
|
||||
//-- Linear Anti-collision Attraction
|
||||
if (distance > 0) {
|
||||
factor = -coefficient * ewc;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
distance = Math.sqrt(xDist ** 2 + yDist ** 2);
|
||||
|
||||
if (config.linLogMode) {
|
||||
if (config.outboundAttractionDistribution) {
|
||||
//-- LinLog Degree Distributed Attraction
|
||||
if (distance > 0) {
|
||||
factor = -coefficient * ewc * Math.log(1 + distance) / distance / source.mass;
|
||||
}
|
||||
} else {
|
||||
//-- LinLog Attraction
|
||||
if (distance > 0) factor = -coefficient * ewc * Math.log(1 + distance) / distance;
|
||||
}
|
||||
} else {
|
||||
if (config.outboundAttractionDistribution) {
|
||||
//-- Linear Attraction Mass Distributed
|
||||
// NOTE: Distance is set to 1 to override next condition
|
||||
distance = 1;
|
||||
factor = -coefficient * ewc / source.mass;
|
||||
} else {
|
||||
//-- Linear Attraction
|
||||
// NOTE: Distance is set to 1 to override next condition
|
||||
distance = 1;
|
||||
factor = -coefficient * ewc;
|
||||
}
|
||||
}
|
||||
} // Updating nodes' dx and dy
|
||||
// TODO: if condition or factor = 1?
|
||||
|
||||
|
||||
if (distance > 0) {
|
||||
// Updating nodes' dx and dy
|
||||
source.dx += xDist * factor;
|
||||
source.dy += yDist * factor;
|
||||
target.dx -= xDist * factor;
|
||||
target.dy -= yDist * factor;
|
||||
result += distance * factor;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function getOutboundAttCompensation(nodes, config) {
|
||||
let outboundAttCompensation = 0; // If outbound attraction distribution, compensate
|
||||
|
||||
if (config.outboundAttractionDistribution) {
|
||||
outboundAttCompensation = 0;
|
||||
let node;
|
||||
|
||||
for (node of nodes) {
|
||||
outboundAttCompensation += node.mass;
|
||||
}
|
||||
|
||||
outboundAttCompensation /= nodes.count;
|
||||
}
|
||||
|
||||
return outboundAttCompensation;
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.computeGravity = computeGravity;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Computes the gravity component of the FA2 algorithm
|
||||
* @param nodes The set of node data
|
||||
* @param config The layout configuration
|
||||
* @returns The total gravity in the system
|
||||
*/
|
||||
function computeGravity(nodes, config) {
|
||||
const g = config.gravity / config.scalingRatio;
|
||||
const coefficient = config.scalingRatio;
|
||||
let node;
|
||||
let distance;
|
||||
let factor;
|
||||
let totalGravity = 0;
|
||||
|
||||
for (node of nodes) {
|
||||
distance = Math.sqrt(node.x ** 2 + node.y ** 2);
|
||||
factor = 0;
|
||||
|
||||
if (config.strongGravityMode) {
|
||||
// strong gravity
|
||||
if (distance > 0) {
|
||||
factor = coefficient * node.mass * g;
|
||||
}
|
||||
} else {
|
||||
// linear anti-collision repulsion
|
||||
if (distance > 0) {
|
||||
factor = coefficient * node.mass * g / distance;
|
||||
}
|
||||
}
|
||||
|
||||
totalGravity += distance * factor; // Updating node's dx and dy
|
||||
|
||||
node.dx -= node.x * factor;
|
||||
node.dy -= node.y * factor;
|
||||
}
|
||||
|
||||
return totalGravity;
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.computeNodeRepulsion = computeNodeRepulsion;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Computes the repulsion between the two given nodes
|
||||
* @param n1 The first node
|
||||
* @param n2 The second node
|
||||
* @returns The amount of repulsion
|
||||
*/
|
||||
function computeNodeRepulsion(n1, n2, config) {
|
||||
const coefficient = config.scalingRatio; // Common to both methods
|
||||
|
||||
const xDist = n1.x - n2.x;
|
||||
const yDist = n1.y - n2.y;
|
||||
const massCoeff = coefficient * n1.mass * n2.mass;
|
||||
let distance = 0;
|
||||
let factor = 0;
|
||||
let xdf;
|
||||
let ydf;
|
||||
|
||||
if (config.adjustSize) {
|
||||
//-- Anticollision Linear Repulsion
|
||||
distance = Math.sqrt(xDist ** 2 + yDist ** 2) - n1.size - n2.size;
|
||||
|
||||
if (distance > 0) {
|
||||
// Updating nodes' dx and dy
|
||||
factor = massCoeff / distance ** 2;
|
||||
xdf = xDist * factor;
|
||||
ydf = yDist * factor;
|
||||
n1.dx += xdf;
|
||||
n1.dy += ydf;
|
||||
n2.dx -= xdf;
|
||||
n2.dy -= ydf;
|
||||
} else if (distance < 0) {
|
||||
// Updating nodes' dx and dy
|
||||
factor = 100 * massCoeff;
|
||||
xdf = xDist * factor;
|
||||
ydf = yDist * factor;
|
||||
n1.dx += xdf;
|
||||
n1.dy += ydf;
|
||||
n2.dx -= xdf;
|
||||
n2.dy -= ydf;
|
||||
} else {
|
||||
console.log('Zero Distance 2');
|
||||
}
|
||||
} else {
|
||||
//-- Linear Repulsion
|
||||
distance = Math.sqrt(xDist ** 2 + yDist ** 2);
|
||||
|
||||
if (distance > 0) {
|
||||
// Updating nodes' dx and dy
|
||||
factor = massCoeff / distance ** 2;
|
||||
xdf = xDist * factor;
|
||||
ydf = yDist * factor;
|
||||
n1.dx += xdf;
|
||||
n1.dy += ydf;
|
||||
n2.dx -= xdf;
|
||||
n2.dy -= ydf;
|
||||
} else {// hit often
|
||||
// console.log("Zero Distance 1")
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.computeRepulsion = computeRepulsion;
|
||||
|
||||
var _computeRepulsionBarnesHut = require("./computeRepulsionBarnesHut");
|
||||
|
||||
var _computeRepulsionUnoptimized = require("./computeRepulsionUnoptimized");
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Computes graph repulsion
|
||||
* @param nodes The set of nodes
|
||||
* @param config The force atlas 2 configuration
|
||||
* @returns The amount of repulsion in the graph
|
||||
*/
|
||||
function computeRepulsion(nodes, config) {
|
||||
return config.barnesHutOptimize ? (0, _computeRepulsionBarnesHut.computeRepulsionBarnesHut)(nodes, config) : (0, _computeRepulsionUnoptimized.computeRepulsionUnoptimized)(nodes, config);
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.computeRepulsionBarnesHut = computeRepulsionBarnesHut;
|
||||
|
||||
var _computeNodeRepulsion = require("./computeNodeRepulsion");
|
||||
|
||||
var _graph = require("@graspologic/graph");
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* Computes repulsion using the Barnes Hut algorithm
|
||||
* @param nodes The set of nodes
|
||||
* @param config The force atlas 2 configuration
|
||||
* @returns The amount of repulsion in the graph
|
||||
*/
|
||||
function computeRepulsionBarnesHut(nodes, config) {
|
||||
const qt = new _graph.QuadTree([...nodes]);
|
||||
let node;
|
||||
let result = 0;
|
||||
|
||||
for (node of nodes) {
|
||||
result += applyQuadTreeRepulsion(qt, node, config);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Applies repulsion to the given node using the quad tree
|
||||
* @param root The root tree
|
||||
* @param n1 The current node
|
||||
* @param config The force atlas 2 configuration
|
||||
*/
|
||||
|
||||
|
||||
function applyQuadTreeRepulsion(root, n1, config) {
|
||||
root.visit(qt => {
|
||||
if (qt.isLeaf) {
|
||||
if (qt.node) {
|
||||
(0, _computeNodeRepulsion.computeNodeRepulsion)(n1, qt.node, config);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const xDist = n1.x - qt.cx;
|
||||
const yDist = n1.y - qt.cy;
|
||||
const distance = Math.sqrt(xDist ** 2 + yDist ** 2);
|
||||
const applyQuadForce = qt.size / distance < config.barnesHutTheta;
|
||||
|
||||
if (applyQuadForce) {
|
||||
const coefficient = config.scalingRatio;
|
||||
const massCoeff = coefficient * n1.mass * qt.mass; //-- Linear Repulsion
|
||||
|
||||
if (distance > 0) {
|
||||
// Updating nodes' dx and dy
|
||||
const factor = massCoeff / distance ** 2;
|
||||
n1.dx += xDist * factor;
|
||||
n1.dy += yDist * factor; // repulsionApplied += distance * factor
|
||||
} else {
|
||||
console.log('Zero Distance 3');
|
||||
}
|
||||
}
|
||||
|
||||
return applyQuadForce;
|
||||
});
|
||||
return 0;
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче