V2, with qualitative comparisons. I still don't induce the utility function at the end, but I do have the data to do so
This commit is contained in:
parent
9cae559df3
commit
bc132010bb
124
lib/slider.js
Normal file
124
lib/slider.js
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
/* Imports */
|
||||||
|
import { Slider, Rail, Handles, Tracks, Ticks } from "react-compound-slider";
|
||||||
|
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',
|
||||||
|
height: 40,
|
||||||
|
border: '5em',
|
||||||
|
}
|
||||||
|
|
||||||
|
const railStyle = {
|
||||||
|
position: 'absolute',
|
||||||
|
width: '100%',
|
||||||
|
height: 15,
|
||||||
|
marginTop: 30,
|
||||||
|
borderRadius: 5,
|
||||||
|
backgroundColor: 'lightgrey',
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Support functions */
|
||||||
|
function Handle({
|
||||||
|
handle: { id, value, percent },
|
||||||
|
getHandleProps,
|
||||||
|
displayFunction,
|
||||||
|
handleWidth
|
||||||
|
}) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="justify-center text-center text-gray-600 text-xs">
|
||||||
|
{displayFunction(value)}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
left: `${percent}%`,
|
||||||
|
position: 'absolute',
|
||||||
|
marginLeft: -10,
|
||||||
|
marginTop: 0,
|
||||||
|
zIndex: 2,
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
cursor: 'pointer',
|
||||||
|
borderRadius: '50%',
|
||||||
|
backgroundColor: '#374151',
|
||||||
|
color: '#374151',
|
||||||
|
}}
|
||||||
|
{...getHandleProps(id)}
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Track({ source, target, getTrackProps }) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
height: 15,
|
||||||
|
zIndex: 1,
|
||||||
|
marginTop: 7,
|
||||||
|
backgroundColor: ' #3B82F6',
|
||||||
|
borderRadius: 5,
|
||||||
|
cursor: 'pointer',
|
||||||
|
left: `${source.percent}%`,
|
||||||
|
width: `${target.percent - source.percent}%`,
|
||||||
|
}}
|
||||||
|
{...getTrackProps() /* this will set up events if you want it to be clickeable (optional) */}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Body */
|
||||||
|
// Two functions, essentially identical.
|
||||||
|
export function SliderElement({ onChange, value, displayFunction }) {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Slider
|
||||||
|
rootStyle={sliderStyle /* inline styles for the outer div. Can also use className prop. */}
|
||||||
|
domain={[-3,3]}
|
||||||
|
values={[value]}
|
||||||
|
onChange={onChange}
|
||||||
|
>
|
||||||
|
<Rail>
|
||||||
|
{({ getRailProps }) => (
|
||||||
|
<div style={railStyle} {...getRailProps()} />
|
||||||
|
)}
|
||||||
|
</Rail>
|
||||||
|
<Handles>
|
||||||
|
{({ handles, getHandleProps }) => (
|
||||||
|
<div className="slider-handles">
|
||||||
|
{handles.map(handle => (
|
||||||
|
<Handle
|
||||||
|
key={handle.id}
|
||||||
|
handle={handle}
|
||||||
|
getHandleProps={getHandleProps}
|
||||||
|
displayFunction={displayFunction}
|
||||||
|
handleWidth={"15em"}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Handles>
|
||||||
|
<Tracks right={false}>
|
||||||
|
{({ tracks, getTrackProps }) => (
|
||||||
|
<div className="slider-tracks">
|
||||||
|
{tracks.map(({ id, source, target }) => (
|
||||||
|
<Track
|
||||||
|
key={id}
|
||||||
|
source={source}
|
||||||
|
target={target}
|
||||||
|
getTrackProps={getTrackProps}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Tracks>
|
||||||
|
</Slider>
|
||||||
|
)
|
||||||
|
}
|
6317
package-lock.json
generated
6317
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "with-tailwindcss",
|
"name": "utility-function-extractor",
|
||||||
"version": "0.1.0",
|
"version": "0.2.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
|
@ -10,6 +10,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"next": "latest",
|
"next": "latest",
|
||||||
"react": "^17.0.1",
|
"react": "^17.0.1",
|
||||||
|
"react-compound-slider": "^3.3.1",
|
||||||
"react-dom": "^17.0.1"
|
"react-dom": "^17.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
142
pages/index.js
142
pages/index.js
|
@ -1,5 +1,6 @@
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
|
import { SliderElement } from "../lib/slider.js";
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
Array.prototype.containsArray = function(val) {
|
Array.prototype.containsArray = function(val) {
|
||||||
|
@ -10,46 +11,65 @@ Array.prototype.containsArray = function(val) {
|
||||||
return hash.hasOwnProperty(val);
|
return hash.hasOwnProperty(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
let checkIfListIsOrdered = (arr, comparisons) => {
|
let checkIfListIsOrdered = (arr, binaryComparisons) => {
|
||||||
let l = arr.length
|
let l = arr.length
|
||||||
let isOrdered = true
|
let isOrdered = true
|
||||||
for(let i=0; i<l-1; i++){
|
for(let i=0; i<l-1; i++){
|
||||||
isOrdered = isOrdered && comparisons.containsArray([arr[i], arr[i+1]])
|
isOrdered = isOrdered && binaryComparisons.containsArray([arr[i], arr[i+1]])
|
||||||
}
|
}
|
||||||
return isOrdered
|
return isOrdered
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let simplifySliderValue = value => 10**value >= 3 ? Math.round(10**value) : Math.round(10*10**value)/10
|
||||||
|
let displayFunctionSlider = (value) => {
|
||||||
|
let result
|
||||||
|
if(value >= 0){
|
||||||
|
result = simplifySliderValue(value)
|
||||||
|
}else{
|
||||||
|
let inverseresult = simplifySliderValue(-value)
|
||||||
|
result = `1/${inverseresult}`
|
||||||
|
}
|
||||||
|
result = `The first option is ${result}x as valuable as the second one`
|
||||||
|
return result
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Main
|
// Main
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
// State
|
// State
|
||||||
let list = [1,2,3,4,5,6,7,8,9,10]
|
let list = [1,2,3,4,5,6,7,8,9,10]
|
||||||
let initialComparisonPair = [9,10]
|
// let initialComparisonPair = [9,10]
|
||||||
const [toComparePair, setToComparePair] = useState(initialComparisonPair)
|
const [toComparePair, setToComparePair] = useState([list[list.length-2], list[list.length-1]])
|
||||||
const [comparisons, updateComparisons] = useState([])
|
const [binaryComparisons, setBinaryComparisons] = useState([])
|
||||||
|
|
||||||
|
const [sliderValue, setSliderValue] = useState(0)
|
||||||
|
const [quantitativeComparisons, setQuantitativeComparisons] = useState([])
|
||||||
|
|
||||||
const [isListOrdered, setIsListOrdered] = useState(false)
|
const [isListOrdered, setIsListOrdered] = useState(false)
|
||||||
const [orderedList, setOrderedList] = useState(null)
|
const [orderedList, setOrderedList] = useState(null)
|
||||||
|
|
||||||
|
|
||||||
// Manipulations
|
// Manipulations
|
||||||
let compareTwoElements = (newComparisons, element1, element2) => {
|
let compareTwoElements = (newBinaryComparisons, element1, element2) => {
|
||||||
let element1Greater = newComparisons.containsArray([element1, element2])
|
let element1Greater = newBinaryComparisons.containsArray([element1, element2])
|
||||||
let element2Greater = newComparisons.containsArray([element2, element1])
|
let element2Greater = newBinaryComparisons.containsArray([element2, element1])
|
||||||
if(element1Greater || element2Greater){
|
if(element1Greater || element2Greater){
|
||||||
return element1Greater && !element2Greater
|
return element1Greater && !element2Greater
|
||||||
} else{
|
} else{
|
||||||
setToComparePair([element1, element2])
|
setToComparePair([element1, element2])
|
||||||
console.log(`No comparison found between ${element1} and ${element2}`)
|
console.log(`No comparison found between ${element1} and ${element2}`)
|
||||||
console.log(`Comparisons:`)
|
console.log(`Comparisons:`)
|
||||||
console.log(JSON.stringify(newComparisons, null, 4));
|
console.log(JSON.stringify(newBinaryComparisons, null, 4));
|
||||||
return "No comparison found"
|
return "No comparison found"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function merge(newComparisons, left, right) {
|
function merge(newBinaryComparisons, left, right) {
|
||||||
let sortedArr = []; // the sorted elements will go here
|
let sortedArr = []; // the sorted elements will go here
|
||||||
|
|
||||||
while (left.length && right.length) {
|
while (left.length && right.length) {
|
||||||
// insert the biggest element to the sortedArr
|
// insert the biggest element to the sortedArr
|
||||||
let comparison = compareTwoElements(newComparisons, left[0], right[0])
|
let comparison = compareTwoElements(newBinaryComparisons, left[0], right[0])
|
||||||
if(comparison == "No comparison found"){
|
if(comparison == "No comparison found"){
|
||||||
return "No comparison found; unable to proceed"
|
return "No comparison found; unable to proceed"
|
||||||
}
|
}
|
||||||
|
@ -64,7 +84,7 @@ export default function Home() {
|
||||||
return [...sortedArr, ...left, ...right]; // if they don't have the same size, the remaining ones will be greater than the ones before
|
return [...sortedArr, ...left, ...right]; // if they don't have the same size, the remaining ones will be greater than the ones before
|
||||||
}
|
}
|
||||||
|
|
||||||
function mergeSort(arr, newComparisons) {
|
function mergeSort(arr, newBinaryComparisons) {
|
||||||
if(arr == "No comparison found; unable to proceed"){
|
if(arr == "No comparison found; unable to proceed"){
|
||||||
return "No comparison found; unable to proceed"
|
return "No comparison found; unable to proceed"
|
||||||
}
|
}
|
||||||
|
@ -77,10 +97,10 @@ export default function Home() {
|
||||||
|
|
||||||
const left = arr.splice(0, half); // the first half of the array
|
const left = arr.splice(0, half); // the first half of the array
|
||||||
const right = arr;
|
const right = arr;
|
||||||
let orderedFirstHalf = mergeSort(left, newComparisons)
|
let orderedFirstHalf = mergeSort(left, newBinaryComparisons)
|
||||||
let orderedSecondHalf = mergeSort(right, newComparisons)
|
let orderedSecondHalf = mergeSort(right, newBinaryComparisons)
|
||||||
if(orderedFirstHalf != "No comparison found; unable to proceed" && orderedSecondHalf != "No comparison found; unable to proceed"){
|
if(orderedFirstHalf != "No comparison found; unable to proceed" && orderedSecondHalf != "No comparison found; unable to proceed"){
|
||||||
let result = merge(newComparisons, orderedFirstHalf, orderedSecondHalf);
|
let result = merge(newBinaryComparisons, orderedFirstHalf, orderedSecondHalf);
|
||||||
return result
|
return result
|
||||||
}else{
|
}else{
|
||||||
return "No comparison found; unable to proceed"
|
return "No comparison found; unable to proceed"
|
||||||
|
@ -88,25 +108,40 @@ export default function Home() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let nextStep = (comparisons, element1, element2) => {
|
let nextStepSimple = (binaryComparisons, element1, element2) => {
|
||||||
console.log("Comparisons: ")
|
console.log("Binary comparisons: ")
|
||||||
console.log(JSON.stringify(comparisons, null, 4));
|
console.log(JSON.stringify(binaryComparisons, null, 4));
|
||||||
|
|
||||||
let newComparison = [element1, element2] // [element1, element2]
|
let newComparison = [element1, element2] // [element1, element2]
|
||||||
let newComparisons = [...comparisons, newComparison]
|
let newBinaryComparisons = [...binaryComparisons, newComparison]
|
||||||
console.log("New comparisons: ")
|
console.log("New binaryComparisons: ")
|
||||||
console.log(JSON.stringify(newComparisons, null, 4));
|
console.log(JSON.stringify(newBinaryComparisons, null, 4));
|
||||||
updateComparisons(newComparisons)
|
setBinaryComparisons(newBinaryComparisons)
|
||||||
let result = mergeSort(list, newComparisons)
|
|
||||||
|
let result = mergeSort(list, newBinaryComparisons)
|
||||||
console.log(result)
|
console.log(result)
|
||||||
console.log(toComparePair)
|
if(result != "No comparison found; unable to proceed" && checkIfListIsOrdered(result, newBinaryComparisons)){
|
||||||
if(result != "No comparison found; unable to proceed" && checkIfListIsOrdered(result, newComparisons)){
|
|
||||||
alert("Order complete")
|
|
||||||
console.log(result)
|
console.log(result)
|
||||||
setIsListOrdered(true)
|
setIsListOrdered(true)
|
||||||
setOrderedList(result)
|
setOrderedList(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let nextStepSlider = (binaryComparisons, sliderValue, element1, element2) => {
|
||||||
|
if(sliderValue < 0){
|
||||||
|
sliderValue = -sliderValue;
|
||||||
|
[element1,element2] = [element2,element1]
|
||||||
|
}
|
||||||
|
|
||||||
|
nextStepSimple(binaryComparisons, element1, element2)
|
||||||
|
|
||||||
|
let newQuantitativeComparison = [element1, element2, simplifySliderValue(sliderValue)]
|
||||||
|
let newQuantitativeComparisons = [...quantitativeComparisons, newQuantitativeComparison]
|
||||||
|
setQuantitativeComparisons(newQuantitativeComparisons)
|
||||||
|
|
||||||
|
setSliderValue(0)
|
||||||
|
}
|
||||||
|
|
||||||
// Html
|
// Html
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center min-h-screen py-2">
|
<div className="flex flex-col items-center justify-center min-h-screen py-2">
|
||||||
|
@ -117,28 +152,47 @@ export default function Home() {
|
||||||
|
|
||||||
<main className="flex flex-col items-center justify-center w-full flex-1 px-20 text-center">
|
<main className="flex flex-col items-center justify-center w-full flex-1 px-20 text-center">
|
||||||
<h1 className="text-6xl font-bold">
|
<h1 className="text-6xl font-bold">
|
||||||
Hot or not?
|
Utility Function Extractor
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div className={`flex flex-wrap items-center max-w-4xl mt-6 sm:w-full mt-20 ${isListOrdered? "hidden" : ""}`}>
|
<div className = {`${isListOrdered ? "hidden" : ""}`}>
|
||||||
<button
|
<div className="flex flex-wrap items-center max-w-4xl mt-6 sm:w-full mt-20">
|
||||||
className="flex m-auto border-gray-300 border-4 h-64 w-64"
|
<div
|
||||||
onClick={() => nextStep(comparisons, toComparePair[0], toComparePair[1])}
|
className="flex m-auto border-gray-300 border-4 h-64 w-64"
|
||||||
>
|
//onClick={() => nextStep(binaryComparisons, toComparePair[0], toComparePair[1])}
|
||||||
<p className="block m-auto text-center">{toComparePair[0]}</p>
|
>
|
||||||
</button>
|
<p className="block m-auto text-center">{toComparePair[0]}</p>
|
||||||
<button
|
</div>
|
||||||
className="flex m-auto border-gray-300 border-4 h-64 w-64"
|
<div
|
||||||
onClick={() => nextStep(comparisons, toComparePair[1], toComparePair[0])}
|
className="flex m-auto border-gray-300 border-4 h-64 w-64"
|
||||||
>
|
//onClick={() => nextStep(binaryComparisons, toComparePair[1], toComparePair[0])}
|
||||||
<p className="block m-auto text-center">{toComparePair[1]}</p>
|
>
|
||||||
</button>
|
<p className="block m-auto text-center">{toComparePair[1]}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className={`mt-10 ${isListOrdered? "": "hidden" }`}>
|
</div>
|
||||||
<p>{`Ordered list: ${JSON.stringify(orderedList, null, 4)}`}</p>
|
<div className={`flex row-start-3 row-end-3 col-start-1 col-end-4 md:col-start-3 md:col-end-3 md:row-start-1 md:row-end-1 lg:col-start-3 lg:col-end-3 lg:row-start-1 lg:row-end-1 items-center justify-center mb-4 mt-10 ${isListOrdered? "hidden" : ""}`}>
|
||||||
<p>{`Comparisons: ${JSON.stringify(comparisons, null, 4)}`}</p>
|
<SliderElement
|
||||||
|
className="flex items-center justify-center"
|
||||||
|
onChange={(event) => (setSliderValue(event[0]))}
|
||||||
|
value={sliderValue}
|
||||||
|
displayFunction={displayFunctionSlider}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
className="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent rounded mt-5"
|
||||||
|
onClick={() => nextStepSlider(binaryComparisons, sliderValue, toComparePair[1], toComparePair[0])}>
|
||||||
|
Submit
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div className={`mt-10 ${isListOrdered? "": "hidden" }`}>
|
||||||
|
<p>{`Ordered list: ${JSON.stringify(orderedList, null, 4)}`}</p>
|
||||||
|
<p>{`Binary comparisons: ${JSON.stringify(binaryComparisons, null, 4)}`}</p>
|
||||||
|
<p>{`Quantitative comparisons: ${JSON.stringify(quantitativeComparisons, null, 4)}`}</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user