// ==UserScript==
// @name MyFitnessPal Percentages and Net Carbs
// @version 1.16
// @namespace surye
// @description Adds display of Carb/Protein/Fat percentages to any daily food diary page. Also adds "Real Calories" calcalation based off 4/4/9 algorithm. Based on "MyFitnessPal Percentages and Net Carbs"
// @downloadURL https://github.com/Surye/mfp-keto-userscript/raw/master/mfpketo.user.js
// @include http*://www.myfitnesspal.com/food/diary*
// ==/UserScript==
/*
* ------------------------------------------------------------
* Much credit to Bompus, author of the original script!
* Thanks to kt123 and Wickity for the fixes.
* ------------------------------------------------------------
*/
function exec(fn) {
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = '(' + fn + ')();';
document.body.appendChild(script); // run the script
document.body.removeChild(script); // clean up
}
function startRun() {
// Load Google API for Charts
var script = document.createElement("script");
script.setAttribute("src", "//www.google.com/jsapi");
script.addEventListener('load', function() {
exec(jsapiLoaded);
}, false);
document.body.appendChild(script);
// Load jQuery
script = document.createElement("script");
script.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js");
script.addEventListener('load', function() {
exec("jQuery.noConflict()");
}, false);
document.body.appendChild(script);
// Inject this script into page.
script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = main;
document.body.appendChild(script);
}
startRun();
function jsapiLoaded() {
google.load("visualization", "1", { packages: ["corechart"], "callback": main });
}
function main() {
var calories_i = 0;
var net_carbs_i = 0;
var carbs_i = 0;
var fiber_i = 0;
var protein_i = 0;
var fat_i = 0;
var daily_total_carbs = 0;
var daily_total_protein = 0;
var daily_total_fat = 0;
var net_carb_total = 0;
var net_carb_total_goal = 0;
var header_tr_element = jQuery('.food_container tr.meal_header:first');
var elem_i = 0;
header_tr_element.find('td').each(function() {
var myval = jQuery(this).text().toLowerCase().trim();
if (myval.indexOf('calories') !== -1) { calories_i = elem_i; }
if (myval.indexOf('carbs') !== -1) { carbs_i = elem_i; }
if (myval.indexOf('fiber') !== -1) { fiber_i = elem_i; }
if (myval.indexOf('fat') !== -1) { fat_i = elem_i; }
if (myval.indexOf('protein') !== -1) { protein_i = elem_i; }
elem_i += 1;
});
// Add new column for net carbs
var net_carb_tr_elements = jQuery('tr');
net_carb_tr_elements.each(function() {
var tds = jQuery(this).find('td');
jQuery('
| ').insertBefore(tds.eq(carbs_i));
});
// Recalculate offsets
net_carbs_i = carbs_i;
calories_i = calories_i >= net_carbs_i ? calories_i + 1 : calories_i;
carbs_i = carbs_i >= net_carbs_i ? carbs_i + 1 : carbs_i;
fiber_i = fiber_i >= net_carbs_i ? fiber_i + 1 : fiber_i;
protein_i = protein_i >= net_carbs_i ? protein_i + 1 : protein_i;
fat_i = fat_i >= net_carbs_i ? fat_i + 1 : fat_i;
// Set header
header_tr_element.find('td').eq(net_carbs_i).text("Net Carbs");
header_tr_element.find('td').eq(net_carbs_i).addClass("alt");
header_tr_element.find('td').eq(net_carbs_i).addClass("nutrient-column");
// Change to say net carbs
var footer_tr_element = jQuery('tfoot tr');
footer_tr_element.find('td').eq(net_carbs_i).text("Net Carbs");
footer_tr_element.find('td').eq(net_carbs_i).addClass("alt");
header_tr_element.find('td').eq(net_carbs_i).addClass("nutrient-column");
var alreadyCountedFiber = [0];
var alreadyCountedFiberIdx = 0;
var food_tr_elements = jQuery('tr');
food_tr_elements.each(function() {
if($(this).hasClass('bottom')) {
alreadyCountedFiberIdx++;
alreadyCountedFiber[alreadyCountedFiberIdx] = 0;
}
var tds = jQuery(this).find('td');
var carbs = parseFloat(tds.eq(carbs_i).text());
var fiber = parseFloat(tds.eq(fiber_i).text());
// Find only food rows!
var delete_td = tds.eq(tds.length - 1);
if (delete_td.hasClass('delete')) {
var name = jQuery(this).find('.js-show-edit-food').text().toLowerCase();
tds.eq(net_carbs_i).text(carbs - fiber);
if (name.indexOf("net carbs") !== -1 || (carbs - fiber) < 0) {
alreadyCountedFiber[alreadyCountedFiberIdx] += Number(fiber);
tds.eq(net_carbs_i).text(carbs);
}
}
});
var totalAlreadyCountedFiber = 0;
for (var i=0; i < alreadyCountedFiber.length; i++){ totalAlreadyCountedFiber += alreadyCountedFiber[i];}
var bottom_tr_elements = jQuery('.food_container tr.bottom, .food_container tr.total');
var meal_idx = 0;
bottom_tr_elements.each(function() {
if (jQuery(this).hasClass('remaining')) {
return false; /* continue */
}
var tds = jQuery(this).find('td');
var cals = parseFloat(tds.eq(calories_i).text());
var carbs = 0;
if($(this).hasClass('bottom')) {
carbs = parseFloat(tds.eq(carbs_i).text());
} else {
carbs = parseFloat(tds.eq(carbs_i).text()) + totalAlreadyCountedFiber;
}
var fiber = parseFloat(tds.eq(fiber_i).text());
var protein = parseFloat(tds.eq(protein_i).text());
var fat = parseFloat(tds.eq(fat_i).text());
var net_carbs = carbs;
// HACK to show net carbs
if (!jQuery(this).hasClass('alt')) {
net_carbs = carbs - fiber + alreadyCountedFiber[meal_idx];
if (!isNaN(net_carbs)) {
tds.eq(net_carbs_i).text(net_carbs);
} else if (jQuery(this).hasClass("total")) {
tds.eq(net_carbs_i).text("0");
}
} else {
// record goal
net_carb_total_goal = net_carbs;
}
/* do nothing if cannot calculate for the row */
if (isNaN(cals) ||
isNaN(carbs) ||
isNaN(protein) ||
isNaN(fat) ||
isNaN(fiber) ||
isNaN(net_carbs) ||
cals === 0) {
meal_idx++;
return true;
}
tds.eq(net_carbs_i).text(net_carbs);
// if (net_carbs == 0 &&
// protein == 0 &&
// fat == 0) {
// return true;
// }
var carb_cals = (net_carbs * 4);
var protein_cals = (protein * 4);
var fat_cals = (fat * 9);
if (jQuery(this).hasClass('total') &&
!jQuery(this).hasClass('alt') &&
daily_total_carbs === 0) {
daily_total_carbs = carb_cals;
daily_total_protein = protein_cals;
daily_total_fat = fat_cals;
net_carb_total = net_carbs - totalAlreadyCountedFiber;
}
var real_cals = carb_cals + protein_cals + fat_cals;
var carb_pct = ((carb_cals / real_cals) * 100).toFixed(2);
var fat_pct = ((fat_cals / real_cals) * 100).toFixed(2);
var protein_pct = ((protein_cals / real_cals) * 100).toFixed(2);
//alert(daily_total_carbs + ", " + daily_total_protein + ", " + daily_total_fat + ", " + net_carb_total);
carb_pct = Math.round(carb_pct);
fat_pct = Math.round(fat_pct);
protein_pct = Math.round(protein_pct);
tds.each(function() {
jQuery(this).append('
');
});
tds.eq(0).find('div.myfp_us').html("");
/*tds.eq(calories_i).find('div.myfp_us').html(real_cals);*/
if (!isNaN(carb_pct)) {
tds.eq(net_carbs_i).find('div.myfp_us').html(carb_pct + "%");
}
if (!isNaN(fat_pct)) {
tds.eq(fat_i).find('div.myfp_us').html(fat_pct + "%");
}
if (!isNaN(protein_pct)) {
tds.eq(protein_i).find('div.myfp_us').html(protein_pct + "%");
}
meal_idx++;
});
var remaining_tr_elements = jQuery('.food_container tr.total.remaining');
remaining_tr_elements.each(function() {
// Show remaining as net carbs
var net_carbs = net_carb_total_goal - net_carb_total - totalAlreadyCountedFiber;
var tds = jQuery(this).find('td');
tds.eq(net_carbs_i).text(parseInt(net_carbs));
// Fix color
tds.eq(net_carbs_i).removeClass("positive");
tds.eq(net_carbs_i).removeClass("negative");
if (net_carbs < 0) {
tds.eq(net_carbs_i).addClass("negative");
} else {
tds.eq(net_carbs_i).addClass("positive");
}
});
if (daily_total_carbs !== 0 ||
daily_total_protein !== 0 ||
daily_total_fat !== 0) {
jQuery('.food_container').append('');
var data1 = new google.visualization.DataTable();
data1.addColumn('string', 'Type');
data1.addColumn('number', 'Cals');
data1.addRows(
[
['Net Carbs', daily_total_carbs],
['Protein', daily_total_protein],
['Fat', daily_total_fat]
]
);
var chart = new google.visualization.PieChart(document.getElementById('google_graph_1'));
chart.draw(data1, {
width: 350,
height: 300,
title: 'Daily Totals by Calories (This is what you use for your macro ratios)'
});
document.getElementById('google_graph_1').style.cssFloat = "left";
jQuery('.food_container').append('');
var carb_grams = daily_total_carbs / 4;
var pro_grams = daily_total_protein / 4;
var fat_grams = daily_total_fat / 9;
var data2 = new google.visualization.DataTable();
data2.addColumn('string', 'Type');
data2.addColumn('number', 'Grams');
data2.addRows(
[
['Net Carbs (' + carb_grams + 'g)', carb_grams],
['Protein (' + pro_grams + 'g)', pro_grams],
['Fat (' + fat_grams + 'g)', fat_grams]
]
);
var chart2 = new google.visualization.PieChart(document.getElementById('google_graph_2'));
chart2.draw(data2, {
width: 350,
height: 300,
title: 'Daily Totals by Grams'
});
document.getElementById('google_graph_2').style.cssFloat = "right";
}
}