Skip to content

Commit

Permalink
Merge pull request #79 from brauliorivas/feat/better-tree-and-list
Browse files Browse the repository at this point in the history
Incorporate suggested changes for tree views and list views
  • Loading branch information
kjvbrt authored Aug 14, 2024
2 parents c46073f + f42bddc commit 9903888
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 33 deletions.
72 changes: 57 additions & 15 deletions js/views/templates/list.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,69 @@
const minHorizontalGapPercentage = 0.3;
const verticalGapPercentage = 0.3;

const bestHorizontalFit = (windowWidth, objectWidth) => {
let columns = 1;
let percentage =
(windowWidth - columns * objectWidth) / (objectWidth * (1 + columns));
let prevPercentage = percentage;

while (percentage >= minHorizontalGapPercentage) {
prevPercentage = percentage;
columns += 1;
percentage =
(windowWidth - columns * objectWidth) / (objectWidth * (1 + columns));
}

return [columns - 1, prevPercentage];
};

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 objHeight = collection[0].height;
const objVerticalGap = gap * objHeight;
const objVerticalGap = parseInt(verticalGapPercentage * objHeight);
const objWidth = collection[0].width;
const [cols, horizontalGapPercentage] = bestHorizontalFit(width, objWidth);
const objHorizontalGap = parseInt(horizontalGapPercentage * objWidth);

const cols = Math.ceil(width / (objWidth + objHorizontalGap));
const rows = Math.ceil(collection.length / cols);
const rows = Math.ceil(length / cols);

const height = rows * (objHeight + objVerticalGap / 2) + objVerticalGap / 2;
const height = rows * (objHeight + objVerticalGap) + objVerticalGap;
const finalHeight = height > window.innerHeight ? height : window.innerHeight;

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;

collection[i].x = x;
collection[i].y = y;
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];
}
84 changes: 66 additions & 18 deletions js/views/templates/tree.js
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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] = [];
}
Expand All @@ -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];
}

0 comments on commit 9903888

Please sign in to comment.