Yahoo4Factors

By Cherokee Last update Oct 31, 2009 — Installed 313 times. Daily Installs: 0, 0, 0, 7, 5, 2, 3, 5, 8, 3, 5, 3, 3, 1, 4, 2, 1, 2, 22, 4, 3, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 2

There are 1 previous version of this script.

// Yahoo 4 factors boxscore
// version 0.3 
// 2009-10-31
//
// --------------------------------------------------------------------
//
// This is a Greasemonkey user script that adds team 4-factors stats
// to Yahoho NBA boxscores
//
// To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
// Then restart Firefox and revisit this script.
// Under Tools, there will be a new menu item to "Install User Script".
// Accept the default configuration and install.
//
// To uninstall, go to Tools/Manage User Scripts,
// select "Yahoo4Factors", and click Uninstall.
//
//
// ==UserScript==
// @name          Yahoo4Factors
// @description   Adds team 4-factors stats to Yahoo NBA boxscores
// @include       http://sports.yahoo.com/nba/boxscore*
// ==/UserScript==

/* BEGIN LICENSE BLOCK
Copyright (C) 2008 cherokee_acb (cherokee_acb@yahoo.es)

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You can download a copy of the GNU General Public License at
http://diveintomark.org/projects/greasemonkey/COPYING
or get a free printed copy by writing to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
END LICENSE BLOCK */

var mainDiv = document.getElementById('boxscore');
mainDiv.addEventListener('DOMNodeInserted', update4factors, false);
update4factors()

