From 43fcaf595013d8cb99f53cee5e3356737c65803b Mon Sep 17 00:00:00 2001 From: Miodec Date: Sun, 4 Jul 2021 23:58:11 +0100 Subject: [PATCH] added burst heatmap to the result screen --- src/js/misc.js | 11 +++++ src/js/test/test-logic.js | 4 ++ src/js/test/test-ui.js | 88 +++++++++++++++++++++++++++++++++++++++ src/sass/style.scss | 72 ++++++++++++++++++++++++++++---- static/index.html | 20 +++++++++ 5 files changed, 186 insertions(+), 9 deletions(-) diff --git a/src/js/misc.js b/src/js/misc.js index 6a2e2c3d5..7b159badd 100644 --- a/src/js/misc.js +++ b/src/js/misc.js @@ -371,6 +371,17 @@ export function mean(array) { } } +//https://www.w3resource.com/javascript-exercises/fundamental/javascript-fundamental-exercise-88.php +export function median (arr) { + try{ + const mid = Math.floor(arr.length / 2), + nums = [...arr].sort((a, b) => a - b); + return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2; + }catch(e){ + return 0; + } +} + export function getReleasesFromGitHub() { $.getJSON( "https://api.github.com/repos/Miodec/monkeytype/releases", diff --git a/src/js/test/test-logic.js b/src/js/test/test-logic.js index 1f88426fc..78998af14 100644 --- a/src/js/test/test-logic.js +++ b/src/js/test/test-logic.js @@ -1945,9 +1945,13 @@ export function finish(difficultyFailed = false) { TestUI.setResultCalculating(false); $("#words").empty(); ChartController.result.resize(); + if (Config.alwaysShowWordsHistory) { TestUI.toggleResultWords(); } + if(TestUI.heatmapEnabled){ + TestUI.applyBurstHeatmap(); + } $("#testModesNotice").addClass("hidden"); }, () => { diff --git a/src/js/test/test-ui.js b/src/js/test/test-ui.js index 0760dd6eb..dd97738ba 100644 --- a/src/js/test/test-ui.js +++ b/src/js/test/test-ui.js @@ -15,6 +15,7 @@ import * as ManualRestart from "./manual-restart-tracker"; import * as PractiseMissed from "./practise-missed"; import * as Replay from "./replay"; import * as TestStats from "./test-stats"; +import * as Misc from './misc'; export let currentWordElementIndex = 0; export let resultVisible = false; @@ -783,6 +784,88 @@ export function toggleResultWords() { } } } +export let heatmapEnabled = false; +function toggleBurstHeatmap(){ + if(!heatmapEnabled){ + applyBurstHeatmap(); + }else{ + //clear all classes + $("#resultWordsHistory .heatmapLegend").addClass('hidden'); + $('#resultWordsHistory .words .word').removeClass("heatmap-0"); + $('#resultWordsHistory .words .word').removeClass("heatmap-1"); + $('#resultWordsHistory .words .word').removeClass("heatmap-2"); + $('#resultWordsHistory .words .word').removeClass("heatmap-3"); + $('#resultWordsHistory .words .word').removeClass("heatmap-4"); + + } + heatmapEnabled = !heatmapEnabled; +} + +export function applyBurstHeatmap(){ + $("#resultWordsHistory .heatmapLegend").removeClass('hidden'); + let min = Math.min(...TestStats.burstHistory); + let max = Math.max(...TestStats.burstHistory); + // let step = (max - min) / 5; + // let steps = [ + // { + // val: min, + // class: 'heatmap-0' + // }, + // { + // val: min + (step * 1), + // class: 'heatmap-1' + // }, + // { + // val: min + (step * 2), + // class: 'heatmap-2' + // }, + // { + // val: min + (step * 3), + // class: 'heatmap-3' + // }, + // { + // val: min + (step * 4), + // class: 'heatmap-4' + // }, + // ]; + let median = Misc.median(TestStats.burstHistory); + let adatm = []; + TestStats.burstHistory.forEach(burst => { + adatm.push(Math.abs(median - burst)); + }) + let step = Misc.mean(adatm); + // let step = Misc.stdDev(TestStats.burstHistory)/2; + let steps = [ + { + val: 0, + class: 'heatmap-0' + }, + { + val: median - (step * 1.5), + class: 'heatmap-1' + }, + { + val: median - (step * 0.5), + class: 'heatmap-2' + }, + { + val: median + (step * 0.5), + class: 'heatmap-3' + }, + { + val: median + (step * 1.5), + class: 'heatmap-4' + }, + ]; + $('#resultWordsHistory .words .word').each((index, word) => { + let wordBurstVal = parseInt($(word).attr('burst')); + let cls = ''; + steps.forEach(step => { + if(wordBurstVal > step.val) cls = step.class; + }) + $(word).addClass(cls); + }) +} export function highlightBadWord(index, showError) { if (!showError) return; @@ -819,6 +902,11 @@ $(".pageTest #copyWordsListButton").click(async (event) => { } }); + +$(".pageTest #toggleBurstHeatmap").click(async (event) => { + toggleBurstHeatmap(); +}); + $(document).on("mouseleave", "#resultWordsHistory .words .word", (e) => { $(".wordInputAfter").remove(); }); diff --git a/src/sass/style.scss b/src/sass/style.scss index 3db0fbe5e..6ad97dffc 100644 --- a/src/sass/style.scss +++ b/src/sass/style.scss @@ -1879,6 +1879,43 @@ key { // grid-area: wordsHistory; color: var(--sub-color); grid-column: 1/3; + .heatmapLegend{ + display: inline-grid; + grid-template-columns: auto auto auto; + gap: 1rem; + font-size: .75rem; + color: var(--sub-color); + width: min-content; + .boxes{ + display: flex; + .box{ + width: 1rem; + height: 1rem; + } + .box:nth-child(1){ + background: var(--colorful-error-color); + border-radius: var(--roundness) 0 0 var(--roundness); + } + .box:nth-child(2){ + background: var(--colorful-error-color); + filter: opacity(0.6); + } + .box:nth-child(3){ + background: var(--sub-color); + } + .box:nth-child(4){ + background: var(--main-color); + filter: opacity(0.6); + } + .box:nth-child(5){ + background: var(--main-color); + border-radius: 0 var(--roundness) var(--roundness) 0; + } + } + } + .title{ + user-select: none; + } .words { display: flex; flex-wrap: wrap; @@ -1888,6 +1925,32 @@ key { .word { position: relative; margin: 0.18rem 0.6rem 0.15rem 0; + letter.correct { + color: var(--text-color); + } + letter.incorrect { + color: var(--error-color); + } + letter.incorrect.extra { + color: var(--error-extra-color); + } + &.heatmap-0 letter{ + color: var(--colorful-error-color); + } + &.heatmap-1 letter{ + color: var(--colorful-error-color); + filter: opacity(0.6); + } + &.heatmap-2 letter{ + color: var(--sub-color); + } + &.heatmap-3 letter{ + color: var(--main-color); + filter: opacity(0.6); + } + &.heatmap-4 letter{ + color: var(--main-color); + } } &.rightToLeftTest { //flex-direction: row-reverse; // no need for hacking 😉, CSS fully support right-to-left languages @@ -1903,15 +1966,6 @@ key { } } } - .correct { - color: var(--text-color); - } - .incorrect { - color: var(--error-color); - } - .incorrect.extra { - color: var(--error-extra-color); - } } .chart { diff --git a/static/index.html b/static/index.html index 0de709767..c84ca09cd 100644 --- a/static/index.html +++ b/static/index.html @@ -1440,6 +1440,26 @@ > + + + +