diff --git "a/lib/\\" "b/lib/\\"
deleted file mode 100644
index 11c5eb8..0000000
--- "a/lib/\\"
+++ /dev/null
@@ -1,583 +0,0 @@
-/* Imports */
-import Head from "next/head";
-import React, { useState } from "react";
-import { DrawGraph, removeOldSvg } from "./labeledGraph";
-import { SubmitSliderButton } from "./slider";
-import { DisplayElement } from "./displayElement";
-import { DisplayAsMarkdown } from "./displayAsMarkdown";
-import { CreateTable, buildRows } from "./findPaths";
-import { DataSetChanger } from "./datasetChanger";
-import { ComparisonsChanger } from "./comparisonsChanger";
-import { pushToMongo } from "./pushToMongo.js";
-import {
- increasingList,
- maxMergeSortSteps,
- expectedNumMergeSortSteps,
- conservativeNumMergeSortSteps,
-} from "./utils.js";
-
-/* DEFINTIONS */
-const DEFAULT_COMPARE = () => 1; // 1/Math.random() - 1
-
-/* Misc. helpers */
-let buildLinks = (quantitativeComparisons) =>
- quantitativeComparisons.map(([element1, element2, distance, reasoning]) => ({
- source: element1,
- target: element2,
- distance: distance,
- reasoning: reasoning,
- }));
-
-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 nicelyFormatLinks = (quantitativeComparisons, listOfElements) =>
- quantitativeComparisons.map(([element1, element2, distance, reasoning]) => ({
- source: listOfElements[element1].name,
- target: listOfElements[element2].name,
- distance: distance,
- reasoning: reasoning,
- }));
-
-// Main react component
-export default function ComparisonView({ listOfElementsForView }) {
- /* State */
- // initial state values
- let initialListOfElements = listOfElementsForView.map((element, i) => ({
- ...element,
- id: i,
- }));
- let initialPosList = increasingList(listOfElementsForView.length); // [0,1,2,3,4]
- let initialComparePair = [
- initialPosList[initialPosList.length - 2],
- initialPosList[initialPosList.length - 1],
- ];
- let initialSliderValue = 1;
- let initialReasoning = "";
- let initialBinaryComparisons = [];
- let initialQuantitativeComparisons = [];
- let initialIsListOdered = false;
- let initialOrderedList = [];
- let initialShowAdvancedOptions = false;
- let initialShowComparisons = false;
- let initialShowLoadComparisons = false;
- let initialShowChangeDataSet = false;
- let initialNumSteps = 0;
- let initialMaxSteps = maxMergeSortSteps(listOfElementsForView.length);
- let initialExpectedSteps = expectedNumMergeSortSteps(
- listOfElementsForView.length
- );
- let initialTableRows = [];
- let initialDontPushSubmitButtonAnyMore = false;
-
- // state variables and functions
- const [listOfElements, setListOfElements] = useState(initialListOfElements);
- const [posList, setPosList] = useState(initialPosList);
- const [toComparePair, setToComparePair] = useState(initialComparePair);
- const [sliderValue, setSliderValue] = useState(initialSliderValue);
- const [reasoning, setReasoning] = useState(initialReasoning);
- 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);
- const [dontPushSubmitButtonAnyMore, setDontPushSubmitButtonAnyMore] =
- useState(initialDontPushSubmitButtonAnyMore);
-
- let [showAdvancedOptions, changeShowAdvanceOptions] = useState(
- initialShowAdvancedOptions
- );
- let [showComparisons, changeShowComparisons] = useState(
- initialShowComparisons
- );
- let [showLoadComparisons, changeShowLoadComparisons] = useState(
- initialShowLoadComparisons
- );
- let [showChangeDataSet, changeshowChangeDataSet] = useState(
- initialShowChangeDataSet
- );
- let [numSteps, changeNumSteps] = useState(initialNumSteps);
- let [maxSteps, changeMaxSteps] = useState(initialMaxSteps);
- let [expectedSteps, changeExpectedSteps] = useState(initialExpectedSteps);
- let [tableRows, setTableRows] = useState(initialTableRows);
-
- /* Convenience utils: restart + changeDataSet */
- let restart = (
- posList,
- initialBinaryComparisons2,
- initialQuantitativeComparisons2
- ) => {
- //({posList, initialBinaryComparisons2, initialQuantitativeComparisons2}) => {
- setToComparePair([
- posList[posList.length - 2],
- posList[posList.length - 1],
- ]);
- setSliderValue(initialSliderValue);
- setBinaryComparisons(initialBinaryComparisons2 || initialBinaryComparisons);
- setQuantitativeComparisons(
- initialQuantitativeComparisons2 || initialQuantitativeComparisons
- );
- setIsListOrdered(initialIsListOdered);
- setOrderedList(initialOrderedList);
- changeNumSteps(initialNumSteps);
- removeOldSvg();
- setTableRows(initialTableRows);
- setDontPushSubmitButtonAnyMore(initialDontPushSubmitButtonAnyMore);
- };
-
- let changeDataSet = (listOfElementsNew) => {
- listOfElementsNew = listOfElementsNew.map((element, i) => ({
- ...element,
- id: i,
- }));
- let newPosList = increasingList(listOfElementsNew.length);
- let newListLength = listOfElementsNew.length;
-
- setListOfElements(listOfElementsNew);
- setPosList(increasingList(listOfElementsNew.length));
- setToComparePair([
- newPosList[newPosList.length - 2],
- newPosList[newPosList.length - 1],
- ]);
-
- changeExpectedSteps(expectedNumMergeSortSteps(newListLength));
- changeMaxSteps(maxMergeSortSteps(newListLength));
-
- restart(newPosList);
- // restart({posList: newPosList})
- };
-
- let changeComparisons = async (links) => {
- let quantitativeComparisons2 = [];
- let binaryComparisons2 = [];
- links.shift();
- for (let link of links) {
- let { source, target, distance, reasoning } = link;
- let searchByName = (name, candidate) => candidate.name == name;
- let testForSource = (candidate) => searchByName(source, candidate);
- let testForTarget = (candidate) => searchByName(target, candidate);
- let element1 = listOfElements.findIndex(testForSource);
- let element2 = listOfElements.findIndex(testForTarget);
- if (element1 == -1 || element2 == -1) {
- console.log("link", link);
- console.log(source);
- console.log(target);
- throw new Error("Comparisons include unknown elements, please retry");
- }
- quantitativeComparisons2.push([element1, element2, distance, reasoning]);
- binaryComparisons2.push([element1, element2]);
- }
- // return ({quantitativeComparisons: quantitativeComparisons2, binaryComparisons: binaryComparisons2})
- //restart({posList, initialBinaryComparisons2=initialBinaryComparisons, initialQuantitativeComparisons2=initialQuantitativeComparisons})
- // restart(posList, binaryComparisons2, quantitativeComparisons2)
- setQuantitativeComparisons(quantitativeComparisons2);
- setBinaryComparisons(binaryComparisons2);
- };
-
- // 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);
-
- return [true, result];
- } else {
- return [false, result];
- }
- };
-
- let nextStepSlider = async ({
- posList,
- binaryComparisons,
- sliderValue,
- reasoning,
- element1,
- element2,
- }) => {
- if (!dontPushSubmitButtonAnyMore) {
- if (sliderValue < 1 && sliderValue > 0) {
- sliderValue = 1 / sliderValue;
- [element1, element2] = [element2, element1];
- }
- console.log(`posList@nextStepSlider:`);
- console.log(posList);
- let [successStatus, result] = nextStepSimple(
- posList,
- binaryComparisons,
- element1,
- element2
- );
-
- let newQuantitativeComparison = [
- element1,
- element2,
- sliderValue,
- reasoning,
- ];
- let newQuantitativeComparisons = [
- ...quantitativeComparisons,
- newQuantitativeComparison,
- ];
- setQuantitativeComparisons(newQuantitativeComparisons);
-
- setSliderValue(DEFAULT_COMPARE());
- setReasoning("");
- changeNumSteps(numSteps + 1);
- if (successStatus) {
- setDontPushSubmitButtonAnyMore(true);
-
- let jsObject = nicelyFormatLinks(
- quantitativeComparisons,
- listOfElements
- );
- await pushToMongo(jsObject);
- console.log(jsObject);
-
- alert(
- "Comparisons completed. Background work might take a while, or straight-out fail"
- );
- setIsListOrdered(true);
- setOrderedList(result);
-
- await buildRows({
- isListOrdered: true,
- orderedList: result,
- listOfElements,
- links: buildLinks(newQuantitativeComparisons),
- rows: tableRows,
- setTableRows,
- });
- /*
- setTimeout(async () => {
- // Make sure to do this after the
-
- }, 100);
- */
- }
- }
- };
-
- // Html
- return (
-
- {/* Webpage name & favicon */}
-
-
-
Utility Function Extractor
-
-
-
-
- {/* Heading */}
- Utility Function Extractor
- {/* Approximate progress indicator */}
-
- {`${numSteps} out of ~${expectedSteps} (max ${maxSteps}) comparisons`}
-
- {/* Comparison section */}
-
-
- {/* Element 1 */}
-
-
- {/* Comparison actuator (text, previously slider) */}
-
-
-
-
-
-
-
-
-
-
- {/* Element 2 */}
-
-
-
-
-
-
-
- {/* Old slider element (previous actuator)
-
-
- (setSliderValue(event[0]))}
- value={sliderValue}
- displayFunction={displayFunctionSlider}
- domain={domain}
- />
-
- */}
-
-
- {/* Results section */}
-
- {/* Graph */}
-
-
-
-
- {/* Comparison table */}
-
-
-
-
-
- {/* Convenience functions */}
-
-
-
-
-
- {/* Button: Restart */}
-
-
-
- {/* Button: Show comparisons */}
-
-
-
- {/* Button: Load comparisons */}
-
-
-
- {/* Button: Change dataset */}
-
-
-
-
- {/* Change dataset section */}
-
-
-
-
- {/* Show comparisons section */}
-
- {/* Load comparisons section */}
-
-
- {/**/}
-
-
-
- );
-}
diff --git a/lib/comparisonsChanger.js b/lib/comparisonsChanger.js
index 93a5aa4..a0e08f3 100644
--- a/lib/comparisonsChanger.js
+++ b/lib/comparisonsChanger.js
@@ -1,38 +1,39 @@
-import React, { useState } from 'react';
+import React, { useState } from "react";
-export function ComparisonsChanger({handleSubmit}){
+export function ComparisonsChanger({ handleSubmit }) {
// let defaultText=JSON.stringify(nicelyFormatLinks(quantitativeComparisons, listOfElements), null, 4)
- let [value, setValue] = useState(``)
- const [displayingDoneMessage, setDisplayingDoneMessage] = useState(false)
- const [displayingDoneMessageTimer, setDisplayingDoneMessageTimer] = useState(null)
+ let [value, setValue] = useState(``);
+ const [displayingDoneMessage, setDisplayingDoneMessage] = useState(false);
+ const [displayingDoneMessageTimer, setDisplayingDoneMessageTimer] =
+ useState(null);
let handleChange = (event) => {
- setValue(event.target.value)
- }
+ setValue(event.target.value);
+ };
let handleSubmitInner = (event) => {
- clearTimeout(displayingDoneMessageTimer)
+ clearTimeout(displayingDoneMessageTimer);
event.preventDefault();
//console.log(event)
- console.log("value@handleSubmitInner@ComparisonsChanger")
+ console.log("value@handleSubmitInner@ComparisonsChanger");
//console.log(typeof(value));
console.log(value);
- try{
- let newData = JSON.parse(value)
+ try {
+ let newData = JSON.parse(value);
//console.log(typeof(newData))
//console.log(newData)
- handleSubmit(newData)
+ handleSubmit(newData);
/*
if(!newData.length || newData.length < 2){
throw Error("Not enough objects")
}
*/
- setDisplayingDoneMessage(true)
+ setDisplayingDoneMessage(true);
let timer = setTimeout(() => setDisplayingDoneMessage(false), 3000);
- setDisplayingDoneMessageTimer(timer)
- }catch(error){
- setDisplayingDoneMessage(false)
+ setDisplayingDoneMessageTimer(timer);
+ } catch (error) {
+ setDisplayingDoneMessage(false);
//alert(error)
//console.log(error)
let substituteText = `Error: ${error.message}
@@ -59,35 +60,40 @@ Try something like:
}
]
-Your old input was: ${value}`
- setValue(substituteText)
+Your old input was: ${value}`;
+ setValue(substituteText);
}
-
-
- }
+ };
return (
);
-}
\ No newline at end of file
+}
+
diff --git a/lib/d3experiment.js b/lib/d3experiment.js
index c1e358a..f26aa08 100644
--- a/lib/d3experiment.js
+++ b/lib/d3experiment.js
@@ -1,262 +1,280 @@
import React, { useState, useEffect } from "react";
-import * as d3 from 'd3';
+import * as d3 from "d3";
-export function drawChart(height, width){
-
- d3.select("#chart")
- .append("svg")
- .attr("width", width)
- .attr("height", height)
- .style("border", "1px solid black")
- .append("text")
- .attr("fill", "green")
- .attr("x", 50)
- .attr("y", 50)
- .text("Hello D3")
-}
-
-export function drawCircles(){
- var svg = d3.select("#circles")
- .append("svg")
- .attr("width", 960)
- .attr("height", 500)
- .attr("bgcolor", "blue")
-
- var background = svg.append("rect")
- .attr("width", "100%")
- .attr("height", "100%")
- .attr("fill", "blue")
-
- var ball = svg.append("circle")
- .attr("r", 73)
- .attr("cx", 480)
- .attr("cy", 250)
- .style("fill", "#ffe41e");
-}
-
-export function drawGraph(){
- let margin = {top: 20, right: 30, bottom: 20, left: 30};
- let width = 900 - margin.left - margin.right;
- let height = 600 - margin.top - margin.bottom;
-
- var svg = d3.select("#graph")
- .append("svg")
- .attr("width", width + margin.left + margin.right)
- .attr("height", height + margin.top + margin.bottom)
- .append("g")
- .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
-
- let data = ({
- "nodes": [
- {
- "id": 1,
- "name": "A"
- },
- {
- "id": 2,
- "name": "B"
- },
- {
- "id": 3,
- "name": "C"
- },
- {
- "id": 4,
- "name": "D"
- },
- {
- "id": 5,
- "name": "E"
- },
- {
- "id": 6,
- "name": "F"
- },
- {
- "id": 7,
- "name": "G"
- },
- {
- "id": 8,
- "name": "H"
- },
- {
- "id": 9,
- "name": "I"
- },
- {
- "id": 10,
- "name": "J"
- }
- ],
- "links": [
-
- {
- "source": 1,
- "target": 2
- },
- {
- "source": 1,
- "target": 5
- },
- {
- "source": 1,
- "target": 6
- },
-
- {
- "source": 2,
- "target": 3
- },
- {
- "source": 2,
- "target": 7
- }
- ,
-
- {
- "source": 3,
- "target": 4
- },
- {
- "source": 8,
- "target": 3
- }
- ,
- {
- "source": 4,
- "target": 5
- }
- ,
-
- {
- "source": 4,
- "target": 9
- },
- {
- "source": 5,
- "target": 10
- }
- ]
- })
-
- console.log(data)
- // List of node names
- var allNodes = data.nodes.map(function(d){return d.name})
-
- // A linear scale to position the nodes on the X axis
- var x = d3.scalePoint()
- .range([0, width])
- .domain(allNodes)
-
- // Add the circle for the nodes
- svg
- .selectAll("mynodes")
- .data(data.nodes)
- .enter()
- .append("circle")
- .attr("cx", function(d){ return(x(d.name))})
- .attr("cy", height-30)
- .attr("r", 8)
- .style("fill", "#69b3a2")
-
- // And give them a label
- svg
- .selectAll("mylabels")
- .data(data.nodes)
- .enter()
- .append("text")
- .attr("x", function(d){ return(x(d.name))})
- .attr("y", height-10)
- .text(function(d){ return(d.name)})
- .style("text-anchor", "middle")
-
- // Add links between nodes. Here is the tricky part.
- // In my input data, links are provided between nodes -id-, NOT between node names.
- // So I have to do a link between this id and the name
- var idToNode = {};
- data.nodes.forEach(function (n) {
- idToNode[n.id] = n;
- });
- // Cool, now if I do idToNode["2"].name I've got the name of the node with id 2
-
- // Add the links
- svg
- .selectAll('mylinks')
- .data(data.links)
- .enter()
- .append('path')
- .attr('d', function (d) {
- let start = x(idToNode[d.source].name)
- // X position of start node on the X axis
- let end = x(idToNode[d.target].name)
- // X position of end node
- return ['M',
- start,
- height-30,
- // the arc starts at the coordinate x=start, y=height-30 (where the starting node is)
- 'A',
- // This means we're gonna build an elliptical arc
- (start - end)/2, ',',
- // Next 2 lines are the coordinates of the inflexion point. Height of this point is proportional with start - end distance
- (start - end)/2, 0, 0, ',',
- start < end ? 1 : 0, end, ',', height-30]
- // We always want the arc on top. So if end is before start, putting 0 here turn the arc upside down.
- .join(' ');
- })
- .style("fill", "none")
- .attr("stroke", "black")
-
- // labels for links
- svg
- .selectAll('mylinks')
- .data(data.links)
- .enter()
- .append("text")
- .attr("x", function(d){
- let start = x(idToNode[d.source].name)
- // X position of start node on the X axis
- let end = x(idToNode[d.target].name)
- // X position of end node
- return start + (end-start)/2
- })
- .attr("y", function(d){
- let start = x(idToNode[d.source].name)
- // X position of start node on the X axis
- let end = x(idToNode[d.target].name)
- // X position of end node
- return height-30-(Math.abs(start-end)/2)//height-30
- })
- .text(function(d){ return(`${idToNode[d.source].name}-${idToNode[d.target].name}`)})
- .style("text-anchor", "top")
-
- svg.selectAll("text").data(data.links).enter()
+export function drawChart(height, width) {
+ d3.select("#chart")
+ .append("svg")
+ .attr("width", width)
+ .attr("height", height)
+ .style("border", "1px solid black")
.append("text")
- .attr("x", function(d) { return d.source.x + (d.target.x - d.source.x)/2; })
- .attr("y", function(d) { return d.source.y + (d.target.y - d.source.y)/2; })
- .text(function(d) { return d.something; });
+ .attr("fill", "green")
+ .attr("x", 50)
+ .attr("y", 50)
+ .text("Hello D3");
+}
+export function drawCircles() {
+ var svg = d3
+ .select("#circles")
+ .append("svg")
+ .attr("width", 960)
+ .attr("height", 500)
+ .attr("bgcolor", "blue");
+ var background = svg
+ .append("rect")
+ .attr("width", "100%")
+ .attr("height", "100%")
+ .attr("fill", "blue");
+
+ var ball = svg
+ .append("circle")
+ .attr("r", 73)
+ .attr("cx", 480)
+ .attr("cy", 250)
+ .style("fill", "#ffe41e");
+}
+
+export function drawGraph() {
+ let margin = { top: 20, right: 30, bottom: 20, left: 30 };
+ let width = 900 - margin.left - margin.right;
+ let height = 600 - margin.top - margin.bottom;
+
+ var svg = d3
+ .select("#graph")
+ .append("svg")
+ .attr("width", width + margin.left + margin.right)
+ .attr("height", height + margin.top + margin.bottom)
+ .append("g")
+ .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
+
+ let data = {
+ nodes: [
+ {
+ id: 1,
+ name: "A",
+ },
+ {
+ id: 2,
+ name: "B",
+ },
+ {
+ id: 3,
+ name: "C",
+ },
+ {
+ id: 4,
+ name: "D",
+ },
+ {
+ id: 5,
+ name: "E",
+ },
+ {
+ id: 6,
+ name: "F",
+ },
+ {
+ id: 7,
+ name: "G",
+ },
+ {
+ id: 8,
+ name: "H",
+ },
+ {
+ id: 9,
+ name: "I",
+ },
+ {
+ id: 10,
+ name: "J",
+ },
+ ],
+ links: [
+ {
+ source: 1,
+ target: 2,
+ },
+ {
+ source: 1,
+ target: 5,
+ },
+ {
+ source: 1,
+ target: 6,
+ },
+
+ {
+ source: 2,
+ target: 3,
+ },
+ {
+ source: 2,
+ target: 7,
+ },
+ {
+ source: 3,
+ target: 4,
+ },
+ {
+ source: 8,
+ target: 3,
+ },
+ {
+ source: 4,
+ target: 5,
+ },
+ {
+ source: 4,
+ target: 9,
+ },
+ {
+ source: 5,
+ target: 10,
+ },
+ ],
+ };
+
+ console.log(data);
+ // List of node names
+ var allNodes = data.nodes.map(function (d) {
+ return d.name;
+ });
+
+ // A linear scale to position the nodes on the X axis
+ var x = d3.scalePoint().range([0, width]).domain(allNodes);
+
+ // Add the circle for the nodes
+ svg
+ .selectAll("mynodes")
+ .data(data.nodes)
+ .enter()
+ .append("circle")
+ .attr("cx", function (d) {
+ return x(d.name);
+ })
+ .attr("cy", height - 30)
+ .attr("r", 8)
+ .style("fill", "#69b3a2");
+
+ // And give them a label
+ svg
+ .selectAll("mylabels")
+ .data(data.nodes)
+ .enter()
+ .append("text")
+ .attr("x", function (d) {
+ return x(d.name);
+ })
+ .attr("y", height - 10)
+ .text(function (d) {
+ return d.name;
+ })
+ .style("text-anchor", "middle");
+
+ // Add links between nodes. Here is the tricky part.
+ // In my input data, links are provided between nodes -id-, NOT between node names.
+ // So I have to do a link between this id and the name
+ var idToNode = {};
+ data.nodes.forEach(function (n) {
+ idToNode[n.id] = n;
+ });
+ // Cool, now if I do idToNode["2"].name I've got the name of the node with id 2
+
+ // Add the links
+ svg
+ .selectAll("mylinks")
+ .data(data.links)
+ .enter()
+ .append("path")
+ .attr("d", function (d) {
+ let start = x(idToNode[d.source].name);
+ // X position of start node on the X axis
+ let end = x(idToNode[d.target].name);
+ // X position of end node
+ return (
+ [
+ "M",
+ start,
+ height - 30,
+ // the arc starts at the coordinate x=start, y=height-30 (where the starting node is)
+ "A",
+ // This means we're gonna build an elliptical arc
+ (start - end) / 2,
+ ",",
+ // Next 2 lines are the coordinates of the inflexion point. Height of this point is proportional with start - end distance
+ (start - end) / 2,
+ 0,
+ 0,
+ ",",
+ start < end ? 1 : 0,
+ end,
+ ",",
+ height - 30,
+ ]
+ // We always want the arc on top. So if end is before start, putting 0 here turn the arc upside down.
+ .join(" ")
+ );
+ })
+ .style("fill", "none")
+ .attr("stroke", "black");
+
+ // labels for links
+ svg
+ .selectAll("mylinks")
+ .data(data.links)
+ .enter()
+ .append("text")
+ .attr("x", function (d) {
+ let start = x(idToNode[d.source].name);
+ // X position of start node on the X axis
+ let end = x(idToNode[d.target].name);
+ // X position of end node
+ return start + (end - start) / 2;
+ })
+ .attr("y", function (d) {
+ let start = x(idToNode[d.source].name);
+ // X position of start node on the X axis
+ let end = x(idToNode[d.target].name);
+ // X position of end node
+ return height - 30 - Math.abs(start - end) / 2; //height-30
+ })
+ .text(function (d) {
+ return `${idToNode[d.source].name}-${idToNode[d.target].name}`;
+ })
+ .style("text-anchor", "top");
+
+ svg
+ .selectAll("text")
+ .data(data.links)
+ .enter()
+ .append("text")
+ .attr("x", function (d) {
+ return d.source.x + (d.target.x - d.source.x) / 2;
+ })
+ .attr("y", function (d) {
+ return d.source.y + (d.target.y - d.source.y) / 2;
+ })
+ .text(function (d) {
+ return d.something;
+ });
}
export function D3Experiment() {
+ useEffect(() => {
+ drawGraph();
+ }, []);
- useEffect(() => {
- drawGraph();
- }, []);
-
- return (
-
- );
-
+ return (
+
+ );
}
+export default D3Experiment;
-export default D3Experiment;
\ No newline at end of file
diff --git a/lib/datasetChanger.js b/lib/datasetChanger.js
index e404b6d..87f5c01 100644
--- a/lib/datasetChanger.js
+++ b/lib/datasetChanger.js
@@ -1,6 +1,6 @@
-import React, { useState } from 'react';
+import React, { useState } from "react";
-export function DataSetChanger({handleSubmit}){
+export function DataSetChanger({ handleSubmit }) {
let [value, setValue] = useState(`[
{
"name": "Some element. The name field is necessary",
@@ -18,34 +18,35 @@ export function DataSetChanger({handleSubmit}){
"isReferenceValue": true,
"somethirdfield": "c"
}
- ]`)
- const [displayingDoneMessage, setDisplayingDoneMessage] = useState(false)
- const [displayingDoneMessageTimer, setDisplayingDoneMessageTimer] = useState(null)
+ ]`);
+ const [displayingDoneMessage, setDisplayingDoneMessage] = useState(false);
+ const [displayingDoneMessageTimer, setDisplayingDoneMessageTimer] =
+ useState(null);
let handleChange = (event) => {
- setValue(event.target.value)
- }
+ setValue(event.target.value);
+ };
let handleSubmitInner = (event) => {
- clearTimeout(displayingDoneMessageTimer)
+ clearTimeout(displayingDoneMessageTimer);
event.preventDefault();
//console.log(event)
- console.log("value@handleSubmitInner@DataSetChanger")
+ console.log("value@handleSubmitInner@DataSetChanger");
//console.log(typeof(value));
console.log(value);
- try{
- let newData = JSON.parse(value)
+ try {
+ let newData = JSON.parse(value);
//console.log(typeof(newData))
//console.log(newData)
- handleSubmit(newData)
- if(!newData.length || newData.length < 2){
- throw Error("Not enough objects")
+ handleSubmit(newData);
+ if (!newData.length || newData.length < 2) {
+ throw Error("Not enough objects");
}
- setDisplayingDoneMessage(true)
+ setDisplayingDoneMessage(true);
let timer = setTimeout(() => setDisplayingDoneMessage(false), 3000);
- setDisplayingDoneMessageTimer(timer)
- }catch(error){
- setDisplayingDoneMessage(false)
+ setDisplayingDoneMessageTimer(timer);
+ } catch (error) {
+ setDisplayingDoneMessage(false);
//alert(error)
//console.log(error)
let substituteText = `Error: ${error.message}
@@ -70,34 +71,39 @@ Try something like:
}
]
-Your old input was: ${value}`
- setValue(substituteText)
+Your old input was: ${value}`;
+ setValue(substituteText);
}
-
-
- }
+ };
return (
);
-}
\ No newline at end of file
+}
+
diff --git a/lib/displayAsMarkdown.js b/lib/displayAsMarkdown.js
index bc1158f..b7144d8 100644
--- a/lib/displayAsMarkdown.js
+++ b/lib/displayAsMarkdown.js
@@ -3,25 +3,28 @@ import ReactMarkdown from "react-markdown";
import gfm from "remark-gfm";
if (!String.prototype.replaceAll) {
- String.prototype.replaceAll = function(str, newStr){
+ String.prototype.replaceAll = function (str, newStr) {
+ // If a regex pattern
+ if (
+ Object.prototype.toString.call(str).toLowerCase() === "[object regexp]"
+ ) {
+ return this.replace(str, newStr);
+ }
- // If a regex pattern
- if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
- return this.replace(str, newStr);
- }
-
- // If a string
- return this.replace(new RegExp(str, 'g'), newStr);
-
- };
+ // If a string
+ return this.replace(new RegExp(str, "g"), newStr);
+ };
+}
+
+export function DisplayAsMarkdown({ markdowntext, className }) {
+ //console.log(markdowntext)
+ markdowntext = markdowntext.replaceAll("\n", "\n\n");
+ return (
+
+ );
}
-export function DisplayAsMarkdown({markdowntext, className}){
- //console.log(markdowntext)
- markdowntext = markdowntext.replaceAll("\n", "\n\n")
- return( )
-}
\ No newline at end of file
diff --git a/lib/displayElement.js b/lib/displayElement.js
index 04ff366..03133fa 100644
--- a/lib/displayElement.js
+++ b/lib/displayElement.js
@@ -1,31 +1,44 @@
import React from "react";
-let capitalizeFirstLetter = (string) => string.charAt(0).toUpperCase() + string.slice(1)
+let capitalizeFirstLetter = (string) =>
+ string.charAt(0).toUpperCase() + string.slice(1);
+
+export function DisplayElement({ element }) {
+ let otherkeys = Object.keys(element).filter(
+ (key) =>
+ key != "name" && key != "url" && key != "id" && key != "isReferenceValue"
+ );
+ let othervalues = otherkeys.map((key) => element[key]);
+ let otherpairs = otherkeys.map((key, i) => ({
+ key: capitalizeFirstLetter(key),
+ value: othervalues[i],
+ }));
+
+ if (element.url) {
+ return (
+
+ );
+ } else {
+ return (
+
+
{`${element.name}`}
+ {otherpairs.map((pair) => (
+
{`${pair.key}: ${pair.value}`}
+ ))}
+
+ );
+ }
+}
-export function DisplayElement({element}){
- let otherkeys = Object.keys(element).filter(key => key!="name" && key!="url" && key != "id" && key != "isReferenceValue")
- let othervalues = otherkeys.map(key => element[key])
- let otherpairs = otherkeys.map((key,i) => ({key: capitalizeFirstLetter(key), value: othervalues[i]}))
-
- if(element.url){
- return(
-
- )
- }else{
- return(
-
-
{`${element.name}`}
- {otherpairs.map(pair =>
{`${pair.key}: ${pair.value}`}
)}
-
- )
- }
-
-}
\ No newline at end of file
diff --git a/lib/pushToMongo.js b/lib/pushToMongo.js
index 32ffc16..2543d5c 100644
--- a/lib/pushToMongo.js
+++ b/lib/pushToMongo.js
@@ -1,14 +1,17 @@
-import axios from "axios"
+import axios from "axios";
-const CONNECTION_IS_ACTIVE = true
+const CONNECTION_IS_ACTIVE = true;
-export async function pushToMongo(data){
- if(CONNECTION_IS_ACTIVE){
- let response = await axios.post('https://server.loki.red/utility-function-extractor', {
- data: data
- })
- console.log(response)
- }
-
+export async function pushToMongo(data) {
+ if (CONNECTION_IS_ACTIVE) {
+ let response = await axios.post(
+ "https://server.loki.red/utility-function-extractor",
+ {
+ data: data,
+ }
+ );
+ console.log(response);
+ }
}
-// pushToMongo()
\ No newline at end of file
+// pushToMongo()
+
diff --git a/lib/slider.js b/lib/slider.js
index a29b1cc..9baadf8 100644
--- a/lib/slider.js
+++ b/lib/slider.js
@@ -1,34 +1,34 @@
/* Imports */
import { Slider, Rail, Handles, Tracks, Ticks } from "react-compound-slider";
-import React, { useState } from 'react';
+import React, { useState } from "react";
// https://sghall.github.io/react-compound-slider/#/getting-started/tutorial
/* Definitions */
-const sliderStyle = { // Give the slider some width
- position: 'relative',
- width: '40em',
+const sliderStyle = {
+ // Give the slider some width
+ position: "relative",
+ width: "40em",
height: 40,
- border: '5em',
-}
+ border: "5em",
+};
const railStyle = {
- position: 'absolute',
- width: '100%',
+ position: "absolute",
+ width: "100%",
height: 15,
marginTop: 32.5,
borderRadius: 5,
- backgroundColor: 'lightgrey',
-}
+ backgroundColor: "lightgrey",
+};
/* Support functions */
function Handle({
handle: { id, value, percent },
getHandleProps,
displayFunction,
- handleWidth
+ handleWidth,
}) {
-
return (
<>
@@ -37,50 +37,56 @@ function Handle({
-
+ >
>
- )
+ );
}
function Track({ source, target, getTrackProps }) {
return (
- )
+ );
}
/* Body */
-// Two functions, essentially identical.
+// Two functions, essentially identical.
export function SliderElement({ onChange, value, displayFunction, domain }) {
- let toLogDomain = (arr) => [Math.log(arr[0]) / Math.log(10), Math.log(arr[1]) / Math.log(10)]
+ let toLogDomain = (arr) => [
+ Math.log(arr[0]) / Math.log(10),
+ Math.log(arr[1]) / Math.log(10),
+ ];
return (
- {({ getRailProps }) => (
-
- )}
+ {({ getRailProps }) => }
{({ handles, getHandleProps }) => (
- {handles.map(handle => (
+ {handles.map((handle) => (
- )
+ );
}
-export function SubmitSliderButton({ posList, binaryComparisons, sliderValue, reasoning, toComparePair, nextStepSlider, dontPushSubmitButtonAnyMore }) {
+export function SubmitSliderButton({
+ posList,
+ binaryComparisons,
+ sliderValue,
+ reasoning,
+ toComparePair,
+ nextStepSlider,
+ dontPushSubmitButtonAnyMore,
+}) {
// This element didn't necessarily have to exist, but it made it easier for debugging purposes
let onClick = (event) => {
- if(!dontPushSubmitButtonAnyMore){
+ if (!dontPushSubmitButtonAnyMore) {
//event.preventDefault();
- let obj = { posList, binaryComparisons, sliderValue, reasoning, element1: toComparePair[1], element2: toComparePair[0] }
+ let obj = {
+ posList,
+ binaryComparisons,
+ sliderValue,
+ reasoning,
+ element1: toComparePair[1],
+ element2: toComparePair[0],
+ };
//
- console.log("input@SubmitSliderButton")
- console.log(obj)
+ console.log("input@SubmitSliderButton");
+ console.log(obj);
if (!!Number(sliderValue) && sliderValue >= 0) {
- nextStepSlider(obj)
+ nextStepSlider(obj);
} else if (!!Number(sliderValue) && sliderValue < 0) {
- alert("Negative numbers not yet allowed")
+ alert("Negative numbers not yet allowed");
} else {
- alert("Your input is not a number")
+ alert("Your input is not a number");
}
}
-
- }
+ };
- return ()
+ return (
+
+ );
+}
-}
\ No newline at end of file
diff --git a/pages/distancesExample.json b/pages/distancesExample.json
index 5a700eb..1e17405 100644
--- a/pages/distancesExample.json
+++ b/pages/distancesExample.json
@@ -1,53 +1,42 @@
[
+ {
+ "source": 3,
+
+ "target": 4,
+
+ "distance": 5
+ },
+
+ {
+ "source": 2,
+
+ "target": 3,
+
+ "distance": 4
+ },
+
+ {
+ "source": 0,
+
+ "target": 1,
+
+ "distance": 4
+ },
+
+ {
+ "source": 0,
+
+ "target": 2,
+
+ "distance": 5
+ },
+
+ {
+ "source": 1,
+
+ "target": 2,
+
+ "distance": 5
+ }
+]
- {
-
- "source": 3,
-
- "target": 4,
-
- "distance": 5
-
- },
-
- {
-
- "source": 2,
-
- "target": 3,
-
- "distance": 4
-
- },
-
- {
-
- "source": 0,
-
- "target": 1,
-
- "distance": 4
-
- },
-
- {
-
- "source": 0,
-
- "target": 2,
-
- "distance": 5
-
- },
-
- {
-
- "source": 1,
-
- "target": 2,
-
- "distance": 5
-
- }
-
- ]
\ No newline at end of file
diff --git a/pages/index.js b/pages/index.js
index 0a36556..5519d2a 100644
--- a/pages/index.js
+++ b/pages/index.js
@@ -5,25 +5,28 @@
/* Imports */
import React from "react";
-import fs from 'fs';
-import path from 'path';
-import ComparisonView from '../lib/comparisonView.js'
+import fs from "fs";
+import path from "path";
+import ComparisonView from "../lib/comparisonView.js";
/* Definitions */
-const elementsDocument = '../data/listOfMoralGoods.json'
+const elementsDocument = "../data/listOfMoralGoods.json";
/* React components */
export async function getStaticProps() {
- const directory = path.join(process.cwd(), "pages")
- let listOfElementsForView = JSON.parse(fs.readFileSync(path.join(directory, elementsDocument), 'utf8'));
+ const directory = path.join(process.cwd(), "pages");
+ let listOfElementsForView = JSON.parse(
+ fs.readFileSync(path.join(directory, elementsDocument), "utf8")
+ );
return {
props: {
- listOfElementsForView
+ listOfElementsForView,
},
};
}
// Main react component
export default function Home({ listOfElementsForView }) {
- return()
-}
\ No newline at end of file
+ return ;
+}
+
diff --git a/pages/research.js b/pages/research.js
index 1857347..6727a9d 100644
--- a/pages/research.js
+++ b/pages/research.js
@@ -26,4 +26,4 @@ export async function getStaticProps() {
// Main react component
export default function Home({ listOfElementsForView }) {
return()
-}
\ No newline at end of file
+}