Всем здравствуйте.
Есть некоторый код:
<script type="text/javascript">
function drawPoly (id, arr) { //id тега <canvas> и массив координат
var canvas = document.getElementById(id).getContext('2d');
// Отрисовка
canvas.clearRect(0,0,500,400);
canvas.beginPath();
clear_all();
for (var i = 0; i < arr.length; i++) {
*!*
canvas.strokeRect(arr[`${i}`].x + 250, arr[`${i}`].y * 10, 5, 5);
console.log("x: " + arr[`${i}`].x + " y: " + arr[`${i}`].y);
*/!*
}
}
function clear_all (){
console.clear();
}
function BinarySearchTree() {
this.root = null;
this.index = 0;
}
BinarySearchTree.prototype.add = function(value) {
var currentNode = this.makeNode(value);
if (!this.root) {
this.root = currentNode;
} else {
this.insert(currentNode);
}
return this;
};
BinarySearchTree.prototype.makeNode = function(value) {
var node = {};
node.value = value;
node.info = {};
node.left = null;
node.right = null;
node.parent = null;
node.depth = 0;
node.drawPoint = {
x: 0,
y: 0
}
node.index = this.index;
this.index += 1;
return node;
};
BinarySearchTree.prototype.insert = function(currentNode) {
var value = currentNode.value;
var traverse = function(node) {
//if value is equal to the value of the node, ignore
//and exit function since we don't want duplicates
if (value === node.value) {
return;
} else if (value > node.value) {
if (!node.right) {
node.right = currentNode;
node.depth++;
return;
} else
traverse(node.right);
} else if (value < node.value) {
if (!node.left) {
node.left = currentNode;
node.depth++;
return;
} else
traverse(node.left);
}
};
traverse(this.root);
};
BinarySearchTree.prototype.setDepth = function() {
var node = this.root;
var maxDepth = 0;
var traverse = function(node, depth) {
if (!node) return null;
if (node) {
maxDepth = depth > maxDepth ? depth : maxDepth;
node.depth = depth;
//set parent too
if (node.right){
(node.right).parent = node;
}
if (node.left){
(node.left).parent = node;
}
traverse(node.left, depth + 1);
traverse(node.right, depth + 1);
}
};
traverse(node, 1);
};
BinarySearchTree.prototype.maxDepth = function() {
var node = this.root;
var maxDepth = 0;
var traverse = function(node) {
if (!node) return null;
if (node) {
maxDepth = node.depth > maxDepth ? node.depth : maxDepth;
traverse(node.left);
traverse(node.right);
}
};
traverse(node, 0);
return maxDepth;
};
BinarySearchTree.prototype.setDrawPoint = function(maxDepth, resizer) {
var node = this.root;
var parentX, coef;
var traverse = function(node, left) {
if (!node) return null;
if (node) {
*!*
parentX = node.parent ? (node.parent).drawPoint.x : 0;
parentX = left ? - parentX : parentX;
coef = left ? -coef : coef;
node.drawPoint.x = parentX + Math.pow(2, maxDepth - node.depth);
node.drawPoint.y = node.depth + resizer;
*/!*
traverse(node.left, true);
traverse(node.right);
}
};
traverse(node);
};
BinarySearchTree.prototype.checkDrawPoint = function() {
var node = this.root;
var drawPoint = {};
var counter = 0;
var traverse = function(node) {
if (!node) return null;
if (node) {
*!*drawPoint[`${node.index}`] = node.drawPoint;*/!*
counter++;
traverse(node.left);
traverse(node.right);
}
};
traverse(node, 0);
drawPoint.length = counter;
return drawPoint;
};
BinarySearchTree.prototype.setInfo = function() {
var node = this.root;
var traverse = function(node) {
if (!node) return null;
if (node) {
node.info = {};
node.info.depth = node.depth;
node.info.index = node.index;
node.info.parent = node.parent;
delete node.parent;
delete node.depth;
delete node.index;
traverse(node.left);
traverse(node.right);
}
};
traverse(node, 0);
};
function BinaryTreeConstructor (num) {
var tree = new BinarySearchTree();
for (let i = 0; i < num; i++) {
tree.add(parseInt((Math.random()*1000).toFixed(1)));
}
tree.setDepth();
*!*tree.setDrawPoint(tree.maxDepth(), 0);*/!*
delete(tree.index);
return tree;
}
function createCoordArray(num) {
var tree = new BinaryTreeConstructor(num);
*!*var coordArray = tree.checkDrawPoint();*/!*
return coordArray;
}
</script>
<form>
<canvas style='border:1px dashed #888;' id='canvasId' width='500' height='400'>
Извините, тег Canvas недоступен!
</canvas>
<br>
<input style="width:auto;" type="button" value="Draw" onclick="drawPoly('canvasId', createCoordArray(document.getElementById('count').value))">
<input style="width:auto;" type="text" value="10" id="count">
</form>
Суть проблемы: при работе функции отрисовки на большом кол-ве элементов вылезает ошибка
Uncaught TypeError: Cannot read property 'x' of undefined
at drawPoly (Отрисовка.html:16)// в текущем документе - 10
at HTMLInputElement.onclick (Отрисовка.html:207)
Почему вылезает - не знаю, замучился уже гадать.
Подскажите, пожалуйста, причину, и способ исправить.
Суть второй проблемы: как правильно менять координаты ветки дерева, чтобы точки друг-друга не перекрывали и линии (которые я добавлю позже) не пересекались?
Мое решение, реализованное в коде, пока не проходит (по логике вещей, второй этаж сверху должен рисоваться симметрично, ну и т.д.).
Спасибо.
P.S. Извините за большую пасту, спойлеров не нашел.