From ec9dd815cc575edd895ae4ec348b2c47aefca8ff Mon Sep 17 00:00:00 2001 From: NunoSempere Date: Tue, 19 Jul 2022 19:00:29 -0400 Subject: [PATCH] feat: cleanup --- README.md | 92 +-------------- components/advancedOptions/advancedOptions.js | 85 -------------- .../advancedOptions/comparisonsChanger.js | 105 ------------------ components/advancedOptions/datasetChanger.js | 86 -------------- components/advancedOptions/showComparisons.js | 22 ---- components/dynamicSquiggleChart.js | 79 +++++++------ components/graph/createGraph.js | 13 --- components/graph/graph.js | 42 ++----- components/title.js | 2 +- lib/pushToMongo.js | 15 --- lib/squiggleCalculations.js | 57 ---------- lib/stringManipulations.js | 11 -- lib/truncateNums.js | 39 ------- public/example-graph-and-squiggle.png | Bin 236520 -> 0 bytes public/example-graph.png | Bin 186157 -> 0 bytes public/example-graph2.png | Bin 249258 -> 0 bytes public/example-hierarchical.png | Bin 0 -> 100372 bytes public/example-prompt.png | Bin 59647 -> 0 bytes public/example-table.png | Bin 148478 -> 0 bytes 19 files changed, 52 insertions(+), 596 deletions(-) delete mode 100644 components/advancedOptions/advancedOptions.js delete mode 100644 components/advancedOptions/comparisonsChanger.js delete mode 100644 components/advancedOptions/datasetChanger.js delete mode 100644 components/advancedOptions/showComparisons.js delete mode 100644 lib/pushToMongo.js delete mode 100644 lib/squiggleCalculations.js delete mode 100644 lib/stringManipulations.js delete mode 100644 lib/truncateNums.js delete mode 100644 public/example-graph-and-squiggle.png delete mode 100644 public/example-graph.png delete mode 100644 public/example-graph2.png create mode 100644 public/example-hierarchical.png delete mode 100644 public/example-prompt.png delete mode 100644 public/example-table.png diff --git a/README.md b/README.md index 4c05caa..0aa6c0a 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,14 @@ ## About -This repository creates a react webpage that allows to extract a utility function from possibly inconsistent binary comparisons. - -It presents the users with a series of elements to compare, using merge-sort in the background to cleverly minimize the number of choices needed. +This repository displays hierarchical estimates. It presents the user with a tree with nodes which can be clicked on and inspected, which visualizes the underlying squiggle calculation.

- +

-Then, it cleverly aggregates them, on the one hand by producing a graphical representation: +So far, this mostly has visualization capabilities, meaning that edits are impermanent. -

- -

- -and on the other hand doing some fast and clever mean aggregation [^1]: - -

- -