function update4factors() {
	doc = window.document;

    var live = 0;

    // Read team names
  	var teamCells = doc.evaluate("//td[@class='yspscores team']", doc.body, null,  
                                    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var awayTeam = teamCells.snapshotItem(0).textContent;
	var homeTeam = teamCells.snapshotItem(1).textContent;
	
	// Get team stats
  	var totals = doc.evaluate("//tr[@class='ysptblclbg5']", doc.body, null,  
                                    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
                                    
    // First, the away team
	var fgcA = totals.snapshotItem(2).cells[3];
	var fgmA = parseInt(fgcA.textContent.substring(0, fgcA.textContent.indexOf("-")));
	var fgaA = parseInt(fgcA.textContent.substring(fgcA.textContent.indexOf("-")+1));

	var p3cA = totals.snapshotItem(2).cells[4];
	var p3mA = parseInt(p3cA.textContent.substring(0, p3cA.textContent.indexOf("-")));
	var p3aA = parseInt(p3cA.textContent.substring(p3cA.textContent.indexOf("-")+1));

	var ftcA = totals.snapshotItem(2).cells[5];
	var ftmA = parseInt(ftcA.textContent.substring(0, ftcA.textContent.indexOf("-")));
	var ftaA = parseInt(ftcA.textContent.substring(ftcA.textContent.indexOf("-")+1));

	var orcA = totals.snapshotItem(2).cells[7];
    var trcA = totals.snapshotItem(2).cells[8];
	var orA = parseInt(orcA.textContent);
	var trA = parseInt(trcA.textContent);
    var drA = trA-orA;
    
    var toA = parseInt(totals.snapshotItem(2).cells[10].textContent);


    // Now the home team
	var fgcH = totals.snapshotItem(3).cells[3];
	var fgmH = parseInt(fgcH.textContent.substring(0, fgcH.textContent.indexOf("-")));
	var fgaH = parseInt(fgcH.textContent.substring(fgcH.textContent.indexOf("-")+1));

	var p3cH = totals.snapshotItem(3).cells[4];
	var p3mH = parseInt(p3cH.textContent.substring(0, p3cH.textContent.indexOf("-")));
	var p3aH = parseInt(p3cH.textContent.substring(p3cH.textContent.indexOf("-")+1));

	var ftcH = totals.snapshotItem(3).cells[5];
	var ftmH = parseInt(ftcH.textContent.substring(0, ftcH.textContent.indexOf("-")));
	var ftaH = parseInt(ftcH.textContent.substring(ftcH.textContent.indexOf("-")+1));

	var orcH = totals.snapshotItem(3).cells[7];
	var trcH = totals.snapshotItem(3).cells[8];
	var orH = parseInt(orcH.textContent);
	var trH = parseInt(trcH.textContent);
    var drH = trH-orH;

    var toH = parseInt(totals.snapshotItem(3).cells[10].textContent);
    

	// Get minutes played
	var yspscores = doc.evaluate("//span[@class='yspscores']", doc.body, null,  
                        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    var clock = yspscores.snapshotItem(1);
    var quarter = yspscores.snapshotItem(3);
	var min = 48;
    if (clock.textContent.match(/Final/)) {
    	if (quarter.textContent.match(/OT/)) {
    		if (quarter.textContent.charAt(0) == 'O' ) {
    			min = 53;
    		}
    		else {
    			min = 48 + 5*quarter.textContent.charAt(0);
    		}
    	}
    }
    else if (clock.textContent.match(/Half/)) {
        min = 24;
    }
    else if (clock.textContent.match(/End/)) {
        min = 12 * clock.textContent.charAt(4);
    }
    else {
        delimIndex = clock.textContent.indexOf(":");
		if (delimIndex==0) {
		 min = 11;
		}
        else {
            min = 11-parseInt(clock.textContent.substr(0, delimIndex));
        }
    	var secs = 60-parseInt(clock.textContent.substr(delimIndex+1, 2));
        quarter = parseInt(quarter.textContent.substr(0, 1));
        min += secs/60 + 12*(quarter-1);
    }

    // For possessions, we use the Hollinger formula with a 0.976 correction factor.
    //  Then we average both team estimates, and round to the nearest integer
	var possA = fgaA + 0.44*ftaA - orA + toA;
	var possH = fgaH + 0.44*ftaH - orH + toH;
	var poss = 0.976*(possH + possA)/2;
	poss = poss.toFixed(0);
	var pace = 48*poss/min;

    // Now, we compute efficiency and the four factors
	var effA = 100*(2*fgmA + p3mA + ftmA)/poss;
	var efgA = 100*(fgmA + 0.5*p3mA)/fgaA;
	var ftrA = 100*ftmA/fgaA;
	var orpA = 100*orA/(orA+drH);
	var torA = 100*toA/poss;

	var effH = 100*(2*fgmH + p3mH + ftmH)/poss;
	var efgH = 100*(fgmH + 0.5*p3mH)/fgaH;
	var ftrH = 100*ftmH/fgaH;
	var orpH = 100*orH/(orH+drA);
	var torH = 100*toH/poss;

    // Finally, we create the table, rows and cells where data will be displayed.
    // Format is the same as in the per-quarter score table
	var tdAux;	
	var bold;
	var cellWidth = '40px';  
	var teamWidth = '100px';  

	var factors = doc.createElement("table");
	// factors.setAttribute('align','center');

	var header = doc.createElement("tr");
	header.setAttribute('align', 'center');
    header.setAttribute('bgcolor',"#DEDEC6");
    tdAux = doc.createElement("td");
	header.appendChild(tdAux);
	tdAux = doc.createElement("td");
    bold = doc.createElement("b");
    if (min == 48) {
        bold.textContent = "Pace";
        tdAux.setAttribute('width',cellWidth );
    }
    else {
        bold.textContent = "Pace (Poss)";
        tdAux.setAttribute('width',2*cellWidth );
    }
    tdAux.appendChild(bold);
	header.appendChild(tdAux);
	tdAux = doc.createElement("td");
    bold = doc.createElement("b");
    bold.textContent = "Eff";
    tdAux.appendChild(bold);
	tdAux.setAttribute('width',cellWidth );
	header.appendChild(tdAux);
	tdAux = doc.createElement("td");
    bold = doc.createElement("b");
    bold.textContent = "eFG";
    tdAux.appendChild(bold);
	tdAux.setAttribute('width',cellWidth );
	header.appendChild(tdAux);
	tdAux = doc.createElement("td");
    bold = doc.createElement("b");
    bold.textContent = "FT/FG";
    tdAux.appendChild(bold);
	tdAux.setAttribute('width',cellWidth );
	header.appendChild(tdAux);
	tdAux = doc.createElement("td");
    bold = doc.createElement("b");
    bold.textContent = "OREB%";
    tdAux.appendChild(bold);
	tdAux.setAttribute('width',cellWidth );
	header.appendChild(tdAux);
	tdAux = doc.createElement("td");
    bold = doc.createElement("b");
    bold.textContent = "TOr";
    tdAux.appendChild(bold);
	tdAux.setAttribute('width',cellWidth );
	header.appendChild(tdAux);


	var aRow = doc.createElement("tr");
	aRow.setAttribute('align', 'center');
    aRow.setAttribute('class', 'ysptblclbg5');
	tdAux = doc.createElement("td");
	tdAux.setAttribute('align', 'left');
	tdAux.setAttribute('width', teamWidth);
	tdAux.setAttribute('class','yspscores team');
    tdAux.innerHTML = teamCells.snapshotItem(0).innerHTML;
	aRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
    if (min == 48) {
        tdAux.textContent = pace.toFixed(1);
    }
    else {
        tdAux.textContent = pace.toFixed(1) + " (" + poss + ")";
    }
	aRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	tdAux.textContent = effA.toFixed(1);
	aRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	tdAux.textContent = efgA.toFixed(1) + "%";
	aRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	tdAux.textContent = ftrA.toFixed(1);
	aRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	tdAux.textContent = orpA.toFixed(1);
	aRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	tdAux.textContent = torA.toFixed(1);
	aRow.appendChild(tdAux);

	var hRow = doc.createElement("tr");
	hRow.setAttribute('align', 'center');
    hRow.setAttribute('class', 'ysptblclbg5');
	tdAux = doc.createElement("td");
	tdAux.setAttribute('align', 'left');
	tdAux.setAttribute('width', teamWidth);
	tdAux.setAttribute('class','yspscores team');
    tdAux.innerHTML = teamCells.snapshotItem(1).innerHTML;
	hRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	// tdAux.textContent = pace.toFixed(1);
	hRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	tdAux.textContent = effH.toFixed(1);
	hRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	tdAux.textContent = efgH.toFixed(1) + "%";
	hRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	tdAux.textContent = ftrH.toFixed(1);
	hRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	tdAux.textContent = orpH.toFixed(1);
	hRow.appendChild(tdAux);
	tdAux = doc.createElement("td");
	tdAux.textContent = torH.toFixed(1);
	hRow.appendChild(tdAux);

	factors.appendChild(header);
	factors.appendChild(aRow);
	factors.appendChild(hRow);

    // We insert the 4 factors table into a <table> element, and this div just above the boxscore table
	var factorsTable = doc.createElement("table");
    factorsTable.setAttribute('align','center');
	factorsTable.appendChild(factors);

  	var tables = doc.evaluate("//table", doc.body, null,  
                                    XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    var boxscore = tables.snapshotItem(9);
    boxscore.parentNode.insertBefore(factorsTable, boxscore);

    // As an add-on, I insert a link to the ESPN PbP. Hopefully, it works for all games
    // First of all, I insert a separation hyphen. I don't know how to do it except by creating a <span> element
    var separation = doc.createElement("span");
    separation.textContent = " - ";
    var pbpLink = doc.createElement("a");
    var gameId = window.location.toString().substring(window.location.toString().indexOf("=")+1);
    var espnGameId = "2" + gameId.substr(3, 5) + "0" + gameId.substr(8,2);
    pbpLink.setAttribute("href", "http://scores.espn.go.com/nba/playbyplay?gameId=" + espnGameId);
    pbpLink.textContent = "ESPN PbP";
    var links = tables.snapshotItem(4).rows[0].cells[0];
    var newline = links.getElementsByTagName('br')[0];
    links.insertBefore(separation, newline);
    links.insertBefore(pbpLink, newline);

    //mainDiv.addEventListener('DOMNodeInserted', update4factors, false);
}    

//
// ChangeLog
// 2008-10-24 - 0.1 - First draft
// 2009-10-31 - 0.3 - Updated to 2009-10 format