|
|
| |
| shapeParams.forEach((d) => (d.startX = d.startX * 1.1)); |
|
|
| |
| const classifierBgPathTop = "M 420 150 H 0 V 0 H 420 V 150"; |
| const classifierBgPathBottom = "M 420 300 H 0 V 0 H 420 V 300"; |
|
|
| const toDropdownValueStringDict = { |
| shape_name: "circles, triangles, or rectangles", |
| pointiness: "pointy shapes or round shapes", |
| size: "small shapes or big shapes", |
| }; |
|
|
| const toShortValueStringDict = { |
| shape_name: "circles, triangles, or rectangles", |
| pointiness: "pointy or round", |
| size: "small or big", |
| }; |
|
|
| const toDropdownValueRoundingStringDict = { |
| true: "with our best guess", |
| false: 'as "other"', |
| }; |
|
|
| const toPropertyStringDict = { |
| pointy: "pointy shapes", |
| round: "round shapes", |
| small: "small shapes", |
| large: "big shapes", |
| circle: "circles", |
| triangle: "triangles", |
| rect: "rectangles", |
| }; |
|
|
| function toOriginalString(inputString) { |
| for (const [key, value] of Object.entries(toPropertyStringDict)) { |
| if (inputString == value) { |
| return key; |
| } |
| } |
| } |
|
|
| function toPropertyString(inputProperty, isRounding = true) { |
| if (!isRounding && inputProperty.startsWith("rt_")) { |
| return "others"; |
| } |
| return toPropertyStringDict[inputProperty.replace("rt_", "")]; |
| } |
|
|
| |
| var allResults = {}; |
| var summaries = {}; |
|
|
| function toBool(inputString) { |
| if (inputString == "true") { |
| return true; |
| } |
| return false; |
| } |
| function updateResults() { |
| allResults["default-classifier"] = calculateResults(); |
| allResults["second-classifier"] = calculateResults( |
| "shape_name", |
| toBool( |
| document.getElementById("second-classifier-select-rounding").value |
| ) |
| ); |
|
|
| allResults["final-classifier"] = calculateResults( |
| document.getElementById("final-classifier-select-category").value, |
| toBool( |
| document.getElementById("final-classifier-select-rounding").value |
| ) |
| ); |
|
|
| allResults["conclusion"] = calculateResults( |
| document.getElementById("conclusion-select-category").value, |
| true |
| ); |
|
|
| updateSummaries(); |
| updateSecondInterfaceImages(); |
| } |
|
|
| |
| |
| |
| function updateSummaries() { |
| summaries["default-classifier"] = getPerformanceSummary("none"); |
| summaries["second-classifier"] = getPerformanceSummary( |
| "shape_name:" + |
| document.getElementById("second-classifier-select-rounding").value |
| ); |
|
|
| summaries["final-classifier"] = getPerformanceSummary( |
| document.getElementById("final-classifier-select-category").value + |
| ":" + |
| document.getElementById("final-classifier-select-rounding").value |
| ); |
|
|
| summaries["conclusion"] = getPerformanceSummary( |
| document.getElementById("conclusion-select-category").value + ":" + true |
| ); |
| } |
|
|
| |
| |
| function getPerformanceSummary(key) { |
| allSummaries = { |
| "shape_name:true": |
| '<mark style="background-color: rgb(206, 234, 135);" class="well">well</mark> on circles, <mark style="background-color: rgb(244, 123, 74);" class="terribly">terribly</mark> on triangles, and <mark style="background-color: rgb(173, 220, 114);" class="best">best</mark> on rectangles', |
| "shape_name:false": |
| '<mark style="background-color: rgb(251, 163, 94);" class="poorly">poorly</mark> on circles, <mark style="background-color: rgb(155, 212, 108);" class="best">best</mark> on triangles and rectangles, and <mark style="background-color: rgb(252, 244, 171);" class="fine">fine</mark> on other shapes', |
| "pointiness:true": |
| '<mark style="background-color: rgb(184, 225, 119);" class="better">better</mark> on pointy shapes and <mark style="background-color: rgb(254, 206, 125);" class="worse">worse</mark> on round shapes', |
| "pointiness:false": |
| '<mark style="background-color: rgb(140, 205, 104);" class="best">best</mark> on pointy shapes, <mark style="background-color: rgb(243, 248, 171);" class="fine">fine</mark> on round shapes, and <mark style="background-color: rgb(253, 190, 111);" class="poorly">poorly</mark> on other shapes', |
| "size:true": |
| '<mark style="background-color: rgb(206, 234, 135);" class="better">better</mark> on small shapes, <mark style="background-color: rgb(254, 232, 154);" class="worse">worse</mark> on big shapes', |
| "size:false": |
| '<mark style="background-color: rgb(254, 215, 135);" class="poorly">poorly</mark> on small shapes, <mark style="background-color: rgb(165, 0, 38); color: #FFCCD8;" class="terribly">terribly</mark> on big shapes, and <mark style="background-color: rgb(110, 192, 99);" class="best">best</mark> on other shapes', |
| "none:true": |
| '<mark style="background-color: rgb(246, 248, 173);" class="fine">fine</mark> on all shapes', |
| "none:false": |
| '<mark style="background-color: rgb(246, 248, 173);" class="fine">fine</mark> on all shapes', |
| none: '<mark style="background-color: rgb(246, 248, 173);" class="fine">fine</mark> on all shapes', |
| }; |
|
|
| return "The Is-Shaded Classifier performs " + allSummaries[key] + "."; |
| } |
|
|
| |
| function updateSecondInterfaceImages() { |
| d3.select(".second-interface").html(function () { |
| if ( |
| !document.getElementById("second-classifier-select-rounding").value |
| ) { |
| return; |
| } |
| var imgPath = |
| "img/interface_shape_name_" + |
| document.getElementById("second-classifier-select-rounding").value; |
| return ( |
| '<img src="' + |
| imgPath + |
| '.png" alt="" class="interface-image" srcset="' + |
| imgPath + |
| '.svg"></img>' |
| ); |
| }); |
| } |
|
|
| |
| function calculateResults(property = "none", useGuess = false) { |
| switch (property) { |
| case "none": |
| var nAccurate = shapeParams.filter( |
| (shape) => shape.correctness == "correct" |
| ).length; |
| var totalShapes = shapeParams.length; |
|
|
| var results = [ |
| { |
| object: "shape", |
| n: totalShapes, |
| "n correct": nAccurate, |
| accuracy: (nAccurate / totalShapes).toFixed(3), |
| rawCategoryName: "none", |
| }, |
| ]; |
|
|
| return results; |
| case "pointiness": |
| categories = ["pointy", "round"]; |
| break; |
| case "size": |
| categories = ["small", "large"]; |
| break; |
| case "shape_name": |
| categories = ["circle", "triangle", "rect"]; |
| break; |
| } |
|
|
| var results = []; |
| if (useGuess == true) { |
| |
|
|
| for (const category of categories) { |
| |
| var theseShapes = shapeParams.filter( |
| (shape) => |
| shape[property] == category || |
| shape[property] == "rt_" + category |
| ); |
| var nAccurate = theseShapes.filter( |
| (shape) => shape.correctness == "correct" |
| ).length; |
| var totalShapes = theseShapes.length; |
|
|
| results.push({ |
| object: toPropertyString(category), |
| n: totalShapes, |
| "n correct": nAccurate, |
| accuracy: (nAccurate / totalShapes).toFixed(3), |
| rawCategoryName: category, |
| }); |
| } |
| } else { |
| |
|
|
| |
| for (const category of categories) { |
| var theseShapes = shapeParams.filter( |
| (shape) => shape[property] == category |
| ); |
| var nAccurate = theseShapes.filter( |
| (shape) => shape.correctness == "correct" |
| ).length; |
| var totalShapes = theseShapes.length; |
| results.push({ |
| object: toPropertyString(category), |
| n: totalShapes, |
| "n correct": nAccurate, |
| accuracy: (nAccurate / totalShapes).toFixed(3), |
| rawCategoryName: category, |
| }); |
| } |
|
|
| |
| var theseShapes = shapeParams.filter( |
| (shape) => !categories.includes(shape[property]) |
| ); |
| var nAccurate = theseShapes.filter( |
| (shape) => shape.correctness == "correct" |
| ).length; |
| var totalShapes = theseShapes.length; |
| results.push({ |
| object: "other shapes", |
| n: totalShapes, |
| "n correct": nAccurate, |
| accuracy: (nAccurate / totalShapes).toFixed(3), |
| rawCategoryName: "other", |
| }); |
| } |
|
|
| return results; |
| } |
|
|