- -Initially, users could only input numbers, e.g., "A is `3` times better than B". But now, users can also input distributions, using the [squiggle](https://www.squiggle-language.com/) syntax, e.g., "A is `1 to 10` times better than B", or "A is `mm(normal(1, 10), uniform(0,100))` better than B". - -**If you want to use the utility function extractor for a project, we are happy to add a page for your project, like `utility-function-extractor.quantifieduncertainty.org/your-project`**. +**If you want to use the utility function extractor for a project, we are happy to add a page for your project, like `hierarchical-visualization.quantifieduncertainty.org/your-project`**. ## Built with @@ -30,56 +16,10 @@ Initially, users could only input numbers, e.g., "A is `3` times better than B". - [Netlify](https://github.com/netlify/netlify-plugin-nextjs/#readme) - [React](https://reactjs.org/) - [Squiggle](https://www.squiggle-language.com/) -- [Utility tools](https://github.com/quantified-uncertainty/utility-function-extractor/tree/master/packages/utility-tools) ## Usage -Navigate to [utility-function-extractor.quantifieduncertainty.org/](https://utility-function-extractor.quantifieduncertainty.org/), and start comparing objects. - -You can change the list of objects to be compared by clicking on "advanced options". - -After comparing objects for a while, you will get a table and a graph with results. You can also use the [utility tools](https://github.com/quantified-uncertainty/utility-function-extractor/tree/master/packages/utility-tools) package to process these results, for which you will need the json of comparisons, which can be found in "Advanced options" -> "Load comparisons" - -## Notes - -The core structure is json array of objects. Only the "name" attribute is required. If there is a "url", it is displayed nicely. - -``` -[ - { - "name": "Peter Parker", - "someOptionalKey": "...", - "anotherMoreOptionalKey": "...", - }, - { - "name": "Spiderman", - "someOptionalKey": "...", - "anotherMoreOptionalKey": "..." - } -] -``` - -The core structure for links is as follows: - -``` -[ - { - "source": "Peter Parker", - "target": "Spiderman", - "squiggleString": "1 to 100", - "distance": 26.639800977355474 - }, - { - "source": "Spiderman", - "target": "Jonah Jameson", - "squiggleString": "20 to 2000", - "distance": 6.76997149080232 - }, - -] -``` - -A previous version of this webpage had a more complicated structure, but it has since been simplified. +Navigate to [hierarchical-visualization.quantifieduncertainty.org/](https://utility-function-extractor.quantifieduncertainty.org/) (to do: point to subdomain), and start visualizing. ## Contributions and help @@ -91,24 +31,4 @@ Distributed under the MIT License. See LICENSE.txt for more information. ## To do -- [x] Extract merge, findPath and aggregatePath functionality into different repos -- [x] Send to mongo upon completion -- [x] Push to github -- [x] Push to netlify -- [x] Don't allow further comparisons after completion -- [x] Paths table - - [x] Add paths table - - [x] warn that the paths table is approximate. - - I really don't feel like re-adding this after having worked out the distribution rather than the mean aggregation - - On the other hand, I think it does make it more user to other users. -- [x] Change README. -- [ ] Add functionality like names, etc. - - I also don't feel like doing this -- [ ] Look back at Amazon thing which has been running -- [ ] Simplify Graph and DynamicSquiggleChart components -- [ ] Add squiggle component to initial comparison? -- [ ] Understand why the rewrite doesn't - - Maybe: When two elements are judged to be roughly equal - - Maybe: Slightly different merge-sort algorithm. - -[^1]: The program takes each element as a reference point in turn, and computing the possible distances from that reference point to all other points, and taking the geometric mean of these distances. This produces a number representing the value of each element, such that the ratios between elements represent the user's preferences: a utility function. However, this isn't perfect; the principled approach woud be to aggregate the distributions rather than their means. But this principled approach is much more slowly. For the principled approach, see the `utility-tools` repository. +- [ ] Allow for edits. \ No newline at end of file diff --git a/components/advancedOptions/advancedOptions.js b/components/advancedOptions/advancedOptions.js deleted file mode 100644 index f52f164..0000000 --- a/components/advancedOptions/advancedOptions.js +++ /dev/null @@ -1,85 +0,0 @@ -import React, { useState } from "react"; -import { ShowComparisons } from "./showComparisons.js"; -import { ComparisonsChanger } from "./comparisonsChanger.js"; -import { DataSetChanger } from "./datasetChanger.js"; -import { setRevalidateHeaders } from "next/dist/server/send-payload/revalidate-headers.js"; - -const effectButtonStyle = - "bg-transparent m-2 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"; - -export function AdvancedOptions({ - links, - setLinks, - listOfElements, - moveToNextStep, - onChangeOfDataset, -}) { - const [showAdvancedOptions, changeShowAdvanceOptions] = useState(false); - - const [showComparisons, setShowComparisons] = useState(false); - const toggleShowComparisons = () => setShowComparisons(!showComparisons); - - const [showLoadComparisons, setShowLoadComparisons] = useState(false); - const toggleShowLoadComparisons = () => - setShowLoadComparisons(!showLoadComparisons); - - const [showChangeDataset, setShowChangeDataset] = useState(false); - const toggleShowChangeDataset = () => - setShowChangeDataset(!showChangeDataset); - - const buttonNames = [ - // "Show Comparisons", - "Load comparisons", - "Use your own data", - ]; - const buttonToggles = [ - // toggleShowComparisons, - toggleShowLoadComparisons, - toggleShowChangeDataset, - ]; - - return ( -
- {/* Show advanced options*/} - - {/* Toggle buttons */} -
- {buttonNames.map((buttonName, i) => { - return ( - - ); - })} - {/* Element: Show comparisons */} - {/* */} - - {/* Element: Change comparisons */} - - - {/* Element: Dataset changer */} - -
-
- ); -} diff --git a/components/advancedOptions/comparisonsChanger.js b/components/advancedOptions/comparisonsChanger.js deleted file mode 100644 index 74b42bc..0000000 --- a/components/advancedOptions/comparisonsChanger.js +++ /dev/null @@ -1,105 +0,0 @@ -import React, { useState, useEffect } from "react"; -import { Separator } from "../separator.js"; - -const checkLinksAreOk = (links, listOfElements) => { - let linkSourceNames = links.map((link) => link.source.name); - let linkTargetNames = links.map((link) => link.target.name); - let allLinkNames = [...linkSourceNames, ...linkTargetNames]; - let uniqueNames = [...new Set(allLinkNames)]; - - let listOfElementNames = listOfElements.map((element) => element.name); - let anyInvalidNames = uniqueNames.indexOf( - (name) => !listOfElementNames.includes(name) - ); - let anyElementsWithoutDistances = links.indexOf( - (link) => !link.distance && link.distance != 0 - ); - if (anyInvalidNames == -1 && anyElementsWithoutDistances == -1) { - return true; - } else { - return false; - } -}; - -export function ComparisonsChanger({ - setLinks, - listOfElements, - show, - moveToNextStep, - links, -}) { - let [value, setValue] = useState(JSON.stringify(links, null, 4)); - const [displayingDoneMessage, setDisplayingDoneMessage] = useState(false); - const [displayingDoneMessageTimer, setDisplayingDoneMessageTimer] = - useState(null); - - let handleTextChange = (event) => { - setValue(event.target.value); - }; - - let handleSubmitInner = (event) => { - clearTimeout(displayingDoneMessageTimer); - event.preventDefault(); - - try { - let newData = JSON.parse(value); - - if (checkLinksAreOk(newData, listOfElements)) { - setLinks(newData); - moveToNextStep({ - listOfElements, - whileChangingStuff: true, - newLinksFromChangingStuff: newData, - }); - setDisplayingDoneMessage(true); - let timer = setTimeout(() => setDisplayingDoneMessage(false), 3000); - setDisplayingDoneMessageTimer(timer); - } else { - throw Error("Links are not ok"); - } - } catch (error) { - setDisplayingDoneMessage(false); - alert(error); - } - }; - - useEffect(() => { - setValue(JSON.stringify(links, null, 4)); - }, [links]); - - return ( -
- -

Load comparisons

-

These can be edited, which will override your current comparisons.

-
-