diff --git a/lib/comparisonView.js b/lib/comparisonView.js index 025d302..f6489c4 100644 --- a/lib/comparisonView.js +++ b/lib/comparisonView.js @@ -1,6 +1,3 @@ -/* Definitions */ -const elementsDocument = null// - /* Imports */ import Head from 'next/head' import React, { useState } from "react"; @@ -13,6 +10,9 @@ import { TextAreaForJson } from "./textAreaForJson" import { pushToMongo } from "./pushToMongo.js" import { maxMergeSortSteps, expectedNumMergeSortSteps } from "./utils.js" +/* DEFINTIONS */ +const DEFAULT_COMPARE = 2 // 1, unless you're testing smth. + /* Helpers */ let increasingList = (n) => Array.from(Array(n).keys()) let buildLinks = quantitativeComparisons => quantitativeComparisons.map(([element1, element2, distance, reasoning]) => ({ source: element1, target: element2, distance: distance, reasoning: reasoning })) @@ -76,7 +76,7 @@ export default function ComparisonView({ listOfElementsForView }) { let [showAdvancedOptions, changeShowAdvanceOptions] = useState(initialShowAdvancedOptions); let [showComparisons, changeShowComparisons] = useState(initialShowComparisons); let [showChangeDataSet, changeshowChangeDataSet] = useState(initialShowChangeDataSet); - let [numSteps, increaseNumSteps] = useState(initialNumSteps); + let [numSteps, changeNumSteps] = useState(initialNumSteps); let [maxSteps, changeMaxSteps] = useState(initialMaxSteps) let [expectedSteps, changeExpectedSteps] = useState(initialExpectedSteps) @@ -87,6 +87,7 @@ export default function ComparisonView({ listOfElementsForView }) { setQuantitativeComparisons(initialQuantitativeComparisons) setIsListOrdered(initialIsListOdered) setOrderedList(initialOrderedList) + changeNumSteps(0) removeOldSvg() } @@ -203,9 +204,9 @@ export default function ComparisonView({ listOfElementsForView }) { let newQuantitativeComparisons = [...quantitativeComparisons, newQuantitativeComparison] setQuantitativeComparisons(newQuantitativeComparisons) - setSliderValue(1) + setSliderValue(DEFAULT_COMPARE) setReasoning('') - increaseNumSteps(numSteps + 1) + changeNumSteps(numSteps + 1) if (successStatus) { let jsObject = nicelyFormatLinks(quantitativeComparisons, listOfElements) await pushToMongo(jsObject) diff --git a/lib/findPaths.js b/lib/findPaths.js index 6c8f4c3..1a5f324 100644 --- a/lib/findPaths.js +++ b/lib/findPaths.js @@ -3,72 +3,66 @@ import React from "react"; import { toLocale, truncateValueForDisplay, numToAlphabeticalString, formatLargeOrSmall } from "../lib/utils.js" /* Utilities */ -let avg = arr => arr.reduce((a,b) => (a+b)) / arr.length +let avg = arr => arr.reduce((a, b) => (a + b), 0) / arr.length /* Main function */ -function findPathsInner({sourceElementId, targetElementId, pathSoFar, links, nodes, maxLengthOfPath}){ - // THis has a tendency to produce too much recursion errors - // could be refactored +function findPathsInner({ sourceElementId, targetElementId, pathSoFar, links, nodes, maxLengthOfPath }) { let paths = [] - if(maxLengthOfPath > 0){ - for(let link of links){ - if( - ((link.source == sourceElementId) && (link.target == targetElementId)) || + if (maxLengthOfPath > 0) { + for (let link of links) { + if ( + ((link.source == sourceElementId) && (link.target == targetElementId)) || ((link.source == targetElementId) && (link.target == sourceElementId)) - ){ + ) { paths.push(pathSoFar.concat(link).flat()) - } else if((link.source == sourceElementId)){ - let newPaths = findPathsInner({sourceElementId:link.target, targetElementId, pathSoFar: pathSoFar.concat(link).flat(), links, nodes, maxLengthOfPath: (maxLengthOfPath-1)}) - if(newPaths.length != 0){ + } else if ((link.source == sourceElementId)) { + let newPaths = findPathsInner({ sourceElementId: link.target, targetElementId, pathSoFar: pathSoFar.concat(link).flat(), links, nodes, maxLengthOfPath: (maxLengthOfPath - 1) }) + if (newPaths.length != 0) { paths.push(...newPaths) } - }else if((link.target == sourceElementId)){ - let newPaths = findPathsInner({sourceElementId:link.source, targetElementId, pathSoFar: pathSoFar.concat(link).flat(), links, nodes, maxLengthOfPath: (maxLengthOfPath-1)}) - if(newPaths.length != 0){ + } else if ((link.target == sourceElementId)) { + let newPaths = findPathsInner({ sourceElementId: link.source, targetElementId, pathSoFar: pathSoFar.concat(link).flat(), links, nodes, maxLengthOfPath: (maxLengthOfPath - 1) }) + if (newPaths.length != 0) { paths.push(...newPaths) } } } } - + return paths } -function findPaths({sourceElementId, targetElementId, links, nodes}){ +function findPaths({ sourceElementId, targetElementId, links, nodes }) { let positionSourceElement = nodes.map((element, i) => (element.id)).indexOf(sourceElementId) let positionTargetElement = nodes.map((element, i) => (element.id)).indexOf(targetElementId) let maxLengthOfPath = Math.abs(positionSourceElement - positionTargetElement) - - let paths = [] - try{ - paths = findPathsInner({sourceElementId, targetElementId, pathSoFar: [], links, nodes, maxLengthOfPath}) - }catch(error){ - console.log("Error: probably too much recursion.") - } - return paths + + return findPathsInner({ sourceElementId, targetElementId, pathSoFar: [], links, nodes, maxLengthOfPath }) } -function findDistance({sourceElementId, targetElementId, nodes, links}){ - let paths = findPaths({sourceElementId, targetElementId, nodes, links}) +function findDistance({ sourceElementId, sourceElementPosition, targetElementId, targetElementPosition, nodes, links, direction }) { + let paths = findPaths({ sourceElementId, targetElementId, nodes, links }) + console.log(`findDistance from ${sourceElementPosition} to ${targetElementPosition}`) console.log(targetElementId) + console.log(direction) console.log(paths) let weights = [] - for(let path of paths){ + for (let path of paths) { let currentSource = sourceElementId let weight = 1 - for(let element of path){ + for (let element of path) { let distance = 0 - if(element.source == currentSource){ + if (element.source == currentSource) { distance = element.distance currentSource = element.target - }else if(element.target == currentSource){ - distance = 1/Number(element.distance) + } else if (element.target == currentSource) { + distance = 1 / Number(element.distance) currentSource = element.source } - weight = weight*distance - + weight = weight * distance + } weights.push(weight) } @@ -78,119 +72,161 @@ function findDistance({sourceElementId, targetElementId, nodes, links}){ //return weights.map(weight => Math.round(weight*100)/100) } -function findDistancesForAllElements({nodes, links}){ +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 }) { 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] // console.log(nodes) - let distances = nodes.map(node => - node.isReferenceValue || (node.id == referenceElement.id) ? [1] : findDistance({sourceElementId: referenceElement.id, targetElementId: node.id, nodes, links}) - ) + let [upwardsLinks, downwardsLinks] = getDirectionalLinks({ nodes, links }) + console.log(`referenceElement.position: ${referenceElement.position}`) + let distances = nodes.map(node => { + if (node.isReferenceValue || (node.id == referenceElement.id)) { + return [1] + } else { + console.log("node") + console.log(node) + let isUpwardsDirection = referenceElement.position < node.position; + let distance = findDistance({ + sourceElementId: referenceElement.id, + sourceElementPosition: referenceElement.position, + targetElementId: node.id, + targetElementPosition: node.position, + nodes: nodes, + links: links, // isUpwardsDirection ? upwardsLinks : downwardsLinks, // links + direction: isUpwardsDirection ? "upwards" : "downwards" + }) + return distance + } + }) return distances } -function abridgeArrayAndDisplay(array){ +function abridgeArrayAndDisplay(array) { let newArray let formatForDisplay - if(array.length > 10){ - newArray = array.slice(0,9) - formatForDisplay= newArray.map(d => formatLargeOrSmall(d)) + 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)) + } else { + newArray = array + formatForDisplay = newArray.map(d => formatLargeOrSmall(d)) } let result = JSON.stringify(formatForDisplay, null, 2).replaceAll(`"`, "") return result } -function CreateTableWithDistances({isListOrdered, orderedList, listOfElements, links}){ - // Not used anywhere because it's too resource intensive - // The culprit is findPathsInner, a recursive function which - // has a tendency to produce "Maximum call stack size exceeded" - // or "too much recursion" errors - if(!isListOrdered || orderedList.length < listOfElements.length){ +export function CreateTableWithDistances({ isListOrdered, orderedList, listOfElements, links }) { + if (!isListOrdered || orderedList.length < listOfElements.length) { return (
{""}
) } else { - let nodes = orderedList.map(i => listOfElements[i]) - let distances = findDistancesForAllElements({nodes, links}) - let rows = nodes.map((element, i) => ({id: numToAlphabeticalString(element.id), name: element.name, distances: distances[i]})) + let nodes = orderedList.map((id, pos) => ({ ...listOfElements[id], position: pos })) + 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( + return (
- - - - - - - - - + + + + + + + + + + + - {rows.filter(row => row.distances.length > 0).map(row => - + {rows.map(row => + + + - - )} - 0 ? "hidden": ""}> - "Maximum compute exceeded, rely on the graph instead" - - {} + + )}
Id   Element    Possible relative values    Average relative value
Id   Position   Element    Possible relative values    Average relative value
{row.id}
{row.id}   {row.position}     {row.name}     {abridgeArrayAndDisplay(row.distances)}     {formatLargeOrSmall(avg(row.distances))}
) } - + } - -function CreateTableWithoutDistances({isListOrdered, orderedList, listOfElements, links}){ - if(!isListOrdered || orderedList.length < listOfElements.length){ +function CreateTableWithoutDistances({ isListOrdered, orderedList, listOfElements, links }) { + if (!isListOrdered || orderedList.length < listOfElements.length) { return (
{""}
) } else { let nodes = orderedList.map(i => listOfElements[i]) - let rows = nodes.map((element, i) => ({id: numToAlphabeticalString(element.id), name: element.name})) + let rows = nodes.map((element, i) => ({ id: numToAlphabeticalString(element.id), name: element.name })) console.log("rows@CreateTableWithoutDistances") console.log(rows) - return( + return (
- - - - - - + + + + + + - {rows.map(row => - + {rows.map(row => + - - )} - {} + + )} + { }
Id   Element    
Id   Element    
{row.id}
{row.id}     {row.name}
) } - + } -export const CreateTable = CreateTableWithoutDistances; +export const CreateTable = CreateTableWithDistances // CreateTableWithoutDistances; /* Testing */ //import fs from 'fs'; @@ -203,7 +239,7 @@ let nodes = JSON.parse(fs.readFileSync(path.join(directory, 'listOfPosts.json'), let paths = findPathsInner({sourceElementId:2, targetElementId:0, pathSoFar: [], links, nodes, maxLengthOfPath: 2}) console.log(JSON.stringify(paths, null, 2)) */ -/* +/* let paths = findPaths({sourceElementId:2, targetElementId:0, links, nodes}) console.log(JSON.stringify(paths, null, 2)) */ diff --git a/lib/labeledgraph.js b/lib/labeledgraph.js index dfe0b04..3259dd3 100644 --- a/lib/labeledgraph.js +++ b/lib/labeledgraph.js @@ -67,7 +67,7 @@ function drawGraphInner({ nodes, links }) { .append("text") .attr("x", function (d) { return (x(d.id)) }) .attr("y", height - 10) - .text(function (d) { return numToAlphabeticalString(d.id) }) + .text(function (d) { return numToAlphabeticalString(d.position) }) .style("text-anchor", "middle") // Add the links @@ -119,7 +119,7 @@ function drawGraphInner({ nodes, links }) { }) .text(function (d) { return formatLargeOrSmall(Number(d.distance)) - return (truncateValueForDisplay(Number(d.distance))) + // return (truncateValueForDisplay(Number(d.distance))) //return(Number(d.distance).toPrecision(2).toString()) }) .style("text-anchor", "middle") @@ -127,7 +127,7 @@ function drawGraphInner({ nodes, links }) { export function DrawGraph({ isListOrdered, orderedList, listOfElements, links }) { if (isListOrdered) { - let nodes = orderedList.map(i => listOfElements[i]) + let nodes = orderedList.map((id, pos) => ({ ...listOfElements[id], position: pos })) drawGraphInner({ nodes, links }); } return ( diff --git a/lib/pushToMongo.js b/lib/pushToMongo.js index 6f0424a..7bb7e93 100644 --- a/lib/pushToMongo.js +++ b/lib/pushToMongo.js @@ -1,9 +1,11 @@ import axios from "axios" export async function pushToMongo(data){ + /* let response = await axios.post('http://metaforecast-twitter-bot.herokuapp.com/utility-function-extractor', { data: data }) console.log(response) + */ } // pushToMongo() \ No newline at end of file