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*/ /* Imports*/
import React from "react"; import React, { useState, useEffect } from 'react';
import { toLocale, truncateValueForDisplay, numToAlphabeticalString, formatLargeOrSmall } from "../lib/utils.js" import { toLocale, truncateValueForDisplay, numToAlphabeticalString, formatLargeOrSmall } from "../lib/utils.js"
/* Utilities */ /* Utilities */
@ -7,14 +7,13 @@ let avg = arr => arr.reduce((a, b) => (a + b), 0) / arr.length
/* Main function */ /* Main function */
function findPathsInner({ async function findPathsInner({
sourceElementId, sourceElementPosition, sourceElementId, sourceElementPosition,
targetElementId, targetElementPosition, targetElementId, targetElementPosition,
links, nodes, links, nodes,
maxLengthOfPath, pathSoFar maxLengthOfPath, pathSoFar
}) { }) {
let paths = [] let paths = []
let minPos = Math.min(sourceElementPosition, targetElementPosition) let minPos = Math.min(sourceElementPosition, targetElementPosition)
let maxPos = Math.max(sourceElementPosition, targetElementPosition) let maxPos = Math.max(sourceElementPosition, targetElementPosition)
let linksInner = links.filter(link => let linksInner = links.filter(link =>
@ -30,7 +29,7 @@ function findPathsInner({
) { ) {
paths.push(pathSoFar.concat(link).flat()) paths.push(pathSoFar.concat(link).flat())
} else if ((link.source == sourceElementId)) { } else if ((link.source == sourceElementId)) {
let newPaths = findPathsInner({ let newPaths = await findPathsInner({
sourceElementId: link.target, sourceElementPosition: link.sourceElementPosition, sourceElementId: link.target, sourceElementPosition: link.sourceElementPosition,
targetElementId, targetElementPosition, targetElementId, targetElementPosition,
pathSoFar: pathSoFar.concat(link).flat(), pathSoFar: pathSoFar.concat(link).flat(),
@ -40,7 +39,7 @@ function findPathsInner({
paths.push(...newPaths) paths.push(...newPaths)
} }
} else if ((link.target == sourceElementId)) { } else if ((link.target == sourceElementId)) {
let newPaths = findPathsInner({ let newPaths = await findPathsInner({
sourceElementId: link.source, sourceElementPosition: link.sourceElementPosition, sourceElementId: link.source, sourceElementPosition: link.sourceElementPosition,
targetElementId, targetElementPosition, targetElementId, targetElementPosition,
pathSoFar: pathSoFar.concat(link).flat(), pathSoFar: pathSoFar.concat(link).flat(),
@ -72,13 +71,13 @@ function findPaths({
} }
*/ */
function findDistance({ async function findDistance({
sourceElementId, sourceElementPosition, sourceElementId, sourceElementPosition,
targetElementId, targetElementPosition, targetElementId, targetElementPosition,
nodes, links, direction nodes, links, direction
}) { }) {
let maxLengthOfPath = Math.abs(sourceElementPosition - targetElementPosition) let maxLengthOfPath = Math.abs(sourceElementPosition - targetElementPosition)
let paths = findPathsInner({ let paths = await findPathsInner({
sourceElementId, sourceElementPosition, sourceElementId, sourceElementPosition,
targetElementId, targetElementPosition, targetElementId, targetElementPosition,
links, nodes, direction, links, nodes, direction,
@ -112,36 +111,7 @@ function findDistance({
//return weights.map(weight => Math.round(weight*100)/100) //return weights.map(weight => Math.round(weight*100)/100)
} }
function getDirectionalLinks({ nodes, links }) { async function findDistancesForAllElements({ 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 }) {
let referenceElements = nodes.filter(x => x.isReferenceValue) let referenceElements = nodes.filter(x => x.isReferenceValue)
let midpoint = Math.round(nodes.length / 2) let midpoint = Math.round(nodes.length / 2)
let referenceElement = referenceElements.length > 0 ? referenceElements[0] : nodes[midpoint] let referenceElement = referenceElements.length > 0 ? referenceElements[0] : nodes[midpoint]
@ -166,6 +136,7 @@ function findDistancesForAllElements({ nodes, links }) {
return distance return distance
} }
}) })
distances = await Promise.all(distances)
return distances return distances
} }
@ -185,60 +156,71 @@ function abridgeArrayAndDisplay(array) {
} }
export function CreateTableWithDistances({ isListOrdered, orderedList, listOfElements, links }) { export function CreateTableWithDistances({ isListOrdered, orderedList, listOfElements, links }) {
if (!isListOrdered || orderedList.length < listOfElements.length) { const [rows, setRows] = useState([])
return (<div>{""}</div>)
} else { useEffect(async () => {
let nodes = [] // https://stackoverflow.com/questions/57847626/using-async-await-inside-a-react-functional-component
let positionDictionary=({}) // https://stackoverflow.com/questions/54936559/using-async-await-in-react-component
orderedList.forEach((id, pos) => { // https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects
nodes.push({ ...listOfElements[id], position: pos }) if (isListOrdered && ! (orderedList.length < listOfElements.length) && rows.length == 0) {
positionDictionary[id] = pos let nodes = []
}) let positionDictionary=({})
// let nodes = orderedList.map((id, pos) => ({ ...listOfElements[id], position: pos })) orderedList.forEach((id, pos) => {
/* Pre-process links to talk in terms of distances */ nodes.push({ ...listOfElements[id], position: pos })
links = links.map(link => ({...link, positionDictionary[id] = pos
sourceElementPosition: positionDictionary[link.source], })
targetElementPosition: positionDictionary[link.target] // let nodes = orderedList.map((id, pos) => ({ ...listOfElements[id], position: pos }))
})) /* Pre-process links to talk in terms of distances */
/* Continue */ links = links.map(link => ({...link,
let distances = findDistancesForAllElements({ nodes, links }) sourceElementPosition: positionDictionary[link.source],
let rows = nodes.map((element, i) => ({ id: numToAlphabeticalString(element.position), position: element.position, name: element.name, distances: distances[i] })) targetElementPosition: positionDictionary[link.target]
console.log("rows@CreateTableWithDistances") }))
console.log(rows)
return ( let distances = await findDistancesForAllElements({ nodes, links })
<div> setRows(nodes.map((element, i) => ({
<table className=""> id: numToAlphabeticalString(element.position),
<thead > position: element.position,
<tr > name: element.name,
<th >Id</th> distances: distances[i]
<th>&nbsp;&nbsp;&nbsp;</th> })))
<th >Position</th> console.log("rows@CreateTableWithDistances")
<th>&nbsp;&nbsp;&nbsp;</th> console.log(rows)
<th >Element</th> }
<th> &nbsp;&nbsp;&nbsp;</th> }); // this useEffect should ideally only work when isListOrdered changes, but I haven't bothered to program that.
<th >Possible relative values</th>
<th> &nbsp;&nbsp;&nbsp;</th> return (
<th >Average relative value</th> <div>
</tr> <table className="">
</thead> <thead>
<tbody> <tr >
{rows.map(row => <tr key={row.id}> <th >Id</th>
<td className="" >{row.id}</td> <th>&nbsp;&nbsp;&nbsp;</th>
<td>&nbsp;&nbsp;&nbsp;</td> <th >Position</th>
<td className="" >{row.position}</td> <th>&nbsp;&nbsp;&nbsp;</th>
<td>&nbsp;&nbsp;&nbsp;</td> <th >Element</th>
<td className="">{row.name}</td> <th> &nbsp;&nbsp;&nbsp;</th>
<td>&nbsp;&nbsp;&nbsp;</td> <th >Possible relative values</th>
<td className="">{abridgeArrayAndDisplay(row.distances)}</td> <th> &nbsp;&nbsp;&nbsp;</th>
<td>&nbsp;&nbsp;&nbsp;</td> <th >Average relative value</th>
<td className="">{formatLargeOrSmall(avg(row.distances))}</td> </tr>
</tr> </thead>
)} <tbody>
</tbody> {rows.map(row => <tr key={row.id}>
</table> <td className="" >{row.id}</td>
</div> <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>
)
} }