tweak: Asynchronous refactoring
This commit is contained in:
parent
b99aa05318
commit
ed59faafe1
164
lib/findPaths.js
164
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 (<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> </th>
|
||||
<th >Position</th>
|
||||
<th> </th>
|
||||
<th >Element</th>
|
||||
<th> </th>
|
||||
<th >Possible relative values</th>
|
||||
<th> </th>
|
||||
<th >Average relative value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map(row => <tr key={row.id}>
|
||||
<td className="" >{row.id}</td>
|
||||
<td> </td>
|
||||
<td className="" >{row.position}</td>
|
||||
<td> </td>
|
||||
<td className="">{row.name}</td>
|
||||
<td> </td>
|
||||
<td className="">{abridgeArrayAndDisplay(row.distances)}</td>
|
||||
<td> </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> </th>
|
||||
<th >Position</th>
|
||||
<th> </th>
|
||||
<th >Element</th>
|
||||
<th> </th>
|
||||
<th >Possible relative values</th>
|
||||
<th> </th>
|
||||
<th >Average relative value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows.map(row => <tr key={row.id}>
|
||||
<td className="" >{row.id}</td>
|
||||
<td> </td>
|
||||
<td className="" >{row.position}</td>
|
||||
<td> </td>
|
||||
<td className="">{row.name}</td>
|
||||
<td> </td>
|
||||
<td className="">{abridgeArrayAndDisplay(row.distances)}</td>
|
||||
<td> </td>
|
||||
<td className="">{formatLargeOrSmall(avg(row.distances))}</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user