MSD
MSD

Reputation: 313

Can't figure out how to expand Beats Per Minute counter functionality in Javascript?

I have written this code, that lets the user hit the mouse button each time he or she feels a heart beat. And subsquently it will calculate the time between first and last click and from that it will calculate your BPM if this pace continues.

What I want to add is, that it will put about 10 BPM-data (clicks) into an array and then after 10 times clicking it will calculate from the 10 BPM-data your average heart rate and it will tell you wether that is healthy or not. I know it sounds simple, but I am new to javascript, and I find it really awesome to learn this language through making such small applications, there is no better way of learning!

If someone can point me into the right direction, that would be great.

This is what I have so far:

    lastTapSeconds = 0;
    bpm = 0;

    var tapDiv = document.getElementById("tapDiv");

    function bpmCounter() { 

        var tapSeconds = new Date().getTime();

        bpm = ((1 / ((tapSeconds - lastTapSeconds) / 1000)) * 60);
        lastTapSeconds = tapSeconds;            
        tapDiv.innerHTML = '<h1 style="display:inline;">' + 
                            Math.floor(bpm) + 
                           '</h1><img style="height:150px;width:150px;" src="img/heart.png"/>';  
    }

    tapDiv.onmousedown = bpmCounter;

Upvotes: 1

Views: 1257

Answers (2)

Paulo Busato Favarato
Paulo Busato Favarato

Reputation: 302

Using Rxjs Observables is easy:

import { fromEvent } from 'rxjs'; 
import { bufferCount, map, pluck, timeInterval } from 'rxjs/operators';

const btn = document.getElementById("btn"); // get button
fromEvent(btn, 'click').pipe(
  timeInterval(), // get interval between clicks in ms
  pluck('interval'), // strips the inverval property
  bufferCount(10,1),  // buffers last 10 values and return a array of them
  map(arr => arr.reduce((a, b) => a + b, 0) / arr.length), // get avarage of the array
  map(ms => Math.round(60000 / ms)), // calculate bpm
).subscribe(bpm => console.log(bpm + ' bpm'));

using bufferCount you'll need to click 10 times until the results shows up at the console. if you want to show the bpm right when you start clicking and then keep getting avarage of last 10 values, replace the bufferCount line with:

.scan((acc, curr) => {
    acc.push(curr);

    if (acc.length > 10) {
        acc.shift();
    }
    return acc;
}, []),

Upvotes: 0

Kilenaitor
Kilenaitor

Reputation: 664

So I fixed some parts of your code including a way to calculate average on the fly for you.

Check this fiddle to see if that's what you're looking for!

http://jsfiddle.net/q85awqsp/2/

Main thing would be creation of var beats = [] and then using beats.push(Math.floor(bpm)) to add the values;

Full JS here:

var lastTapSeconds = 0;
var bpm = 0;
var beats = [];
var average = 0;
var count = 0;

var tapDiv = document.getElementById("tapDiv");

$(document).on('click', function() {
    var tapSeconds = new Date().getTime();

    bpm = ((1 / ((tapSeconds - lastTapSeconds) / 1000)) * 60);
    lastTapSeconds = tapSeconds;
    tapDiv.innerHTML = '<h1 style="display:inline;">' + Math.floor(bpm) + '</h1>';
    beats.push(Math.floor(bpm));
    average *= count;
    average += Math.floor(bpm);
    count++;
    average /= count;

    if(beats.length >= 10) {
        alert("Average " + average);
    }
});

Upvotes: 2

Related Questions