Classes and Instances in Javascript

I was reading a question about what every Javascript programmer should know on StackOverflow and found this useful pattern for using the more classic class/instance pattern instead of Javascript’s standard prototype method. I found the last example to be quite elegant and want to preserve it here for reference.

function Shape(x, y) {
    var self = {};

    self.x = x;
    self.y = y;

    self.toString = function() {
        return 'Shape at ' + self.x + ', ' + self.y;
    };

    return self;
}

function Circle(x, y, r) {
  var self = Shape(x, y);

  self.r = r;

  var _baseToString = self.toString;
  self.toString = function() {
    return 'Circular ' + _baseToString(self) + ' with radius ' + r;
  };

  return self;
};

var mycircle = Circle(2, 3, 5);
console.log(mycircle.x === 2);
console.log(mycircle.y === 3);
console.log(mycircle.r === 5);
console.log(mycircle.toString());

With this pattern you have to use the ‘self’ variable (which you can name anything you wish, the original was named ‘that’) to access and modify attributes of the class just like in Python. Unlike Python you must explicitly declare the self variable at the beginning of the class and return it at the end. Also if you are going to override an attribute in the parent class, but still need to access the parent attribute, you must rename it before overriding it, otherwise the reference to self.toString will end up in an infinite recursive loop.

Getting WordPress SyntaxHighlighter Evolved to Validate

I’ve been using Alex Gorbatchev’s SyntaxHighlighter Evolved to post code to my blog since early this year. I’ve recently moved to self-hosting my blog and it was one of the first plugins I installed. I can’t say enough good things about it. It is a great plugin for simple syntax highlighting of anything from html to C to Python (though unfortunately not Scheme, maybe I should write a brush for that).

When I ran my blog through the validator at w3c I noticed two problems. The first was with the Page Links To plugin using target=”_blank”. This was simple enough to fix, just uncheck the “Open this link in a new window” box. It’s probably better to let your visitors choose where they want their links to open, after all they can always middle click to open in a new tab.

The second problem was with SyntaxHighlighter Evolved’s use of <meta id=”syntaxhighlighteranchor” …> in the head tag. This is not valid html and was a bit harder to fix. I came across this post explaining the problem and rational behind the design while Googling for a solution. It seems that the id tag was used to provide a method for users to customize the plugin without editing the source files. Since I quite enjoy digging into the source files, this wasn’t a show stopper for me. In the end my solution was simple. Remove the feature and get on with my life.

The first thing to do is to locate this line…

		echo 'pluginver ) . '" /&gt;' . "\n";

and remove the id=”syntaxhighlighteranchor” tag.

The plugin uses document.getElementById(“syntaxhighlighteranchor”) twice so you have to make two changes. Instead of using the .insertBefore method to inject the css into the head element, use the .appendChild method.

		document.getElementsByTagName("head")[0].insertBefore( corecss, document.getElementById("syntaxhighlighteranchor") );
// becomes
		document.getElementsByTagName("head")[0].appendChild( corecss );

and

		document.getElementsByTagName("head")[0].insertBefore( themecss, document.getElementById("syntaxhighlighteranchor") );
// becomes
		document.getElementsByTagName("head")[0].appendChild( themecss );

You might want to put a comment in the sourcecode describing your change so you know what you did in the future in case it breaks. If you really think you’re going to forget, you can always write a blog post about it too.

Again I can’t say enough good things about SyntaxHighlighter Evolved. If you have an idea for a fix for this that preserves the original feature of being able to customize the plugin through css without delving into the sourcecode, please leave it in the comments.

Jumping Into Javascript – Drawing JSONP Data on the Canvas

The last article in this series was a bit of a digression into the module pattern and namespaces in Javascript. This article will focus on a very simple charting algorithm.

Now that we have the data to draw and know how to move things on the canvas, we need to focus on making the chart look more like a normal chart. This post will focus on the drawing algorithms that will turn our data into a nice display and redrawing that same chart at different time periods/scales. Here’s the screenshot representing our progress from last time.

No Modifications

The first step is to find out the lowest value that will have to be drawn on the chart. We can align all the rest of the values with the bottom of the chart if we subtract the lowest value from each value on the chart. To do this we first have to traverse the sequence of data that will be shown and look for the lowest value.

var width = 600, height = 500
var chart = document.getElementById("chart");
var c = chart.getContext("2d");
chart.width = width; chart.height = height

