diff --git a/backend/src/api/schemas/config-schema.ts b/backend/src/api/schemas/config-schema.ts index 1ef254b94..5c3009630 100644 --- a/backend/src/api/schemas/config-schema.ts +++ b/backend/src/api/schemas/config-schema.ts @@ -87,8 +87,9 @@ const CONFIG_SCHEMA = joi.object({ paceCaretCustomSpeed: joi.number().min(0), repeatedPace: joi.boolean(), pageWidth: joi.string().valid("100", "125", "150", "200", "max"), - chartAccuracy: joi.boolean(), - chartStyle: joi.string().valid("line", "scatter"), + accountChart: joi.array().items(joi.string()), + chartAccuracy: joi.boolean().optional(), //remove after a bit + chartStyle: joi.string().valid("line", "scatter").optional(), //remove after a bit minWpm: joi.string().valid("off", "custom"), minWpmCustomSpeed: joi.number().min(0), highlightMode: joi.string().valid("off", "letter", "word"), diff --git a/frontend/src/styles/account.scss b/frontend/src/styles/account.scss index c67b1a787..9fddefbf4 100644 --- a/frontend/src/styles/account.scss +++ b/frontend/src/styles/account.scss @@ -231,28 +231,16 @@ color: var(--sub-color); margin-top: 1rem; display: grid; - grid-template-columns: auto 300px; + grid-template-columns: auto 400px; align-items: center; .text { height: min-content; } .buttons { + font-size: 0.75rem; display: grid; gap: 0.5rem; - .smoothing { - display: grid; - gap: 0.25rem; - grid-template-columns: 1fr auto; - grid-template-rows: auto auto; - justify-items: start; - color: var(--text-color); - .title { - color: var(--text-color); - } - input[type="range"] { - grid-column: 1/3; - } - } + grid-template-columns: 1fr 1fr 1fr; } } .chart { diff --git a/frontend/src/styles/z_media-queries.scss b/frontend/src/styles/z_media-queries.scss index d50f923ca..e5767306f 100644 --- a/frontend/src/styles/z_media-queries.scss +++ b/frontend/src/styles/z_media-queries.scss @@ -448,6 +448,13 @@ } } + .pageAccount { + .group.chart .below { + grid-template-columns: 1fr; + gap: 0.5rem; + } + } + .pageSettings { .section.themes .tabContent.customTheme { } @@ -496,10 +503,6 @@ display: none; } } - .group.chart .below { - grid-template-columns: 1fr; - gap: 0.5rem; - } .group.topFilters .buttonsAndTitle .buttons { display: grid; justify-content: unset; diff --git a/frontend/src/ts/config.ts b/frontend/src/ts/config.ts index 2088730b5..daf6bfc2b 100644 --- a/frontend/src/ts/config.ts +++ b/frontend/src/ts/config.ts @@ -299,32 +299,64 @@ export function setBlindMode(blind: boolean, nosave?: boolean): boolean { return true; } -export function setChartAccuracy( - chartAccuracy: boolean, +export function setAccountChart( + array: MonkeyTypes.AccountChart, nosave?: boolean ): boolean { - if (!isConfigValueValid("chart accuracy", chartAccuracy, ["boolean"])) { + if ( + !isConfigValueValid("account chart", array, [["on", "off"], "stringArray"]) + ) { return false; } - config.chartAccuracy = chartAccuracy; - saveToLocalStorage("chartAccuracy", nosave); - ConfigEvent.dispatch("chartAccuracy", config.chartAccuracy); + config.accountChart = array; + saveToLocalStorage("accountChart", nosave); + ConfigEvent.dispatch("accountChart", config.accountChart); return true; } -export function setChartStyle( - chartStyle: MonkeyTypes.ChartStyle, +export function setAccountChartAccuracy( + value: boolean, nosave?: boolean ): boolean { - if (!isConfigValueValid("chart style", chartStyle, [["line", "scatter"]])) { + if (!isConfigValueValid("account chart accuracy", value, ["boolean"])) { return false; } - config.chartStyle = chartStyle; - saveToLocalStorage("chartStyle", nosave); - ConfigEvent.dispatch("chartStyle", config.chartStyle); + config.accountChart[0] = value ? "on" : "off"; + saveToLocalStorage("accountChart", nosave); + ConfigEvent.dispatch("accountChart", config.accountChart); + + return true; +} + +export function setAccountChartAvg10( + value: boolean, + nosave?: boolean +): boolean { + if (!isConfigValueValid("account chart avg 10", value, ["boolean"])) { + return false; + } + + config.accountChart[1] = value ? "on" : "off"; + saveToLocalStorage("accountChart", nosave); + ConfigEvent.dispatch("accountChart", config.accountChart); + + return true; +} + +export function setAccountChartAvg100( + value: boolean, + nosave?: boolean +): boolean { + if (!isConfigValueValid("account chart avg 100", value, ["boolean"])) { + return false; + } + + config.accountChart[2] = value ? "on" : "off"; + saveToLocalStorage("accountChart", nosave); + ConfigEvent.dispatch("accountChart", config.accountChart); return true; } @@ -1824,8 +1856,7 @@ export function apply( setPaceCaretCustomSpeed(configObj.paceCaretCustomSpeed, true); setRepeatedPace(configObj.repeatedPace, true); setPageWidth(configObj.pageWidth, true); - setChartAccuracy(configObj.chartAccuracy, true); - setChartStyle(configObj.chartStyle, true); + setAccountChart(configObj.accountChart, true); setMinBurst(configObj.minBurst, true); setMinBurstCustomSpeed(configObj.minBurstCustomSpeed, true); setMinWpm(configObj.minWpm, true); diff --git a/frontend/src/ts/constants/default-config.ts b/frontend/src/ts/constants/default-config.ts index e27ecb0bc..318da4c72 100644 --- a/frontend/src/ts/constants/default-config.ts +++ b/frontend/src/ts/constants/default-config.ts @@ -69,8 +69,7 @@ export default { paceCaretCustomSpeed: 100, repeatedPace: true, pageWidth: "125", - chartAccuracy: true, - chartStyle: "line", + accountChart: ["on", "on", "on"], minWpm: "off", minWpmCustomSpeed: 100, highlightMode: "letter", diff --git a/frontend/src/ts/controllers/chart-controller.ts b/frontend/src/ts/controllers/chart-controller.ts index 019739f35..ce9d2e6d3 100644 --- a/frontend/src/ts/controllers/chart-controller.ts +++ b/frontend/src/ts/controllers/chart-controller.ts @@ -243,38 +243,76 @@ export let accountHistoryActiveIndex: number; export const accountHistory: ChartWithUpdateColors< "line", - MonkeyTypes.HistoryChartData[] | MonkeyTypes.AccChartData[], + | MonkeyTypes.HistoryChartData[] + | MonkeyTypes.AccChartData[] + | MonkeyTypes.OtherChartData[], string > = new ChartWithUpdateColors($(".pageAccount #accountHistoryChart"), { type: "line", data: { - labels: [], datasets: [ { yAxisID: "wpm", - label: "wpm", - fill: false, data: [], - borderColor: "#f44336", - borderWidth: 2, - trendlineLinear: { - style: "rgba(255,105,180, .8)", - lineStyle: "dotted", - width: 4, - }, + fill: false, + borderWidth: 0, + order: 3, + }, + { + yAxisID: "pb", + data: [], + fill: false, + stepped: true, + pointRadius: 0, + pointHoverRadius: 0, + order: 4, }, { yAxisID: "acc", - label: "acc", fill: false, data: [], - borderColor: "#cccccc", - borderWidth: 2, + pointStyle: "triangle", + borderWidth: 0, + pointRadius: 3.5, + order: 3, + }, + { + yAxisID: "wpmAvgTen", + data: [], + fill: false, + pointRadius: 0, + pointHoverRadius: 0, + order: 2, + }, + { + yAxisID: "accAvgTen", + data: [], + fill: false, + pointRadius: 0, + pointHoverRadius: 0, + order: 2, + }, + { + yAxisID: "wpmAvgHundred", + data: [], + fill: false, + pointRadius: 0, + pointHoverRadius: 0, + order: 1, + }, + { + yAxisID: "accAvgHundred", + label: "accAvgHundred", + data: [], + fill: false, + pointRadius: 0, + pointHoverRadius: 0, + order: 1, }, ], }, options: { - responsive: true, + // responsive: true, maintainAspectRatio: false, hover: { mode: "nearest", @@ -283,13 +321,18 @@ export const accountHistory: ChartWithUpdateColors< scales: { x: { axis: "x", - type: "timeseries", - bounds: "ticks", + type: "linear", + min: 0, + ticks: { + stepSize: 10, + }, display: false, - offset: true, title: { + display: true, + text: "Test Number", + }, + grid: { display: false, - text: "Date", }, }, wpm: { @@ -306,21 +349,86 @@ export const accountHistory: ChartWithUpdateColors< }, position: "right", }, + pb: { + axis: "y", + beginAtZero: true, + min: 0, + ticks: { + stepSize: 10, + }, + display: false, + }, acc: { axis: "y", beginAtZero: true, + min: 0, max: 100, + reverse: true, + ticks: { + stepSize: 10, + }, display: true, - position: "left", title: { display: true, - text: "Error rate (100 - accuracy)", + text: "Accuracy", }, grid: { display: false, }, + position: "left", + }, + wpmAvgTen: { + axis: "y", + beginAtZero: true, + min: 0, + ticks: { + stepSize: 10, + }, + display: false, + grid: { + display: false, + }, + }, + accAvgTen: { + axis: "y", + beginAtZero: true, + min: 0, + reverse: true, + ticks: { + stepSize: 10, + }, + display: false, + grid: { + display: false, + }, + }, + wpmAvgHundred: { + axis: "y", + beginAtZero: true, + min: 0, + ticks: { + stepSize: 10, + }, + display: false, + grid: { + display: false, + }, + }, + accAvgHundred: { + axis: "y", + beginAtZero: true, + min: 0, + reverse: true, + ticks: { + stepSize: 10, + }, + display: false, + grid: { + display: false, + }, }, }, + plugins: { annotation: { annotations: [], @@ -329,15 +437,26 @@ export const accountHistory: ChartWithUpdateColors< animation: { duration: 250 }, // Disable the on-canvas tooltip enabled: true, + intersect: false, external: function (ctx): void { if (!ctx) return; ctx.tooltip.options.displayColors = false; }, + filter: function (tooltipItem): boolean { + return ( + tooltipItem.datasetIndex !== 1 && + tooltipItem.datasetIndex !== 3 && + tooltipItem.datasetIndex !== 4 && + tooltipItem.datasetIndex !== 5 && + tooltipItem.datasetIndex !== 6 + ); + }, callbacks: { title: function (): string { return ""; }, + beforeLabel: function (tooltipItem): string { if (tooltipItem.datasetIndex !== 0) { const resultData = tooltipItem.dataset.data[ @@ -828,21 +947,55 @@ export const miniResult: ChartWithUpdateColors< }); function updateAccuracy(): void { - accountHistory.data.datasets[1].hidden = !Config.chartAccuracy; + const accOn = Config.accountChart[0] === "on"; + const avg10On = Config.accountChart[1] === "on"; + const avg100On = Config.accountChart[2] === "on"; + + if (avg10On && avg100On) { + accountHistory.data.datasets[2].hidden = !accOn; + accountHistory.data.datasets[4].hidden = !accOn; + accountHistory.data.datasets[6].hidden = !accOn; + } else if (avg10On) { + accountHistory.data.datasets[2].hidden = !accOn; + accountHistory.data.datasets[4].hidden = !accOn; + } else if (Config.accountChart[2] === "on") { + accountHistory.data.datasets[2].hidden = !accOn; + accountHistory.data.datasets[6].hidden = !accOn; + } else { + accountHistory.data.datasets[2].hidden = !accOn; + } + (accountHistory.options as ScaleChartOptions<"line">).scales["acc"].display = - Config.chartAccuracy; + accOn; accountHistory.update(); } -function updateStyle(): void { - if (Config.chartStyle == "scatter") { - accountHistory.data.datasets[0].showLine = false; - accountHistory.data.datasets[1].showLine = false; +function updateAverage10(): void { + const accOn = Config.accountChart[0] === "on"; + const avg10On = Config.accountChart[1] === "on"; + + if (accOn) { + accountHistory.data.datasets[3].hidden = !avg10On; + accountHistory.data.datasets[4].hidden = !avg10On; } else { - accountHistory.data.datasets[0].showLine = true; - accountHistory.data.datasets[1].showLine = true; + accountHistory.data.datasets[3].hidden = !avg10On; } accountHistory.updateColors(); + accountHistory.update(); +} + +function updateAverage100(): void { + const accOn = Config.accountChart[0] === "on"; + const avg100On = Config.accountChart[2] === "on"; + + if (accOn) { + accountHistory.data.datasets[5].hidden = !avg100On; + accountHistory.data.datasets[6].hidden = !avg100On; + } else { + accountHistory.data.datasets[5].hidden = !avg100On; + } + accountHistory.updateColors(); + accountHistory.update(); } export async function updateColors< @@ -866,6 +1019,7 @@ export async function updateColors< const color = isPb ? textcolor : maincolor; return color; }; + if (chart.data.datasets[1]) { chart.data.datasets[1].borderColor = subcolor; } @@ -910,6 +1064,60 @@ export async function updateColors< )[1].pointBackgroundColor = subcolor; } } + if (chart.data.datasets.length === 2) { + chart.data.datasets[1].borderColor = (): string => { + const color = subcolor; + return color; + }; + } + + if (chart.data.datasets.length === 7) { + chart.data.datasets[2].borderColor = (): string => { + const color = subcolor; + return color; + }; + const avg10On = Config.accountChart[1] === "on"; + const avg100On = Config.accountChart[2] === "on"; + + const text02 = Misc.blendTwoHexColors(bgcolor, textcolor, 0.2); + const main02 = Misc.blendTwoHexColors(bgcolor, maincolor, 0.2); + const main04 = Misc.blendTwoHexColors(bgcolor, maincolor, 0.4); + + const sub02 = Misc.blendTwoHexColors(bgcolor, subcolor, 0.2); + const sub04 = Misc.blendTwoHexColors(bgcolor, subcolor, 0.4); + + const [ + wpmDataset, + pbDataset, + accDataset, + ao10wpmDataset, + ao10accDataset, + ao100wpmDataset, + ao100accDataset, + ] = chart.data.datasets as ChartDataset<"line", TData>[]; + + if (avg10On && avg100On) { + wpmDataset.pointBackgroundColor = main02; + pbDataset.borderColor = text02; + accDataset.pointBackgroundColor = sub02; + ao10wpmDataset.borderColor = main04; + ao10accDataset.borderColor = sub04; + ao100wpmDataset.borderColor = maincolor; + ao100accDataset.borderColor = subcolor; + } else if ((avg10On && !avg100On) || (!avg10On && avg100On)) { + pbDataset.borderColor = text02; + wpmDataset.pointBackgroundColor = main04; + accDataset.pointBackgroundColor = sub04; + ao10wpmDataset.borderColor = maincolor; + ao100wpmDataset.borderColor = maincolor; + ao10accDataset.borderColor = subcolor; + ao100accDataset.borderColor = subcolor; + } else { + pbDataset.borderColor = text02; + wpmDataset.pointBackgroundColor = maincolor; + accDataset.pointBackgroundColor = subcolor; + } + } const chartScaleOptions = chart.options as ScaleChartOptions; Object.keys(chartScaleOptions.scales).forEach((scaleID) => { @@ -923,10 +1131,6 @@ export async function updateColors< chart.data.datasets[0] .trendlineLinear as TrendlineLinearPlugin.TrendlineLinearOptions ).style = subcolor; - ( - chart.data.datasets[1] - .trendlineLinear as TrendlineLinearPlugin.TrendlineLinearOptions - ).style = subcolor; } catch {} ( @@ -958,7 +1162,10 @@ export function updateAllChartColors(): void { } ConfigEvent.subscribe((eventKey, eventValue) => { - if (eventKey === "chartAccuracy") updateAccuracy(); - if (eventKey === "chartStyle") updateStyle(); + if (eventKey === "accountChart") { + updateAccuracy(); + updateAverage10(); + updateAverage100(); + } if (eventKey === "fontFamily") setDefaultFontFamily(eventValue as string); }); diff --git a/frontend/src/ts/pages/account.ts b/frontend/src/ts/pages/account.ts index e12b61e3a..d40b2aa0e 100644 --- a/frontend/src/ts/pages/account.ts +++ b/frontend/src/ts/pages/account.ts @@ -196,53 +196,17 @@ export function reset(): void { ChartController.accountActivity.data.datasets[1].data = []; ChartController.accountHistory.data.datasets[0].data = []; ChartController.accountHistory.data.datasets[1].data = []; + ChartController.accountHistory.data.datasets[2].data = []; + ChartController.accountHistory.data.datasets[3].data = []; + ChartController.accountHistory.data.datasets[4].data = []; + ChartController.accountHistory.data.datasets[5].data = []; + ChartController.accountHistory.data.datasets[6].data = []; } let totalSecondsFiltered = 0; let chartData: MonkeyTypes.HistoryChartData[] = []; let accChartData: MonkeyTypes.AccChartData[] = []; -export function smoothHistory(factor: number): void { - const smoothedWpmData = Misc.smooth( - chartData.map((a) => a.y), - factor - ); - const smoothedAccData = Misc.smooth( - accChartData.map((a) => a.y), - factor - ); - - const chartData2 = chartData.map((a, i) => { - const ret = Object.assign({}, a); - ret.y = smoothedWpmData[i]; - return ret; - }); - - const accChartData2 = accChartData.map((a, i) => { - const ret = Object.assign({}, a); - ret.y = smoothedAccData[i]; - return ret; - }); - - ChartController.accountHistory.data.datasets[0].data = chartData2; - ChartController.accountHistory.data.datasets[1].data = accChartData2; - - if (chartData2.length || accChartData2.length) { - ChartController.accountHistory.options.animation = false; - ChartController.accountHistory.update(); - delete ChartController.accountHistory.options.animation; - } -} - -async function applyHistorySmoothing(): Promise { - const smoothing = $( - ".pageAccount .content .below .smoothing input" - ).val() as string; - $(".pageAccount .content .below .smoothing .value").text(smoothing); - smoothHistory(parseInt(smoothing)); - await Misc.sleep(0); -} - function fillContent(): void { LoadingPage.updateText("Displaying stats..."); LoadingPage.updateBar(100); @@ -310,6 +274,9 @@ function fillContent(): void { filteredResults = []; $(".pageAccount .history table tbody").empty(); + + let testNum = DB.getSnapshot()?.results?.length || 0; + DB.getSnapshot()?.results?.forEach( (result: MonkeyTypes.Result) => { // totalSeconds += tt; @@ -634,7 +601,7 @@ function fillContent(): void { } chartData.push({ - x: result.timestamp, + x: testNum, y: Config.alwaysShowCPM ? Misc.roundTo2(result.wpm * 5) : result.wpm, wpm: Config.alwaysShowCPM ? Misc.roundTo2(result.wpm * 5) : result.wpm, acc: result.acc, @@ -653,11 +620,13 @@ function fillContent(): void { wpmChartData.push(result.wpm); accChartData.push({ - x: result.timestamp, - y: 100 - result.acc, + x: testNum, + y: result.acc, errorRate: 100 - result.acc, }); + testNum--; + if (result.wpm > topWpm) { const puncsctring = result.punctuation ? ",
with punctuation" : ""; const numbsctring = result.numbers @@ -759,8 +728,76 @@ function fillContent(): void { accountHistoryScaleOptions["wpm"].title.text = "Words per Minute"; } - ChartController.accountHistory.data.datasets[0].data = chartData; - ChartController.accountHistory.data.datasets[1].data = accChartData; + if (chartData.length > 0) { + chartData.reverse(); + accChartData.reverse(); + + // get pb points + let currentPb = 0; + const pb: { x: number; y: number }[] = []; + + chartData.forEach((a) => { + if (a.y > currentPb) { + currentPb = a.y; + pb.push(a); + } + }); + + // add last point to pb + const xMax = chartData.length; + + pb.push({ + x: xMax, + y: pb[pb.length - 1].y, + }); + + const avgTen = []; + const avgTenAcc = []; + const avgHundred = []; + const avgHundredAcc = []; + + for (let i = 0; i < chartData.length; i++) { + // calculate 10 subset averages + const startIdxTen = i < 10 ? 0 : i - 9; + const subsetTen = chartData.slice(startIdxTen, i + 1); + const accSubsetTen = accChartData.slice(startIdxTen, i + 1); + const avgTenValue = + subsetTen.reduce((acc, { y }) => acc + y, 0) / subsetTen.length; + const accAvgTenValue = + accSubsetTen.reduce((acc, { y }) => acc + y, 0) / subsetTen.length; + + // add values to arrays + avgTen.push({ x: i + 1, y: avgTenValue }); + avgTenAcc.push({ x: i + 1, y: accAvgTenValue }); + + // calculate 100 subset averages + const startIdxHundred = i < 100 ? 0 : i - 99; + const subsetHundred = chartData.slice(startIdxHundred, i + 1); + const accSubsetHundred = accChartData.slice(startIdxHundred, i + 1); + const avgHundredValue = + subsetHundred.reduce((acc, { y }) => acc + y, 0) / subsetHundred.length; + const accAvgHundredValue = + accSubsetHundred.reduce((acc, { y }) => acc + y, 0) / + subsetHundred.length; + + // add values to arrays + avgHundred.push({ x: i + 1, y: avgHundredValue }); + avgHundredAcc.push({ x: i + 1, y: accAvgHundredValue }); + } + + ChartController.accountHistory.data.datasets[0].data = chartData; + ChartController.accountHistory.data.datasets[1].data = pb; + ChartController.accountHistory.data.datasets[2].data = accChartData; + ChartController.accountHistory.data.datasets[3].data = avgTen; + ChartController.accountHistory.data.datasets[4].data = avgTenAcc; + ChartController.accountHistory.data.datasets[5].data = avgHundred; + ChartController.accountHistory.data.datasets[6].data = avgHundredAcc; + + accountHistoryScaleOptions["x"].max = xMax + 1; + + chartData.reverse(); + accChartData.reverse(); + } const wpms = chartData.map((r) => r.y); const minWpmChartVal = Math.min(...wpms); @@ -769,6 +806,12 @@ function fillContent(): void { // let accuracies = accChartData.map((r) => r.y); accountHistoryScaleOptions["wpm"].max = Math.floor(maxWpmChartVal) + (10 - (Math.floor(maxWpmChartVal) % 10)); + accountHistoryScaleOptions["pb"].max = + Math.floor(maxWpmChartVal) + (10 - (Math.floor(maxWpmChartVal) % 10)); + accountHistoryScaleOptions["wpmAvgTen"].max = + Math.floor(maxWpmChartVal) + (10 - (Math.floor(maxWpmChartVal) % 10)); + accountHistoryScaleOptions["wpmAvgHundred"].max = + Math.floor(maxWpmChartVal) + (10 - (Math.floor(maxWpmChartVal) % 10)); if (!Config.startGraphsAtZero) { accountHistoryScaleOptions["wpm"].min = Math.floor(minWpmChartVal); @@ -800,8 +843,6 @@ function fillContent(): void { Misc.secondsToString(Math.round(totalSecondsFiltered), true, true) ); - const wpmCpm = Config.alwaysShowCPM ? "cpm" : "wpm"; - let highestSpeed: number | string = topWpm; if (Config.alwaysShowCPM) { highestSpeed = topWpm * 5; @@ -812,6 +853,8 @@ function fillContent(): void { highestSpeed = Math.round(highestSpeed); } + const wpmCpm = Config.alwaysShowCPM ? "cpm" : "wpm"; + $(".pageAccount .highestWpm .title").text(`highest ${wpmCpm}`); $(".pageAccount .highestWpm .val").text(highestSpeed); @@ -981,12 +1024,17 @@ function fillContent(): void { Misc.roundTo2( Config.alwaysShowCPM ? wpmChangePerHour * 5 : wpmChangePerHour ) - } ${Config.alwaysShowCPM ? "cpm" : "wpm"}.` + } ${Config.alwaysShowCPM ? "cpm" : "wpm"}` ); $(".pageAccount .estimatedWordsTyped .val").text(totalEstimatedWords); - applyHistorySmoothing(); + if (chartData.length || accChartData.length) { + ChartController.accountHistory.options.animation = false; + ChartController.accountHistory.update(); + delete ChartController.accountHistory.options.animation; + } + ChartController.accountActivity.update(); ChartController.accountHistogram.update(); LoadingPage.updateBar(100, true); @@ -1117,15 +1165,15 @@ function sortAndRefreshHistory( } $(".pageAccount .toggleAccuracyOnChart").on("click", () => { - UpdateConfig.setChartAccuracy(!Config.chartAccuracy); + UpdateConfig.setAccountChartAccuracy(!(Config.accountChart[0] == "on")); }); -$(".pageAccount .toggleChartStyle").on("click", () => { - if (Config.chartStyle == "line") { - UpdateConfig.setChartStyle("scatter"); - } else { - UpdateConfig.setChartStyle("line"); - } +$(".pageAccount .toggleAverage10OnChart").on("click", () => { + UpdateConfig.setAccountChartAvg10(!(Config.accountChart[1] == "on")); +}); + +$(".pageAccount .toggleAverage100OnChart").on("click", () => { + UpdateConfig.setAccountChartAvg100(!(Config.accountChart[2] == "on")); }); $(".pageAccount .loadMoreButton").on("click", () => { @@ -1232,10 +1280,6 @@ $(".pageAccount .group.presetFilterButtons").on( } ); -$(".pageAccount .content .below .smoothing input").on("input", () => { - applyHistorySmoothing(); -}); - $(".pageAccount .content .group.aboveHistory .exportCSV").on("click", () => { Misc.downloadResultsCSV(filteredResults); }); diff --git a/frontend/src/ts/types/types.d.ts b/frontend/src/ts/types/types.d.ts index 8e5c6fede..e911620db 100644 --- a/frontend/src/ts/types/types.d.ts +++ b/frontend/src/ts/types/types.d.ts @@ -119,7 +119,7 @@ declare namespace MonkeyTypes { type PageWidth = "100" | "125" | "150" | "200" | "max"; - type ChartStyle = "line" | "scatter"; + type AccountChart = ("off" | "on")[]; type MinimumWordsPerMinute = "off" | "custom"; @@ -177,6 +177,11 @@ declare namespace MonkeyTypes { errorRate: number; } + interface OtherChartData { + x: number; + y: number; + } + interface ActivityChartDataPoint { x: number; y: number; @@ -448,8 +453,7 @@ declare namespace MonkeyTypes { paceCaretCustomSpeed: number; repeatedPace: boolean; pageWidth: PageWidth; - chartAccuracy: boolean; - chartStyle: ChartStyle; + accountChart: AccountChart; minWpm: MinimumWordsPerMinute; minWpmCustomSpeed: number; highlightMode: HighlightMode; diff --git a/frontend/src/ts/utils/misc.ts b/frontend/src/ts/utils/misc.ts index 5f96307d5..68659a226 100644 --- a/frontend/src/ts/utils/misc.ts +++ b/frontend/src/ts/utils/misc.ts @@ -288,6 +288,7 @@ function hexToRgb(hex: string): } else { return undefined; } + return { r, g, b }; } diff --git a/frontend/static/html/pages/account.html b/frontend/static/html/pages/account.html index a9547ca62..b11809418 100644 --- a/frontend/static/html/pages/account.html +++ b/frontend/static/html/pages/account.html @@ -430,21 +430,21 @@
+
-
-
smoothing
-
0
- -
- Toggle Accuracy + Accuracy
-
+
- Toggle Chart Style + Avg of 10 +
+
+ + Avg of 100