Skip to content

Commit 300e8cb

Browse files
author
Bot
committed
rewrite wpm over time stats and fix chart time sync
1 parent de34102 commit 300e8cb

File tree

8 files changed

+87
-93
lines changed

8 files changed

+87
-93
lines changed

public/exampleResults.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,11 +1908,7 @@
19081908
"firstCharTime": 1597688868017,
19091909
"complete": true,
19101910
"startTime": 1597688867022,
1911-
"oneThirdCharsCount": 103,
1912-
"oneThirdTime": 34888,
1913-
"lastThirdCharsCount": 53,
1914-
"lastThirdStartTime": 50622,
1915-
"timeFromFirstInput": 61782,
1911+
"time": 61782,
19161912
"correctLines": 12,
19171913
"mode": 0,
19181914
"codeInfo": {

src/components/CodeEditor.vue

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ const codemirror = () => import(/* webpackChunkName: "cmLoader" */ '@/cmLoader.j
5252
return module.default;
5353
});
5454
55-
const DEV = process.env.NODE_ENV !== 'production';
55+
const DEV = process.env.NODE_ENV === 'production'; // dev
5656
5757
5858
export default {
@@ -69,6 +69,7 @@ export default {
6969
cm: {},
7070
codeText: '',
7171
started: false,
72+
pauseTime: 0,
7273
isCompleted: false,
7374
cmReady: false,
7475
toFix: 0,
@@ -82,6 +83,7 @@ export default {
8283
currentChange: {},
8384
stats: {
8485
history: [],
86+
wpmOverTime: [],
8587
firstCharTime: 0,
8688
},
8789
};
@@ -147,9 +149,6 @@ export default {
147149
this.cm.focus();
148150
}
149151
150-
if (this.popUpText === 'resume') {
151-
this.$emit('pause', action);
152-
}
153152
this.showPopUp = action;
154153
},
155154
onCmReady(cm) {
@@ -176,27 +175,6 @@ export default {
176175
text: 'Enter',
177176
};
178177
179-
if (!this.stats.oneThirdTime && this.currentLine === Math.floor(this.codeInfo.lines / 3)) {
180-
console.log('one third');
181-
const oneThirdText = this.cm.getRange(
182-
{ line: 0, ch: 0 },
183-
{ line: this.currentLine, ch: 0 },
184-
);
185-
186-
this.stats.oneThirdCharsCount = oneThirdText.length;
187-
this.stats.oneThirdTime = this.timeElapsed();
188-
} else if (!this.stats.lastThirdStartTime && this.currentLine === Math.floor(this.codeInfo.lines / 3 * 2)) {
189-
console.log('last third');
190-
191-
const lastThirdText = this.cm.getRange(
192-
{ line: this.currentLine, ch: 0 },
193-
{ line: this.codeInfo.lines + 1, ch: 0 },
194-
);
195-
196-
this.stats.lastThirdCharsCount = lastThirdText.length;
197-
this.stats.lastThirdStartTime = this.timeElapsed();
198-
}
199-
200178
if (this.currentLine + 1 === this.codeInfo.lines && this.cm.getLine(this.currentLine).trim().length === 0) {
201179
console.red('Last line is empty');
202180
this.stats.history.push(this.currentChange);
@@ -508,6 +486,12 @@ export default {
508486
},
509487
onFocus() {
510488
console.log('cmFocus');
489+
if (this.pauseStart) {
490+
this.$emit('pause', false);
491+
this.pauseTime += Date.now() - this.pauseStart;
492+
this.pauseStart = null;
493+
}
494+
511495
console.log(this.liveWpmInterval);
512496
if (this.liveWpmInterval === null) {
513497
this.liveWpmInterval = setInterval(this.updateLiveWpm, this.options.liveWpmRefreshRate);
@@ -518,6 +502,7 @@ export default {
518502
if (DEV) ev.preventDefault();
519503
clearInterval(this.liveWpmInterval);
520504
this.liveWpmInterval = null;
505+
this.pauseStart = Date.now();
521506
if (!this.isCompleted && this.popUpText !== 'Try again' && ev) {
522507
if (DEV) this.cm.focus();
523508
if (ev.relatedTarget !== null) {
@@ -529,6 +514,8 @@ export default {
529514
} else {
530515
// eslint-disable-next-line no-lonely-if
531516
if (!DEV) this.popUp(true, 'Resume');
517+
518+
this.$emit('pause', true);
532519
}
533520
}
534521
}
@@ -555,15 +542,18 @@ export default {
555542
}
556543
},
557544
timeElapsed() {
558-
return Date.now() - this.stats.firstCharTime;
545+
return Date.now() - this.stats.firstCharTime - this.pauseTime;
559546
},
560547
updateLiveWpm() {
561-
console.log('correct: ', this.freshCorrect);
562-
const currentWpm = this.freshCorrect / (this.options.liveWpmRefreshRate / 1000 / 60) / 5;
563-
console.blue(`wpm: ${currentWpm}`);
564-
this.$emit('liveWpmUpdate', currentWpm || 0);
565-
566-
this.freshCorrect = 0;
548+
if (this.stats.firstCharTime) {
549+
console.log('correct: ', this.freshCorrect);
550+
const currentWpm = (this.freshCorrect / (this.options.liveWpmRefreshRate / 1000 / 60) / 5) || 0;
551+
console.blue(`wpm: ${currentWpm}`);
552+
this.$emit('liveWpmUpdate', currentWpm);
553+
554+
this.stats.wpmOverTime.push([this.timeElapsed(), Math.round(currentWpm)]);
555+
this.freshCorrect = 0;
556+
}
567557
},
568558
start(interval) {
569559
clearInterval(interval);
@@ -652,7 +642,7 @@ export default {
652642
} else {
653643
this.stats = {
654644
...this.stats,
655-
timeFromFirstInput: this.timeElapsed(),
645+
time: this.timeElapsed(),
656646
correctLines: this.currentLine + 1,
657647
codeInfo: {
658648
...this.codeInfo,

src/components/VirtualKeyboard.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ export default {
336336
align-itemes: center
337337
338338
p
339-
font-size: 1.1em
339+
font-size: 1.05em
340340
max-width: 60%
341341
min-width: 50%
342342

src/components/charts/BarChart.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,14 +90,14 @@ export default {
9090
order: this.chartData.player.order,
9191
},
9292
{
93-
label: 'AVG',
93+
label: 'Global AVG',
9494
backgroundColor: this.backgroundColors[this.chartData.avg.order],
9595
data: [this.chartData.avg.value],
9696
order: this.chartData.avg.order,
9797
barPercentage: 0.7,
9898
},
9999
{
100-
label: 'Best',
100+
label: 'Global Best',
101101
backgroundColor: this.backgroundColors[this.chartData.best.order],
102102
data: [this.chartData.best.value],
103103
order: this.chartData.best.order,

src/components/charts/LinesChart.vue

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export default {
3737
}
3838
}
3939
}
40+
acc.points.push({
41+
x: this.history[this.history.length - 1].time,
42+
y: acc.totalTime,
43+
});
4044
return acc.points;
4145
},
4246
mistakesPoints() {
@@ -104,8 +108,8 @@ export default {
104108
},
105109
ticks: {
106110
fontColor: '#aaa',
107-
108-
stepSize: 10000,
111+
autoSkip: true,
112+
autoSkipPadding: 100,
109113
max: this.timePoints[this.timePoints.length - 1].x,
110114
callback: (time) => {
111115
const seconds = Math.ceil(time / 1000);

src/components/charts/MixedChart.vue

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,23 @@ export default {
2727
},
2828
avgInputIntervals() {
2929
const avg = Math.round(this.inputIntervalsPoints.reduce((acc, point) => acc + point.y, 0) / this.inputIntervalsPoints.length);
30-
return [{ x: 0, y: avg }, { x: this.stats.timeFromFirstInput, y: avg }];
30+
return [{ x: 0, y: avg }, { x: this.stats.time, y: avg }];
3131
},
3232
wpmPoints() {
33-
const oneThirdTime = this.format(this.stats.oneThirdTime);
34-
const oneThirdWPM = this.stats.oneThirdCharsCount / oneThirdTime * 60 / 5;
33+
const points = this.stats.wpmOverTime.map((wpmEvent) => ({
34+
x: wpmEvent[0],
35+
y: wpmEvent[1],
36+
}));
37+
points.unshift({
38+
x: 0,
39+
y: points[0].y,
40+
});
41+
points.push({
42+
x: this.stats.time,
43+
y: points[points.length - 1].y,
44+
});
3545
36-
const halfCharsCount = this.stats.codeInfo.length - this.stats.oneThirdCharsCount - this.stats.lastThirdCharsCount;
37-
const halfTime = this.format(this.stats.lastThirdStartTime - this.stats.oneThirdTime);
38-
const halfWPM = halfCharsCount / halfTime * 60 / 5;
39-
40-
const lastThirdTime = this.format(this.stats.timeFromFirstInput - this.stats.lastThirdStartTime);
41-
const lastThirdWPM = this.stats.lastThirdCharsCount / lastThirdTime * 60 / 5;
42-
43-
return [
44-
{ x: 0, y: this.format(oneThirdWPM, 1, 1) },
45-
{ x: this.format(this.stats.timeFromFirstInput / 2, 0, 1), y: this.format(halfWPM, 1, 1) },
46-
{ x: this.stats.timeFromFirstInput, y: this.format(lastThirdWPM, 1, 1) },
47-
];
46+
return points;
4847
},
4948
options() {
5049
return {
@@ -94,34 +93,24 @@ export default {
9493
},
9594
},
9695
scales: {
97-
xAxes: [{
98-
type: 'linear',
99-
ticks: {
100-
stepSize: 10000,
101-
fontColor: '#aaa',
102-
103-
max: this.avgInputIntervals[this.avgInputIntervals.length - 1].x,
104-
callback: (time) => {
105-
const seconds = Math.ceil(time / 1000);
106-
const minutes = Math.floor(seconds / 60);
107-
return `${minutes ? `${minutes}min` : ''} ${seconds ? `${seconds % 60}s` : '0'}`;
108-
},
109-
},
110-
}],
111-
yAxes: [
96+
xAxes: [
11297
{
113-
id: 'inputIntervals',
11498
type: 'linear',
115-
position: 'left',
11699
ticks: {
100+
autoSkip: true,
101+
autoSkipPadding: 100,
117102
fontColor: '#aaa',
118-
min: 0,
119-
callback(value) {
120-
return `${value} ms`;
103+
max: this.avgInputIntervals[this.avgInputIntervals.length - 1].x,
104+
callback: (time) => {
105+
const seconds = Math.ceil(time / 1000);
106+
const minutes = Math.floor(seconds / 60);
107+
return `${minutes ? `${minutes}min` : ''} ${seconds ? `${seconds % 60}s` : '0'}`;
121108
},
122109
},
123-
124110
},
111+
112+
],
113+
yAxes: [
125114
{
126115
id: 'wpm',
127116
type: 'linear',
@@ -131,10 +120,23 @@ export default {
131120
},
132121
ticks: {
133122
fontColor: '#aaa',
134-
135123
min: 0,
136124
},
137125
},
126+
{
127+
id: 'inputIntervals',
128+
type: 'linear',
129+
position: 'left',
130+
ticks: {
131+
fontColor: '#aaa',
132+
min: 0,
133+
callback(value) {
134+
return `${value} ms`;
135+
},
136+
},
137+
138+
},
139+
138140
],
139141
},
140142
};
@@ -169,9 +171,8 @@ export default {
169171
cubicInterpolationMode: 'default',
170172
borderColor: '#c957e0',
171173
pointBackgroundColor: '#ddd',
172-
pointBorderColor: '#ddd',
173174
pointRadius: 2,
174-
borderWidth: 2,
175+
pointHoverRadius: 1,
175176
backgroundColor: this.pinkGradient,
176177
order: 1,
177178
yAxisID: 'wpm',

src/views/Results.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,13 @@ export default {
120120
return this.history.reduce((acc, event) => (event.type === 'correct' ? acc + 1 : acc), 0);
121121
},
122122
minutes() {
123-
return Math.floor(this.stats.timeFromFirstInput / 1000 / 60);
123+
return Math.floor(this.stats.time / 1000 / 60);
124124
},
125125
seconds() {
126-
return Math.round((this.stats.timeFromFirstInput / 1000) % 60);
126+
return Math.round((this.stats.time / 1000) % 60);
127127
},
128128
CPM() {
129-
return this.correctInputs / this.format(this.stats.timeFromFirstInput, 4) * 60;
129+
return this.correctInputs / this.format(this.stats.time, 4) * 60;
130130
},
131131
WPM() {
132132
return this.CPM / 5;
@@ -159,7 +159,7 @@ export default {
159159
return timesAcc;
160160
},
161161
WPMWithoutTimeLost() {
162-
return this.correctInputs / this.format(this.stats.timeFromFirstInput - this.totalTimeLost, 4) * 60 / 5;
162+
return this.correctInputs / this.format(this.stats.time - this.totalTimeLost, 4) * 60 / 5;
163163
},
164164
totalTimeLost() {
165165
return this.correctionTimes.reduce((acc, value) => acc + value, 0);
@@ -169,7 +169,7 @@ export default {
169169
},
170170
},
171171
beforeMount() {
172-
if (!this.stats.timeFromFirstInput) {
172+
if (!this.stats.time) {
173173
this.$router.push('/');
174174
}
175175
},
@@ -231,7 +231,7 @@ export default {
231231
// console.log('Stats sent');
232232
})
233233
.catch((err) => {
234-
console.eror('Sending stats failed');
234+
console.error('Sending stats failed');
235235
console.error(err.response);
236236
});
237237
},

0 commit comments

Comments
 (0)