//___________________________________________________________________________//
// Query and Init Procedures
//___________________________________________________________________________//

function getUrl(symbol) {
  return "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20csv%20where%20url%3D'http%3A%2F%2Fichart.finance.yahoo.com%2Ftable.csv%3Fs%3D" + symbol + "%26d%3D2%26e%3D27%26f%3D2011%26g%3Dd%26a%3D0%26b%3D1%26c%3D2000%26ignore%3D.csv'&format=json&callback=?";
}

$.getJSON(getUrl("ibm"), init);

function init(result) {
  var data = result.query.results.row;
  drawRects(data, 1);
}


//___________________________________________________________________________//
// Chart Drawing Procedures
//___________________________________________________________________________//

function drawRects(d, s) {
  var e = s + 30;
  var low = d[s].col3;
  
  for (var i = s; i < e; i++) {
    if (d[i].col3 < low) { low = d[i].col3 }
  }
  
  for (var i = s; i < e; i++) {
    c.fillRect(i*30, height-(d[i].col1-low), 20, d[i].col1 - d[i].col4);
  }
}

Align at Bottom

The next thing to do is scale up the bar heights to match the height of the chart. For this we also have to determine the highest high. Then we take the difference between the highest high and the lowest low and divide the chart height by that number, this gives us our multiple. Then we take the multiple and use it to compute the lower starting position as well as the height of each bar.

Before we were using the open data, however this won’t always give the lowest price. On any day the stock price fell, the open will represent the highest price. We don’t have to compute if the open is lower or higher than the close because our data gives us the low and high prices for the day. This is also beneficial as the low or high from the day could be significantly lower/higher than the open or close.

Also we’ve been drawing our chart backward, to flip it we need to subtract the offset from the width of the chart. In addition we should put in some color to tell what days are up or down. Since code is probably the best description of this formula I’ll stop trying to explain it and just show you the algorithm. I’m sure there is a cleaner/simpler solution (or maybe this solution is even too simple) however this can be updated a bit later down the road.

var width = 600, height = 500
var chart = document.getElementById("chart");
var c = chart.getContext("2d");
chart.width = width; chart.height = height

//chart.onclick = moveRects;


//___________________________________________________________________________//
// Query and Init Procedures
//___________________________________________________________________________//

function getUrl(symbol) {
  return "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20csv%20where%20url%3D'http%3A%2F%2Fichart.finance.yahoo.com%2Ftable.csv%3Fs%3D" + symbol + "%26d%3D2%26e%4D04%26f%3D2011%26g%3Dd%26a%3D0%26b%3D1%26c%3D2000%26ignore%3D.csv'&format=json&callback=?";
}

$.getJSON(getUrl("ibm"), init);

function init(result) {
  var data = result.query.results.row;
  console.log(data[1].col0);
  drawRects(data, 1);
}


//___________________________________________________________________________//
// Chart Drawing Procedures
//___________________________________________________________________________//

function drawRects(d, s) {
  var e = s + 15;
  var low = d[s].col3;
  var high = d[s].col2;
  
  for (var i = s; i < e; i++) {
    if (d[i].col3 < low) { low = d[i].col3 }
    if (d[i].col2 > high) { high = d[i].col2 }
  }

  var mul = height / (high - low);

  for (var i = e; i > s; i--) {
    if (d[i].col1 < d[i].col4) { c.fillStyle = "#00f"; }
    else { c.fillStyle = "#f00"; }
    c.fillRect(width - (i*30), 
               height - (mul * (d[i].col1-low)),
               20,
               (mul * (d[i].col1 - d[i].col4)));
  }
}

Simple Chart

And here’s the Yahoo Finance chart as comparison…

Yahoo Finance Chart

Finally here’s a snapshot of pyTrade, the father of JamochaTrade. Something similar to this is the ultimate goal of JamochaTrade.

pyTrade

As you can see our chart now looks a lot more like a stock chart! However, we still have a long way to go. Wicks, labeled axes, hover tags and much more need to be added, not to mention different styles of charts (line, mountain, dot, etc.). There are also a few bugs with our current implementation that need to be worked out.

The next article will concentrate on refactoring and debugging. Notably we’ll move our code into a namespace, as was discussed in the previous article. We’ll also rip out the drawing logic and put it into a function so we can make a more general drawing procedure that can handle different types of bar charts (Candlestick, OHLC, HLC).

Get JamochaTrade on GitHub