From cbbfc6c8025c22b9dcf866a6e9adee05f0a3632a Mon Sep 17 00:00:00 2001 From: Braulio Rivas Abad Date: Sat, 10 Aug 2024 19:05:06 -0500 Subject: [PATCH] incorporate suggested changes for tree views and list views --- js/views/templates/list.js | 61 ++++++++++++++++++++------- js/views/templates/tree.js | 84 ++++++++++++++++++++++++++++++-------- 2 files changed, 113 insertions(+), 32 deletions(-) diff --git a/js/views/templates/list.js b/js/views/templates/list.js index caef9ab2..01d741cd 100644 --- a/js/views/templates/list.js +++ b/js/views/templates/list.js @@ -1,27 +1,60 @@ +const horizontalGapPercentage = 0.4; +const verticalGapPercentage = 0.3; + export function listView(collection) { const width = window.innerWidth; + const length = collection.length; - const gap = 1; const objWidth = collection[0].width; - const objHorizontalGap = gap * objWidth; + const objHorizontalGap = parseInt(horizontalGapPercentage * objWidth); const objHeight = collection[0].height; - const objVerticalGap = gap * objHeight; + const objVerticalGap = parseInt(verticalGapPercentage * objHeight); - const cols = Math.ceil(width / (objWidth + objHorizontalGap)); - const rows = Math.ceil(collection.length / cols); + let cols = (width - objHorizontalGap) / (objWidth + objHorizontalGap); + const decimal = cols % 1; - const height = rows * (objHeight + objVerticalGap / 2) + objVerticalGap / 2; - const finalHeight = height > window.innerHeight ? height : window.innerHeight; + if (decimal >= 0.5) { + cols = cols + 1; + } + cols = Math.floor(cols); - for (let i = 0; i < collection.length; i++) { - const x = (i % cols) * objWidth + (((i % cols) + 1) * objHorizontalGap) / 2; - const y = - Math.floor(i / cols) * objHeight + - ((Math.floor(i / cols) + 1) * objVerticalGap) / 2; + const rows = Math.ceil(length / cols); - collection[i].x = x; - collection[i].y = y; + const height = rows * (objHeight + objVerticalGap) + objVerticalGap; + const finalHeight = height > window.innerHeight ? height : window.innerHeight; + + const allX = []; + for (let i = 1; i <= cols; i++) { + allX.push(i * objHorizontalGap + (i - 1) * objWidth); } + const maxLength = rows * cols; + const halfCols = Math.ceil(cols / 2); + + collection.forEach((object, index) => { + const numElement = index + 1; + + const objRow = Math.ceil(numElement / cols); + let objCol; + const res = numElement % cols; + if (res === 0) { + objCol = cols; + } else { + objCol = res; + } + + const rowLength = + maxLength - numElement >= cols ? cols : length - cols * (rows - 1); + const halfCol = Math.ceil(rowLength / 2); + + const allXIndex = halfCols - (halfCol - objCol); + + const x = allX[allXIndex - 1]; + const y = objRow * objVerticalGap + (objRow - 1) * objHeight; + + object.x = x; + object.y = y; + }); + return [width, finalHeight]; } diff --git a/js/views/templates/tree.js b/js/views/templates/tree.js index 40a57d75..16275be2 100644 --- a/js/views/templates/tree.js +++ b/js/views/templates/tree.js @@ -1,28 +1,68 @@ +import { listView } from "./list.js"; + // All particles that are related to itself have an one to many relation export function buildTree(collection, relationOfReference) { + collection.forEach((object) => { + object.row = null; + }); + const nodes = new Set(); const children = new Set(); + const childless = new Set(); for (const object of collection) { - const objects = object.oneToManyRelations[relationOfReference].map( + const childObjects = object.oneToManyRelations[relationOfReference].map( (link) => link.to ); - nodes.add(`${object.index}-${object.collectionId}`); - for (const childObject of objects) { + const objectId = `${object.index}-${object.collectionId}`; + nodes.add(objectId); + + if (childObjects.length === 0) { + childless.add(objectId); + } + + for (const childObject of childObjects) { children.add(`${childObject.index}-${childObject.collectionId}`); } } const rootNodesIds = nodes.difference(children); - const rootNodes = []; + const childlessRootNodesIds = rootNodesIds.intersection(childless); + const rootNodesWithChildrenIds = rootNodesIds.difference( + childlessRootNodesIds + ); + const rootNodesWithChildren = []; + const childlessRootNodes = []; collection.forEach((object) => { - if (rootNodesIds.has(`${object.index}-${object.collectionId}`)) { - rootNodes.push(object); + const objectId = `${object.index}-${object.collectionId}`; + if (rootNodesWithChildrenIds.has(objectId)) { + rootNodesWithChildren.push(object); + } + if (childlessRootNodesIds.has(objectId)) { + childlessRootNodes.push(object); } }); - rootNodes.forEach((rootNode) => { + const horizontalGap = collection[0].width * 0.4; + const verticalGap = collection[0].height * 0.3; + const boxWidth = collection[0].width; + const boxHeight = collection[0].height; + + const [_, listHeight] = listView(childlessRootNodes); + + let cols = (window.innerWidth - horizontalGap) / (boxWidth + horizontalGap); + const decimal = cols % 1; + + if (decimal >= 0.5) { + cols = cols + 1; + } + cols = Math.floor(cols); + + const rows = Math.ceil(childlessRootNodes.length / cols); + const startingRow = rows; + + rootNodesWithChildren.forEach((rootNode) => { const stack = [[rootNode, 0]]; while (stack.length > 0) { @@ -41,15 +81,15 @@ export function buildTree(collection, relationOfReference) { } }); - const horizontalGap = collection[0].width * 0.4; - const verticalGap = collection[0].height * 0.3; - const boxWidth = collection[0].width; - const boxHeight = collection[0].height; - const matrix = []; collection.forEach((object) => { const row = object.row; + + if (row === null) { + return; + } + if (matrix[row] === undefined) { matrix[row] = []; } @@ -58,21 +98,29 @@ export function buildTree(collection, relationOfReference) { matrix.forEach((row, i) => { row.forEach((object, j) => { - object.x = j * horizontalGap + j * boxWidth + horizontalGap; - object.y = i * verticalGap + i * boxHeight + verticalGap; + const row = i + startingRow; + const col = j; + object.x = col * horizontalGap + col * boxWidth + horizontalGap; + object.y = row * verticalGap + row * boxHeight + verticalGap; }); }); - const totalWidth = - boxWidth * matrix[0].length + horizontalGap * (matrix[0].length + 1); + let maxWidth = 0; + matrix.forEach((row) => { + const rowLength = row.length; + if (rowLength > maxWidth) { + maxWidth = rowLength; + } + }); + + const totalWidth = boxWidth * maxWidth + horizontalGap * (maxWidth + 1); const width = totalWidth > window.innerWidth ? totalWidth : window.innerWidth; const totalHeight = boxHeight * (matrix.length + 1) + verticalGap * (matrix.length + 2); - const height = totalHeight > window.innerHeight ? totalHeight : window.innerHeight; - return [width, height]; + return [width, height + listHeight]; }