import Head from 'next/head' import React, { useState } from "react"; import fs from 'fs'; import path from 'path'; import { DrawGraph, removeOldSvg } from '../lib/labeledgraph'; import { SliderElement, SubmitSliderButton } from "../lib/slider"; import { DisplayElement } from '../lib/displayElement' import { DisplayAsMarkdown } from '../lib/displayAsMarkdown' import { CreateTableWithDistances } from '../lib/findPaths' import { TextAreaForJson } from "../lib/textAreaForJson" import { pushToMongo } from "./lib/pushToMongo.js" let increasingList = (n) => Array.from(Array(n).keys()) let buildLinks = quantitativeComparisons => quantitativeComparisons.map(([element1, element2, distance]) => ({ source: element1, target: element2, distance: distance })) Array.prototype.containsArray = function (val) { var hash = {}; for (var i = 0; i < this.length; i++) { hash[this[i]] = i; } return hash.hasOwnProperty(val); } let checkIfListIsOrdered = (arr, binaryComparisons) => { let l = arr.length let isOrdered = true for (let i = 0; i < l - 1; i++) { isOrdered = isOrdered && binaryComparisons.containsArray([arr[i], arr[i + 1]]) } return isOrdered } let transformSliderValueToActualValue = value => 10 ** value //>= 2 ? Math.round(10 ** value) : Math.round(10 * 10 ** value) / 10 let truncateValueForDisplay = value => value > 10 ? Math.round(value) : Math.round(value * 10) / 10 let transformSliderValueToPracticalValue = value => truncateValueForDisplay(transformSliderValueToActualValue(value)) let displayFunctionSlider = (value) => { let result if (value >= 0) { result = transformSliderValueToPracticalValue(value) } else { let inverseresult = transformSliderValueToPracticalValue(-value) result = `1/${inverseresult}` } result = `The first option is ${result}x as valuable as the second one` return result }; let nicelyFormatLinks = (quantitativeComparisons, listOfElements) => quantitativeComparisons.map(([element1, element2, distance]) => ({ source: listOfElements[element1].name, target: listOfElements[element2].name, distance: distance })) /* React components */ // fs can only be used here. export async function getStaticProps() { //getServerSideProps // const { metaforecasts } = await getForecasts(); const directory = path.join(process.cwd(), "pages") let listOfMoralGoods = JSON.parse(fs.readFileSync(path.join(directory, 'listOfMoralGoods.json'), 'utf8')); //console.log(directory) //console.log("metaforecasts", metaforecasts) return { props: { listOfElementsDefault: listOfMoralGoods, }, }; } // Main react component export default function Home({ listOfElementsDefault }) { // State let initialListOfElements = listOfElementsDefault.map((element, i) => ({ ...element, id: i })) let initialPosList = increasingList(listOfElementsDefault.length) // [0,1,2,3,4] //let listOfElements = listOfElementsDefault.map((element, i) => ({...element, id: i})) //let list = increasingList(listOfElementsDefault.length) // [0,1,2,3,4] //let initialComparePair = [list[list.length-2], list[list.length-1]] let initialComparePair = [initialPosList[initialPosList.length - 2], initialPosList[initialPosList.length - 1]] let initialSliderValue = 0 let initialBinaryComparisons = [] let initialQuantitativeComparisons = [] let initialIsListOdered = false let initialOrderedList = [] let initialShowAdvancedOptions = false let initialShowComparisons = false let initialShowChangeDataSet = false const [listOfElements, setListOfElements] = useState(initialListOfElements) const [posList, setPosList] = useState(initialPosList) //const posList = initialPosList // let listOfElements = initialListOfElements const [toComparePair, setToComparePair] = useState(initialComparePair) const [sliderValue, setSliderValue] = useState(initialSliderValue) const [binaryComparisons, setBinaryComparisons] = useState(initialBinaryComparisons) const [quantitativeComparisons, setQuantitativeComparisons] = useState(initialQuantitativeComparisons) // More expressive, but more laborious to search through. For the ordering step, I only manipulate the binaryComparisons. const [isListOrdered, setIsListOrdered] = useState(initialIsListOdered) const [orderedList, setOrderedList] = useState(initialOrderedList) let [showAdvancedOptions, changeShowAdvanceOptions] = useState(initialShowAdvancedOptions); let [showComparisons, changeShowComparisons] = useState(initialShowComparisons); let [showChangeDataSet, changeshowChangeDataSet] = useState(initialShowChangeDataSet); let restart = (posList) => { setToComparePair([posList[posList.length - 2], posList[posList.length - 1]]) setSliderValue(initialSliderValue) setBinaryComparisons(initialBinaryComparisons) setQuantitativeComparisons(initialQuantitativeComparisons) setIsListOrdered(initialIsListOdered) setOrderedList(initialOrderedList) removeOldSvg() } let changeDataSet = (listOfElementsNew) => { listOfElementsNew = listOfElementsNew.map((element, i) => ({ ...element, id: i })) let newPosList = increasingList(listOfElementsNew.length) setListOfElements(listOfElementsNew) setPosList(increasingList(listOfElementsNew.length)) setToComparePair([newPosList[newPosList.length - 2], newPosList[newPosList.length - 1]]) restart(newPosList) } // Manipulations let compareTwoElements = (newBinaryComparisons, element1, element2) => { let element1Greater = newBinaryComparisons.containsArray([element1, element2]) let element2Greater = newBinaryComparisons.containsArray([element2, element1]) if (element1Greater || element2Greater) { return element1Greater && !element2Greater } else { setToComparePair([element1, element2]) //console.log(`No comparison found between ${element1} and ${element2}`) //console.log(`Comparisons:`) //console.log(JSON.stringify(newBinaryComparisons, null, 4)); return "No comparison found" } } function merge(newBinaryComparisons, left, right) { let sortedArr = []; // the sorted elements will go here while (left.length && right.length) { // insert the biggest element to the sortedArr let comparison = compareTwoElements(newBinaryComparisons, left[0], right[0]) if (comparison == "No comparison found") { return "No comparison found; unable to proceed" } else if (comparison) { // left[0] > right[0] sortedArr.push(left.shift()); } else { sortedArr.push(right.shift()); } } // use spread operator and create a new array, combining the three arrays return [...sortedArr, ...left, ...right]; // if they don't have the same size, the remaining ones will be greater than the ones before } function mergeSort({ array, comparisons }) { if (array == "No comparison found; unable to proceed") { return "No comparison found; unable to proceed" } const half = array.length / 2; // the base case is array length <=1 if (array.length <= 1) { return array; } const left = array.slice(0, half); // the first half of the array const right = array.slice(half, array.length) // Note that splice is destructive. let orderedFirstHalf = mergeSort({ array: left, comparisons }) let orderedSecondHalf = mergeSort({ array: right, comparisons }) if (orderedFirstHalf != "No comparison found; unable to proceed" && orderedSecondHalf != "No comparison found; unable to proceed") { let result = merge(comparisons, orderedFirstHalf, orderedSecondHalf); return result } else { return "No comparison found; unable to proceed" } } let nextStepSimple = (posList, binaryComparisons, element1, element2) => { //console.log("Binary comparisons: ") //console.log(JSON.stringify(binaryComparisons, null, 4)); let newComparison = [element1, element2] // [element1, element2] let newBinaryComparisons = [...binaryComparisons, newComparison] //console.log("New binaryComparisons: ") //console.log(JSON.stringify(newBinaryComparisons, null, 4)); setBinaryComparisons(newBinaryComparisons) let result = mergeSort({ array: posList, comparisons: newBinaryComparisons }) //console.log(result) if (result != "No comparison found; unable to proceed" && checkIfListIsOrdered(result, newBinaryComparisons)) { // console.log(`isListOrdered: ${isListOrdered}`) console.log("poslist@nextStepSimple") console.log(posList) console.log("result@nextStepSimple") console.log(result) setIsListOrdered(true) setOrderedList(result) return true } else { return false } } let nextStepSlider = ({ posList, binaryComparisons, sliderValue, element1, element2 }) => { if (sliderValue < 0) { sliderValue = -sliderValue; [element1, element2] = [element2, element1] } console.log(`posList@nextStepSlider:`) console.log(posList) let successStatus = nextStepSimple(posList, binaryComparisons, element1, element2) let newQuantitativeComparison = [element1, element2, transformSliderValueToPracticalValue(sliderValue)] let newQuantitativeComparisons = [...quantitativeComparisons, newQuantitativeComparison] setQuantitativeComparisons(newQuantitativeComparisons) setSliderValue(0) if (successStatus) { let jsObject = nicelyFormatLinks(quantitativeComparisons, listOfElements) pushToMongo(jsObject) console.log(jsObject) } } // Html return (
Utility Function Extractor

Utility Function Extractor

nextStep(binaryComparisons, toComparePair[0], toComparePair[1])} >
nextStep(binaryComparisons, toComparePair[1], toComparePair[0])} >
(setSliderValue(event[0]))} value={sliderValue} displayFunction={displayFunctionSlider} />
{/* listOfElements[i]), null, 4)}> */}

Comparisons

{/*

{`Binary comparisons: ${JSON.stringify(binaryComparisons, null, 4)}`}

{`Quantitative comparisons: ${JSON.stringify(quantitativeComparisons, null, 4)}`}

*/}
) }