chore: Refactored and added comments
This commit is contained in:
parent
3d6a544a72
commit
849a09207e
|
@ -1,7 +1,7 @@
|
||||||
/* Imports */
|
/* Imports */
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { DrawGraph, removeOldSvg } from './labeledgraph';
|
import { DrawGraph, removeOldSvg } from './labeledGraph';
|
||||||
import { SubmitSliderButton } from "./slider";
|
import { SubmitSliderButton } from "./slider";
|
||||||
import { DisplayElement } from './displayElement'
|
import { DisplayElement } from './displayElement'
|
||||||
import { DisplayAsMarkdown } from './displayAsMarkdown'
|
import { DisplayAsMarkdown } from './displayAsMarkdown'
|
||||||
|
|
387
lib/findPaths.js
387
lib/findPaths.js
|
@ -1,49 +1,55 @@
|
||||||
/* Imports*/
|
/* Imports*/
|
||||||
import React, { useState, useEffect } from 'react';
|
import React from 'react';
|
||||||
import { toLocale, truncateValueForDisplay, numToAlphabeticalString, formatLargeOrSmall } from "../lib/utils.js"
|
import { numToAlphabeticalString, formatLargeOrSmall, avg } from "../lib/utils.js"
|
||||||
|
|
||||||
/* Utilities */
|
/* Functions */
|
||||||
let avg = arr => arr.reduce((a, b) => (a + b), 0) / arr.length
|
|
||||||
|
|
||||||
/* Main function */
|
const pathPlusLink = (pathSoFar, link) => {
|
||||||
|
return [...pathSoFar, link]
|
||||||
|
// previously: pathSoFar.concat(link).flat()
|
||||||
|
// Note that concat is not destructive
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
|
||||||
|
}
|
||||||
|
|
||||||
async function findPathsInner({
|
async function findPathsWithoutPrunning({
|
||||||
sourceElementId, sourceElementPosition,
|
sourceElementId, targetElementId,
|
||||||
targetElementId, targetElementPosition,
|
maxLengthOfPath, pathSoFar,
|
||||||
links, nodes,
|
links, nodes
|
||||||
maxLengthOfPath, pathSoFar
|
|
||||||
}) {
|
}) {
|
||||||
|
// This is an un-used function which might make findPaths more understandable
|
||||||
|
// It uses the same recursive functionality
|
||||||
|
// but has no path prunning
|
||||||
let paths = []
|
let paths = []
|
||||||
let minPos = Math.min(sourceElementPosition, targetElementPosition)
|
|
||||||
let maxPos = Math.max(sourceElementPosition, targetElementPosition)
|
/* Path traversing */
|
||||||
let linksInner = links.filter(link =>
|
|
||||||
(minPos <= link.sourceElementPosition && link.sourceElementPosition <= maxPos) &&
|
|
||||||
(minPos <= link.targetElementPosition && link.targetElementPosition <= maxPos)
|
|
||||||
)
|
|
||||||
let linksNow = linksInner.filter(link => (link.source == sourceElementId || link.target == sourceElementId))
|
|
||||||
if (maxLengthOfPath > 0) {
|
if (maxLengthOfPath > 0) {
|
||||||
for (let link of linksNow) {
|
for (let link of links) { // vs let link of linksNow in findPaths
|
||||||
if (
|
if (
|
||||||
((link.source == sourceElementId) && (link.target == targetElementId)) ||
|
((link.source == sourceElementId) && (link.target == targetElementId)) ||
|
||||||
((link.source == targetElementId) && (link.target == sourceElementId))
|
((link.source == targetElementId) && (link.target == sourceElementId))
|
||||||
) {
|
) { // direct Path
|
||||||
paths.push(pathSoFar.concat(link).flat())
|
let newPath = pathPlusLink(pathSoFar, link)
|
||||||
|
paths.push(newPath)
|
||||||
} else if ((link.source == sourceElementId)) {
|
} else if ((link.source == sourceElementId)) {
|
||||||
let newPaths = await findPathsInner({
|
let newPaths = await findPaths({
|
||||||
sourceElementId: link.target, sourceElementPosition: link.sourceElementPosition,
|
pathSoFar: pathPlusLink(pathSoFar, link),
|
||||||
targetElementId, targetElementPosition,
|
maxLengthOfPath: (maxLengthOfPath - 1),
|
||||||
pathSoFar: pathSoFar.concat(link).flat(),
|
sourceElementId: link.target,
|
||||||
links: linksInner, nodes, maxLengthOfPath: (maxLengthOfPath - 1)
|
targetElementId,
|
||||||
|
links: links, // vs let link of linksInner in findPaths
|
||||||
|
nodes
|
||||||
})
|
})
|
||||||
if (newPaths.length != 0) {
|
if (newPaths.length != 0) {
|
||||||
paths.push(...newPaths)
|
paths.push(...newPaths)
|
||||||
}
|
}
|
||||||
} else if ((link.target == sourceElementId)) {
|
} else if ((link.target == sourceElementId)) {
|
||||||
let newPaths = await findPathsInner({
|
let newPaths = await findPaths({
|
||||||
sourceElementId: link.source, sourceElementPosition: link.sourceElementPosition,
|
pathSoFar: pathPlusLink(pathSoFar, link),
|
||||||
targetElementId, targetElementPosition,
|
maxLengthOfPath: (maxLengthOfPath - 1),
|
||||||
pathSoFar: pathSoFar.concat(link).flat(),
|
sourceElementId: link.source,
|
||||||
links: linksInner, nodes, maxLengthOfPath: (maxLengthOfPath - 1)
|
targetElementId,
|
||||||
|
links: links, // vs let link of linksInner in findPaths
|
||||||
|
nodes
|
||||||
})
|
})
|
||||||
if (newPaths.length != 0) {
|
if (newPaths.length != 0) {
|
||||||
paths.push(...newPaths)
|
paths.push(...newPaths)
|
||||||
|
@ -54,40 +60,93 @@ async function findPathsInner({
|
||||||
|
|
||||||
return paths
|
return paths
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
function findPaths({
|
async function findPaths({
|
||||||
sourceElementId, sourceElementPosition,
|
sourceElementId, sourceElementPosition,
|
||||||
targetElementId, targetElementPosition,
|
targetElementId, targetElementPosition,
|
||||||
nodes, links, direction
|
maxLengthOfPath, pathSoFar,
|
||||||
|
links, nodes
|
||||||
}) {
|
}) {
|
||||||
let positionSourceElement = nodes.map((element, i) => (element.id)).indexOf(sourceElementId)
|
// This is the key path finding function
|
||||||
let positionTargetElement = nodes.map((element, i) => (element.id)).indexOf(targetElementId)
|
// It finds the path from one element to another, recursively
|
||||||
let maxLengthOfPath = Math.abs(positionSourceElement - positionTargetElement)
|
// It used to be very computationally expensive until I added
|
||||||
return findPathsInner({
|
// the path prunning step: Instead of traversing all links,
|
||||||
sourceElementId, sourceElementPosition,
|
// traverse only those which are between the origin and target links
|
||||||
targetElementId, targetElementPosition,
|
// this requires us to have a notion of "between"
|
||||||
links, nodes, direction,
|
|
||||||
maxLengthOfPath, pathSoFar: []
|
let paths = []
|
||||||
})
|
|
||||||
|
/* Path prunning*/
|
||||||
|
let minPos = Math.min(sourceElementPosition, targetElementPosition)
|
||||||
|
let maxPos = Math.max(sourceElementPosition, targetElementPosition)
|
||||||
|
let linksInner = links.filter(link =>
|
||||||
|
(minPos <= link.sourceElementPosition && link.sourceElementPosition <= maxPos) &&
|
||||||
|
(minPos <= link.targetElementPosition && link.targetElementPosition <= maxPos)
|
||||||
|
)
|
||||||
|
let linksNow = linksInner.filter(link => (link.source == sourceElementId || link.target == sourceElementId))
|
||||||
|
|
||||||
|
/* Path traversing */
|
||||||
|
if (maxLengthOfPath > 0) {
|
||||||
|
for (let link of linksNow) {
|
||||||
|
if (
|
||||||
|
((link.source == sourceElementId) && (link.target == targetElementId)) ||
|
||||||
|
((link.source == targetElementId) && (link.target == sourceElementId))
|
||||||
|
) { // direct Path
|
||||||
|
let newPath = pathPlusLink(pathSoFar, link)
|
||||||
|
paths.push(newPath)
|
||||||
|
} else if ((link.source == sourceElementId)) {
|
||||||
|
let newPaths = await findPaths({
|
||||||
|
pathSoFar: pathPlusLink(pathSoFar, link),
|
||||||
|
maxLengthOfPath: (maxLengthOfPath - 1),
|
||||||
|
sourceElementPosition: link.sourceElementPosition,
|
||||||
|
sourceElementId: link.target,
|
||||||
|
targetElementId, targetElementPosition,
|
||||||
|
links: linksInner,
|
||||||
|
nodes
|
||||||
|
})
|
||||||
|
if (newPaths.length != 0) {
|
||||||
|
paths.push(...newPaths)
|
||||||
|
}
|
||||||
|
} else if ((link.target == sourceElementId)) {
|
||||||
|
let newPaths = await findPaths({
|
||||||
|
pathSoFar: pathPlusLink(pathSoFar, link),
|
||||||
|
maxLengthOfPath: (maxLengthOfPath - 1),
|
||||||
|
sourceElementPosition: link.sourceElementPosition,
|
||||||
|
sourceElementId: link.source,
|
||||||
|
targetElementPosition,
|
||||||
|
targetElementId,
|
||||||
|
links: linksInner,
|
||||||
|
nodes
|
||||||
|
})
|
||||||
|
if (newPaths.length != 0) {
|
||||||
|
paths.push(...newPaths)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
async function findDistance({
|
async function findDistance({
|
||||||
sourceElementId, sourceElementPosition,
|
sourceElementId, sourceElementPosition,
|
||||||
targetElementId, targetElementPosition,
|
targetElementId, targetElementPosition,
|
||||||
nodes, links, direction
|
nodes, links
|
||||||
}) {
|
}) {
|
||||||
|
// This function gets all possible paths using findPaths
|
||||||
|
// then orders them correctly in the for loop
|
||||||
|
// (by flipping the distance to 1/distance when necessary)
|
||||||
|
// and then gets the array of weights for the different paths.
|
||||||
|
console.log(`findDistance@findPaths.js from ${sourceElementPosition} to ${targetElementPosition}`)
|
||||||
|
|
||||||
let maxLengthOfPath = Math.abs(sourceElementPosition - targetElementPosition)
|
let maxLengthOfPath = Math.abs(sourceElementPosition - targetElementPosition)
|
||||||
let paths = await findPathsInner({
|
let paths = await findPaths({
|
||||||
sourceElementId, sourceElementPosition,
|
sourceElementId, sourceElementPosition,
|
||||||
targetElementId, targetElementPosition,
|
targetElementId, targetElementPosition,
|
||||||
links, nodes, direction,
|
links, nodes,
|
||||||
maxLengthOfPath, pathSoFar: []
|
maxLengthOfPath, pathSoFar: []
|
||||||
});
|
});
|
||||||
console.log(`findDistance from ${sourceElementPosition} to ${targetElementPosition}`)
|
|
||||||
console.log(targetElementId)
|
|
||||||
console.log(direction)
|
|
||||||
console.log(paths)
|
|
||||||
let weights = []
|
let weights = []
|
||||||
for (let path of paths) {
|
for (let path of paths) {
|
||||||
let currentSource = sourceElementId
|
let currentSource = sourceElementId
|
||||||
|
@ -106,25 +165,26 @@ async function findDistance({
|
||||||
}
|
}
|
||||||
weights.push(weight)
|
weights.push(weight)
|
||||||
}
|
}
|
||||||
//let sum = JSON.stringify(weights)//weights.length > 0 ? weights.reduce((a,b) => (a+b)) / weights.length : "Not found"
|
|
||||||
//return sum
|
|
||||||
return weights
|
return weights
|
||||||
//return weights.map(weight => Math.round(weight*100)/100)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function findDistancesForAllElements({ nodes, links }) {
|
async function findDistancesForAllElements({ nodes, links }) {
|
||||||
|
// Simple wrapper function around findDistance
|
||||||
|
// Needs to find the reference point first
|
||||||
|
console.log("findDistancesForAllElements@findPaths.js")
|
||||||
|
/* Get or build reference element */
|
||||||
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]
|
||||||
// console.log(nodes)
|
|
||||||
console.log(`referenceElement.position: ${referenceElement.position}`)
|
console.log(`referenceElement.position: ${referenceElement.position}`)
|
||||||
|
|
||||||
|
/* Get distances. */
|
||||||
let distances = nodes.map(node => {
|
let distances = nodes.map(node => {
|
||||||
if (node.isReferenceValue || (node.id == referenceElement.id)) {
|
if (node.isReferenceValue || (node.id == referenceElement.id)) {
|
||||||
return [1]
|
return [1]
|
||||||
} else {
|
} else {
|
||||||
console.log("node")
|
console.log("node")
|
||||||
console.log(node)
|
console.log(node)
|
||||||
let isUpwardsDirection = referenceElement.position < node.position
|
|
||||||
let distance = findDistance({
|
let distance = findDistance({
|
||||||
sourceElementId: referenceElement.id,
|
sourceElementId: referenceElement.id,
|
||||||
sourceElementPosition: referenceElement.position,
|
sourceElementPosition: referenceElement.position,
|
||||||
|
@ -132,7 +192,6 @@ async function findDistancesForAllElements({ nodes, links }) {
|
||||||
targetElementPosition: node.position,
|
targetElementPosition: node.position,
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
links: links,
|
links: links,
|
||||||
direction: isUpwardsDirection ? "upwards" : "downwards"
|
|
||||||
})
|
})
|
||||||
return distance
|
return distance
|
||||||
}
|
}
|
||||||
|
@ -141,23 +200,11 @@ async function findDistancesForAllElements({ nodes, links }) {
|
||||||
return distances
|
return distances
|
||||||
}
|
}
|
||||||
|
|
||||||
function abridgeArrayAndDisplay(array) {
|
|
||||||
let newArray
|
|
||||||
let formatForDisplay
|
|
||||||
if (array.length > 10) {
|
|
||||||
newArray = array.slice(0, 9)
|
|
||||||
formatForDisplay = newArray.map(d => formatLargeOrSmall(d))
|
|
||||||
formatForDisplay[9] = "..."
|
|
||||||
} else {
|
|
||||||
newArray = array
|
|
||||||
formatForDisplay = newArray.map(d => formatLargeOrSmall(d))
|
|
||||||
}
|
|
||||||
let result = JSON.stringify(formatForDisplay, null, 2).replaceAll(`"`, "")
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function buildRows({ isListOrdered, orderedList, listOfElements, links, rows, setTableRows }) {
|
export async function buildRows({ isListOrdered, orderedList, listOfElements, links, rows, setTableRows }) {
|
||||||
// Not used yet.
|
console.log("buildRows@findPaths.js")
|
||||||
|
// This function is used in pages/comparisonView.js to create the rows that will be displayed.
|
||||||
|
// it is in there because it needs to be deployed after isListOrdered becomes true,
|
||||||
|
// and using an useEffect inside CreateTable was too messy.
|
||||||
if (isListOrdered && !(orderedList.length < listOfElements.length) && rows.length == 0) {
|
if (isListOrdered && !(orderedList.length < listOfElements.length) && rows.length == 0) {
|
||||||
let nodes = []
|
let nodes = []
|
||||||
let positionDictionary = ({})
|
let positionDictionary = ({})
|
||||||
|
@ -165,8 +212,6 @@ export async function buildRows({ isListOrdered, orderedList, listOfElements, li
|
||||||
nodes.push({ ...listOfElements[id], position: pos })
|
nodes.push({ ...listOfElements[id], position: pos })
|
||||||
positionDictionary[id] = 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 => ({
|
links = links.map(link => ({
|
||||||
...link,
|
...link,
|
||||||
sourceElementPosition: positionDictionary[link.source],
|
sourceElementPosition: positionDictionary[link.source],
|
||||||
|
@ -180,161 +225,63 @@ export async function buildRows({ isListOrdered, orderedList, listOfElements, li
|
||||||
name: element.name,
|
name: element.name,
|
||||||
distances: distances[i]
|
distances: distances[i]
|
||||||
}))
|
}))
|
||||||
console.log("rows@CreateTableWithDistances")
|
|
||||||
console.log(rows)
|
console.log(rows)
|
||||||
setTableRows(rows)
|
setTableRows(rows)
|
||||||
} else {
|
|
||||||
// rows = []
|
|
||||||
// Do nothing
|
|
||||||
}
|
}
|
||||||
// return rows
|
|
||||||
}
|
}
|
||||||
export function CreateTableWithDistancesWithUseEffect({ isListOrdered, orderedList, listOfElements, links, tableRows, setTableRows }) {
|
|
||||||
|
|
||||||
useEffect(async () => {
|
export function CreateTable({ tableRows }) {
|
||||||
await buildRows({ isListOrdered, orderedList, listOfElements, links, rows: tableRows, setTableRows })
|
/* This function receives a list of rows, and displays them nicely. */
|
||||||
/*
|
function abridgeArrayAndDisplay(array) {
|
||||||
// https://stackoverflow.com/questions/57847626/using-async-await-inside-a-react-functional-component
|
let newArray
|
||||||
// https://stackoverflow.com/questions/54936559/using-async-await-in-react-component
|
let formatForDisplay
|
||||||
// https://reactjs.org/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects
|
if (array.length > 10) {
|
||||||
if (isListOrdered && ! (orderedList.length < listOfElements.length) && rows.length == 0) {
|
newArray = array.slice(0, 9)
|
||||||
let nodes = []
|
formatForDisplay = newArray.map(d => formatLargeOrSmall(d))
|
||||||
let positionDictionary=({})
|
formatForDisplay[9] = "..."
|
||||||
orderedList.forEach((id, pos) => {
|
} else {
|
||||||
nodes.push({ ...listOfElements[id], position: pos })
|
newArray = array
|
||||||
positionDictionary[id] = pos
|
formatForDisplay = newArray.map(d => formatLargeOrSmall(d))
|
||||||
})
|
|
||||||
// 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)
|
|
||||||
}
|
}
|
||||||
*/
|
let result = JSON.stringify(formatForDisplay, null, 2).replaceAll(`"`, "")
|
||||||
}); // this useEffect should ideally only work when isListOrdered changes, but I haven't bothered to program that.
|
return result
|
||||||
|
|
||||||
|
|
||||||
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>
|
|
||||||
{tableRows.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>
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export function CreateTableWithDistances({ tableRows }) {
|
|
||||||
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>
|
|
||||||
{tableRows.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>
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function CreateTableWithoutDistances({ isListOrdered, orderedList, listOfElements, links }) {
|
|
||||||
if (!isListOrdered || orderedList.length < listOfElements.length) {
|
|
||||||
return (<div>{""}</div>)
|
|
||||||
} else {
|
|
||||||
let nodes = orderedList.map(i => listOfElements[i])
|
|
||||||
let rows = nodes.map((element, i) => ({ id: numToAlphabeticalString(element.id), name: element.name }))
|
|
||||||
console.log("rows@CreateTableWithoutDistances")
|
|
||||||
console.log(rows)
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<table className="">
|
|
||||||
<thead >
|
|
||||||
<tr >
|
|
||||||
<th >Id</th>
|
|
||||||
<th> </th>
|
|
||||||
<th >Element</th>
|
|
||||||
<th> </th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{rows.map(row => <tr key={row.id}>
|
|
||||||
<td className="" >{row.id}</td>
|
|
||||||
<td> </td>
|
|
||||||
<td className="">{row.name}</td>
|
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
{ }
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
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>
|
||||||
|
{tableRows.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>
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CreateTable = CreateTableWithDistances // CreateTableWithoutDistances;
|
|
||||||
|
|
||||||
/* Testing */
|
/* Testing */
|
||||||
//import fs from 'fs';
|
//import fs from 'fs';
|
||||||
//import path from 'path';
|
//import path from 'path';
|
||||||
|
@ -343,7 +290,7 @@ const directory = path.join(process.cwd(),"pages")
|
||||||
let links = JSON.parse(fs.readFileSync(path.join(directory, 'distancesExample.json'), 'utf8'));
|
let links = JSON.parse(fs.readFileSync(path.join(directory, 'distancesExample.json'), 'utf8'));
|
||||||
let nodes = JSON.parse(fs.readFileSync(path.join(directory, 'listOfPosts.json'), 'utf8'));
|
let nodes = JSON.parse(fs.readFileSync(path.join(directory, 'listOfPosts.json'), 'utf8'));
|
||||||
|
|
||||||
let paths = findPathsInner({sourceElementId:2, targetElementId:0, pathSoFar: [], links, nodes, maxLengthOfPath: 2})
|
let paths = findPaths({sourceElementId:2, targetElementId:0, pathSoFar: [], links, nodes, maxLengthOfPath: 2})
|
||||||
console.log(JSON.stringify(paths, null, 2))
|
console.log(JSON.stringify(paths, null, 2))
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import * as d3 from 'd3';
|
import * as d3 from 'd3';
|
||||||
import { toLocale, truncateValueForDisplay, numToAlphabeticalString, formatLargeOrSmall } from "../lib/utils.js"
|
import { toLocale, truncateValueForDisplay, numToAlphabeticalString, formatLargeOrSmall } from "./utils.js"
|
||||||
|
|
||||||
let getlength = (number) => number.toString().length;
|
let getlength = (number) => number.toString().length;
|
||||||
|
|
|
@ -68,3 +68,5 @@ export function expectedNumMergeSortSteps(n) {
|
||||||
return Math.ceil((n ** 2) / (n + 2)) + expectedNumMergeSortSteps(Math.ceil(n / 2))
|
return Math.ceil((n ** 2) / (n + 2)) + expectedNumMergeSortSteps(Math.ceil(n / 2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const avg = arr => arr.reduce((a, b) => (a + b), 0) / arr.length
|
||||||
|
|
Loading…
Reference in New Issue
Block a user