From ed59faafe1cabb01abdd29df173337acfa8fc5b4 Mon Sep 17 00:00:00 2001 From: NunoSempere Date: Wed, 8 Dec 2021 00:44:55 +0100 Subject: [PATCH] tweak: Asynchronous refactoring --- lib/findPaths.js | 164 +++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 91 deletions(-) diff --git a/lib/findPaths.js b/lib/findPaths.js index a29dafc..05c32aa 100644 --- a/lib/findPaths.js +++ b/lib/findPaths.js @@ -1,5 +1,5 @@ /* Imports*/ -import React from "react"; +import React, { useState, useEffect } from 'react'; import { toLocale, truncateValueForDisplay, numToAlphabeticalString, formatLargeOrSmall } from "../lib/utils.js" /* Utilities */ @@ -7,14 +7,13 @@ let avg = arr => arr.reduce((a, b) => (a + b), 0) / arr.length /* Main function */ -function findPathsInner({ +async function findPathsInner({ sourceElementId, sourceElementPosition, targetElementId, targetElementPosition, links, nodes, maxLengthOfPath, pathSoFar }) { let paths = [] - let minPos = Math.min(sourceElementPosition, targetElementPosition) let maxPos = Math.max(sourceElementPosition, targetElementPosition) let linksInner = links.filter(link => @@ -30,7 +29,7 @@ function findPathsInner({ ) { paths.push(pathSoFar.concat(link).flat()) } else if ((link.source == sourceElementId)) { - let newPaths = findPathsInner({ + let newPaths = await findPathsInner({ sourceElementId: link.target, sourceElementPosition: link.sourceElementPosition, targetElementId, targetElementPosition, pathSoFar: pathSoFar.concat(link).flat(), @@ -40,7 +39,7 @@ function findPathsInner({ paths.push(...newPaths) } } else if ((link.target == sourceElementId)) { - let newPaths = findPathsInner({ + let newPaths = await findPathsInner({ sourceElementId: link.source, sourceElementPosition: link.sourceElementPosition, targetElementId, targetElementPosition, pathSoFar: pathSoFar.concat(link).flat(), @@ -72,13 +71,13 @@ function findPaths({ } */ -function findDistance({ +async function findDistance({ sourceElementId, sourceElementPosition, targetElementId, targetElementPosition, nodes, links, direction }) { let maxLengthOfPath = Math.abs(sourceElementPosition - targetElementPosition) - let paths = findPathsInner({ + let paths = await findPathsInner({ sourceElementId, sourceElementPosition, targetElementId, targetElementPosition, links, nodes, direction, @@ -112,36 +111,7 @@ function findDistance({ //return weights.map(weight => Math.round(weight*100)/100) } -function getDirectionalLinks({ nodes, links }) { - console.log("getDirectionalLinks") - // direction: 1 for upwards, -1 for downwards - let upwardsLinks = [] - let downwardsLinks = [] - links.forEach(link => { - console.log(link) - let sourceElementId = link.source - let targetElementId = link.target - if (link.distance < 1) { - // We already deal with this case upstream, but whatever. - [sourceElementId, targetElementId] = [targetElementId, sourceElementId] - } - let sourceElementPosition = nodes.find(element => element.id == sourceElementId).position - let targetElementPosition = nodes.find(element => element.id == targetElementId).position - if (link.distance == 1) { - // If two elements are the same, then they belong to both upwards and downwards paths!! - upwardsLinks.push(link) - downwardsLinks.push(link) - } else if (sourceElementPosition < targetElementPosition) { - upwardsLinks.push(link) - } else { - downwardsLinks.push(link) - } - }) - console.log([upwardsLinks, downwardsLinks]) - return [upwardsLinks, downwardsLinks] -} - -function findDistancesForAllElements({ nodes, links }) { +async function findDistancesForAllElements({ nodes, links }) { let referenceElements = nodes.filter(x => x.isReferenceValue) let midpoint = Math.round(nodes.length / 2) let referenceElement = referenceElements.length > 0 ? referenceElements[0] : nodes[midpoint] @@ -166,6 +136,7 @@ function findDistancesForAllElements({ nodes, links }) { return distance } }) + distances = await Promise.all(distances) return distances } @@ -185,60 +156,71 @@ function abridgeArrayAndDisplay(array) { } export function CreateTableWithDistances({ isListOrdered, orderedList, listOfElements, links }) { - if (!isListOrdered || orderedList.length < listOfElements.length) { - return (
{""}
) - } else { - let nodes = [] - let positionDictionary=({}) - orderedList.forEach((id, pos) => { - nodes.push({ ...listOfElements[id], position: pos }) - positionDictionary[id] = pos - }) - // let nodes = orderedList.map((id, pos) => ({ ...listOfElements[id], position: pos })) - /* Pre-process links to talk in terms of distances */ - links = links.map(link => ({...link, - sourceElementPosition: positionDictionary[link.source], - targetElementPosition: positionDictionary[link.target] - })) - /* Continue */ - let distances = findDistancesForAllElements({ nodes, links }) - let rows = nodes.map((element, i) => ({ id: numToAlphabeticalString(element.position), position: element.position, name: element.name, distances: distances[i] })) - console.log("rows@CreateTableWithDistances") - console.log(rows) - return ( -
- - - - - - - - - - - - - - - - {rows.map(row => - - - - - - - - - - - )} - -
Id   Position   Element    Possible relative values    Average relative value
{row.id}   {row.position}   {row.name}   {abridgeArrayAndDisplay(row.distances)}   {formatLargeOrSmall(avg(row.distances))}
-
- ) - } + const [rows, setRows] = useState([]) + + useEffect(async () => { + // https://stackoverflow.com/questions/57847626/using-async-await-inside-a-react-functional-component + // https://stackoverflow.com/questions/54936559/using-async-await-in-react-component + // https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects + if (isListOrdered && ! (orderedList.length < listOfElements.length) && rows.length == 0) { + let nodes = [] + let positionDictionary=({}) + orderedList.forEach((id, pos) => { + nodes.push({ ...listOfElements[id], position: pos }) + positionDictionary[id] = pos + }) + // let nodes = orderedList.map((id, pos) => ({ ...listOfElements[id], position: pos })) + /* Pre-process links to talk in terms of distances */ + links = links.map(link => ({...link, + sourceElementPosition: positionDictionary[link.source], + targetElementPosition: positionDictionary[link.target] + })) + + let distances = await findDistancesForAllElements({ nodes, links }) + setRows(nodes.map((element, i) => ({ + id: numToAlphabeticalString(element.position), + position: element.position, + name: element.name, + distances: distances[i] + }))) + console.log("rows@CreateTableWithDistances") + console.log(rows) + } + }); // this useEffect should ideally only work when isListOrdered changes, but I haven't bothered to program that. + + return ( +
+ + + + + + + + + + + + + + + + {rows.map(row => + + + + + + + + + + + )} + +
Id   Position   Element    Possible relative values    Average relative value
{row.id}   {row.position}   {row.name}   {abridgeArrayAndDisplay(row.distances)}   {formatLargeOrSmall(avg(row.distances))}
+
+ ) }