tweak: Asynchronous refactoring

This commit is contained in:
NunoSempere 2021-12-08 00:44:55 +01:00
parent b99aa05318
commit ed59faafe1

View File

@ -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 (<div>{""}</div>)
} 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 (
<div>
<table className="">
<thead >
<tr >
<th >Id</th>
<th>&nbsp;&nbsp;&nbsp;</th>
<th >Position</th>
<th>&nbsp;&nbsp;&nbsp;</th>
<th >Element</th>
<th> &nbsp;&nbsp;&nbsp;</th>
<th >Possible relative values</th>
<th> &nbsp;&nbsp;&nbsp;</th>
<th >Average relative value</th>
</tr>
</thead>
<tbody>
{rows.map(row => <tr key={row.id}>
<td className="" >{row.id}</td>
<td>&nbsp;&nbsp;&nbsp;</td>
<td className="" >{row.position}</td>
<td>&nbsp;&nbsp;&nbsp;</td>
<td className="">{row.name}</td>
<td>&nbsp;&nbsp;&nbsp;</td>
<td className="">{abridgeArrayAndDisplay(row.distances)}</td>
<td>&nbsp;&nbsp;&nbsp;</td>
<td className="">{formatLargeOrSmall(avg(row.distances))}</td>
</tr>
)}
</tbody>
</table>
</div>
)
}
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 (
<div>
<table className="">
<thead>
<tr >
<th >Id</th>
<th>&nbsp;&nbsp;&nbsp;</th>
<th >Position</th>
<th>&nbsp;&nbsp;&nbsp;</th>
<th >Element</th>
<th> &nbsp;&nbsp;&nbsp;</th>
<th >Possible relative values</th>
<th> &nbsp;&nbsp;&nbsp;</th>
<th >Average relative value</th>
</tr>
</thead>
<tbody>
{rows.map(row => <tr key={row.id}>
<td className="" >{row.id}</td>
<td>&nbsp;&nbsp;&nbsp;</td>
<td className="" >{row.position}</td>
<td>&nbsp;&nbsp;&nbsp;</td>
<td className="">{row.name}</td>
<td>&nbsp;&nbsp;&nbsp;</td>
<td className="">{abridgeArrayAndDisplay(row.distances)}</td>
<td>&nbsp;&nbsp;&nbsp;</td>
<td className="">{formatLargeOrSmall(avg(row.distances))}</td>
</tr>
)}
</tbody>
</table>
</div>
)
}