Fancy Stats

Displays Corsi, Fenwick, and Shot data in real-time.

当前为 2014-10-09 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Fancy Stats
  3. // @namespace http://some.homepage.orsomething/
  4. // @version 1.1009
  5. // @description Displays Corsi, Fenwick, and Shot data in real-time.
  6. // @grant none
  7. // @match http://www.nhl.com/scores/htmlreports/*
  8. // @match http://www.nhl.com/ice/gamestats.htm*
  9. // @match http://www.japersrink.com/*
  10. // @match http://www.stanleycupofchowder.com/*
  11. // @match http://www.diebytheblade.com/*
  12. // @match http://www.canescountry.com/*
  13. // @match http://www.jacketscannon.com/*
  14. // @match http://www.wingingitinmotown.com/*
  15. // @match http://www.litterboxcats.com/*
  16. // @match http://www.habseyesontheprize.com/*
  17. // @match http://www.inlouwetrust.com/*
  18. // @match http://www.lighthousehockey.com/*
  19. // @match http://www.blueshirtbanter.com/*
  20. // @match http://www.silversevensens.com/*
  21. // @match http://www.broadstreethockey.com/*
  22. // @match http://www.pensburgh.com/*
  23. // @match http://www.rawcharge.com/*
  24. // @match http://www.pensionplanpuppets.com/*
  25. // @match http://www.anaheimcalling.com/*
  26. // @match http://www.matchsticksandgasoline.com/*
  27. // @match http://www.secondcityhockey.com/*
  28. // @match http://www.milehighhockey.com/*
  29. // @match http://www.defendingbigd.com/*
  30. // @match http://www.coppernblue.com/*
  31. // @match http://www.jewelsfromthecrown.com/*
  32. // @match http://www.hockeywilderness.com/*
  33. // @match http://www.ontheforecheck.com/*
  34. // @match http://www.fiveforhowling.com/*
  35. // @match http://www.fearthefin.com/*
  36. // @match http://www.stlouisgametime.com/*
  37. // @match http://www.nucksmisconduct.com/*
  38. // @match http://www.arcticicehockey.com/*
  39. // @copyright 2012+, You
  40. // ==/UserScript==
  41. var gameEvents;
  42. var xInit=60,yInit=60,xMaxInit=320,yMaxInit=240, fontSize=16;
  43. var xscale,yscale,y2scale,scaleFactor=1,average=5;
  44. var visitor,home;
  45. var cbHash;
  46. var graph;
  47. var PAGE;
  48. var RTSS_PAGE = "http://www.nhl.com/ice/gamestats.htm?fetchKey=20152ALLSATAll&sort=gameDate&viewName=teamRTSSreports";
  49.  
  50. window.document.onload = begin();
  51.  
  52. function Curve(c,v,y2){
  53. this.color = (typeof(c)==='undefined') ? "#000000" : c;
  54. this.vertline = (typeof(c)==='undefined') ? false : v;
  55. this.y2axis = (typeof(c)==='undefined') ? false : y2;
  56. }
  57.  
  58. function Team(){
  59. this.fullname="";
  60. this.nickname="";
  61. this.score=0;
  62. this.fenwick=new Curve();
  63. this.dFenwick=new Curve();
  64. this.corsi=new Curve();
  65. this.dCorsi=new Curve();
  66. this.shots=new Curve();
  67. this.dShots=new Curve();
  68. this.goals=new Curve('#000000',true);
  69. this.penalties=new Curve('#000000',true);
  70. }
  71.  
  72. function begin(){
  73. if(document.URL.indexOf("www.nhl.com/scores/htmlreports")>0){
  74. if(window.top != window.self){
  75. document.body.style.display='none';
  76. respondToSizingMessage = function(e) {
  77. //if(e.origin == 'http://origin-domain.com') {
  78. // e.data is the string sent by the origin with postMessage.
  79. if(e.data == 'sizing?') {
  80. var h = document.getElementById('cbtable').offsetHeight;
  81. h += document.getElementById('graph').height;
  82. h += 10;
  83. var w = Math.max(document.getElementById('cbtable').offsetWidth, document.getElementById('graph').width)+10;
  84. window.top.postMessage('sizing:'+h+','+w, e.origin);
  85. }
  86. //}
  87. };
  88. window.addEventListener('message', respondToSizingMessage, false);
  89. }
  90. Curve.prototype=new Array;
  91. gameEvents=new Array();
  92. visitor=new Team();
  93. home=new Team();
  94. cbHash=new Array();
  95. PAGE=document.URL.substring(document.URL.lastIndexOf("/")+1,document.URL.lastIndexOf("."));
  96. loadxml();
  97. parseEvents();
  98. insertElements();
  99. createCurves();
  100. updateFromCookie();
  101. //Load and display Fenwick data by default
  102. //curves.push(home.fenwick);
  103. //curves.push(visitor.fenwick);
  104. //drawGrid(Math.max(home.fenwick.length,visitor.fenwick.length));
  105. //plotCurve(home.fenwick);
  106. //plotCurve(visitor.fenwick);
  107. } else if(document.URL.indexOf("www.nhl.com/ice/gamestats.htm")>0){
  108. if( window.top != window.self && document.URL.indexOf("teamRTSSreports")>0 ){
  109. document.getElementById("fullPage").style.display = 'none';
  110. document.getElementById("c_copyright").style.display = 'none';
  111. document.getElementById("c_drippan").style.display = 'none';
  112. document.getElementById("dripTopAd").style.display = 'none';
  113. document.getElementById("masthead").style.display = 'none';
  114. document.getElementById("drippan").style.display = 'none';
  115. document.getElementById("leagueSiteMenu").style.display = 'none';
  116. var rows = document.getElementById("statsLegend").previousSibling.tBodies[0].childNodes;
  117. var t = document.createElement("table");
  118. t.setAttribute('class','data');
  119. var tb = document.createElement('tbody');
  120. t.appendChild(tb);
  121. for(var i=0; i<Math.min(15,rows.length); i++){
  122. var row = rows[i].childNodes;
  123. var tr = document.createElement('tr');
  124. tr.appendChild(row[0].cloneNode(true));
  125. tr.appendChild(row[2].cloneNode(true));
  126. tr.appendChild(row[3].cloneNode(true));
  127. tr.appendChild(row[8].cloneNode(true));
  128. tb.appendChild(tr);
  129. }
  130. document.getElementById("pageBody").insertBefore(t,document.getElementById("fullPage"));
  131. }
  132. } else { //create an iframe element that will load the game report
  133. var d = document.createElement("div");
  134. d.id = 'div';
  135. d.style.position = "fixed";
  136. d.style.right = "10px";
  137. d.style.zIndex = "100000";
  138. var ss = document.createElement("style");
  139. ss.type = "text/css";
  140. document.getElementsByTagName("head")[0].appendChild(ss);
  141. var toggle = document.createElement("button");
  142. toggle.textContent = 'Toggle Graph';
  143. toggle.onclick=function(){
  144. if(document.getElementById('frame').style.display == 'none'){
  145. document.getElementById('frame').style.display = '';
  146. document.getElementById('resizeBtn').style.display = '';
  147. //document.getElementById('cookieBtn').style.display = '';
  148. document.getElementById('switchBtn').style.display = '';
  149. ss.innerHTML = ".l-page-wrap{margin:0 !important;}";
  150. } else {
  151. document.getElementById('frame').style.display = 'none';
  152. document.getElementById('resizeBtn').style.display = 'none';
  153. //document.getElementById('cookieBtn').style.display = 'none';
  154. document.getElementById('switchBtn').style.display = 'none';
  155. ss.innerHTML = "";
  156. }
  157. return; };
  158. d.appendChild(toggle);
  159. //d.appendChild(document.createElement("br"));
  160. //document.body.insertBefore(d, document.body.firstChild);
  161. /*
  162. toggle = document.createElement("button");
  163. toggle.textContent = 'Clear Cookie';
  164. toggle.id='cookieBtn';
  165. toggle.onclick=function(){
  166. eraseCookie('myCookie'+PAGE);
  167. eraseCookie('mySize');
  168. eraseCookie('myColors'+PAGE);
  169. eraseCookie('myAverage'+PAGE); };
  170. d.appendChild(toggle);
  171. */
  172. //d.appendChild(document.createElement("br"));
  173. //document.body.insertBefore(d, document.body.firstChild);
  174. toggle = document.createElement("button");
  175. toggle.textContent = 'Resize';
  176. toggle.id='resizeBtn';
  177. toggle.style.display='none';
  178. toggle.onclick=function(){
  179. frame.contentWindow.postMessage('sizing?', '*'); };
  180. d.appendChild(toggle);
  181. toggle = document.createElement("button");
  182. toggle.textContent = 'Switch Game';
  183. toggle.style.display='none';
  184. toggle.id='switchBtn';
  185. toggle.onclick=function(){
  186. document.getElementById('frame').src=RTSS_PAGE; };
  187. d.appendChild(toggle);
  188. d.appendChild(document.createElement("br"));
  189. //var sp=document.createElement('span');
  190. //var inp=document.createElement('input');
  191. //var t=document.createTextNode('Width:');
  192. //inp.type='text';
  193. //inp.size=3;
  194. //inp.setAttribute('id','average');
  195. //sp.setAttribute('class','curves visitor');
  196. //inp.value='400';
  197. //inp.onchange=function(){
  198. // document.getElementById("frame").width=document.getElementById('graph').width;
  199. // document.getElementById("div").width=this.value;};
  200. //sp.appendChild(t);
  201. //sp.appendChild(inp);
  202. //d.appendChild(sp);
  203. document.body.insertBefore(d, document.body.firstChild);
  204. handleSizingResponse = function(e) {
  205. //if(e.origin == 'http://remote-domain.com') {
  206. var action = e.data.split(':')[0];
  207. if(action == 'sizing') {
  208. var f = document.getElementById("frame");
  209. f.height=e.data.split(':')[1].split(",")[0];
  210. f.width=e.data.split(':')[1].split(",")[1];
  211. } else {
  212. console.log("Unknown message: "+e.data);
  213. }
  214. //}
  215. };
  216. window.addEventListener('message', handleSizingResponse, false);
  217. var frame = document.createElement("iframe");
  218. frame.id='frame';
  219. frame.height = "500";
  220. frame.width = "400";
  221. frame.style.right = "10px";
  222. frame.setAttribute('style',"background-color:white;float:right");
  223. frame.style.display = 'none';
  224. frame.src = RTSS_PAGE;
  225. d.appendChild(frame);
  226. }
  227. }
  228.  
  229. function loadxml(){
  230. //var req=new XMLHttpRequest();
  231. //req.open("GET","PL020467.HTM",false);
  232. //req.send();
  233. //var txt=req.responseText;
  234. //var txt=document.firstChild.getElementsByTagName("body")[0].outerHTML;
  235. var txt=document.body.outerHTML;
  236. txt=txt.replace(/<img(.*?)>/ig,"");
  237. txt=txt.replace(/<head([\s\S]*?)<\/head>/ig,"");
  238. txt=txt.replace(/<html(.*?)>/ig,"<xmlnode>");
  239. txt=txt.replace("</html>","</xmlnode>");
  240. txt=txt.replace(/<xmlfile(.*?)>/ig,"");
  241. txt=txt.replace("</xmlfile>","");
  242. txt=txt.replace(/<body(.*?)>/ig,"");
  243. txt=txt.replace("</body>","");
  244. txt=txt.replace(/<br>/g,"<br/>");
  245. txt=txt.replace(/&nbsp;/g,"");
  246. txt=txt.replace(/<style([\s\S]*?)<\/style>/ig,"");
  247. txt=txt.replace(/<font([\s\S]*?)<\/font>/ig,"");
  248. txt=txt.replace(/<script([\s\S]*?)<\/script>/ig,"");
  249. //doc=document.createDocumentFragment();
  250. var gamexml=document.createElement("div");
  251. gamexml.id="xml";
  252. gamexml.innerHTML=txt;
  253. gamexml.hidden=true;
  254. document.firstChild.insertBefore(gamexml,document.body);
  255. //var kid=txt.firstChild;
  256. //events=parser.parseFromString(txt,"text/xml");
  257. //alert(xml.firstChild.hasChildren);
  258. //xmlDoc=document.implementation.createDocument("","",null);
  259. //xmlDoc.async=false;
  260. //xmlDoc.load("PL020420.HTM");
  261. }
  262.  
  263. function parseEvents(){
  264. var nodes=document.getElementById("xml").children;
  265. getTeam(visitor,document.getElementById("Visitor").firstElementChild.children[2].firstElementChild.textContent);
  266. getTeam(home,document.getElementById("Home").firstElementChild.children[2].firstElementChild.textContent);
  267. for(var i=0; i<nodes.length; i++){
  268. if(nodes[i].nodeName.toLowerCase()!="table"){
  269. continue;
  270. }
  271. var rows=nodes[i].firstElementChild.children;
  272. for(var j=0; j<rows.length; j++){
  273. if(!(rows[j].nodeName.toLowerCase()=="tr" && rows[j].className=="evenColor")){
  274. continue;
  275. }
  276. var period=parseFloat(rows[j].children[1].innerHTML);
  277. var status=rows[j].children[2].innerHTML;
  278. var time=rows[j].children[3].childNodes[0].nodeValue;
  279. time=time.replace(/\"/g,"");
  280. var min=parseFloat(time.replace(/:.*[0-9]/g,""));
  281. var sec=parseFloat(time.replace(/.*[0-9]:/g,""));
  282. time=((period-1)*20 + min + sec/60);
  283. var event=rows[j].children[4].innerHTML;
  284. var description=rows[j].children[5].innerHTML;
  285. if(description.substring(0,3)==visitor.nickname){
  286. description=visitor.nickname;
  287. } else if(description.substring(0,3)==home.nickname) {
  288. description=home.nickname;
  289. }
  290. var arr=new Array(time,event,description,status);
  291. gameEvents.push(arr);
  292. }
  293. }
  294. }
  295.  
  296. function insertElements(){
  297. addStyle();
  298. var container = document.createElement('div');
  299. container.setAttribute('id','fancystats');
  300. document.firstChild.insertBefore(container,document.body);
  301. var cbtable = document.createElement('table');
  302. cbtable.id='cbtable';
  303. var cbb = document.createElement('tbody');
  304. cbtable.appendChild(cbb);
  305. cbtable.align='center';
  306. container.appendChild(cbtable);
  307. var tr = cbb.appendChild(document.createElement('tr'));
  308. var td = tr.appendChild(document.createElement('td'));
  309. td.appendChild(createCB(visitor.corsi, visitor.nickname+' Corsi'));
  310. td = tr.appendChild(document.createElement('td'));
  311. td.appendChild(createCB(home.corsi, home.nickname+' Corsi'));
  312.  
  313. tr = cbb.appendChild(document.createElement('tr'));
  314. td = tr.appendChild(document.createElement('td'));
  315. td.appendChild(createCB(visitor.fenwick, visitor.nickname+' Fenwick'));
  316. td = tr.appendChild(document.createElement('td'));
  317. td.appendChild(createCB(home.fenwick, home.nickname+' Fenwick'));
  318. tr = cbb.appendChild(document.createElement('tr'));
  319. td = tr.appendChild(document.createElement('td'));
  320. td.appendChild(createCB(visitor.shots, visitor.nickname+' Shots'));
  321. td = tr.appendChild(document.createElement('td'));
  322. td.appendChild(createCB(home.shots, home.nickname+' Shots'));
  323. tr = cbb.appendChild(document.createElement('tr'));
  324. td = tr.appendChild(document.createElement('td'));
  325. td.appendChild(createCB(visitor.dCorsi, visitor.nickname+' dCorsi',visitor.nickname+' Corsi Rate'));
  326. td = tr.appendChild(document.createElement('td'));
  327. td.appendChild(createCB(home.dCorsi, home.nickname+' dCorsi',home.nickname+' Corsi Rate'));
  328. tr = cbb.appendChild(document.createElement('tr'));
  329. td = tr.appendChild(document.createElement('td'));
  330. td.appendChild(createCB(visitor.dFenwick, visitor.nickname+' dFenwick',visitor.nickname+' Fenwick Rate'));
  331. td = tr.appendChild(document.createElement('td'));
  332. td.appendChild(createCB(home.dFenwick, home.nickname+' dFenwick',home.nickname+' Fenwick Rate'));
  333. tr = cbb.appendChild(document.createElement('tr'));
  334. td = tr.appendChild(document.createElement('td'));
  335. td.appendChild(createCB(visitor.dShots, visitor.nickname+' dShots',visitor.nickname+' Shot Rate'));
  336. td = tr.appendChild(document.createElement('td'));
  337. td.appendChild(createCB(home.dShots, home.nickname+' dShots',home.nickname+' Shot Rate'));
  338. tr = cbb.appendChild(document.createElement('tr'));
  339. td = tr.appendChild(document.createElement('td'));
  340. td.appendChild(createCB(visitor.goals, visitor.nickname+' Goals'));
  341. td = tr.appendChild(document.createElement('td'));
  342. td.appendChild(createCB(home.goals, home.nickname+' Goals'));
  343. tr = cbb.appendChild(document.createElement('tr'));
  344. td = tr.appendChild(document.createElement('td'));
  345. var sel=document.createElement('select');
  346. sel.setAttribute('id','visitorColor');
  347. //sel.setAttribute('class','curves visitor');
  348. var opt=document.createElement('option');
  349. opt.setAttribute('value',visitor.fenwick.color);
  350. opt.innerHTML='Color:';
  351. sel.appendChild(opt);
  352. opt=document.createElement('option');
  353. opt.setAttribute('value','#000000');
  354. opt.innerHTML='black';
  355. sel.appendChild(opt);
  356. opt=document.createElement('option');
  357. opt.setAttribute('value','#FF0000');
  358. opt.innerHTML='red';
  359. sel.appendChild(opt);
  360. opt=document.createElement('option');
  361. opt.setAttribute('value','#0000FF');
  362. opt.innerHTML='blue';
  363. sel.appendChild(opt);
  364. sel.onchange=function(){return changeColors();};
  365. //document.firstChild.insertBefore(sel,document.body);
  366. td.appendChild(sel);
  367. td = tr.appendChild(document.createElement('td'));
  368. sel=document.createElement('select');
  369. sel.setAttribute('id','homeColor');
  370. //sel.setAttribute('class','curves home');
  371. opt=document.createElement('option');
  372. opt.setAttribute('value',home.fenwick.color);
  373. opt.innerHTML='Color:';
  374. sel.appendChild(opt);
  375. opt=document.createElement('option');
  376. opt.setAttribute('value','#000000');
  377. opt.innerHTML='black';
  378. sel.appendChild(opt);
  379. opt=document.createElement('option');
  380. opt.setAttribute('value','#FF0000');
  381. opt.innerHTML='red';
  382. sel.appendChild(opt);
  383. opt=document.createElement('option');
  384. opt.setAttribute('value','#0000FF');
  385. opt.innerHTML='blue';
  386. sel.appendChild(opt);
  387. sel.onchange=function(){return changeColors();};
  388. //document.firstChild.insertBefore(sel,document.body);
  389. td.appendChild(sel);
  390. tr = cbb.appendChild(document.createElement('tr'));
  391. td = tr.appendChild(document.createElement('td'));
  392. var sp=document.createElement('span');
  393. var inp=document.createElement('input');
  394. var t=document.createTextNode('Scale Graph:');
  395. inp.type='text';
  396. inp.size=2;
  397. inp.setAttribute('id','graphSize');
  398. sp.setAttribute('class','curves visitor');
  399. inp.value='1';
  400. inp.onchange=function(){return changeSize();};
  401. sp.appendChild(t);
  402. sp.appendChild(inp);
  403. //document.firstChild.insertBefore(sp,document.body);
  404. td.appendChild(sp);
  405.  
  406.  
  407. tr = cbb.appendChild(document.createElement('tr'));
  408. td = tr.appendChild(document.createElement('td'));
  409. sp=document.createElement('span');
  410. inp=document.createElement('input');
  411. t=document.createTextNode('Time for Rates(min):');
  412. inp.type='text';
  413. inp.size=2;
  414. inp.setAttribute('id','average');
  415. sp.setAttribute('class','curves visitor');
  416. inp.value='5';
  417. inp.onchange=function(){return changeAverage();};
  418. sp.appendChild(t);
  419. sp.appendChild(inp);
  420. //document.firstChild.insertBefore(sp,document.body);
  421. td.appendChild(sp);
  422. var d=document.createElement('div');
  423. var canvas=document.createElement("canvas");
  424. d.setAttribute('class','graph');
  425. canvas.id="graph";
  426. d.appendChild(canvas);
  427. //document.firstChild.insertBefore(d,document.body);
  428. container.appendChild(d);
  429.  
  430. }
  431.  
  432. function createCB(arr,id,t){
  433. t=typeof t !== 'undefined' ? t : id;
  434. var sp=document.createElement('span');
  435. var cb=document.createElement('input');
  436. var tx=document.createTextNode(t);
  437. var cls=id.split(" ")[0].toLowerCase();
  438. sp.setAttribute('class',"curves "+cls);
  439. cb.type='checkbox';
  440. cb.setAttribute('id',id.replace(" ","-"));
  441. cb.onclick=function(){
  442. return updateGraph();
  443. };
  444. sp.appendChild(cb);
  445. sp.appendChild(tx);
  446. //document.firstChild.insertBefore(sp,document.body);
  447. cbHash.push([id.replace(" ","-"),arr]);
  448. return sp;
  449. }
  450.  
  451. function addStyle(){
  452. var css = document.createElement("style");
  453. var hd=document.firstChild.getElementsByTagName("head")[0];
  454. css.type = "text/css";
  455. css.innerHTML = ".curves{position:relative;} "+
  456. ".home{float:left;} "+
  457. ".visitor{display:block;left:50px;} "+
  458. ".graph{text-align:center;}";
  459. hd.appendChild(css);
  460. }
  461.  
  462. function createCurves(){
  463. for(var i=0; i<gameEvents.length; i++){
  464. var time=gameEvents[i][0];
  465. var event=gameEvents[i][1];
  466. var team=gameEvents[i][2];
  467. //Fenwick and Corsi lines
  468. if(event=='SHOT' || event=='MISS' || event=='BLOCK' || event=='GOAL'){
  469. if(event!='BLOCK'){
  470. (team==home.nickname) ? home.fenwick.push([time,home.fenwick.length+1]) :
  471. visitor.fenwick.push([time,visitor.fenwick.length+1]);
  472. if(event!='MISS'){
  473. (team==home.nickname) ? home.shots.push([time,home.shots.length+1]) :
  474. visitor.shots.push([time,visitor.shots.length+1]);
  475. }
  476. }
  477.  
  478. (team==home.nickname) ? home.corsi.push([time,home.corsi.length+1]) :
  479. visitor.corsi.push([time,visitor.corsi.length+1]);
  480. //Vertical line for goals
  481. if(event=='GOAL'){
  482. (team==home.nickname) ? home.goals.push([time,home.goals.length+1]) :
  483. visitor.goals.push([time,visitor.goals.length+1]);
  484. }
  485. checkCurveTimes(home.fenwick);
  486. checkCurveTimes(home.corsi);
  487. checkCurveTimes(home.shots);
  488. checkCurveTimes(visitor.fenwick);
  489. checkCurveTimes(visitor.corsi);
  490. checkCurveTimes(visitor.shots);
  491. }
  492. //Vertical line for penalties
  493. if(event=='PENL'){
  494. (team==home.nickname) ? home.penalties.push([time,home.penalties.length+1]) :
  495. visitor.penalties.push([time,visitor.penalties.length+1]);
  496. }
  497. }
  498. //Make sure that the lines continue until the end of game time
  499. var endTime=gameEvents[gameEvents.length-1][0];
  500. home.fenwick.push([endTime,home.fenwick.length+1]);
  501. home.corsi.push([endTime,home.corsi.length+1]);
  502. home.shots.push([endTime,home.shots.length+1]);
  503. visitor.fenwick.push([endTime,visitor.fenwick.length+1]);
  504. visitor.corsi.push([endTime,visitor.corsi.length+1]);
  505. visitor.shots.push([endTime,visitor.shots.length+1]);
  506. //Adjust the fenwick/corsi curves. Sometimes mulitple events
  507. //occur at the same second. When the derivative is taken, it
  508. //throws an error bc division by t(n)-t(n-1)=0 is INF
  509. //Calculate rolling average Fenwick and Corsi lines
  510. avgCurve(home.fenwick,home.dFenwick);
  511. avgCurve(home.corsi,home.dCorsi);
  512. avgCurve(home.shots,home.dShots);
  513. avgCurve(visitor.fenwick,visitor.dFenwick);
  514. avgCurve(visitor.corsi,visitor.dCorsi);
  515. avgCurve(visitor.shots,visitor.dShots);
  516. }
  517.  
  518. function checkCurveTimes(arr){
  519. if(arr.length<2){
  520. return;
  521. }
  522. if(arr[arr.length-1][0]==arr[arr.length-2][0]){
  523. var n=arr.pop();
  524. arr[arr.length-1][1]=n[1];
  525. }
  526. }
  527.  
  528. function avgCurve(c,dc){
  529. //clear the old dCurve values
  530. while(dc[0] != undefined){
  531. dc.pop();
  532. }
  533. dc.color=c.color;
  534. dc.y2axis=true;
  535. var arr=new Curve();
  536. var dt=1/60;
  537. var numpts=c[c.length-1][0]/dt;
  538. var avg=average/dt;
  539. var cTime=0;
  540. arr.push([0,0]);
  541. for(var i=0;i<numpts;i++){
  542. var time=dt*i
  543. if(time>=c[cTime][0]){
  544. cTime++;
  545. }
  546. if(cTime==0){
  547. arr.push([time,0]);
  548. //arr.push([time,(time)*c[0][1]/c[cTime][0]]);
  549. }else{
  550. arr.push([time, c[cTime-1][1]]);
  551. //arr.push([time, c[cTime-1][1]+(time-c[cTime-1][0])*(c[cTime][1]-c[cTime-1][1])/(c[cTime][0]-c[cTime-1][0])]);
  552. }
  553. }
  554. for(var i=avg;i<numpts;i++){
  555. dc.push([ (arr[i][0]+arr[i-avg][0])/2, (arr[i][1]-arr[i-avg][1])/(arr[i][0]-arr[i-avg][0]) ]);
  556. }
  557. }
  558.  
  559. function updateGraph(){
  560. var i,curveMax=0,curveY2Max=0;
  561. var curves=new Array();
  562. var cookieVal='';
  563. eraseCookie('myCookie'+PAGE);
  564. //Update the array containing all the curves to be plotted
  565. for(i=0;i<cbHash.length;i++){
  566. var cb=document.getElementById(cbHash[i][0]);
  567. var arr=cbHash[i][1];
  568. if(cb.checked){
  569. curves.push(arr);
  570. cookieVal=cookieVal+cb.id+'/';
  571. }
  572. }
  573. createCookie('myCookie'+PAGE,cookieVal);
  574. //Find the max value of the plotted curves
  575. for(i=0;i<curves.length;i++){
  576. if(curves[i].vertline){
  577. continue;
  578. }
  579. if(curves[i].y2axis){
  580. for(var j=0;j<curves[i].length;j++){
  581. curveY2Max=Math.max(curveY2Max,curves[i][j][1]);
  582. }
  583. }else{
  584. curveMax=Math.max(curveMax,curves[i][curves[i].length-1][1]);
  585. }
  586. }
  587. drawGrid(curveMax,curveY2Max);
  588. for(i=0;i<curves.length;i++){
  589. if(curves[i].vertline){
  590. plotVertLine(curves[i]);
  591. }else{
  592. plotCurve(curves[i]);
  593. }
  594. }
  595. }
  596.  
  597. function drawGrid(fmax,f2max){
  598. var graph=document.getElementById("graph");
  599. var ctx=graph.getContext("2d");
  600. var tmax=gameEvents[gameEvents.length-1][0],dtic=10*scaleFactor,dt=20,df=10,df2=0.5;
  601. var y0=yInit,
  602. x0=xInit,
  603. ymax=yMaxInit*scaleFactor,
  604. xmax=xMaxInit*scaleFactor;
  605. var showY2=(f2max>0);
  606. var flipY2=false;
  607. if(fmax==0 && f2max>0){
  608. flipY2=true;
  609. showY2=false;
  610. fmax=f2max;
  611. df=df2;
  612. }
  613. var ny=Math.max(Math.floor(fmax/df),Math.floor(f2max/df2))+1;
  614. var dx=xmax/(Math.ceil(tmax/dt));
  615. var dy=ymax/(ny);
  616. xscale=dx/dt;
  617. yscale=dy/df;
  618. y2scale=dy/df2;
  619. graph.width=xmax+2*x0;
  620. graph.height=ymax+2*y0;
  621. ctx.rect(x0,y0,xmax,ymax);
  622. //Draw labels
  623. ctx.font=""+fontSize+"px Ariel";
  624. for(var i=0;i<ny;i++){//Draw y-axis labels
  625. var t=df*(i+1);
  626. var wid=x0-dtic-ctx.measureText(df*(i+1)).width;
  627. var heig=ymax+y0-dy*(i+1)+fontSize/2;
  628. //ctx.fillText(t,wid,heig);
  629. ctx.fillText(df*(i+1), x0-dtic-ctx.measureText(df*(i+1)).width,ymax+y0-dy*(i+1)+fontSize/2);
  630. if(showY2){
  631. ctx.fillText(df2*(i+1),x0+xmax+5,ymax+y0-dy*(i+1)+fontSize/2);
  632. }
  633. }
  634. for(var i=0;i<Math.ceil(tmax/dt);i++){//Draw x-axis labels
  635. ctx.fillText(dt*(i+1),x0+dx*(i+1)-ctx.measureText(dt*(i+1)).width/2,ymax+y0+dtic+fontSize);
  636. }
  637. ctx.font=""+fontSize*1.5+"px Ariel";
  638. ctx.fillText("Time (min)",x0+xmax/2-ctx.measureText("Time (min)").width/2,y0+ymax+dtic+fontSize+fontSize*1.5);
  639. ctx.stroke();
  640. var vscore = document.getElementById("Visitor").firstElementChild.children[1].firstElementChild.firstElementChild.firstElementChild.firstElementChild.children[1].textContent;
  641. var hscore = document.getElementById("Home").firstElementChild.children[1].firstElementChild.firstElementChild.firstElementChild.firstElementChild.children[1].textContent;
  642. var scoreText = visitor.nickname+" "+vscore+" | "+home.nickname+" "+hscore;
  643. ctx.fillText(scoreText,x0+xmax/2-ctx.measureText(scoreText).width/2,y0-dtic);
  644. ctx.stroke();
  645. var txt=(flipY2)?"Rate of Events (#/min)":"Events (#)"
  646. ctx.rotate(-90*Math.PI/180);
  647. ctx.fillText(txt,-(y0+ymax/2+ctx.measureText(txt).width/2),x0-dtic-fontSize-dtic/scaleFactor);
  648. ctx.stroke;
  649. if(showY2){
  650. ctx.rotate(Math.PI);
  651. ctx.fillText("Rate of Events (#/min)",y0+ymax/2-ctx.measureText("Rate of Events (#/min)").width/2,-(x0+xmax+dtic+ctx.measureText('10').width/1.5+dtic/scaleFactor));
  652. ctx.stroke;
  653. }
  654. //Flip the orientation of the canvas so that we can plot
  655. //the stuff with the correct origin and stuff.
  656. ctx.setTransform(1,0,0,-1,0,0);
  657. ctx.translate(0,-graph.height);
  658. ctx.moveTo(x0-dtic,y0+ymax);//Draw y-axis tick marks
  659. ctx.lineTo(x0+xmax,y0+ymax);
  660. for(var i=0;i<ny;i++){
  661. ctx.moveTo(x0-dtic,y0+i*dy);
  662. ctx.lineTo(x0+xmax,y0+i*dy);
  663. for(var j=0;j<4;j++){
  664. ctx.moveTo(x0-dtic/2,y0+i*dy+dy/4*j);
  665. ctx.lineTo(x0,y0+i*dy+dy/4*j);
  666. }
  667. }
  668. ctx.moveTo(x0+xmax,y0-dtic);//Draw x-axis tick marks
  669. ctx.lineTo(x0+xmax,y0+ymax);
  670. for(var i=0;i<Math.ceil(tmax/dt);i++){
  671. ctx.moveTo(x0+i*dx,y0-dtic);
  672. ctx.lineTo(x0+i*dx,y0+ymax);
  673. for(var j=0;j<4;j++){
  674. ctx.moveTo(x0+i*dx+dx/4*j,y0-dtic/2);
  675. ctx.lineTo(x0+i*dx+dx/4*j,y0);
  676. }
  677. }
  678. ctx.stroke();
  679. }
  680.  
  681. function plotCurve(arr){
  682. var graph=document.getElementById("graph");
  683. var ctx=graph.getContext("2d");
  684. var y0=yInit,x0=xInit,ymax=yMaxInit*scaleFactor,xmax=xMaxInit*scaleFactor,yPrev;
  685. ctx.beginPath();
  686. ctx.setTransform(1,0,0,-1,0,0);
  687. ctx.translate(0,-graph.height);
  688. ctx.strokeStyle=arr.color;
  689. ctx.moveTo(x0,y0);
  690. yPrev=y0;
  691. for(var i=0; i<arr.length; i++){
  692. if(arr.y2axis){
  693. ctx.lineTo(x0+arr[i][0]*xscale,yPrev);
  694. ctx.lineTo(x0+arr[i][0]*xscale,y0+arr[i][1]*y2scale);
  695. yPrev=y0+arr[i][1]*y2scale;
  696. }else{
  697. ctx.lineTo(x0+arr[i][0]*xscale,yPrev);
  698. ctx.lineTo(x0+arr[i][0]*xscale,y0+arr[i][1]*yscale);
  699. yPrev=y0+arr[i][1]*yscale;
  700. }
  701. }
  702. ctx.stroke();
  703. //ctx.strokeStyle="#000000";
  704. }
  705.  
  706. function plotVertLine(arr){
  707. var graph=document.getElementById("graph");
  708. var ctx=graph.getContext("2d");
  709. var y0=yInit,x0=xInit,ymax=yMaxInit*scaleFactor,xmax=xMaxInit*scaleFactor;
  710. ctx.beginPath();
  711. ctx.setTransform(1,0,0,-1,0,0);
  712. ctx.translate(0,-graph.height);
  713. ctx.strokeStyle=arr.color;
  714. for(var i=0; i<arr.length; i++){
  715. var dashes=50;
  716. var dl=ymax/(2*dashes-1);
  717. for(var j=0;j<2*dashes;j++){
  718. if(j%2==0){
  719. ctx.moveTo(x0+arr[i][0]*xscale,y0+dl*j);
  720. }else{
  721. ctx.lineTo(x0+arr[i][0]*xscale,y0+dl*j);
  722. }
  723. }
  724. }
  725. ctx.stroke();
  726. ctx.strokeStyle="#000000";
  727. }
  728.  
  729. function updateFromCookie(){
  730. var cookie=readCookie('myCookie'+PAGE);
  731. if(cookie!=null){
  732. eraseCookie('myCookie'+PAGE);
  733. var arr=cookie.split("/");
  734. for(var i=0;i<arr.length;i++){
  735. if(arr[i]=='') continue;
  736. var cb=document.getElementById(arr[i]);
  737. if(cb != null) cb.setAttribute('checked','true');
  738. }
  739. }
  740. cookie=readCookie('myColors'+PAGE);
  741. if(cookie!=null){
  742. arr=cookie.split("/");
  743. if(arr.length==2){
  744. document.getElementById('homeColor').value=arr[0];
  745. document.getElementById('visitorColor').value=arr[1];
  746. }
  747. changeColors();
  748. }
  749. cookie=readCookie('mySize');
  750. if(cookie!=null){
  751. document.getElementById('graphSize').value=cookie;
  752. scaleFactor=cookie;
  753. }
  754. cookie=readCookie('myAverage'+PAGE);
  755. if(cookie!=null){
  756. document.getElementById('average').value=cookie;
  757. average=cookie;
  758. avgCurve(home.fenwick,home.dFenwick);
  759. avgCurve(home.corsi,home.dCorsi);
  760. avgCurve(home.shots,home.dShots);
  761. avgCurve(visitor.fenwick,visitor.dFenwick);
  762. avgCurve(visitor.corsi,visitor.dCorsi);
  763. avgCurve(visitor.shots,visitor.dShots);
  764. }
  765. updateGraph();
  766. }
  767.  
  768. function getTeam(team,t){
  769. var fullname=new Array("ANAHEIM DUCKS",
  770. "BOSTON BRUINS",
  771. "BUFFALO SABRES",
  772. "CALGARY FLAMES",
  773. "CAROLINA HURRICANES",
  774. "CHICAGO BLACKHAWKS",
  775. "COLORADO AVALANCHE",
  776. "COLUMBUS BLUE JACKETS",
  777. "DALLAS STARS",
  778. "DETROIT RED WINGS",
  779. "EDMONTON OILERS",
  780. "FLORIDA PANTHERS",
  781. "LOS ANGELES KINGS",
  782. "MINNESOTA WILD",
  783. "MONTREAL CANADIENS",
  784. "NASHVILLE PREDATORS",
  785. "NEW JERSEY DEVILS",
  786. "NEW YORK ISLANDERS",
  787. "NEW YORK RANGERS",
  788. "OTTAWA SENATORS",
  789. "PHILADELPHIA FLYERS",
  790. "PHOENIX COYOTES",
  791. "PITTSBURGH PENGUINS",
  792. "ST. LOUIS BLUES",
  793. "SAN JOSE SHARKS",
  794. "TAMPA BAY LIGHTNING",
  795. "TORONTO MAPLE LEAFS",
  796. "VANCOUVER CANUCKS",
  797. "WASHINGTON CAPITALS",
  798. "WINNIPEG JETS");
  799. var nickname=new Array("ANA",
  800. "BOS",
  801. "BUF",
  802. "CGY",
  803. "CAR",
  804. "CHI",
  805. "COL",
  806. "CBJ",
  807. "DAL",
  808. "DET",
  809. "EDM",
  810. "FLA",
  811. "L.A",
  812. "MIN",
  813. "MTL",
  814. "NSH",
  815. "N.J",
  816. "NYI",
  817. "NYR",
  818. "OTT",
  819. "PHI",
  820. "PHX",
  821. "PIT",
  822. "STL",
  823. "S.J",
  824. "T.B",
  825. "TOR",
  826. "VAN",
  827. "WSH",
  828. "WPG");
  829. var colors=new Array("#FF6600",//"ANAHEIM DUCKS",
  830. "#000000",//"BOSTON BRUINS",
  831. "#FFCC00",//"BUFFALO SABRES",
  832. "#FF3300",//"CALGARY FLAMES",
  833. "#CC0000",//"CAROLINA HURRICANES",
  834. "#FF3300",//"CHICAGO BLACKHAWKS",
  835. "#3366FF",//"COLORADO AVALANCHE",
  836. "#000066",//"COLUMBUS BLUE JACKETS",
  837. "#000000",//"DALLAS STARS",
  838. "#FF0000",//"DETROIT RED WINGS",
  839. "#FF6600",//"EDMONTON OILERS",
  840. "#A31919",//"FLORIDA PANTHERS",
  841. "#000000",//"LOS ANGELES KINGS",
  842. "#197519",//"MINNESOTA WILD",
  843. "#FF0000",//"MONTREAL CANADIENS",
  844. "#CC9900",//"NASHVILLE PREDATORS",
  845. "#CC0000",//"NEW JERSEY DEVILS",
  846. "#0000FF",//"NEW YORK ISLANDERS",
  847. "#0000CC",//"NEW YORK RANGERS",
  848. "#CC0000",//"OTTAWA SENATORS",
  849. "#FF6600",//"PHILADELPHIA FLYERS",
  850. "#800000",//"PHOENIX COYOTES",
  851. "#996600",//"PITTSBURGH PENGUINS",
  852. "#0066FF",//"SAINT LOUIS BLUES",
  853. "#006666",//"SAN JOSE SHARKS",
  854. "#0000FF",//"TAMPA BAY LIGHTNING",
  855. "#0000FF",//"TORONTO MAPLE LEAFS",
  856. "#0000CC",//"VANCOUVER CANUCKS",
  857. "#FF0000",//"WASHINGTON CAPITALS",
  858. "#000033");//"WINNIPEG JETS"
  859. for(var i=0;i<30;i++){
  860. //alert(team.indexOf(fullname[i]));
  861. if(t.indexOf(fullname[i])>=0){
  862. team.nickname=nickname[i];
  863. team.fullname=fullname[i];
  864. team.fenwick.color=colors[i];
  865. team.fenwick.name="fenwick"+nickname[i];
  866. team.corsi.color=colors[i];
  867. team.corsi.name="corsi"+nickname[i];
  868. team.shots.color=colors[i];
  869. team.shots.name="shots"+nickname[i];
  870. team.goals.name="goals"+nickname[i];
  871. team.penalties.name="penalties"+nickname[i];
  872. team.goals.color=colors[i];
  873. return;
  874. }
  875. }
  876. alert('team: '+t+'not found');
  877. return;
  878. }
  879.  
  880. function changeColors(){
  881. var homeColor=document.getElementById('homeColor').value;
  882. var visitorColor=document.getElementById('visitorColor').value;
  883. home.fenwick.color=homeColor;
  884. home.corsi.color=homeColor;
  885. home.shots.color=homeColor;
  886. home.dFenwick.color=homeColor;
  887. home.dCorsi.color=homeColor;
  888. home.dShots.color=homeColor;
  889. home.goals.color=homeColor;
  890. visitor.fenwick.color=visitorColor;
  891. visitor.corsi.color=visitorColor;
  892. visitor.shots.color=visitorColor;
  893. visitor.dFenwick.color=visitorColor;
  894. visitor.dCorsi.color=visitorColor;
  895. visitor.dShots.color=visitorColor;
  896. visitor.goals.color=visitorColor;
  897. eraseCookie('myColors'+PAGE);
  898. createCookie('myColors'+PAGE,homeColor+"/"+visitorColor);
  899. updateGraph();
  900. }
  901.  
  902. function changeSize(){
  903. var s=document.getElementById('graphSize').value;
  904. if(isNaN(s)){
  905. return;
  906. }
  907. createCookie('mySize',''+s);
  908. scaleFactor=s;
  909. updateGraph();
  910. window.postMessage('sizing:'+document.body.scrollHeight+','+document.body.scrollWidth, "*");
  911. //alert('Frames:'+window.top.frames);
  912. }
  913.  
  914. function changeAverage(){
  915. var avg=document.getElementById('average').value;
  916. if(isNaN(avg)){
  917. return;
  918. }
  919. average=avg;
  920. createCookie('myAverage'+PAGE,''+avg);
  921. avgCurve(home.fenwick,home.dFenwick);
  922. avgCurve(home.corsi,home.dCorsi);
  923. avgCurve(home.shots,home.dShots);
  924. avgCurve(visitor.fenwick,visitor.dFenwick);
  925. avgCurve(visitor.corsi,visitor.dCorsi);
  926. avgCurve(visitor.shots,visitor.dShots);
  927. updateGraph();
  928. }
  929.  
  930. function createCookie(name,value,days) {
  931. if (days) {
  932. var date = new Date();
  933. date.setTime(date.getTime()+(days*24*60*60*1000));
  934. var expires = "; expires="+date.toGMTString();
  935. }
  936. else var expires = "";
  937. document.cookie = name+"="+value+expires+"; path=/";
  938. }
  939.  
  940. function readCookie(name) {
  941. var nameEQ = name + "=";
  942. var ca = document.cookie.split(';');
  943. for(var i=0;i < ca.length;i++) {
  944. var c = ca[i];
  945. while (c.charAt(0)==' ') c = c.substring(1,c.length);
  946. if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  947. }
  948. return null;
  949. }
  950.  
  951. function eraseCookie(name) {
  952. createCookie(name,"",-1);
  953. }