Notes on JQuery

Google Download JQuery
jquery.com

Select “Download the compressed, production jQuery 2.1.1” to go to code.jquery.com

Save this code into a file named ‘jquery.js’.


<head>
  <script src="jquery.js"></script>
</head>

Or use the ajax.googleapis.com via:


<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
</head>

PUTTING IT TOGETHER
Create a file named index.html.


<html>
<head>
  <script src="jquery.js"></script>
  <script src="index.js"></script>
</head>
<body>
  <h1>Hello World</h1>
</body>
</html>

In the same folder, add the jquery.js file downloaded above and add a new file index.js with the following code:


$(document).ready(function() {
  console.log('...Hello World');
});

Open index.html in Google Chrome. Right click the heading and select “Inspect Element”. Then, click on the Console tab. This will show the message from the index.js file. This prints “…Hello World” to the console when the page is ready.

FINDING ELEMENTS
See api.jquery.com for more details.


$(document).ready(function() {
  $('div.mydiv').addClass('classToAdd'); // <div class='mydiv classToAdd'>
  $('#myID > li').addClass('classToAdd'); // <div id='myID'><li class='classToAdd'>
  $('#myID li.myclass').addClass('classToAdd'); // <div id='myID'><li class='myclass classToAdd'>
  $('#myID li:not(.classToAdd)').addClass('classToAdd'); // <div id='myID'><li class='classToAdd'> // Adds the classToAdd class to any li tag contained within an element whose id is myID which does not currently have the classToAdd class
  $('a[href^="mailto:"]').addClass('mailto'); // <a href='mailto:scottizu@gmail.com'>e-mail me</a> // Adds the mailto class to any anchor whose href starts with "mailto"
  $('a[href$="pdf"]').addClass('pdflink'); // Ends with pdf
  $('a[href^="http"][href*="google"]').addClass('googleClass'); // <a href='http://www.google.com' class='googleClass'>www.google.com</a>

  $('tr:even').addClass('classToAdd');
  $('tr:nth-child(odd)').addClass('classToAdd');
  $('td:contains(Henry)').nextAll().andSelf().addClass('classToAdd');
  $('td:contains(Henry)').parent().children().addClass('classToAdd');
  $('li li li').addClass('classToAdd');
  $('tr').find('td:eq(2)').addClass('classToAdd');
  $('td:contains(Henry)').parent().first().addClass('classToAdd');
  $('li > a').siblings().addClass('classToAdd');
  $('a[href$="pdf"]').closest('ul').addClass('classToAdd');
}); // starts with http and contains google

Advertisements

Setting Capabilities to Use Selenium WebDriver for Mobile Testing

If you visit: http://www.i4info.info

and then: http://www.i4info.info/history

on your mobile phone, you will get a User Agent.

Anytime a mobile device make a request for a webpage, it sends the User Agent in the headers of the HttpGet, HttpPost request. This in turn lets the server know which page to serve. You may allow WebDriver to test the appropriate environment by setting the Capabilities for Selenium WebDriver appropriately. Here is a class that will help with handling the user agent and setting the appropriate capability for the browser you are testing with.


import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.remote.DesiredCapabilities;

public class UserAgentHandler {
	public void handle(String useragent) {
		if (useragent != null && !useragent.trim().isEmpty()) {
			handleFirefox(useragent);
			handleChrome(useragent);
			handlePhantom(useragent);
		}
	}

