Skip to content

Instantly share code, notes, and snippets.

@medoingthings
Last active September 28, 2022 08:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save medoingthings/53bbdf9203fd6e02569ef64ef4f741a0 to your computer and use it in GitHub Desktop.
Save medoingthings/53bbdf9203fd6e02569ef64ef4f741a0 to your computer and use it in GitHub Desktop.
Calculate Average Storypoints on http://storypoint.poker/
javascript:var id%3D"53bbdf9203fd6e02569ef64ef4f741a0"%2Cfile%3D"storypoint-avg.js"%2Cuser%3D"medoingthings"%2Cxhr%3Dnew XMLHttpRequest%3Bxhr.overrideMimeType("application%2Fjson")%3Bxhr.open("GET"%2C"https%3A%2F%2Fgist.githubusercontent.com%2F"%2Buser%2B"%2F"%2Bid%2B"%2Fraw%2F"%2Bfile%2B"%3F"%2BMath.random())%3Bxhr.onreadystatechange%3Dfunction()%7Bif(4%3D%3D%3Dxhr.readyState)if(200%3D%3D%3Dxhr.status)console.log("Successfully loaded gist%3A"%2C%7Bid%3Aid%2Cfile%3Afile%2Cuser%3Auser%2Cresponse%3Axhr.responseText%7D)%2C(0%2Ceval)(xhr.responseText)%3Belse%7Bvar a%3D"GitHub Gist file did not load successfully and instead returned a status code of "%2Bxhr.status%2B"."%3Bconsole.error(a%2C%7Bid%3Aid%2Cfile%3Afile%2Cuser%3Auser%7D)%3Balert(a)%7D%7D%3Bxhr.send(null)%3Bvoid+0
/*
* Show average of planning poker cards when using https://storypoint.poker
*
* USAGE:
* 1) Save the `bookmarklet.txt` content (see above) from this Gist as a bookmark
* 2) Navigate to your estimation session on https://storypoint.poker
* 3) Click on the previously saved bookmarklet
*
* That’s it – the average will automatically be shown and updated
*/
{
const playersRootEl = document.querySelector('.MuiGrid-root.MuiGrid-container.MuiGrid-spacing-xs-1');
const observerConfig = {
childList: true,
attributes: false,
characterData: false,
subtree: true
};
/**
* Calculate average from array of numbers
*
* @param arr Array of integers to get the average from
* @returns Integer
*/
const calculateAverage = function (array) {
const sum = array.reduce((a, b) => a + b, 0);
const avg = (sum / array.length) || 0;
// Max. 2 decimals
return avg % 1 ? avg.toFixed(2) : avg;
};
/**
* Check DOM for valid votes
*
* @return Array [{
* vote: Integer
* el: Node
* }, ...]
*/
const getValidVotes = function () {
const allVotesElements = getVoteElements();
const allValidVotesArr = [];
// Iterate over NodeList
[].forEach.call(allVotesElements, function (el) {
const input = el.innerText;
if (input && !isNaN(input)) {
allValidVotesArr.push({
vote: parseFloat(input),
el: el
});
}
});
return allValidVotesArr;
};
/**
* Get all elements that can contain votes
*
* @returns Array
*/
const getVoteElements = function () {
return playersRootEl.querySelectorAll('.MuiGrid-root.MuiGrid-container.MuiGrid-spacing-xs-1 > .MuiGrid-root.MuiGrid-item.MuiGrid-grid-xs-1');
};
/**
* Updates the DOM according to the voting state
*
* @param state Array
*/
const updateDOMState = function (state) {
const headlineEl = document.querySelector('.MuiGrid-root.MuiGrid-item.MuiGrid-grid-xs-12 > h6.MuiTypography-h6');
const estimations = [];
if (state && state.length) {
state.forEach(item => {
item.el.style.backgroundColor = '#acbdc5';
estimations.push(item.vote);
});
headlineEl.innerText = `Average: ${calculateAverage(estimations)}`;
} else {
headlineEl.innerText = `Waiting ⏳`;
}
};
/**
* Reset the DOM from earlier styling changes
*/
const resetStyle = function () {
const allVotesElements = getVoteElements();
[].forEach.call(allVotesElements, function (el) {
el.style.backgroundColor = '';
});
};
/**
* Kick off DOM change detection
*/
const init = function () {
window.ignitionStarted = true;
const observer = new MutationObserver(function () {
// Avoid detecting changes
this.disconnect();
// Update DOM
resetStyle();
updateDOMState(getValidVotes());
// Continue observing
this.observe(playersRootEl, observerConfig);
});
updateDOMState(getValidVotes());
observer.observe(playersRootEl, observerConfig);
};
// Prevent multiple instances of this script
if (!window.ignitionStarted) {
init();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment