strong optimization
This commit is contained in:
parent
a120ba3491
commit
743ac4f653
464
graph.js
464
graph.js
|
@ -681,9 +681,6 @@ class graph {
|
|||
* @param {*} hard Увеличить количество итераций для процесса?
|
||||
*/
|
||||
move(x, y, hard = false) {
|
||||
// console.log(this.element.id, this.pushings && !this.pushings.has(this), this.pullings && !this.pullings.has(this));
|
||||
console.log(this.element.id, this.pushings, this.pullings);
|
||||
|
||||
// Проверка входящих параметров
|
||||
if (typeof x !== 'number') x = this.element.getAttribute('data-x') ?? 0;
|
||||
else {
|
||||
|
@ -793,7 +790,7 @@ class graph {
|
|||
|
||||
collision(nodes, hard = false) {
|
||||
// Проверка на превышение ограничения по числу итераций у целевого узла
|
||||
if (++this.iteration >= this.limit) return this.iteration = 0;
|
||||
if (++this.iteration >= this.limit) return (this.iteration = 0, false);
|
||||
|
||||
// Инициализация буфера реестра узлов
|
||||
const registry = new Set(nodes);
|
||||
|
@ -808,91 +805,141 @@ class graph {
|
|||
// Защита от повторной обработки узла
|
||||
if (typeof this.collisions === 'object' && this.collisions.has(node)) continue;
|
||||
|
||||
// Инициализация вектора между узлами
|
||||
let between;
|
||||
|
||||
// Инициализация ускорения
|
||||
let increase = 0;
|
||||
|
||||
// Инициализация счётчика итераций
|
||||
let iterations = 0;
|
||||
|
||||
// Инициализация универсального буфера
|
||||
let buffer;
|
||||
|
||||
do {
|
||||
// Произошла коллизия (границы кругов перекрылись)
|
||||
// Произошла коллизия (границы кругов пересеклись)
|
||||
|
||||
// Проверка на превышение ограничения по числу итераций у целевого узла
|
||||
if (++this.iteration >= this.limit) return this.iteration = 0;
|
||||
if (++this.iteration >= this.limit) break;
|
||||
|
||||
// Проверка на превышение ограничения по числу итераций у обрабатываемого узла
|
||||
if (++node.iteration >= node.limit) return node.iteration = 0;
|
||||
|
||||
// Инициализация универсального буфера
|
||||
let buffer;
|
||||
if (++node.iteration >= node.limit) break;
|
||||
|
||||
// Инициализация координат целевого узла
|
||||
let x1 =
|
||||
(isNaN((buffer = parseInt(node.element.style.left))) ? 0 : buffer) +
|
||||
node.element.offsetWidth / 2;
|
||||
let y1 =
|
||||
(isNaN((buffer = parseInt(node.element.style.top))) ? 0 : buffer) +
|
||||
node.element.offsetHeight / 2;
|
||||
const x1 = (isNaN((buffer = parseInt(node.element.style.left))) ? 0 : buffer) + node.element.offsetWidth / 2;
|
||||
const y1 = (isNaN((buffer = parseInt(node.element.style.top))) ? 0 : buffer) + node.element.offsetHeight / 2;
|
||||
|
||||
// Инициализация координат обрабатываемого узла
|
||||
let x2 =
|
||||
(isNaN((buffer = parseInt(this.element.style.left))) ? 0 : buffer) +
|
||||
this.element.offsetWidth / 2;
|
||||
let y2 =
|
||||
(isNaN((buffer = parseInt(this.element.style.top))) ? 0 : buffer) +
|
||||
this.element.offsetHeight / 2;
|
||||
const x2 = (isNaN((buffer = parseInt(this.element.style.left))) ? 0 : buffer) + this.element.offsetWidth / 2;
|
||||
const y2 = (isNaN((buffer = parseInt(this.element.style.top))) ? 0 : buffer) + this.element.offsetHeight / 2;
|
||||
|
||||
// Реинициализация вектора между узлами
|
||||
between = new Victor(x1 - x2, y1 - y2);
|
||||
// Инициализация вектора между узлами
|
||||
const between = new Victor(x1 - x2, y1 - y2);
|
||||
|
||||
// Узлы преодолели расстояние столкновения? (ограничение выполнения)
|
||||
if (
|
||||
this.actions.collision.current >= this.actions.collision.max ||
|
||||
between.length() > node.diameter / 2 + this.diameter / 2 ||
|
||||
++iterations > (hard ? this.actions.collision.flow.hard : this.actions.collision.flow.medium)
|
||||
)
|
||||
break;
|
||||
) break;
|
||||
|
||||
// Реинициализация реестра обработанных узлов и запись целевого узла
|
||||
node.collisions = node.#operator.actions.collision ? new Set([this]) : null;
|
||||
|
||||
// Реинициализация счётчиков итераций
|
||||
node.actions.collision.current = 0;
|
||||
|
||||
// Инициализация координат вектора (узла с которым произошло столкновение)
|
||||
let vector = new Victor(x1, y1)
|
||||
.add(new Victor(between.x, between.y).norm().unfloat())
|
||||
.subtract(
|
||||
new Victor(
|
||||
node.element.offsetWidth / 2,
|
||||
node.element.offsetHeight / 2
|
||||
)
|
||||
);
|
||||
.subtract(new Victor(node.element.offsetWidth / 2, node.element.offsetHeight / 2));
|
||||
|
||||
if (this.actions.collision.current < this.actions.collision.max) {
|
||||
// Активно столкновение узлов
|
||||
|
||||
// Реинициализация реестра обработанных узлов и запись целевого узла
|
||||
node.collisions = node.#operator.actions.collision ? new Set([_this]) : null;
|
||||
|
||||
// Реинициализация счётчиков итераций
|
||||
node.actions.collision.current = 0;
|
||||
|
||||
// Запись целевого в реестр обработанных узлов в потоке
|
||||
node.collisions.add(_this);
|
||||
|
||||
// Перемещение узла
|
||||
node.move(vector.x, vector.y);
|
||||
}
|
||||
// Перемещение узла
|
||||
node.move(vector.x, vector.y);
|
||||
|
||||
// Проверка на столкновение узлов
|
||||
} while (
|
||||
this.actions.collision.current < this.actions.collision.max &&
|
||||
++this.actions.collision.current < this.actions.collision.max &&
|
||||
between.length() <= node.diameter / 2 + this.diameter / 2
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pushing(nodes = [], add, hard = false) {
|
||||
/**
|
||||
* Обработать отталкивания
|
||||
*
|
||||
* @param {*} nodes
|
||||
* @param {*} add
|
||||
* @param {*} hard
|
||||
* @param {*} distance
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
pushing(nodes = [], add, hard = false, distance = 100) {
|
||||
// Проверка на превышение ограничения по числу итераций у целевого узла
|
||||
if (++this.iteration >= this.limit) return this.iteration = 0;
|
||||
if (++this.iteration >= this.limit) return (this.iteration = 0, false);
|
||||
|
||||
// Инициализация счётчика итераций
|
||||
let iterations = 0;
|
||||
|
||||
// Инициализация универсального буфера
|
||||
let buffer;
|
||||
|
||||
// Инициализация оператора
|
||||
const operator = this;
|
||||
|
||||
/**
|
||||
* Оттолкнуть
|
||||
*
|
||||
* @param {*} node
|
||||
*
|
||||
* @returns {boolean} Узлы преодолели расстояние отталкивания?
|
||||
*/
|
||||
function move(node) {
|
||||
// Защита от повторной обработки узла
|
||||
if (typeof operator.pushings === 'object' && operator.pushings.has(node)) return false;
|
||||
|
||||
// Проверка на превышение ограничения по числу итераций у целевого узла
|
||||
if (++operator.iteration >= operator.limit) return (operator.iteration = 0, false);
|
||||
|
||||
// Инициализация координат целевого узла
|
||||
const x1 = (isNaN((buffer = parseInt(node.element.style.left))) ? 0 : buffer) + node.element.offsetWidth / 2;
|
||||
const y1 = (isNaN((buffer = parseInt(node.element.style.top))) ? 0 : buffer) + node.element.offsetHeight / 2;
|
||||
|
||||
// Инициализация координат обрабатываемого узла
|
||||
const x2 = (isNaN((buffer = parseInt(operator.element.style.left))) ? 0 : buffer) + operator.element.offsetWidth / 2;
|
||||
const y2 = (isNaN((buffer = parseInt(operator.element.style.top))) ? 0 : buffer) + operator.element.offsetHeight / 2;
|
||||
|
||||
// Инициализация вектора между узлами
|
||||
const between = new Victor(x1 - x2, y1 - y2);
|
||||
|
||||
// Инициализация увеличения
|
||||
const increase =
|
||||
operator.shift + node.shift +
|
||||
(operator.diameter + node.diameter) /
|
||||
2 ** (operator.increase + node.increase);
|
||||
|
||||
// Узлы преодолели расстояние отталкивания?
|
||||
if (
|
||||
between.length() >
|
||||
(node.diameter + operator.diameter) / 2 +
|
||||
distance +
|
||||
increase +
|
||||
(typeof add === 'number' ? add : 0) ||
|
||||
++iterations > (hard ? operator.actions.pushing.flow.hard : operator.actions.pushing.flow.medium)
|
||||
) return true;
|
||||
|
||||
// Реинициализация реестра обработанных узлов и запись целевого узла
|
||||
node.pushings = node.#operator.actions.pushing ? new Set([operator]) : null;
|
||||
|
||||
// Реинициализация счётчиков итераций
|
||||
node.actions.pushing.current = 0;
|
||||
|
||||
// Инициализация координат обрабатываемого узла (с которым произошло столкновение)
|
||||
const vector = new Victor(x1, y1)
|
||||
.add(new Victor(between.x, between.y).norm().unfloat())
|
||||
.subtract(new Victor(node.element.offsetWidth / 2, node.element.offsetHeight / 2));
|
||||
|
||||
// Перемещение узла
|
||||
node.move(vector.x, vector.y);
|
||||
|
||||
// Вход в рекурсию
|
||||
setTimeout(move, between.length() / 100, node);
|
||||
}
|
||||
|
||||
// Инициализация буфера реестра узлов
|
||||
const registry = new Set(nodes);
|
||||
|
@ -900,117 +947,91 @@ class graph {
|
|||
// Удаление текущего узла из буфера
|
||||
registry.delete(this);
|
||||
|
||||
// Инициализация ссылки на ядро
|
||||
const _this = this;
|
||||
|
||||
// Увеличение дистанции для проверки
|
||||
const distance = 100;
|
||||
|
||||
// Обработка отталкивания узлов
|
||||
for (const node of registry) {
|
||||
// Перебор узлов в буфере реестра
|
||||
|
||||
// Защита от повторной обработки узла
|
||||
if (typeof this.pushings === 'object' && this.pushings.has(node)) continue;
|
||||
|
||||
// Инициализация вектора между узлами
|
||||
let between;
|
||||
|
||||
// Инициализация счётчика итераций
|
||||
let iterations = 0;
|
||||
|
||||
function move() {
|
||||
// Проверка на превышение ограничения по числу итераций у целевого узла
|
||||
if (++_this.iteration >= _this.limit) return _this.iteration = 0;
|
||||
|
||||
// Проверка на превышение ограничения по числу итераций у обрабатываемого узла
|
||||
if (++node.iteration >= node.limit) return node.iteration = 0;
|
||||
|
||||
// Инициализация универсального буфера
|
||||
let buffer;
|
||||
|
||||
// Инициализация координат целевого узла
|
||||
let x1 =
|
||||
(isNaN((buffer = parseInt(node.element.style.left))) ? 0 : buffer) +
|
||||
node.element.offsetWidth / 2;
|
||||
let y1 =
|
||||
(isNaN((buffer = parseInt(node.element.style.top))) ? 0 : buffer) +
|
||||
node.element.offsetHeight / 2;
|
||||
|
||||
// Инициализация координат обрабатываемого узла
|
||||
let x2 =
|
||||
(isNaN((buffer = parseInt(_this.element.style.left)))
|
||||
? 0
|
||||
: buffer) +
|
||||
_this.element.offsetWidth / 2;
|
||||
let y2 =
|
||||
(isNaN((buffer = parseInt(_this.element.style.top))) ? 0 : buffer) +
|
||||
_this.element.offsetHeight / 2;
|
||||
|
||||
// Реинициализация вектора между узлами
|
||||
between = new Victor(x1 - x2, y1 - y2);
|
||||
|
||||
// Инициализация увеличения
|
||||
let increase =
|
||||
_this.shift + node.shift +
|
||||
(_this.diameter + node.diameter) /
|
||||
2 ** (_this.increase + node.increase);
|
||||
|
||||
// Узлы преодолели расстояние отталкивания?
|
||||
if (
|
||||
_this.actions.pushing.current >= _this.actions.pushing.max ||
|
||||
between.length() >
|
||||
(node.diameter + _this.diameter) / 2 +
|
||||
distance +
|
||||
increase +
|
||||
(typeof add === 'number' ? add : 0) ||
|
||||
++iterations > (hard ? _this.actions.pushing.flow.hard : _this.actions.pushing.flow.medium)
|
||||
)
|
||||
return;
|
||||
|
||||
// Инициализация координат вектора (узла с которым произошло столкновение)
|
||||
let vector = new Victor(x1, y1)
|
||||
.add(new Victor(between.x, between.y).norm().unfloat())
|
||||
.subtract(
|
||||
new Victor(
|
||||
node.element.offsetWidth / 2,
|
||||
node.element.offsetHeight / 2
|
||||
)
|
||||
);
|
||||
|
||||
if (_this.actions.pushing.current < _this.actions.pushing.max) {
|
||||
// Активно притягивание узла
|
||||
|
||||
// Реинициализация реестра обработанных узлов и запись целевого узла
|
||||
node.pushings = node.#operator.actions.pushing ? new Set([_this]) : null;
|
||||
|
||||
// Реинициализация счётчиков итераций
|
||||
node.actions.pushing.current = 0;
|
||||
|
||||
// Перемещение узла
|
||||
node.move(vector.x, vector.y);
|
||||
}
|
||||
|
||||
// Проверка расстояния
|
||||
if (
|
||||
_this.actions.pushing.current < _this.actions.pushing.max &&
|
||||
between.length() <=
|
||||
(node.diameter + _this.diameter) / 2 +
|
||||
distance +
|
||||
increase +
|
||||
(typeof add === 'number' ? add : 0)
|
||||
)
|
||||
return setTimeout(move, between.length() / 100);
|
||||
}
|
||||
|
||||
// Повторная обработка (вход в рекурсию)
|
||||
if (_this.actions.pushing.current < _this.actions.pushing.max) move();
|
||||
}
|
||||
// Обработка отталкивания
|
||||
for (const node of registry) if (++this.actions.pushing.current < this.actions.pushing.max) move(node);
|
||||
}
|
||||
|
||||
pulling(nodes = [], add, hard = false) {
|
||||
/**
|
||||
* Обработать притягивания
|
||||
*
|
||||
* @param {*} nodes
|
||||
* @param {*} add
|
||||
* @param {*} hard
|
||||
* @param {*} distance
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
pulling(nodes = [], add, hard = false, distance = 150) {
|
||||
// Проверка на превышение ограничения по числу итераций у целевого узла
|
||||
if (++this.iteration >= this.limit) return this.iteration = 0;
|
||||
if (++this.iteration >= this.limit) return (this.iteration = 0, false);
|
||||
|
||||
// Инициализация счётчика итераций
|
||||
let iterations = 0;
|
||||
|
||||
// Инициализация универсального буфера
|
||||
let buffer;
|
||||
|
||||
// Инициализация ссылки на ядро
|
||||
const operator = this;
|
||||
|
||||
/**
|
||||
* Притянуть
|
||||
*
|
||||
* @param {*} node
|
||||
*
|
||||
* @returns {boolean} Узлы преодолели расстояние отталкивания?
|
||||
*/
|
||||
function move(node) {
|
||||
// Защита от повторной обработки узла
|
||||
if (typeof operator.pullings === 'object' && operator.pullings.has(node)) return false;
|
||||
|
||||
// Проверка на превышение ограничения по числу итераций у целевого узла
|
||||
if (++operator.iteration >= operator.limit) return (operator.iteration = 0, false);
|
||||
|
||||
// Инициализация координат целевого узла
|
||||
const x1 = (isNaN((buffer = parseInt(node.element.style.left))) ? 0 : buffer) + node.element.offsetWidth / 2;
|
||||
const y1 = (isNaN((buffer = parseInt(node.element.style.top))) ? 0 : buffer) + node.element.offsetHeight / 2;
|
||||
|
||||
// Инициализация координат обрабатываемого узла
|
||||
const x2 = (isNaN((buffer = parseInt(operator.element.style.left))) ? 0 : buffer) + operator.element.offsetWidth / 2;
|
||||
const y2 = (isNaN((buffer = parseInt(operator.element.style.top))) ? 0 : buffer) + operator.element.offsetHeight / 2;
|
||||
|
||||
// Инициализация вектора между узлами
|
||||
const between = new Victor(x1 - x2, y1 - y2);
|
||||
|
||||
// Инициализация увеличения
|
||||
const increase =
|
||||
operator.shift + node.shift +
|
||||
(operator.diameter + node.diameter) /
|
||||
2 ** (operator.increase + node.increase);
|
||||
|
||||
// Узлы преодолели расстояние притягивания?
|
||||
if (
|
||||
between.length() <=
|
||||
(node.diameter + operator.diameter) / 2 +
|
||||
distance +
|
||||
increase +
|
||||
(typeof add === 'number' ? add : 0) ||
|
||||
++iterations > (hard ? operator.actions.pulling.flow.hard : operator.actions.pulling.flow.medium)
|
||||
) return true;
|
||||
|
||||
// Реинициализация реестра обработанных узлов и запись целевого узла
|
||||
node.pullings = node.#operator.actions.pulling ? new Set([operator]) : null;
|
||||
|
||||
// Реинициализация счётчиков итераций
|
||||
node.actions.pulling.current = 0;
|
||||
|
||||
// Инициализация координат обрабатываемого узла (с которым произошло столкновение)
|
||||
const vector = new Victor(x1, y1)
|
||||
.add(new Victor(between.x, between.y).norm().invert().unfloat())
|
||||
.subtract(new Victor(node.element.offsetWidth / 2, node.element.offsetHeight / 2));
|
||||
|
||||
// Перемещение узла
|
||||
node.move(vector.x, vector.y);
|
||||
|
||||
// Вход в рекурсию
|
||||
setTimeout(move, between.length() / 10 - between.length() / 10, node);
|
||||
}
|
||||
|
||||
// Инициализация буфера реестра узлов
|
||||
const registry = new Set(nodes);
|
||||
|
@ -1018,115 +1039,8 @@ class graph {
|
|||
// Удаление текущего узла из буфера
|
||||
registry.delete(this);
|
||||
|
||||
// Инициализация ссылки на ядро
|
||||
const _this = this;
|
||||
|
||||
// Увеличение дистанции для проверки !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
const distance = 150;
|
||||
|
||||
// Обработка притягивания узлов
|
||||
for (const node of registry) {
|
||||
// Перебор узлов в буфере реестра
|
||||
|
||||
// Защита от повторной обработки узла
|
||||
if (typeof this.pullings === 'object' && this.pullings.has(node)) continue;
|
||||
|
||||
// Инициализация вектора между узлами
|
||||
let between;
|
||||
|
||||
// Инициализация счётчика итераций
|
||||
let iterations = 0;
|
||||
|
||||
function move() {
|
||||
// Проверка на превышение ограничения по числу итераций у целевого узла
|
||||
if (++_this.iteration >= _this.limit) return _this.iteration = 0;
|
||||
|
||||
// Проверка на превышение ограничения по числу итераций у обрабатываемого узла
|
||||
if (++node.iteration >= node.limit) return node.iteration = 0;
|
||||
|
||||
// Инициализация универсального буфера
|
||||
let buffer;
|
||||
|
||||
// Инициализация координат целевого узла
|
||||
let x1 =
|
||||
(isNaN((buffer = parseInt(node.element.style.left))) ? 0 : buffer) +
|
||||
node.element.offsetWidth / 2;
|
||||
let y1 =
|
||||
(isNaN((buffer = parseInt(node.element.style.top))) ? 0 : buffer) +
|
||||
node.element.offsetHeight / 2;
|
||||
|
||||
// Инициализация координат обрабатываемого узла
|
||||
let x2 =
|
||||
(isNaN((buffer = parseInt(_this.element.style.left)))
|
||||
? 0
|
||||
: buffer) +
|
||||
_this.element.offsetWidth / 2;
|
||||
let y2 =
|
||||
(isNaN((buffer = parseInt(_this.element.style.top))) ? 0 : buffer) +
|
||||
_this.element.offsetHeight / 2;
|
||||
|
||||
// Реинициализация вектора между узлами
|
||||
between = new Victor(x1 - x2, y1 - y2);
|
||||
|
||||
// Инициализация увеличения
|
||||
let increase =
|
||||
_this.shift + node.shift +
|
||||
(_this.diameter + node.diameter) /
|
||||
2 ** (_this.increase + node.increase);
|
||||
|
||||
// Узлы преодолели расстояние притягивания?
|
||||
if (
|
||||
_this.actions.pulling.current >= _this.actions.pulling.max ||
|
||||
between.length() <=
|
||||
(node.diameter + _this.diameter) / 2 +
|
||||
distance +
|
||||
increase +
|
||||
(typeof add === 'number' ? add : 0) ||
|
||||
++iterations > (hard ? _this.actions.pulling.flow.hard : _this.actions.pulling.flow.medium)
|
||||
)
|
||||
return;
|
||||
|
||||
// Инициализация координат вектора (узла с которым произошло столкновение)
|
||||
let vector = new Victor(x1, y1)
|
||||
.add(new Victor(between.x, between.y).norm().invert().unfloat())
|
||||
.subtract(
|
||||
new Victor(
|
||||
node.element.offsetWidth / 2,
|
||||
node.element.offsetHeight / 2
|
||||
)
|
||||
);
|
||||
|
||||
if (_this.actions.pulling.current < _this.actions.pulling.max) {
|
||||
// Активно притягивание узлов
|
||||
|
||||
// Реинициализация реестра обработанных узлов и запись целевого узла
|
||||
node.pullings = node.#operator.actions.pulling ? new Set([_this]) : null;
|
||||
|
||||
// Реинициализация счётчиков итераций
|
||||
node.actions.pulling.current = 0;
|
||||
|
||||
// Перемещение узла
|
||||
node.move(vector.x, vector.y);
|
||||
}
|
||||
|
||||
// Проверка расстояния
|
||||
if (
|
||||
_this.actions.pulling.current < _this.actions.pulling.max &&
|
||||
between.length() >
|
||||
(node.diameter + _this.diameter) / 2 +
|
||||
distance +
|
||||
increase +
|
||||
(typeof add === 'number' ? add : 0)
|
||||
)
|
||||
return setTimeout(
|
||||
move,
|
||||
between.length() / 10 - between.length() / 10
|
||||
);
|
||||
}
|
||||
|
||||
// Повторная обработка (вход в рекурсию)
|
||||
if (_this.actions.pulling.current < _this.actions.pulling.max) move();
|
||||
}
|
||||
// Обработка отталкивания
|
||||
for (const node of registry) if (++this.actions.pulling.current < this.actions.pulling.max) move(node);
|
||||
}
|
||||
|
||||
configure(attribute) {
|
||||
|
@ -1562,4 +1476,4 @@ document.dispatchEvent(
|
|||
new CustomEvent('graph.loaded', {
|
||||
detail: { graph }
|
||||
})
|
||||
);
|
||||
);
|
Loading…
Reference in New Issue