	private void handleFirefox(String useragent) {
		try {
			DesiredCapabilities dc = DesiredCapabilities.firefox();
			FirefoxProfile profile = new FirefoxProfile();
			profile.setPreference("general.useragent.override", useragent);
			dc.setCapability(FirefoxDriver.PROFILE, profile);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	private void handleChrome(String useragent) {
		try {
			DesiredCapabilities dc = DesiredCapabilities.chrome();
			ChromeOptions chromeOptions = new ChromeOptions();
			chromeOptions.addArguments("--user-agent=" + useragent);
			dc.setCapability(ChromeOptions.CAPABILITY, chromeOptions);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	private void handlePhantom(String useragent) {
		try {
			DesiredCapabilities dc = DesiredCapabilities.phantomjs();
			dc.setJavascriptEnabled(true);
			dc.setCapability("phantomjs.page.settings.userAgent", useragent);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
}

Run Javascript through a Firefox Bookmark to Highlight Components

Read <a href=’https://scottizu.wordpress.com/2014/10/31/executing-javascript-through-a-firefox-bookmark/’>Executing Javascript Through A Firefox Bookmark</a> to find out how to run javascript through a bookmark.

The modification from that page will allow you to store your BookmarkScript.js file in the root directory of Tomcat.  This is accessed in the Firefox Bookmark via:

http://localhost:8080/BookmarkScript.js

This code will highlight components whose id matches the string given. For instance, the following code will place an overlay on top of all div elements whose id starts with “abc_”.

This code needs to reside in the Root directory of your local Tomcat instance and be named as BookmarkScript.js.


// Print a message at the bottom of the page
err=function(e){
  s=e.description;
  if(!s){
    s=String(e);
  }
  d=document.createElement("div");
  d.innerHTML=s;
  d.style.color="red";
  document.body.appendChild(d);
  return d;
};
// Create an overlay above the placement
createOverlayDiv=function(e, zind){
  d=document.createElement("div");
  d.id=e.id+"_epo";
  d.name=e.name+"_epo";
  
  // Set style, width and height, top and left offset based off e
  d.style.cssText=e.style.cssText;
  d.style.width=e.clientWidth+"px";
  d.style.height=e.clientHeight+"px";
  d.style.top=e.offsetTop+"px";
  d.style.left=e.offsetLeft+"px";

  // Add extra overlay styling
  d.style.zIndex=zind;
  d.style.position="absolute";
  d.style.opacity = .5;
  d.style.display="block";
  d.style.textAlign="center";
  d.style.border="2px solid #A7A"; // Pink Outline
  d.style.background="#ADF"; // Blue Background
  
  // Set Minimum Width/Height and add text (undefined, auto, 0)
  w=e.clientWidth;
  if((!w)||((w!="auto")&&(w<150))){
	w=150;
	d.style.width="150px";
  }
  h=e.clientHeight;
  if((!h)||((h!="auto")&&(h<50))){
    h=50;
    d.style.height="50px";
  }
  d.innerHTML=d.id+"<br>"+w+" x "+h;
	
  return d;
}
// Highlights the placement by creating an overlay
highlighter=function(es, match){
  els=[];
  for(i=0;i<es.length;i++){
    e=es[i];
    if(e.id.indexOf(match)>-1){
      els.push(e);
    }
  }
  for(i=0;i<els.length;i++){
    e=els[i];
    d=createOverlayDiv(e, 10+i);
	e.parentNode.appendChild(d);
  }
};
err("Highlighter, Version 1.0");
err("Errors:");
err("").style.paddingTop="50px";
// Highlight Divs with Ids starting with abc_
try{
  highlighter(document.getElementsByTagName("div"), "abc_");
}catch(e){
  err(e);
}

Executing Javascript through a Firefox Bookmark

In Firefox, you may open the bookmark menu by clicking on the downward triangle next to the star in the address bar.

ADD A NEW BOOKMARK

  • Go to http://www.google.com.
  • Open the bookmark menu.
  • Select “Bookmark This Page”.
  • In the Name: Field, enter “Hello World”.

CHANGE THE LOCATION TO INCLUDE JAVASCRIPT

  • Open the bookmark menu.
  • Right click the new “Hello World” bookmark and select Properties.
  • In the Location: Field, enter the following line:
    
    javascript:log=function(message){d=document.createElement("div");d.id="bmDiv";d.innerHTML=message;d.style.color="red";document.body.appendChild(d);};log('Hello%20World');
    
  • Hit Save.

Note: This code will create a div element, place the message within the div, style the div with red coloring and add the div with the message to the html (ie DOM).

USE THE NEW BOOKMARK TO EXECUTE JAVASCRIPT ON A PAGE

  • Open the bookmark menu.
  • Select the “Hello World” bookmark.

You should see new text on the bottom of the page, since a div element was added with the text “Hello World”.

MODIFY CODE TO EXECUTE JAVASCRIPT FROM A LOCAL SERVER
You can host javascript on a local instance of Tomcat and execute it on the page.

Step 1. Create the bookmark to execute the script from a server.

  • Create a new book mark named “Bookmark Script”.
  • Right click the “Bookmark Script” and select Properties.
  • In the Location: Field, enter the following line:
    
    javascript:addScript=function(){s=document.getElementById("bmScript");if(s){document.body.removeChild(s);}s=document.createElement("script");s.id="bmScript";s.src="http://localhost:8080/BookmarkScript.js";document.body.appendChild(s);};void(addScript());
    
  • Hit Save.

Note: This code will create a script element, change the source of the div element to point to a script running on the local host (ie local Tomcat Server) and add the script to the html (ie DOM).

Step 2. Run the server and add the script to the server.

  • Start the Tomcat Server (see Step 11: Setup Tomcat on the Server to Host the Front End Display from¬†https://scottizu.wordpress.com/2014/06/21/a-basic-dashboard/).
  • Add a file in the tomcat root directory named “BookmarkScript.js”.
  • Edit the javascript file “BookmarkScript.js” to include the following javascript:
    
    log=function(message){
      d=document.createElement("div");
      d.id="bmDiv";
      d.innerHTML=message;
      d.style.color="red";
      document.body.appendChild(d);
    };
    log('BookmarkScript');
    

Note: This code will create a div element, place the message within the div, style the div with red coloring and add the div with the message to the html (ie DOM).

USE THE NEW BOOKMARK TO EXECUTE JAVASCRIPT ON A PAGE FROM A LOCAL SERVER

  • Open the bookmark menu.
  • Select the “Bookmark Script” bookmark.

Note: In Firefox, you can right click and “Inspect element” which will give you access to the Console Tab, HTML Tab, etc. You can verify the html is being added by looking at the HTML Tab. To avoid getting an “Blocked loading mixed active content” error in the Console Tab, make sure you use http://www.google.com instead of https://www.google.com.

Using Javascript to Calculate Actual Rate of Return

When looking at deposits through the year, most companies do no accurately report earnings for individuals. One thing that I want to change is requiring institutions to be more transparent about individual profit. In other words, who cares how the markets are doing, what the fees are. Let’s focus on profit (after fees and other charges).

If we are not satisfied with profit, lets dig in deeper to see what the income or expenses are.

Here is code to calculate growth based on deposits:


<html>
<body>
<pre>
<script>
function logWrite(arg) {
  document.body.innerHTML = document.body.innerHTML + arg + '\n<br>';
}
function logClear() {
  document.body.innerHTML = '';
}

function parseDate(dateString) {
  var mdy = dateString.split('/')
  return new Date(mdy[2], mdy[0]-1, mdy[1]);
}

function yearsInBetweenDates(date1, date2) {
  return (date2-date1)/(1000*60*60*24*365);
}

function yearsInBetweenAssign(paymentArray, currentNetWorth) {
  for (var i = 0; i<paymentArray.length; i++) {
    paymentArray[i].years = yearsInBetweenDates(paymentArray[i].date, currentNetWorth.date);
  }
}

function findTotalPayments(paymentArray) {
  var total = 0;
  for (var i = 0; i<paymentArray.length; i++) {
    total = total + paymentArray[i].amount;
  }
  return total;
}

function findRateOfReturn(paymentArray, currentNetWorth, lowRate, highRate){
  yearsInBetweenAssign(paymentArray, currentNetWorth);
  while(highRate-lowRate > .0001) {
    var testRate = (lowRate + highRate)/2;
    var calculatedNetWorth = calculateNetWorth(paymentArray, testRate);
    if(calculatedNetWorth < currentNetWorth.amount) {
      lowRate = testRate;
    } else {
      highRate = testRate;
    }
  }
  return lowRate;
}

function calculateNetWorth(paymentArray, interestRate) {
  var total = 0;
  for (var i=0; i<paymentArray.length; i++) {
    var P = paymentArray[i].amount;
    var r = interestRate;
    var y = paymentArray[i].years;
    total = total + P*Math.pow((1+r), y);
  }
  return total;
}

function createTransaction(date, amount) {
  var object = new Object();
  object.date = parseDate(date);
  object.amount = amount;
  return object;
}

var currentNetWorth = createTransaction("10/25/2014", 111197.30);
var paymentArray = [
createTransaction("06/21/2013", 25000.00),
createTransaction("07/26/2013", 15101.06),
createTransaction("10/30/2013", 42084.34),
createTransaction("11/12/2013", 8541.71),
createTransaction("12/13/2013", 11000.00),
createTransaction("03/21/2014", 995.00),
createTransaction("04/21/2014", 995.00),
createTransaction("05/21/2014", 995.00),
createTransaction("06/20/2014", 995.00),
createTransaction("07/22/2014", 995.00),
createTransaction("08/19/2014", 995.00),
createTransaction("09/19/2014", 995.00),
createTransaction("10/21/2014", 995.00)
];
for (var i = 0; i<paymentArray.length; i++) {
  logWrite('DepositDate:'+paymentArray[i].date+' DespositAmount:'+paymentArray[i].amount);
}
var totalDeposits = findTotalPayments(paymentArray);
logWrite('Deposits:'+totalDeposits);
logWrite('Current:'+currentNetWorth.amount);
logWrite('Rate:'+findRateOfReturn(paymentArray, currentNetWorth, -1, 1));
logWrite('Growth:'+(currentNetWorth.amount-totalDeposits));

</script>
</pre>
</body>
</html>

Output:
DepositDate:Fri Jun 21 2013 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:25000
DepositDate:Fri Jul 26 2013 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:15101.06
DepositDate:Wed Oct 30 2013 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:42084.34
DepositDate:Tue Nov 12 2013 00:00:00 GMT-0800 (Pacific Standard Time) DespositAmount:8541.71
DepositDate:Fri Dec 13 2013 00:00:00 GMT-0800 (Pacific Standard Time) DespositAmount:11000
DepositDate:Fri Mar 21 2014 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:995
DepositDate:Mon Apr 21 2014 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:995
DepositDate:Wed May 21 2014 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:995
DepositDate:Fri Jun 20 2014 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:995
DepositDate:Tue Jul 22 2014 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:995
DepositDate:Tue Aug 19 2014 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:995
DepositDate:Fri Sep 19 2014 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:995
DepositDate:Tue Oct 21 2014 00:00:00 GMT-0700 (Pacific Daylight Time) DespositAmount:995
Deposits:109687.10999999999
Current:111197.3
Rate:0.01318359375
Growth:1510.1900000000169

Converting a Maven Project to Create a Runnable JAR

See www.petrikainulainen.net for more information.

In my pom.xml file, I changed build tag to include the “Maven Assembly Plugin”.
Only had to edit the main class value, based on the package and class name.


	<build>
		<plugins>             <!-- The configuration of maven-assembly-plugin -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-assembly-plugin</artifactId>
				<version>2.2.2</version>                 <!-- The configuration of the plugin -->
				<configuration>                     <!-- Specifies the configuration file of the assembly plugin -->
					<descriptors>
						<descriptor>src/main/assembly/assembly.xml</descriptor>
					</descriptors>
				</configuration>
			</plugin>             <!-- The configuration of maven-jar-plugin -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<version>2.3.1</version>                 <!-- The configuration of the plugin -->
				<configuration>                     <!-- Configuration of the archiver -->
					<archive>                         <!-- Manifest specific configuration -->
						<manifest>                             <!-- Classpath is added to the manifest of the created jar file. -->
							<addClasspath>true</addClasspath>                             <!-- Configures the classpath prefix. This configuration option is used to 
								specify that all needed libraries are found under lib/ directory. -->
							<classpathPrefix>lib/</classpathPrefix>                             <!-- Specifies the main class of the application -->
							<mainClass>com.main.SwingApp</mainClass>
						</manifest>
					</archive>
				</configuration>
			</plugin>
		</plugins>
	</build> 

The main class was from this file:


package com.main;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class SwingApp {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
    
    private static void createAndShowGUI() {
        System.out.println("Created GUI on EDT? "+
                SwingUtilities.isEventDispatchThread());
        JFrame f = new JFrame("Swing App");
        
        
        
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(250,250);
        f.setVisible(true);
    }

}

Then, added the default assembly file, creating a new source folder “src/main/assembly” and adding the “assembly.xml” file (reposted from www.petrikainulainen.net)


<assembly>
	<id>bin</id>     <!-- Generates a zip package containing the needed files -->
	<formats>
		<format>zip</format>
	</formats>       <!-- Adds dependencies to zip package under lib directory -->
	<dependencySets>
		<dependencySet>             <!-- Project artifact is not copied under library directory since it is added 
				to the root directory of the zip package. -->
			<useProjectArtifact>false</useProjectArtifact>
			<outputDirectory>lib</outputDirectory>
			<unpack>false</unpack>
		</dependencySet>
	</dependencySets>
	<fileSets>         <!-- Adds startup scripts to the root directory of zip package. The startup 
			scripts are located to src/main/scripts directory as stated by Maven conventions. -->
		<fileSet>
			<directory>${project.build.scriptSourceDirectory}</directory>
			<outputDirectory></outputDirectory>
			<includes>
				<include>startup.*</include>
			</includes>
		</fileSet>         <!-- adds jar package to the root directory of zip package -->
		<fileSet>
			<directory>${project.build.directory}</directory>
			<outputDirectory></outputDirectory>
			<includes>
				<include>*.jar</include>
			</includes>
		</fileSet>
	</fileSets>
</assembly> 

Then, after issuing ‘mvn package’ from Git Bash command prompt in the same directory as the pom.xml file, it created the target directory with a runnable jar. I double clicked the jar to test.

SWING
Help – Install New Software – Copy http://download.eclipse.org/releases/juno into field – Add
http://download.eclipse.org/windowbuilder/WB/integration/4.4/
Capture

Using Document Builder to Access an XML Tag Value

Imports…


import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.xml.sax.InputSource;
import java.io.StringReader;
import org.w3c.dom.Document;
import org.w3c.dom.CharacterData;

Method…


	private static String findXMLTagValueFromXML(String xml, String tag) throws Exception {
		DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		InputSource is = new InputSource();
	    is.setCharacterStream(new StringReader(xml));
	    Document doc = db.parse(is);
	    CharacterData child = (CharacterData) doc.getElementsByTagName(tag).item(0).getFirstChild();
	    return child.getData();
	}

Code to Compare Various Biweekly Programs for Loan Repayment

Output:
1. Bank Monthly – Payment:1054.247934371233 TotalPayments:379529.2563736439 TotalInterest:171529.25637364388 FinalDate:Thu Dec 17 2043 00:00:00 GMT-0800 (Pacific Standard Time)
2. Bank Biweekly – Payment:527.1239671856165 TotalPayments:351546.84394215257 TotalInterest:143546.84394215257 FinalDate:Sat Sep 17 2039 00:00:00 GMT-0700 (Pacific Daylight Time)
3. Bank Self Biweekly – Payment:1142.101928902169 TotalPayments:350690.9345657348 TotalInterest:142690.93456573485 FinalDate:Wed Aug 17 2039 00:00:00 GMT-0700 (Pacific Daylight Time)
4. Real Self Biweekly – Payment:527.1239671856165 TotalPayments:350084.2771545723 TotalInterest:142084.27715457234 FinalDate:Sat Jul 16 2039 00:00:00 GMT-0700 (Pacific Daylight Time)

Biweekly


<html>
<body>
<pre>
<script>
function log(arg) {
  document.body.innerHTML = document.body.innerHTML + arg + '\n<br>';
}

function logClear() {
  document.body.innerHTML = '';
}

function dateGenerateMM(month) {
  if(month>9) {
    return ""+month;
  } else {
    return "0"+month;
  }
}

function dateParse(dateString) {
  var mdy = dateString.split('/')
  return new Date(mdy[2], mdy[0]-1, mdy[1]);
}

function dateCalculateYearsBetween(date1, date2) {
  return (date2-date1)/(1000*60*60*24*365);
}

function createTransaction(date, amount) {
  var object = new Object();
  object.date = dateParse(date);
  object.amount = amount;
  return object;
}

function calculateNetWorth(transactionArray, interestRate) {
  var total = 0;
  for (var i=0; i<transactionArray.length; i++) {
    var P = transactionArray[i].amount;
    var r = interestRate;
    var y = transactionArray[i].years;
    total = total + P*Math.pow((1+r/12), y*12);
  }
  return total;
}

function findMortgagePayment(interestRate, loanAmount, startYear, numberOfYears, paymentLow, paymentHigh) {
  while(paymentHigh-paymentLow > .0001) {
    var payment = (paymentLow + paymentHigh)/2;
    var paymentArray = [];
    paymentArray[0] = createTransaction("12/17/"+(startYear-1), loanAmount);
    for(var i=0; i<numberOfYears; i++) {
      var yyyy = startYear + i;
      for(var j=1; j<=12; j++) {
        var mm = dateGenerateMM(j);
        paymentArray[paymentArray.length] = createTransaction(mm+"/17/"+yyyy, -payment);
	  }
    }
    var finalYear = startYear + numberOfYears - 1;
    var finalDate = dateParse("12/17/"+finalYear);
    for(var i=0; i<paymentArray.length; i++) {
      paymentArray[i].years = dateCalculateYearsBetween(paymentArray[i].date, finalDate);
    }
    var calculatedNetWorth = calculateNetWorth(paymentArray, interestRate);
    if(calculatedNetWorth > 0) {
      paymentLow = payment;
    } else {
      paymentHigh = payment;
    }
    //log('Payment: High'+paymentHigh+' Low:'+paymentLow);
  }
  return paymentHigh;
}

var bankDatesArray = ["01/01", "01/15",    "01/29", "02/12",
                      "02/26", "03/12",    "03/26", "04/09", 
                      "04/23", "05/07",    "05/21", "06/04", 
                      "06/18", "07/02",    "07/16", "07/30", 
                      "08/13", "08/27",    "09/10", "09/24", 
                      "10/08", "10/22",    "11/05", "11/19",
                      "12/03", "12/17"];
function findBankBiweekly(interestRate, loanAmount, startYear, numberOfYears, payment) {
  var leftAmount = loanAmount;
  var numOfPayments = 250;
  while(leftAmount > payment) {
    numOfPayments++;
    var paymentArray = [];
	var finalDate;
    paymentArray[0] = createTransaction("12/17/"+(startYear-1), loanAmount);
	for(var i=0; i<numberOfYears; i++) {
      var yyyy = startYear + i;
      for(var j=1; j<=12; j++) {
        var mm = dateGenerateMM(j); // Bank holds it even though payments are made ahead of time
		if(paymentArray.length <= numOfPayments) {
		  var multiplier = 1;
		  if(j == 11) {
		    multiplier = 2;
          }
		  if(paymentArray.length == numOfPayments) {
		    finalDate = dateParse(mm+"/17/"+yyyy);
		    multiplier = 0;
		  }
          paymentArray[paymentArray.length] = createTransaction(mm+"/17/"+yyyy, -multiplier*payment);
		} 
	  }
    }
	for(var i=0; i<paymentArray.length; i++) {
      paymentArray[i].years = dateCalculateYearsBetween(paymentArray[i].date, finalDate);
    }
	leftAmount = calculateNetWorth(paymentArray, interestRate);
	paymentArray[paymentArray.length-1].amount = -leftAmount;
	if(leftAmount < payment) {
	  return paymentArray;
	}
	//log('leftAmount:'+leftAmount+' finalDate:'+finalDate); 
  }
}

function findSelfBiweekly(interestRate, loanAmount, startYear, numberOfYears, payment) {
  var leftAmount = loanAmount;
  var numOfPayments = 250;
  while(leftAmount > payment) {
    numOfPayments++;
    var paymentArray = [];
	var finalDate;
    paymentArray[0] = createTransaction("12/17/"+(startYear-1), loanAmount);
	for(var i=0; i<numberOfYears; i++) {
      var yyyy = startYear + i;
      for(var j=1; j<=12; j++) {
        var mm = dateGenerateMM(j);
		if(paymentArray.length <= numOfPayments) {
		  var multiplier = 1;
		  if(paymentArray.length == numOfPayments) {
		    finalDate = dateParse(mm+"/17/"+yyyy);
		    multiplier = 0;
		  }
          paymentArray[paymentArray.length] = createTransaction(mm+"/17/"+yyyy, -multiplier*payment);
		} 
	  }
    }
	for(var i=0; i<paymentArray.length; i++) {
      paymentArray[i].years = dateCalculateYearsBetween(paymentArray[i].date, finalDate);
    }
	leftAmount = calculateNetWorth(paymentArray, interestRate);
	paymentArray[paymentArray.length-1].amount = -leftAmount;
	if(leftAmount < payment) {
	  return paymentArray;
	}
	//log('leftAmount:'+leftAmount+' finalDate:'+finalDate); 
  }
}

var realDatesArray = ["01/01", "01/15", "01/29", "02/12", "02/26", 
             "03/12", "03/26", "04/09", "04/23", "05/07", 
             "05/21", "06/04", "06/18", "07/02", "07/16", 
             "07/30", "08/13", "08/27", "09/10", "09/24", 
             "10/08", "10/22", "11/05", "11/19", "12/03", 
             "12/17"];
function findRealBiweekly(interestRate, loanAmount, startYear, numberOfYears, payment) {
  var leftAmount = loanAmount;
  var numOfPayments = 250;
  while(leftAmount > payment) {
    numOfPayments++;
    var paymentArray = [];
	var finalDate;
    paymentArray[0] = createTransaction("12/17/"+(startYear-1), loanAmount);
	for(var i=0; i<numberOfYears; i++) {
      var yyyy = startYear + i;
      for(var j=0; j<26; j++) {
        var mmDD = realDatesArray[j];
        if(paymentArray.length <= numOfPayments) {
          var multiplier = 1;
          if(paymentArray.length == numOfPayments) {
            finalDate = dateParse(mmDD+"/"+yyyy);
            multiplier = 0;
		  } 
          paymentArray[paymentArray.length] = createTransaction(mmDD+"/"+yyyy, -multiplier*payment);
        }
	  }
    }
	for(var i=0; i<paymentArray.length; i++) {
      paymentArray[i].years = dateCalculateYearsBetween(paymentArray[i].date, finalDate);
    }
	leftAmount = calculateNetWorth(paymentArray, interestRate);
	paymentArray[paymentArray.length-1].amount = -leftAmount;
	if(leftAmount < payment) {
	  return paymentArray;
	}
	//log('leftAmount:'+leftAmount+' finalDate:'+finalDate); 
  }
}

// Setup Interest Rate
var interestRate = 0.045;
var loanAmount = 208000;

// Start calculation from 09/2014 and run to 12/2028
var startYear = 2014;
var numberOfYears = 30;

// Give two bounds on the payments
var paymentLow = 0;
var paymentHigh = 100000;
var payment = findMortgagePayment(interestRate, loanAmount, startYear, numberOfYears, paymentLow, paymentHigh);

var totalPayments = payment*12*30;
var totalInterest = totalPayments - loanAmount;
var finalDate = dateParse("12/17/"+(startYear + numberOfYears - 1));
log('Bank Monthly - Payment:'+payment+ ' TotalPayments:'+totalPayments+' TotalInterest:'+totalInterest+' FinalDate:'+finalDate);

var biweeklyPaymentArray = findBankBiweekly(interestRate, loanAmount, startYear, numberOfYears, payment);
totalInterest = 0;
for(var i=0; i<biweeklyPaymentArray.length; i++) {
  	totalInterest = totalInterest - biweeklyPaymentArray[i].amount;
}
totalPayments = loanAmount + totalInterest;
finalDate = biweeklyPaymentArray[biweeklyPaymentArray.length-1].date;
log('<br><br>Bank Biweekly - Payment:'+(payment/2)+ ' TotalPayments:'+totalPayments+' TotalInterest:'+totalInterest+' FinalDate:'+finalDate);

var selfBiweeklyPaymentArray = findSelfBiweekly(interestRate, loanAmount, startYear, numberOfYears, payment+payment/12);
totalInterest = 0;
for(var i=0; i<selfBiweeklyPaymentArray.length; i++) {
  	totalInterest = totalInterest - selfBiweeklyPaymentArray[i].amount;
}
totalPayments = loanAmount + totalInterest;
finalDate = selfBiweeklyPaymentArray[selfBiweeklyPaymentArray.length-1].date;
log('<br><br>Bank Self Biweekly - Payment:'+(payment+payment/12)+ ' TotalPayments:'+totalPayments+' TotalInterest:'+totalInterest+' FinalDate:'+finalDate);

var realBiweeklyPaymentArray = findRealBiweekly(interestRate, loanAmount, startYear, numberOfYears, (payment/2));
totalInterest = 0;
for(var i=0; i<realBiweeklyPaymentArray.length; i++) {
  	totalInterest = totalInterest - realBiweeklyPaymentArray[i].amount;
}
totalPayments = loanAmount + totalInterest;
finalDate = realBiweeklyPaymentArray[realBiweeklyPaymentArray.length-1].date;
log('<br><br>Real Self Biweekly - Payment:'+(payment/2)+ ' TotalPayments:'+totalPayments+' TotalInterest:'+totalInterest+' FinalDate:'+finalDate);

//var vals = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 30];
//var string = "";
//var monthly = 1054.24;
//var biweekly = 527.12;
//var dou = monthly + monthly/12;
//var counter = 1;
//var realBiValues = 0;
//var realBiValuesString = "";
//var biweeklyPayments = 0;
//var biweeklyPaymentsString = "";
//var seweeklyPayments = 0;
//var seweeklyPaymentsString = "";
//for(var i=1;i<=12;i++){
//  var mm = dateGenerateMM(i);
//  for(var k=1;k<=vals[i-1];k++) {
//    if(counter % 14 == 0) {
//	  realBiValues = realBiValues + biweekly;
//	}
//	var dd = dateGenerateMM(k);
//	string = string + "'"+mm+"/"+dd+"',";
//	realBiValuesString = realBiValuesString + realBiValues + ",";
//	biweeklyPaymentsString = biweeklyPaymentsString + biweeklyPayments + ",";
//	seweeklyPaymentsString = seweeklyPaymentsString + seweeklyPayments + ",";
//	counter++;
//  }
//  biweeklyPayments = biweeklyPayments + monthly;
//  seweeklyPayments = seweeklyPayments + dou;
//}
//string = string + "'12/31'";
//realBiValuesString = realBiValuesString + "13705.12";
//biweeklyPaymentsString = biweeklyPaymentsString + "13705.12";
//seweeklyPaymentsString = seweeklyPaymentsString + "13705.12";
//log('<br><br>string:'+string);
//log('realBiValuesString:'+realBiValuesString);
//log('biweeklyPaymentsString:'+biweeklyPaymentsString);
//log('seweeklyPaymentsString:'+seweeklyPaymentsString);
</script>
</pre>
</body>
</html>

Code to use high charts to display the data:



<html>
<head>

<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type='text/javascript'>//<![CDATA[ 

$(function () {
    $('#container').highcharts({
        title: {
            text: 'Mortgages versus Biweekly Programs',
            x: -20 //center
        },
        xAxis: {
            categories: ['01/01','01/02','01/03','01/04','01/05','01/06','01/07','01/08','01/09','01/10','01/11','01/12','01/13','01/14','01/15','01/16','01/17','01/18','01/19','01/20','01/21','01/22','01/23','01/24','01/25','01/26','01/27','01/28','01/29','01/30','01/31','02/01','02/02','02/03','02/04','02/05','02/06','02/07','02/08','02/09','02/10','02/11','02/12','02/13','02/14','02/15','02/16','02/17','02/18','02/19','02/20','02/21','02/22','02/23','02/24','02/25','02/26','02/27','02/28','03/01','03/02','03/03','03/04','03/05','03/06','03/07','03/08','03/09','03/10','03/11','03/12','03/13','03/14','03/15','03/16','03/17','03/18','03/19','03/20','03/21','03/22','03/23','03/24','03/25','03/26','03/27','03/28','03/29','03/30','03/31','04/01','04/02','04/03','04/04','04/05','04/06','04/07','04/08','04/09','04/10','04/11','04/12','04/13','04/14','04/15','04/16','04/17','04/18','04/19','04/20','04/21','04/22','04/23','04/24','04/25','04/26','04/27','04/28','04/29','04/30','05/01','05/02','05/03','05/04','05/05','05/06','05/07','05/08','05/09','05/10','05/11','05/12','05/13','05/14','05/15','05/16','05/17','05/18','05/19','05/20','05/21','05/22','05/23','05/24','05/25','05/26','05/27','05/28','05/29','05/30','05/31','06/01','06/02','06/03','06/04','06/05','06/06','06/07','06/08','06/09','06/10','06/11','06/12','06/13','06/14','06/15','06/16','06/17','06/18','06/19','06/20','06/21','06/22','06/23','06/24','06/25','06/26','06/27','06/28','06/29','06/30','07/01','07/02','07/03','07/04','07/05','07/06','07/07','07/08','07/09','07/10','07/11','07/12','07/13','07/14','07/15','07/16','07/17','07/18','07/19','07/20','07/21','07/22','07/23','07/24','07/25','07/26','07/27','07/28','07/29','07/30','07/31','08/01','08/02','08/03','08/04','08/05','08/06','08/07','08/08','08/09','08/10','08/11','08/12','08/13','08/14','08/15','08/16','08/17','08/18','08/19','08/20','08/21','08/22','08/23','08/24','08/25','08/26','08/27','08/28','08/29','08/30','08/31','09/01','09/02','09/03','09/04','09/05','09/06','09/07','09/08','09/09','09/10','09/11','09/12','09/13','09/14','09/15','09/16','09/17','09/18','09/19','09/20','09/21','09/22','09/23','09/24','09/25','09/26','09/27','09/28','09/29','09/30','10/01','10/02','10/03','10/04','10/05','10/06','10/07','10/08','10/09','10/10','10/11','10/12','10/13','10/14','10/15','10/16','10/17','10/18','10/19','10/20','10/21','10/22','10/23','10/24','10/25','10/26','10/27','10/28','10/29','10/30','10/31','11/01','11/02','11/03','11/04','11/05','11/06','11/07','11/08','11/09','11/10','11/11','11/12','11/13','11/14','11/15','11/16','11/17','11/18','11/19','11/20','11/21','11/22','11/23','11/24','11/25','11/26','11/27','11/28','11/29','11/30','12/01','12/02','12/03','12/04','12/05','12/06','12/07','12/08','12/09','12/10','12/11','12/12','12/13','12/14','12/15','12/16','12/17','12/18','12/19','12/20','12/21','12/22','12/23','12/24','12/25','12/26','12/27','12/28','12/29','12/30','12/31']
        },
        yAxis: {
            title: {
                text: 'Amount'
            },
            plotLines: [{
                value: 0,
                width: 1,
                color: '#808080'
            }]
        },
        legend: {
            layout: 'vertical',
            align: 'right',
            verticalAlign: 'middle',
            borderWidth: 0
        },
        series: [{
            name: 'Bank Monthly',
            data: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64]
        }, {
            name: 'Bank Biweekly',
            data: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,3162.7200000000003,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,9488.16,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,10542.4,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,11596.64,13705.12]
        }, {
            name: 'Bank Self Biweekly',
            data: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,1142.0933333333332,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,2284.1866666666665,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,3426.2799999999997,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,4568.373333333333,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,5710.466666666666,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,7994.653333333333,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,9136.746666666666,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,10278.84,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,11420.933333333334,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,12563.026666666668,13705.12]
        }, {
            name: 'Real Biweekly',
            data: [0,0,0,0,0,0,0,0,0,0,0,0,0,527.12,527.12,527.12,527.12,527.12,527.12,527.12,527.12,527.12,527.12,527.12,527.12,527.12,527.12,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1054.24,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,1581.3600000000001,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2108.48,2635.6,2635.6,2635.6,2635.6,2635.6,2635.6,2635.6,2635.6,2635.6,2635.6,2635.6,2635.6,2635.6,2635.6,3162.72,3162.72,3162.72,3162.72,3162.72,3162.72,3162.72,3162.72,3162.72,3162.72,3162.72,3162.72,3162.72,3162.72,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,3689.8399999999997,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4216.96,4744.08,4744.08,4744.08,4744.08,4744.08,4744.08,4744.08,4744.08,4744.08,4744.08,4744.08,4744.08,4744.08,4744.08,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5271.2,5798.32,5798.32,5798.32,5798.32,5798.32,5798.32,5798.32,5798.32,5798.32,5798.32,5798.32,5798.32,5798.32,5798.32,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6325.44,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,6852.5599999999995,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7379.679999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,7906.799999999999,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8433.92,8961.04,8961.04,8961.04,8961.04,8961.04,8961.04,8961.04,8961.04,8961.04,8961.04,8961.04,8961.04,8961.04,8961.04,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,9488.160000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10015.280000000002,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,10542.400000000003,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11069.520000000004,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,11596.640000000005,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12123.760000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,12650.880000000006,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13178.000000000007,13705.120000000008,13705.12]
        }]
    });
});
//]]>  

</script>


</head>
<body>
  <script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>

<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>

  
</body>


</html>


If you like this blog post and it has helped you save money through a decision you have made, please donate at: finlit.biz.

A Javascript Algorithm to Include Actual Cost of Insurance

Here, the assumed interest rate is included, along with monthly cost of insurance. Typically, for cash value life insurance, the cost is hidden from the consumer. Instead of cost, typical policies show premium, which is different.


<html>
<body>
<pre>
<script>
function log(arg) {
  document.body.innerHTML = document.body.innerHTML + arg + '\n<br>';
}

function logClear() {
  document.body.innerHTML = '';
}

function dateGenerateMM(month) {
  if(month>9) {
    return ""+month;
  } else {
    return "0"+month;
  }
}

function dateParse(dateString) {
  var mdy = dateString.split('/')
  return new Date(mdy[2], mdy[0]-1, mdy[1]);
}

function dateCalculateYearsBetween(date1, date2) {
  return (date2-date1)/(1000*60*60*24*365);
}

function createTransaction(date, amount) {
  var object = new Object();
  object.date = dateParse(date);
  object.amount = amount;
  return object;
}

function calculateNetWorth(transactionArray, interestRate) {
  var total = 0;
  for (var i=0; i<transactionArray.length; i++) {
    var P = transactionArray[i].amount;
    var r = interestRate;
    var y = transactionArray[i].years;
    total = total + P*Math.pow((1+r), y);
  }
  return total;
}

function printEndOfYearValues(transactionArray, interestRate, startMonth, startYear, numberOfYears, monthlyPaymentByYear) {
  for(var j=0;j<numberOfYears;j++){
    var yyyy = startYear + j;
   
    // Setup Monthly Payments
    var monthlyPayment = monthlyPaymentByYear[yyyy];
    var numberOfPayments = 0;
    for(var i=startMonth; i<=12; i++){
      var mm = dateGenerateMM(i);
      transactionArray[transactionArray.length] = createTransaction(mm+"/01/"+yyyy, monthlyPayment);
      numberOfPayments++;
    }
    var total = numberOfPayments*monthlyPayment;
   
    // Modify all transactions to include new end date
    var endOfYear = dateParse("12/31/"+yyyy);
    for (var i=0; i<transactionArray.length; i++) {
      transactionArray[i].years = dateCalculateYearsBetween(transactionArray[i].date, endOfYear);
    }
  
    log('Year:'+yyyy+' EndWorth:'+calculateNetWorth(transactionArray, interestRate)+' AnnualPayment:'+total);
   
    // For next year
    startMonth = 1;
  }
}

// Setup Interest Rate
var interestRate = 0.09;

// Initial deposit
var paymentArray = [];
paymentArray[0] = createTransaction("08/19/2014", 35000.00);

// Start calculation from 09/2014 and run to 12/2028
var startMonth = 9;
var startYear = 2014;
var numberOfYears = 15;

var monthlyPaymentByYear = [];
monthlyPaymentByYear[2014] = -1.3452*455; 
monthlyPaymentByYear[2015] = -1.8550*455;
monthlyPaymentByYear[2016] = -2.0174*455; 
monthlyPaymentByYear[2017] = -2.2008*455; 
monthlyPaymentByYear[2018] = -2.4074*455; 
monthlyPaymentByYear[2019] = -2.6383*455; 
monthlyPaymentByYear[2020] = -2.8908*455; 
monthlyPaymentByYear[2021] = -3.1583*455; 
monthlyPaymentByYear[2022] = -3.4383*455;
monthlyPaymentByYear[2023] = -3.7283*455;
monthlyPaymentByYear[2024] = -4.0324*455;
monthlyPaymentByYear[2025] = -4.3624*455;
monthlyPaymentByYear[2026] = -4.7266*455;
monthlyPaymentByYear[2027] = -5.1358*455;
monthlyPaymentByYear[2028] = -5.5983*455;
printEndOfYearValues(paymentArray, 0.09, startMonth, startYear, numberOfYears, monthlyPaymentByYear);
</script>
</pre>
</body>
</html>

Output:


Year:2014 EndWorth:33632.98636750427 AnnualPayment:-2448.264
Year:2015 EndWorth:26044.853064950486 AnnualPayment:-10128.3
Year:2016 EndWorth:16850.698444102545 AnnualPayment:-11015.003999999999
Year:2017 EndWorth:5773.343973589454 AnnualPayment:-12016.368