<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Carbon Emitter &#187; JavaScript</title>
	<atom:link href="http://blog.carbonfive.com/tag/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.carbonfive.com</link>
	<description>The blog of Carbon Five</description>
	<lastBuildDate>Mon, 23 Jan 2012 18:38:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Interactivity in HTML5 Canvas Visualizations</title>
		<link>http://blog.carbonfive.com/2011/04/11/interactivity-in-html5-canvas-visualizations/</link>
		<comments>http://blog.carbonfive.com/2011/04/11/interactivity-in-html5-canvas-visualizations/#comments</comments>
		<pubDate>Mon, 11 Apr 2011 11:00:35 +0000</pubDate>
		<dc:creator>Alex Cruikshank</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[2D transforms]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=3182</guid>
		<description><![CDATA[In the last canvas visualization post I discussed the canvas API&#8217;s transform functionality and how it greatly simplifies drawing complex visualizations.  In this post, I&#8217;ll talk a little about making canvas visualizations interactive and about problems you might encounter when &#8230; <a href="http://blog.carbonfive.com/2011/04/11/interactivity-in-html5-canvas-visualizations/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In the last <a href="http://blog.carbonfive.com/2011/03/31/taming-2d-transforms/">canvas visualization post</a> I discussed the canvas API&#8217;s transform functionality and how it greatly simplifies drawing complex visualizations.  In this post, I&#8217;ll talk a little about making canvas visualizations interactive and about problems you might encounter when mixing transforms and interactivity in a canvas application.</p>
<p>Examples: (an HTML5 compatible browser is required to view these)<br />
<a href="http://carbonfive.github.com/html5-playground/interest-map/interest-map.html"><img title="interest-map-icon" src="http://blog.carbonfive.com/wp-content/uploads/2011/03/interest-map-icon.jpg" alt="Interest Map Application" width="100" height="100" /></a><a href="http://carbonfive.github.com/html5-playground/transforms/tree.html"><img title="tree-icon" src="http://blog.carbonfive.com/wp-content/uploads/2011/03/tree-icon.jpg" alt="Tree Application" width="100" height="100" /></a><a href="http://carbonfive.github.com/html5-playground/transforms/interactive-tree.html"><img title="interactive-tree-icon" src="http://blog.carbonfive.com/wp-content/uploads/2011/03/interactive-tree-icon.jpg" alt="Interactive Tree Application" width="100" height="100" /></a><a href="http://carbonfive.github.com/html5-playground/transforms/interactive-tree-axis.html"><img title="interactive-tree-axis-icon" src="http://blog.carbonfive.com/wp-content/uploads/2011/03/interactive-tree-axis-icon.jpg" alt="Animated Interactive Tree" width="100" height="100" /></a></p>
<p><span id="more-3182"></span><span style="font-size: 23px; color: #000000; line-height: 35px;">Tracking Mouse Events in Canvas</span></p>
<p>The Canvas API provides very little support for tracking user interactions within a canvas drawing.  You get the standard mouse events you get with any other DOM element (onclick, onmousemove, onmouseup, etc.), and you are more or less on your own from there.  To determine if the user has interacted with a particular part of your canvas visualization, you need to take the clientX and clientY from the mouse event and subtract the absolute top and left of the canvas element from them to get an x and y relative to the top left of the canvas.  The canvas&#8217;s position can be determined by something like jQuery&#8217;s offset() function, or you can calculate it directly by recursing through the canvas&#8217;s offsetParents and looking at their offsetLeft, offsetTop, scrollLeft and scrollTop properties (this can be simplified if your HTML has less structure).</p>
<p>Once you have an x and y in the canvas&#8217;s coordinates, you can check if the mouse event is in some rectangle by checking that x and y are between the rectangle&#8217;s edges.  If you need a more precise target, you can use the canvas <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-ispointinpath">isPointInPath()</a> method by first drawing the target shape using the canvas drawing API and then checking context.isPointInPath(x,y).</p>
<h2>The Problem With Interactivity and Transforms</h2>
<p>This works fine until you start using transforms to draw your controls.  In the <a href="http://carbonfive.github.com/html5-playground/interest-map/interest-map.html">interest map</a> project, I used the bounding box method to detect clicks on the arrow buttons on the right and left of the x axis.  I wanted to use the same code to check the buttons on the top and bottom of the y axis, but soon realized this wouldn&#8217;t work. Because the buttons are drawn in a rotated coordinate system, the coordinates I used to draw the buttons were no longer relative to the top left of the canvas, so they didn&#8217;t match the coordinates of the mouse event.  In this case the actual coordinates were relatively easy to calculate, but there are other interactive parts of the visualization whose canvas coordinates would be much more difficult to calculate.</p>
<p>To a certain extent, the isPointInPath() method works around this problem.  If you draw a shape in a coordinate system defined by any number of transforms and then call isPointInPath() using canvas coordinates, you&#8217;ll still get the desired result.  The downside of this approach is that you need to re-create the sequence of transforms used to draw the control and then draw the correct shape at the time you handle the mouse event. So you need to maintain a copy of at least some of your drawing logic in order to create your mouse targets in your event handlers.  I wasn&#8217;t very happy with this solution so I developed another one.</p>
<p><span style="font-size: 18px; color: #000000; line-height: 27px;">Make2DContextQueryable</span></p>
<p>The problem with the canvas transform API and interactivity is that it&#8217;s a one way street.  You provide the directions, and canvas draws the right picture.  Once you need to figure out where all this transforming has gotten you, you&#8217;ve got no support from the API.  Make2DContextQueryable fills in this gap.</p>
<p>It&#8217;s no mystery how all the canvas transform methods combine to create a transform matrix, and once you have the the matrix, you only need to invert it (think 1/A) to create a transform that converts points in the original coordinates to the current transformed coordinates.  Make2DContextQueryable wraps all of the canvas transform methods with functions that first apply the transform to our own matrix before calling the original method on the canvas context.  The new matrix is stored in a stack so that save() and restore() work as expected.  While you&#8217;re drawing a control, you can call t = context.currrentTransform() to get and store its coordinate transform.  Then in the event handler, you can either call context.canvasToContext({x:canvasX,y:canvasY}, t) to convert the mouse location to a point in the control&#8217;s coordinate system and then test it yourself, or call context.setTransform(t.a,t.b,t.c,t.d,t.e,t.f), draw a path around the click area (in the control&#8217;s coordinate system) and call isPointInPath(canvasX, canvasY).</p>
<p>Here&#8217;s the Make2DContextQueryable function definition:</p>
<pre class="brush: jscript; title: ; wrap-lines: false; notranslate">(function() {
window.TransformArithmetic = {};
var ta = TransformArithmetic;
ta.project=  function(p,t) { return {x:t.a*p.x+t.c*p.y+t.e, y:t.b*p.x+t.d*p.y+t.f}; };
ta.multiply=function(t2,t1){ return {a:t1.a*t2.a+t1.b*t2.c, c:t1.c*t2.a+t1.d*t2.c,
b:t1.a*t2.b+t1.b*t2.d, d:t1.c*t2.b+t1.d*t2.d,
e:t1.e*t2.a+t1.f*t2.c+t2.e, f:t1.e*t2.b+t1.f*t2.d+t2.f}; };
ta.translate=function(x,y) { return {a:1,b:0,c:0,d:1,e:x,f:y}; };
ta.rotate= function(theta) { return {a:Math.cos(theta), b:Math.sin(theta),
c:-Math.sin(theta),d:Math.cos(theta),e:0,f:0}; }
ta.scale=    function(x,y) { return {a:x,b:0,c:0,d:y,e:0,f:0}; }
ta.ident=       function() { return {a:1,b:0,c:0,d:1,e:0,f:0}; }
ta.clone=      function(t) { return {a:t.a,b:t.b,c:t.c,d:t.d,e:t.e,f:t.f}; }
ta.inverse=    function(t) { var det=t.a*t.d-t.c*t.b; return {a:t.d/det, b:-t.b/det, c:-t.c/det,
d:t.a/det, e:(t.c*t.f-t.e*t.d)/det, f:(t.e*t.b-t.a*t.f)/det}; }
ta.interp=function(t1,t2,i) { var t={}, a=['a','b','c','d','e','f'];
for (var j=0,k;k=a[j];j++) t[k]=t1[k]+(t2[k]-t1[k])*i; return t; }
window.Make2DContextQueryable = function(ctx) {
if ( ctx.contextToCanvas ) return;
var transforms = [ta.ident()];
function current() { return transforms[transforms.length-1]; }
function set(t) { transforms[transforms.length-1] = t; }
function apply_to(t) { transforms[transforms.length-1] = ta.multiply(current(),t); }
function proxy_before(o,fn,f) { var oldf=o[fn]; o[fn]=function(){
f.apply(o,arguments); oldf.apply(o,arguments); };}
proxy_before(ctx,'save',function() { transforms.push(ta.clone(current())); });
proxy_before(ctx,'restore',function() { if (transforms.length&amp;gt;1) transforms.pop();
else transforms[0]=ident(); });
proxy_before(ctx,'scale',function(x,y) { apply_to(ta.scale(x,y)); });
proxy_before(ctx,'rotate',function(theta) { apply_to(ta.rotate(theta)); });
proxy_before(ctx,'translate',function(x,y) { apply_to(ta.translate(x,y)); });
proxy_before(ctx,'transform',function(a,b,c,d,e,f) { apply_to({a:a,b:b,c:c,d:d,e:e,f:f}); });
proxy_before(ctx,'setTransform',function(a,b,c,d,e,f) { set({a:a,b:b,c:c,d:d,e:e,f:f}); });
ctx.contextToCanvas = function(p) { return ta.project(p,current()); }
ctx.canvasToContext = function(p) { return ta.project(p,inverse(current())); }
ctx.currentTransform = function() { return current(); }
return ctx;
}
})();</pre>
<p>And here&#8217;s how it&#8217;s used a revised version of the <a href="http://carbonfive.github.com/html5-playground/transforms/interactive-tree.html">tree application</a> (<a href="https://github.com/carbonfive/html5-playground/blob/gh-pages/transforms/interactive-tree.html">full source</a>):</p>
<pre class="brush: jscript; title: ; notranslate">function init() {
var canvas = document.getElementById('display');
// call Make2DContextQueryable to add our transform recorder
// functions.  Although the function returns the context, the
// the modifications are made to the element itself, so we don't
// need to call the function again.
var ctx = Make2DContextQueryable(canvas.getContext('2d'));
ctx.font = FONT; ctx.strokeStyle = OVER_STROKE;
ctx.lineWidth = OVER_LINE_WIDTH;
tree.branches = gen_tree(1);
draw();
canvas.onmousemove = function(evt) {
evt = evt || window.event;
var canvas = document.getElementById('display');
var canvasX = evt.clientX - canvas.offsetLeft
+ document.body.scrollLeft,
canvasY = evt.clientY - canvas.offsetTop
+ document.body.scrollTop;
if ( over(canvas.getContext('2d'), tree, {x:canvasX, y:canvasY}) )
draw();
}
}
function over( ctx, branch, canvasCoords ) {
// tranform the mouse point into the branch's coordinates
// (branch tranform was saved in the middle of the draw function)
var ctxCoords = ctx.canvasToContext(canvasCoords,branch.transform),
changed = false,
text_width = ctx.measureText(PARTS[branch.type]).width;
// perform simple rectangle test to see if mouse is over branch
var is_over = (ctxCoords.x &amp;gt;= 0
&amp;amp;&amp;amp; ctxCoords.x &amp;lt;= text_width + LEFT_OFFSET
&amp;amp;&amp;amp; ctxCoords.y &amp;lt;= TOP_OFFSET &amp;amp;&amp;amp; ctxCoords.y &amp;gt;= -30 );
if ( is_over != branch.over ) {
branch.over = is_over;
changed = true;
}
if ( ! branch.branches ) return changed;
return changed || over(ctx,branch.branches[1],canvasCoords)
|| over(ctx,branch.branches[0],canvasCoords);
}</pre>
<p>The functions under the TransformArithmetic namespace are a by-product of the logic needed to replicate the context transforms, but they can be quite useful themselves.  The <a href="http://carbonfive.github.com/html5-playground/transforms/interactive-tree-axis.html">second interactive tree</a> demo (<a href="https://github.com/carbonfive/html5-playground/blob/gh-pages/transforms/interactive-tree-axis.html">source</a>) uses these functions to calculate a transform that puts the mouse-overed branch of the tree in the center of the screen.  When you mouse over a branch, the application records the active transform, AT.  If we wanted this branch to be drawn in the canvas&#8217;s coordinates, we would simply need to invert AT and apply it using the ctx.transform() method.  We actually want to translate it to the center of the canvas, however.  Let AT be the product of that translation, TL, and all the branch transforms used to get the branch, TT.  So what we really want is TL/TT (here &#8216;/&#8217; means multiply by the inverse). Since AT=TL*TT, TT=(1/TL)*AT (remember order is important), so TL/((1/TL)*AT) is the transform we need.  Using the fact that the inversion of a translation matrix is simply the negation of the translation factors e and f, we can create the transform with the following code:</p>
<pre class="brush: jscript; title: ; notranslate">var ta=TransformArithmetic;
// translate a little left of center
ctx.translate( 100, 300 );
// subtract out the translation from the active transform and invert it
var at = ta.inverse(ta.multiply({a:1,b:0,c:0,d:1,e:-100, f:-300},active_transform));
// apply the calculated matrix
ctx.transform( at.a, at.b, at.c, at.d, at.e, at.f );</pre>
<p>The computations needed to determine whether the mouse is over a branch in this new coordinate system are a little more complicated, but can be calculated using a similar algebraic manipulation.  The TransformArithmetic also contains an interp() function that will interpolate between two transforms, thus making animation possible.</p>
<p>Wrapping the transform functions may seem a little extreme, but it goes a long way towards simplifying interactive visualizations.  It&#8217;s also handy to have the transform math lying around.  I&#8217;ve been using it to create bezier curve functions that permit the second two control points to be drawn in a different coordinate system.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/04/11/interactivity-in-html5-canvas-visualizations/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Taming 2D Transforms in HTML5 Canvas</title>
		<link>http://blog.carbonfive.com/2011/03/31/taming-2d-transforms/</link>
		<comments>http://blog.carbonfive.com/2011/03/31/taming-2d-transforms/#comments</comments>
		<pubDate>Thu, 31 Mar 2011 12:16:15 +0000</pubDate>
		<dc:creator>Alex Cruikshank</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[2D transforms]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=2934</guid>
		<description><![CDATA[This is the second post in a series on creating custom interactive visualizations in canvas.  The first post is here. The canvas API contains five methods (rotate, scale, translate, transform, and setTransform) used to transform the drawing context. We typically &#8230; <a href="http://blog.carbonfive.com/2011/03/31/taming-2d-transforms/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.carbonfive.com/wp-content/uploads/2011/03/interest-map-2d-transforms.jpg"><img class="aligncenter size-full wp-image-3110" title="interest-map-2d-transforms" src="http://blog.carbonfive.com/wp-content/uploads/2011/03/interest-map-2d-transforms.jpg" alt="" width="640" height="236" /></a></p>
<p>This is the second post in a series on creating custom interactive visualizations in canvas.  The first post is <a href="http://blog.carbonfive.com/2011/02/17/visualizing-skillsets-in-html5-canvas-part-1/">here</a>.</p>
<p>The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html">canvas API</a> contains five methods (rotate, scale, translate, transform, and setTransform) used to transform the drawing context.  We typically use the transform API when we want to rotate or scale some element of the visualization (especially text).  In canvas, we don&#8217;t actually move the elements.  Instead we transform into a new coordinate system where the element is no longer scaled, rotated or translated and then draw normally.  The difference is subtle, and you can get by with ignoring it so long as you remember to execute the transforms before you draw.   But, once you embrace this way of thinking, transformed coordinates can be a powerful way to break down complicated drawing tasks into simple steps.  In the remainder of the post I&#8217;ll describe how to use transforms effectively and how to overcome the difficulties involved in making transformed objects interactive.</p>
<p>Examples: (an HTML5 browser is required to view these)<br />
<a href="http://carbonfive.github.com/html5-playground/interest-map/interest-map.html"><img class="size-full wp-image-3143 alignleft" title="interest-map-icon" src="http://blog.carbonfive.com/wp-content/uploads/2011/03/interest-map-icon.jpg" alt="Interest Map Application" width="100" height="100" /></a><a href="http://carbonfive.github.com/html5-playground/transforms/tree.html"><img class="size-full wp-image-3144 alignleft" title="tree-icon" src="http://blog.carbonfive.com/wp-content/uploads/2011/03/tree-icon.jpg" alt="Tree Application" width="100" height="100" /></a></p>
<p><span id="more-2934"></span></p>
<h3>The Basic Idea</h3>
<p><div id="attachment_3115" class="wp-caption alignright" style="width: 310px"><a href="http://blog.carbonfive.com/wp-content/uploads/2011/03/arrow-transforms1.jpg"><img class="size-full wp-image-3115" title="arrow-transforms" src="http://blog.carbonfive.com/wp-content/uploads/2011/03/arrow-transforms1.jpg" alt="" width="300" height="336" /></a><p class="wp-caption-text">Choosing the right coordinate system simplifies calculations.</p></div></p>
<p>In the <a href="http://carbonfive.github.com/html5-playground/interest-map/interest-map.html">interest map</a> project I described in a <a href="http://blog.carbonfive.com/2011/02/17/visualizing-skillsets-in-html5-canvas-part-1/">previous post</a>, I want to use bezier curves to draw arrows using my own formula for the ratios of the arrow length, arrow head length, and arrow head height.  The x and y coordinates of the head and tail of the arrow are known, but using these to figure out the location of the sides of the arrow head and its control points require a lot of rather messy trigonometry. If we create a coordinate system where the tail of the arrow is at the origin and the head lies on the x axis (this still requires a little bit of trig), the coordinates simplify to {0,0}, {l-C,f(l)}, {l,0}, and {l-C,-f(l)} where C is the length of the arrow head and f(l) is a function that gives its height.  Also notice that, after a transform, we can use the same code to draw the horizontal and vertical axes (so long as we can handle the difference in lengths).  Complex visualizations can usually be broken up into components like this that each have a natural coordinate system.  The trick then becomes calculating an appropriate transform.</p>
<h3>A Bit About The Math</h3>
<p>I&#8217;m not going to get deep into <a href="http://en.wikipedia.org/wiki/Linear_algebra">linear algebra</a> or <a href="http://en.wikipedia.org/wiki/Affine_geometry">affine geometry</a>, but I think a little knowledge of how transforms are implemented is required to use them effectively. Any change of coordinates can be represented by a single transformation matrix.  <a href="http://blog.carbonfive.com/wp-content/uploads/2011/03/transform_multiplication.gif"><img class="alignright size-full wp-image-3130" title="transform_multiplication" src="http://blog.carbonfive.com/wp-content/uploads/2011/03/transform_multiplication.gif" alt="" width="280" height="370" /></a>You don&#8217;t need to know what a matrix is so long as you understand that it&#8217;s kind of like a number in the sense that you can multiply it with points or other transformation matrices.  When you multiply a point from your transformed coordinates with a transformation matrix, you get another point that is transformed back into the original coordinate system.  The canvas context always has a transformation matrix, and whenever you call a drawing API method (e.g. <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#simple-shapes-(rectangles)">fillRect</a>, <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#complex-shapes-(paths)">bezierCurveTo</a>, <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#complex-shapes-(paths)">arcTo</a>, etc.) it multiplies each of the points by this matrix before it renders any pixels from the shape to the canvas.</p>
<p>When you multiply a transformation matrix by a another transformation matrix, you get a new transformation matrix that is a combination of the two.  For example, if you have a transformation, A, that represents a coordinate system rotated 45 degrees and another transformation, B, that represents a translation of the origin 100 pixels along the x axis, then C=A*B is a transformation where the origin is 100 pixels out on the 45 degree line.  A lot of the power of Canvas&#8217;s transformation API derives from the ability to combine transforms like this.  With the exception of <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-settransform">setTransform()</a>, all of Canvas&#8217;s transform methods (rotate, scale, translate, and transform) are applied by creating a matrix representing the operation and then multiplying it with its current transform to create its new transform.  One important different between matrix multiplication and normal multiplication in that matrix multiplication does not commute (A*B != B*A).  So you&#8217;ll get a different result if call context.rotate() and then context.translate() than you would if you called context.translate() then context.rotate().</p>
<h3>Save and Restore</h3>
<p>The <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-save">save()</a> and <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-restore">restore()</a> methods in canvas are a convenient way to avoid specifying stroke and fill styles over and over again in a drawing, but they become critical when you start using transforms.  The save() method takes all the current state of the canvas context including the current transform and pushes it on a stack.  You can then make as many modifications or transforms as you like.  When you&#8217;re done drawing, you call context.restore() and everything is back to the way it was before you called save().  You can always reset the fillStyle or lineWidth, but there is no trivial way to reset the transform (you can use setTransform() if you really know what you&#8217;re doing).  Using save() and restore() is habit you want to acquire.</p>
<h3>Some Concrete Examples</h3>
<p>Alright, enough theory:  Here&#8217;s some code.  The <a href="http://carbonfive.github.com/html5-playground/transforms/tree.html">first example</a> is the obligatory fractal demonstration.  2D transforms make quick work of fractals, because, by definition, they are the same thing over and over at different scales and in different places.  At any rate, the application first creates a binary tree (see the <a href="https://github.com/carbonfive/html5-playground/blob/gh-pages/transforms/tree.html">full source</a>).  Then, beginning with the trunk it draws the text at the origin (in its transformed coordinates).  Then, for each branch, it translates the origin to the end of the word, rotates in the direction of the next branch, and scales to the size of the branch.  It then repeats the process until it gets to a leaf.</p>
<pre class="brush: jscript; title: ; notranslate">
function draw() {
    var ctx = document.getElementById('display').getContext('2d');
    ctx.font = 'bold 30pt Georgia,Times New Roman';
    ctx.translate( ctx.canvas.width / 2, ctx.canvas.height );
    ctx.rotate( -Math.PI/2 );
    draw_branch( ctx, tree );
}
function draw_branch(ctx, branch) {
  ctx.fillStyle = branch.branches ? WOOD_COLOR : LEAF_COLOR;
  // draw text in default font
  ctx.fillText(PARTS[branch.type], LEFT_OFFSET, TOP_OFFSET);
  if ( ! branch.branches ) return;
  for ( var i=0,b; b=branch.branches[i]; i++ ) {
    ctx.save();   // IMPORTANT!!
    // move origin to end of text
    var text_width = ctx.measureText(PARTS[branch.type]).width;
    ctx.translate(text_width + LEFT_OFFSET, 0);
    // scale coordinates to predetermined value for branch
    ctx.scale( b.scale, b.scale );
    ctx.rotate( b.theta );   // rotate axes to be in line with branch
    draw_branch(ctx, b);
    ctx.restore();   // IMPORTANT!!
  }
}
</pre>
<p>The name tags in the <a href="http://carbonfive.github.com/html5-playground/interest-map/interest-map.html">interest map</a> (<a href="https://github.com/carbonfive/html5-playground/blob/gh-pages/interest-map/interest-map.html">source</a>) presented a more realistic problem.  We wanted to simulate the way people attached their name tags on the skill cards.  <a href="http://blog.carbonfive.com/wp-content/uploads/2011/03/card_transform.jpg"><img class="alignright size-full wp-image-3124" title="card_transform" src="http://blog.carbonfive.com/wp-content/uploads/2011/03/card_transform.jpg" alt="" width="300" height="233" /></a>The placement of each name tag was essentially random except that the tags were always near the edge of the card and they were always nearly horizontal. This requires 4 transforms: A translation to the center of the skill card (A), A rotation to give it a unique position on the card (B), A translation to the edge of the card with a random messiness factor (C) and a rotation back that&#8217;s roughly equal to B so the text is roughly horizontal (D).  The following is the (somewhat simplified) function that transforms the coordinates then draws the box and the text around the origin.  In this function, the angle of the name tag on the card, r, is given.</p>
<pre class="brush: jscript; title: ; notranslate">function nametag( ctx, cardx, cardy, person, r ) {
  var text_width = ctx.measureText(person.name).width,
        width = text_width+10;
  ctx.save();
  // make center of card the origin
  ctx.translate( cardx, cardy );
  // rotate in direction of tag placement on card
  ctx.rotate( r );
  // translate to edge of card (with a little permutation)
  ctx.translate( -TAG_RADIUS -  + 4*Math.random(), 0 );
  // rotate back with permutation so that text is nearly horizontal
  ctx.rotate( -r + .4*(Math.random()-.5) );
  /* ... set box style parameters ...  */
  // draw box centered around (transformed) origin
  ctx.beginPath(); ctx.rect( -width/2, -10, width, 20 ); ctx.closePath();
  ctx.fill();
  ctx.stroke();
  /* ... set font style ... */
  // draw text centered around (transformed) origin
  ctx.beginPath(); ctx.fillText( person.name, text_width/2, 0 ); ctx.closePath();
  draw_nametag( ctx, person, interest );
  ctx.restore();  // DON'T FORGET!!!
}</pre>
<p>Most of the time, thinking in terms of coordinate transforms will make your life a lot easier.  The exceptions come when you need to relate shapes drawn in one coordinate system with shapes or points specified in another.  This is especially true when you need make transformed elements interactive.  I&#8217;ll talk more about this problem and some solutions in the next post.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/03/31/taming-2d-transforms/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Node.js, Part III: Full Stack Application</title>
		<link>http://blog.carbonfive.com/2011/03/18/node-js-part-iii-full-stack-application/</link>
		<comments>http://blog.carbonfive.com/2011/03/18/node-js-part-iii-full-stack-application/#comments</comments>
		<pubDate>Fri, 18 Mar 2011 14:19:06 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=3166</guid>
		<description><![CDATA[In my previous posts, I introduced you to Node.js and walked through a bit of its codebase. Now I want to get a simple, but non-trivial Node.js application running. My biggest problem with Node.js so far has been the lack &#8230; <a href="http://blog.carbonfive.com/2011/03/18/node-js-part-iii-full-stack-application/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my previous posts, I i<a href="/2011/03/09/node-js-overview/">ntroduced you to Node.js</a> and <a href="/2011/03/14/node-js-part-ii-spelunking-in-the-code/">walked through a bit of its codebase</a>.  Now I want to get a simple, but non-trivial Node.js application running.  My biggest problem with Node.js so far has been the lack of substantial examples: if I see one more Hello World or Echo Server, I&#8217;ll flip my lid (side note: I found the same thing for Ruby&#8217;s EventMachine so I created my <a href="http://github.com/mperham/evented">evented</a> repo).  By far the best resource I&#8217;ve found for learning Node.js has been <a href="http://dailyjs.com">DailyJS</a>, highly recommended!</p>
<p>So I&#8217;ve spent the last few weeks building <a href="http://github.com/mperham/chrono.js">Chrono.js</a>, an application metrics server.  Chrono is still under development so it&#8217;s really not appropriate for general usage but it makes for a decent example app.<br />
<span id="more-3166"></span></p>
<h2>Sample Request</h2>
<p>Here&#8217;s a basic request which fetches data from MongoDB and renders it via jqtpl:</p>
<pre class="brush: jscript; title: ; notranslate">
app.get('/', function(req, res) {
  db.open(function(err, ignored) {
    if (err) console.log(err);
    db.collectionNames(function(err, names) {
      if (err) console.log(err);
      db.close();
      pro = _(names).chain()
        .pluck('name')
        .map(function(x) { return x.substr(x.indexOf('.') + 1); })
        .reject(function(x) { return (x.indexOf('system.') == 0); })
        .value();
      res.render('index.html.jqtpl', {
        locals: {
          metrics: pro
        }
      });
    });
  });
});
</pre>
<p>We are scanning MongoDB for the set of metric collections and displaying them in the selector so the user can switch between them.  See the <a href="https://github.com/mperham/chrono.js/blob/master/chrono.js">main source file</a> for more examples about parameter handling, headers, JSON, etc.</p>
<h2>Installation</h2>
<p>You will need <a href="http://www.mongodb.org/">MongoDB</a> installed and running locally.  You should already have Node.js and npm installed from Part I.  Let&#8217;s install the javascript libraries required and Chrono itself:</p>
<pre>npm install express expresso jqtpl mongodb underscore tobi
git clone git://github.com/mperham/chrono.js.git</pre>
<p>Express is a lightweight application server, similar to Sinatra.  jqtpl is jQuery Templates, which allows us to dynamically render HTML.  mongodb is the MongoDB client driver for Node.js.  expresso is a TDD framework and tobi is an HTTP functional testing package. Finally, underscore is a great little utility library which provides JavaScript with a much more sane functional programming API.</p>
<h2>Running</h2>
<p>You can run the tests:</p>
<blockquote><p>expresso</p></blockquote>
<p>or run the Chrono.js server:</p>
<blockquote><p>node chrono.js</p></blockquote>
<p>Click <a href="http://localhost:3000/load/registrations">http://localhost:3000/load/registrations</a> to load in some fake data and visit <a href="http://localhost:3000">http://localhost:3000</a> (select &#8216;registrations&#8217;) to see the results, graphed in living color for you!</p>
<h2>Testing</h2>
<p><a href="http://vowsjs.org">Expresso</a> gives us a simple DSL for testing our endpoints but I found it to be lacking basic setup/teardown functionality which I had to roll myself in order to insert some test data.  I would have preferred to use <a href="http://vowsjs.org">vows.js</a> but it appears to be incompatible with tobi.  Check out the <a href="https://github.com/mperham/chrono.js/blob/master/test/chrono.test.js">Chrono.js test suite</a> for what I came up with, here&#8217;s a small sample:</p>
<pre class="brush: jscript; title: ; notranslate">
  exports['POST /metrics'] = function() {
    assert.response(app,
      { url: '/metrics', method: 'POST', headers: { 'content-type': 'application/json' }, data: JSON.stringify({ k: 'registrations', v: 4, at: parseInt(Number(new Date())/1000) }) },
      { status: 201, headers: { 'Content-Type': 'text/html; charset=utf8' }, body: '' }
    );
  }
</pre>
<p>With expresso, we export the set of functions to run from our test module.  Expresso runs them all in parallel and collects the results.  The parallelism means that you must be careful with any test data you create.  Since MongoDB doesn&#8217;t support transactions, we can&#8217;t use transactions to isolate each of our tests (e.g. see Rails&#8217;s transactional fixtures) so you need to be careful about the data created or deleted by each test and how you assert the current state.</p>
<h2>Conclusion</h2>
<p>While I&#8217;ve gotten much better in the last week, I&#8217;ll admit I&#8217;m still uncomfortable with Node.js.  Its asynchronous semantics mean that your code runs as part of a chain of callbacks; knowing when, where and how that chain works is still difficult for me to understand.  Frequently you&#8217;ll just get a black screen and a process that won&#8217;t exit or an error message that may or may not be related to the actual bug.</p>
<p>That said, I still remember being very frustrated with Ruby, its frequent use of &#8220;magic&#8221; and poor documentation (e.g. navigating <a href="http://api.rubyonrails.org/">this</a> still befuddles me).  I overcame those issues to be very comfortable with Ruby in general; I hope more time with Node.js will give me the same relief.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/03/18/node-js-part-iii-full-stack-application/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Node.js, Part II: Spelunking in the Code</title>
		<link>http://blog.carbonfive.com/2011/03/14/node-js-part-ii-spelunking-in-the-code/</link>
		<comments>http://blog.carbonfive.com/2011/03/14/node-js-part-ii-spelunking-in-the-code/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 13:46:56 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=3070</guid>
		<description><![CDATA[In my last post, I gave a quick overview of Node.js and showed you how to install and smoke test it. Now let&#8217;s dive deeper and learn what it provides and how it works. Google&#8217;s V8 JavaScript engine provides the &#8230; <a href="http://blog.carbonfive.com/2011/03/14/node-js-part-ii-spelunking-in-the-code/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>In my last post, I gave a quick <a href="/2011/03/09/node-js-overview/">overview of Node.js</a> and showed you how to install and smoke test it.  Now let&#8217;s dive deeper and learn what it provides and how it works.<br />
<span id="more-3070"></span></p>
<p>Google&#8217;s V8 JavaScript engine provides the underlying VM for executing JavaScript code.  Since V8 is typically embedded in a browser, it does not expose any real notion of FileSystems, Processes and I/O streams that are fundamental to a server-side application.  Node.js provides <a href="http://nodejs.org/docs/v0.4.2/api/">core APIs</a> that wrap the standard POSIX functions available on all modern Unixy systems, along with higher-level APIs for HTTP/S support.</p>
<p>Node.js is designed to be an asynchronous system: your application code executes only on a single thread and no blocking I/O is allowed.  Instead, Node.js uses an event loop to process I/O events via the <a href="http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#NAME">libev</a> C library.</p>
<p>Let&#8217;s dive into the Node code to see how it initializes itself.  This writeup is current as of 0.4.2 or 3/14/2011 but obviously things will change over time.</p>
<h2>Process Initialization</h2>
<p>Node initializes itself in the <a href="https://github.com/joyent/node/blob/cf78ce59b3c0a9e7cdcdbd84d71300b04150b6df/src/node.cc#L2240">node::Start method in node.cc</a>.  <code>node::Start</code> performs the housekeeping necessary to use V8 and libev in a well-behaved process.  A brief walkthru:</p>
<ul>
<li>Line 2240-2275: Parse the cmd line arguments, dividing them up between node and v8.</li>
<li>Line 2280: Setup signal handlers so Ctrl-C will actually terminate the Node.js process.</li>
<li>Line 2290-2330: Configure various libev watchers, include the Idle detector which uses a <a href="https://github.com/joyent/node/blob/cf78ce59b3c0a9e7cdcdbd84d71300b04150b6df/src/node.cc#L168">simple hueristic</a> to determine when it would be best for V8 to run garbage collection.</li>
<li>Line 2332: Initialize V8!</li>
<li>Line 2338-2364: Debugging support</li>
<li>Line 2367-2374: Call <code>node::Load</code> to bootstrap the Node.js APIs, see below</li>
<li>Line 2385: The key line: pass control to libev event loop.  This function will not return until the application code decides to exit the process based on some event or SIGINT or SIGTERM are received.</li>
<li>Line 2389-2405: Process is exiting.  Execute any &#8220;exit&#8221; event callbacks in the application code and return.</li>
</ul>
<h2>Bootstrap</h2>
<p><a href="https://github.com/joyent/node/blob/cf78ce59b3c0a9e7cdcdbd84d71300b04150b6df/src/node.cc#L1916">node::Load</a> performs the actual Node.js API bootstrap in three stages:</p>
<ul>
<li>Stage 1: Using C++, it sets up a process object and fills it with various constants and methods, so your JavaScript code can access &#8220;process.argv&#8221;, &#8220;process.env&#8221;, etc.  As far as I can tell, the most fundamental part is the <a href="https://github.com/joyent/node/blob/cf78ce59b3c0a9e7cdcdbd84d71300b04150b6df/src/node.cc#L1766">Process.binding</a> function which allows JS code to lazily bootstrap the C++ bindings. For instance, <a href="https://github.com/joyent/node/blob/cf78ce59b3c0a9e7cdcdbd84d71300b04150b6df/lib/fs.js#L3">this line</a> to fetch the &#8216;fs&#8217; binding actually causes the code within <a href="https://github.com/joyent/node/blob/cf78ce59b3c0a9e7cdcdbd84d71300b04150b6df/src/node_file.cc#L905">node_file.cc</a> to expose various POSIX file functions to the JavaScript module.</li>
<li>Stage 2: It executes the JavaScript in <a href="https://github.com/joyent/node/blob/cf78ce59b3c0a9e7cdcdbd84d71300b04150b6df/src/node.js">src/node.js</a>.  This code sets up the various I/O streams (stdin, stdout and stderr) and creates the JavaScript module loading system which knows how to find JavaScript files in <code>lib/</code> when <code>require(module)</code> is called.</li>
<li>Stage 3: Node.js executes the user&#8217;s code, via debugger, repl or user-provided script file.  Remember this script doesn&#8217;t block so it will load quickly and return back to node::Load.</li>
</ul>
<p>Once the user&#8217;s code has been loaded, we should have set up any listening sockets, timers, etc.  The entire node::Load function unwinds and we enter the event loop, waiting for I/O or Timer events to execute code.</p>
<p>Thanks for staying with me this far &#8211; I hope you learned something new.  Next up, I&#8217;ll show you how to configure and run a full stack application on node.js using MongoDB and Express!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/03/14/node-js-part-ii-spelunking-in-the-code/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Node.js Overview</title>
		<link>http://blog.carbonfive.com/2011/03/09/node-js-overview/</link>
		<comments>http://blog.carbonfive.com/2011/03/09/node-js-overview/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 15:42:37 +0000</pubDate>
		<dc:creator>Mike Perham</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=3039</guid>
		<description><![CDATA[I was a Java guy for 10 years and I&#8217;ve been a Rubyist for the last 5 years. Over the years, I&#8217;ve tried to develop expertise in a particular area of technology that will both pay the bills and make &#8230; <a href="http://blog.carbonfive.com/2011/03/09/node-js-overview/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was a Java guy for 10 years and I&#8217;ve been a Rubyist for the last 5 years.  Over the years, I&#8217;ve tried to develop expertise in a particular area of technology that will both pay the bills and make me happy as a programmer while also watching for upcoming changes in the tech world.  I often find myself diving into a particular technology just to get my hands dirty and get a feel for its strengths and weaknesses.  As my JavaScript skills have always been weak, I&#8217;ve decided to deep dive into <a href="http://nodejs.org">Node.js</a> to understand what it does well and improve my JavaScript skills at the same time.</p>
<p>For this post, I&#8217;m just going to cover the basics; I&#8217;ll follow up soon with deeper posts.<br />
<span id="more-3039"></span></p>
<h2>Overview</h2>
<p>JavaScript has an interesting history &#8211; it hasn&#8217;t developed like most other languages; until recently, executing JavaScript meant embedding it in a web page for a browser to execute.  A few things happened which radically hastened the rise in JavaScript as an reasonable server-side language:</p>
<ul>
<li>AJAX and the Browser Wars have resulted in dramatic improvements in Javascript runtime performance and high-quality developer tools.</li>
<li>Node.js built Process, File and Network I/O APIs on top of Google&#8217;s <a href="http://code.google.com/p/v8/">V8 JavaScript engine</a>, allowing command line programs and daemons to be built in JavaScript.</li>
</ul>
<p>Node.js adds a friendly command line face to V8 and APIs that are conceptually similar to Ruby&#8217;s EventMachine library: all I/O is asynchronous and threads are unavailable to user code.  Additionally JavaScript is a prototype-based language, not object-oriented.  This makes for a programming model that is radically different from what Ruby or Java developers are used to.</p>
<h2>Installation</h2>
<p>I&#8217;m going to assume OSX and I like to install things with <a href="http://mxcl.github.com/homebrew/">Homebrew</a>.  We&#8217;ll install node and npm, node&#8217;s package manager, with these commands:</p>
<pre class="brush: bash; title: ; notranslate">
    brew update # update Homebrew's formulas to the latest
    brew install node # install node
    curl http://npmjs.org/install.sh | sudo sh # install npm
</pre>
<p>Once installed, you should be able to run <code>node --help</code> and <code>npm --help</code>.</p>
<p>A minimal web server using Node.js:</p>
<pre class="brush: jscript; title: ; notranslate">
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello Worldn');
}).listen(8124, &amp;quot;127.0.0.1&amp;quot;);
</pre>
<p>Copy that code into <code>hello.js</code> and run it:</p>
<pre>
node hello.js
</pre>
<p>Now let&#8217;s slam it with some requests:</p>
<pre>
ab -n 10000 -c 50 http://127.0.0.1:8124/
</pre>
<p>Results:</p>
<pre>
Server Hostname:        127.0.0.1
Server Port:            8124
Document Path:          /
Document Length:        12 bytes
Concurrency Level:      50
Time taken for tests:   1.479 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      760000 bytes
HTML transferred:       120000 bytes
Requests per second:    6760.79 [#/sec] (mean)
Time per request:       7.396 [ms] (mean)
Time per request:       0.148 [ms] (mean, across all concurrent requests)
Transfer rate:          501.78 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      0       3
Processing:     1    7   3.6      7      20
Waiting:        1    7   3.6      7      20
Total:          1    7   3.6      7      22

Percentage of the requests served within a certain time (ms)
  50%      7
  66%      9
  75%     10
  80%     11
  90%     12
  95%     13
  98%     15
  99%     16
 100%     22 (longest request)
</pre>
<p>Not bad.  Of course, this is using localhost and a trivial app but at least we know it&#8217;s up and running well.  In my next post, we&#8217;ll explore the Node.js source code itself.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/03/09/node-js-overview/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Visualizing Skillsets in HTML5 Canvas: Part 1</title>
		<link>http://blog.carbonfive.com/2011/02/17/visualizing-skillsets-in-html5-canvas-part-1/</link>
		<comments>http://blog.carbonfive.com/2011/02/17/visualizing-skillsets-in-html5-canvas-part-1/#comments</comments>
		<pubDate>Thu, 17 Feb 2011 14:57:36 +0000</pubDate>
		<dc:creator>Alex Cruikshank</dc:creator>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=2850</guid>
		<description><![CDATA[As Courtney chronicled in the d.build journal, Carbon Five recently engaged in a group exercise to create a physical diagram of our skills and interests.  The activity was entertaining and produced a rather attractive artifact on the wall, but we &#8230; <a href="http://blog.carbonfive.com/2011/02/17/visualizing-skillsets-in-html5-canvas-part-1/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a href="http://carbonfive.github.com/html5-playground/interest-map/interest-map.html"><img class="aligncenter size-full wp-image-2910" title="interest-map-visual" src="http://blog.carbonfive.com/wp-content/uploads/2011/02/interest-map-visual4.jpg" alt="" width="640" height="236" /></a>As Courtney <a href="http://dbuildjournal.com/2011/01/26/carbon-five-visual-metaphors-interactive-skill-and-interest-map/">chronicled</a> in the <a href="http://dbuildjournal.com">d.build journal</a>, Carbon Five recently engaged in a group exercise to create a physical diagram of our skills and interests.  The activity was entertaining and produced a rather attractive artifact on the wall, but we soon realized that (aside from noting that some skills were more popular than others) there was little useful information that could be drawn from the visualization.  If we were going to find any kind of message among the splatter of paint chips, we were going to need to reorganize the data.</p>
<p>Our goal was to create a visualization that would focus in on individual and collective patterns in the skills and interests chosen while still inviting people to explore and draw new conclusions.  It was important to leave some aspects of the interpretation to the group that created it, so we knew we needed an interactive visualization (the opportunity to explore new HTML5 influenced me here).</p>
<p><a href="http://carbonfive.github.com/html5-playground/interest-map/interest-map.html">The result of this effort</a> (this page requires an HTML5 compatible browser) is a single page canvas application that plots Carbon Fives skills and interests along various axes.  In the rest of the article I&#8217;ll explain how we converted the data to something more meaningful.<span id="more-2850"></span></p>
<h3>Identifying Meaning</h3>
<p><a href="http://dbuildjournal.com/2011/01/26/carbon-five-visual-metaphors-interactive-skill-and-interest-map/"><img class="size-full wp-image-2899" title="interest-map-wall" src="http://blog.carbonfive.com/wp-content/uploads/2011/02/interest-map-wall.jpg" alt="" width="640" height="480" /></a></p>
<p>Staring at the wall filled with skill cards and covered with name tags, it was tempting to try to make sense of it all by asking why a certain color seemed to be bunched up in a corner or why others seemed more scattered.  The cards were arbitrarily distributed, however, so any abnormalities were the product of statistical fluctuation.  If we really wanted to interpret the data as a two dimensional graph, we would have to rearrange the cards in such a way that their position on the on the wall had meaning.</p>
<p>So we began identifying opposing qualities that were applicable to all the skills in varying degrees.  In the end, we came up with &#8220;&#8216;server side / client side&#8217;, &#8216;technical / creative&#8217;, &#8216;c5 core / c5 expansion&#8217;, &#8216;public facing / in house&#8217;, &#8216;trendy / old school&#8217;.  We then sat down together and tried to figure out where to place each skill on a scale where, say, &#8216;public facing&#8217; would be zero and &#8216;in house&#8217; would be a one.   The key to this exercise was to talk about where each skill falls relative to the other skills we&#8217;ve already discussed and to keep it quick.  I suspect we would get different orderings if we tried again, but the things that are obviously one thing or the other would still migrate towards the ends, and difference in the rest gets averaged out in the calculations anyway.</p>
<p>Once we had multiple orderings for the skills, we had to digitize the location of all the name tags.  We did this by assigning a number to each of the skill cards, and then writing down that number in either a skill column or an interest column next to the name of each person who put a name tag on that card. This is close to how the data is represented in the application.  It took a couple of passes to get the data right and we had to fill in a few gaps for employees that missed out on the exercise, but eventually I had all the data I needed to create the visualization.</p>
<h3>Designing the Visualization</h3>
<p><div id="attachment_2857" class="wp-caption alignright" style="width: 251px"><a href="http://carbonfive.github.com/html5-playground/interest-map/interest-map.html"><img class="size-full wp-image-2857  " title="interactive-skill-map" src="http://blog.carbonfive.com/wp-content/uploads/2011/02/interactive-skill-map-e1297981045565.jpg" alt="Interactive Skill Map" width="241" height="155" /></a><p class="wp-caption-text">The arrows start at the average location of a person&#039;s skills and end at the average location of his or her interests.</p></div></p>
<p>The visualization itself is designed to look as much like the the wall as possible, while taking into account the limitations of legibility and  vector graphics.  When the application starts, it shows all the cards &#8212; each with the appropriate name tags &#8212; ordered horizontally according to whether the skill is more of a client-side or server-side skill, and vertically by whether the skill is more technical or creative.  Clicking the arrows next to the axis labels switches that axis to a new dichotomy and reorders the cards accordingly.  This view of the data is mainly to allow you to view the actual data.  If you click on the &#8216;show arrows&#8217; button in the top right, you get a view more conducive to story telling.  Each of the arrows represents a Carbon Five employee.  The arrow starts at the average location of all of the person&#8217;s skills, and points to the average location of all of the person&#8217;s interests.  In a sense, it&#8217;s visualizing the direction of the person&#8217;s professional development.</p>
<p>You can also change the axes in the arrows view, and doing so brings up some interesting contrasts.  In some combinations, almost all the arrows are pointing in the same direction, and in others they all criss-cross.  In most combinations, all the arrows are in a pack, but in some there are a few arrows clustered together but away from the pack.  The interpretation of these phenomena depend on the axis in question.   The data has inaccuracies and biases built in at every point, but it has still been interesting to spot some feature in the visualization, interpret what it means and then check the names of the people behind the arrows.  In most cases the characterization highlights something that is unique about one of the Carbon Five team.</p>
<h3>Building Your Own Skill Map</h3>
<p>Aside from the choice of skill cards, there is nothing about  the exercise or the application that is peculiar to Carbon Five.  If you can get your company to generate their own skill map, you can use <a href="https://github.com/carbonfive/html5-playground/blob/gh-pages/interest-map/interest-map.html">the source</a> to create your own visualization by changing the data section in the top of the application.  In fact, I would be willing to do this for you if you can send me the data in some sort of reasonable digital format (limit the first 5 takers within the next year).</p>
<p>In the next post I will be discussing some of the programming challenges involved in writing interactive canvas applications.</p>
<p><strong>update:</strong></p>
<p>The <a href="http://blog.carbonfive.com/2011/03/31/taming-2d-transforms/">second post</a> on using transforms effectively in canvas applications is up.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2011/02/17/visualizing-skillsets-in-html5-canvas-part-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Ew&#8230; you got CSS in my Javascript</title>
		<link>http://blog.carbonfive.com/2010/10/21/ew-you-got-css-in-my-javascript/</link>
		<comments>http://blog.carbonfive.com/2010/10/21/ew-you-got-css-in-my-javascript/#comments</comments>
		<pubDate>Thu, 21 Oct 2010 23:29:32 +0000</pubDate>
		<dc:creator>Andy Peterson</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JavaScript / AJAX]]></category>
		<category><![CDATA[Process]]></category>
		<category><![CDATA[prototyping]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=1328</guid>
		<description><![CDATA[The other weekend I test drove a little Javascript library to output CSS style rules from within Javascript. I took the most obvious Javascript-literal approach to get the most out of Javascript support in editors. I called it Csster (&#8220;sister&#8221;), &#8230; <a href="http://blog.carbonfive.com/2010/10/21/ew-you-got-css-in-my-javascript/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The other weekend I test drove a<a href="http://github.com/ndp/csster"> little Javascript library</a> to output CSS style rules from within Javascript. I took the most obvious Javascript-literal approach to get the most out of Javascript support in editors. I called it Csster (&#8220;sister&#8221;), and it looks like:<br />
<code>Csster.style({<br />
    h1: { fontSize: 18, color: 'chartreuse'    }<br />
});</code><br />
All it does is insert the rule into the DOM so that H1 elements are, well, <span style="font-size:18px;color:chartreuse;">chartreuse</span>. There wasn&#8217;t initially much code behind this, but I thought it might be useful. It&#8217;s pretty much the same as <a href="http://api.jquery.com/css/">jQuery&#8217;s css function</a>, but writes out a rule instead of immediately applying it to all the elements.</p>
<p>I immediately added nesting of rules, similar to how SASS lets you dry-up your stylesheets. Then, with a little help from Alex, I added basic color conversions and functions like &#8220;darken&#8221; and &#8220;saturate&#8221;<a href="http://ndpsoftware.com/csster/demo.html">(demo here)</a>. I then added <a href="http://www.paulgraham.com/avg.html">support for macros</a>, so you could mix-in behaviors like rounded corners, drop shadows, and of course the ubiquitous (and awkwardly named) &#8220;clearfix&#8221;. My last pass was to make sure there are reasonable extension points for other developers. Now you can write concise and expressive CSS right along with your Javascript.</p>
<p>Since it&#8217;s POJS (Plain Old Javascript), it is a compact language. There&#8217;s was no need for me to write math or looping or logic functions, since Javascript&#8217;s already got them (unlike SASS). DSLs are the hottest things these days, but even the not-so-forgiving syntax of Javascript works pretty well in this case.</p>
<p>Why would you want to use this? Well, I thought that was the big question, but everyone I show it to has an answer. For me, I am writing pages that generate lots of their HTML markup anyway, so it is awkward to keep a separate CSS file in sync (and drag it down from the server). It works well to write self-contained jQuery plugins, as I <a href="http://ndpsoftware.com/csster/demo_chart.html">sketched out here</a>. I started using on a new initiative (that I can&#8217;t share yet) of <a href="http://bedsider.org/methods">my latest project</a>, and it made prototyping and initial build-out much faster. It also makes using sprites painless&#8211; all our subtitles are in one sprite and I simply add a <code>has: subtitle("Emotion")</code> as one of the attributes and it works. (Previously I&#8217;d written some Ruby code to generate a CSS. Ughh.)</p>
<p>Please, <a href="http://github.com/ndp/csster">give it a spin</a>, and file bugs or send me comments on github.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/10/21/ew-you-got-css-in-my-javascript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A few experiments with HTML 5 applications</title>
		<link>http://blog.carbonfive.com/2010/07/08/a-few-experiments-with-html-5-applications/</link>
		<comments>http://blog.carbonfive.com/2010/07/08/a-few-experiments-with-html-5-applications/#comments</comments>
		<pubDate>Thu, 08 Jul 2010 14:30:03 +0000</pubDate>
		<dc:creator>Alex Cruikshank</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JavaScript / AJAX]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[spa]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=1052</guid>
		<description><![CDATA[I&#8217;ve had a long-standing interest in taking client-side programming beyond display logic and input validation. The new HTML 5 technologies are making full-scale application development in the browser increasingly practical. Unfortunately, the needs of Carbon Five&#8217;s clients generally exceed the &#8230; <a href="http://blog.carbonfive.com/2010/07/08/a-few-experiments-with-html-5-applications/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve had a long-standing interest in taking client-side programming beyond display logic and input validation.  The new <a href="http://en.wikipedia.org/wiki/HTML5">HTML 5</a> technologies are making full-scale application development in the browser increasingly practical. Unfortunately, the needs of Carbon Five&#8217;s clients generally exceed the capabilities of purely client-side solutions, so I don&#8217;t get to spend as much time developing JavaScript as I&#8217;d like. Consequently, I challenged myself to solve as many of my day-to-day issues as possible by writing applications that require only a single HTML page and a modern browser to run. So far, this has resulted in five applications; they&#8217;re available &#8212; with some additional thoughts on this style of development &#8212; below the fold.</p>
<p><span id="more-1052"></span></p>
<h2>The Applications</h2>
<ul>
<li>
  <b><label><a href="http://carbonfive.github.com/html5-playground/snowballs.html">Snowballs</a></label></b></p>
<p>Snowballs is a video game that was mostly designed by my 7 year old daughter, Ada. She started with a drawing that contained a maze filled with dots, a player and some monsters, and she explained how you throw snowballs at the monsters and build walls to block them. I convinced her we could get roughly the same effect by freezing the monsters instead of blocking them, and then I began developing. We started iterating, and she continued to contribute ideas which, somewhat surprisingly, always made the game more fun. The arrow keys move the player, and the spacebar launches a snowball. It&#8217;s implemented as a single Canvas tag using a JavaScript interval as a run loop. The maze, players, monsters, and snowballs are all drawn with JS functions using the Canvas drawing API. Since this application uses the Canvas tag, it won&#8217;t run in Internet Explorer or older versions of other browsers.
  </p>
</li>
<li>
  <b><label><a href="http://carbonfive.github.com/html5-playground/flashcards.html">Flashcards</a></label></b></p>
<p>I wrote Flashcards one evening when Ada&#8217;s teacher suggested using flash cards to help her memorize the words she shouldn&#8217;t need to sound out. The idea is that the parent clicks the spacebar when the child reads the word and they work together to reduce the time needed to read all the words. The application doesn&#8217;t need any graphics (other than some external images at the end), so it doesn&#8217;t use any HTML 5 features (browser compatibility is unknown).
  </p>
</li>
<li>
  <b><label><a href="http://carbonfive.github.com/html5-playground/timetest.html">Timetest</a></label></b></p>
<p>
    Like Flashcards, I wrote Timetest to help Ada with her schoolwork. In this case, she was getting frustrated with a lesson on analog clocks, so I wrote this application to make it more of a game. The goal is to answer as many questions as possible in the given time. The test turned out to be more difficult than it really needed to be, so I created an easier version (accessed by adding <i>#easy</i> to the URL). Since this application uses the Canvas tag, it won&#8217;t run in Internet Explorer or older versions of other browsers.
  </p>
</li>
<li>
  <b><label><a href="http://carbonfive.github.com/html5-playground/arithmetic.html">Arithmetic</a></label></b></p>
<p>
    Arithmetic is another educational application designed to drill addition that uses carrying. It provides spaces at the top, which you can click to mark a carry from the previous column. It doesn&#8217;t have any fancy HTML 5 features, but it does have a lot of stats.
  </p>
</li>
<li>
  <b><label><a href="http://carbonfive.github.com/html5-playground/surround.html">Surround</a></label></b></p>
<p>
    My wife and I had designed a fireplace surround and mantel for our living room,  but when it came to actually buying the materials and building the thing, we realized we didn&#8217;t know exactly how to scale it.  Since the design was entirely composed of rectangles, I realized it would be possible to build a simple one-off CAD program to help us agree on some dimensions.  The application makes use of the Canvas tag and the new HTML 5 slider inputs (which aren&#8217;t currently supported in Firefox). It translates between pixels and feet/inches constrained to an 8th of an inch, in order to make the measurements easier to use in the shop.
  </p>
</li>
</ul>
<p>  The goal of these exercises was to produce something simple and quick, but not entirely without polish. All the applications except Snowballs took only an evening or two. Each application (also excluding Snowballs) ended up under 300 lines of HTML, CSS, and JS combined.</p>
<h2>Developing without a JavaScript framework</h2>
<p>Limiting the applications to a single page means no importing <a href="http://jquery.com">jQuery</a> or <a href="http://www.prototypejs.org/">Prototype</a>. This might seem like a big constraint in an application written entirely in JavaScript. But these frameworks really only help out with DOM traversal/manipulation, event handling, animation, Ajax, form validation. All the applications make do with a small amount of HTML, so it&#8217;s easy enough to grab elements by ID, and a few visits to <a href="http://www.quirksmode.org/">Quirksmode</a> gave me some reasonably cross-browser event-handling code. Animation isn&#8217;t really that hard in JS, and I needed it to be more custom than frameworks allow anyway. The rest I didn&#8217;t need.  The truth is, I never miss having a framework (though I&#8217;m not about to stop using jQuery when working on client&#8217;s sites).</p>
<h2>Advantages and disadvantages</h2>
<ul>
<li>
  <b>They&#8217;re quick to start.</b>  Since it&#8217;s a single page, there&#8217;s no setup and no integration.
  </li>
<li>
    <b>They&#8217;re easy to deploy.</b>  It&#8217;s only one relatively small file, so you can e-mail it to friends, and you can host it anywhere. If you want to spend a little time making it touch-screen compatible, you can get it on all the smarter smart phones without bothering with app stores. On the other hand, there is no way prevent people from stealing the application or the code if you were developing it commercially, since the source is always just a right-click away.
  </li>
<li>
    <b>HTML+CSS is a powerful display framework.</b>  Although it lacks built-in support for some of the fancier UI widgets, there is no GUI framework that I&#8217;m aware of (and I&#8217;ve developed with quite a few) that provides the same level of design control with the same ease of development as these technologies. Of course, I&#8217;ve been swimming in HTML/CSS for years, so this opinion is a bit biased.
  </li>
<li>
    <b>Canvas has a powerful vector graphics API.</b>  I had done a fair amount of <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CocoaDrawingGuide/Introduction/Introduction.html">Cocoa programming</a> prior to these projects, so this didn&#8217;t come as a surprise. The real power of <a href="https://developer.mozilla.org/en/drawing_graphics_with_canvas">Canvas</a> lies in its transformation functions. I&#8217;d like to find an application for some more advanced spline generation. The downside is that Canvas and HTML don&#8217;t really mix, so you can have great text layout in HTML and sophisticated text animations in Canvas, but not both at the same time.
  </li>
<li>
    <b>JavaScript is a capable if not optimal language.</b>  No one is going to <a href="http://www.crockford.com/javascript/javascript.html">make the case</a> that JavaScript is the greatest language ever designed, but what it lacks in performance and language features, it partially makes up in powerful fundamentals and simplicity.  JavaScript is neither a great functional language nor a great object-oriented one, but it is sufficiently powerful to develop in either of these paradigms. Snowballs, for example, acts a lot like a simulation and benefited from stateful objects. The other applications required less state and I found several uses for <a href="http://en.wikipedia.org/wiki/Higher-order_function">higher-order functions</a>, though I wouldn&#8217;t consider any of them properly functional.
  </li>
<li>
    <b>Single-page applications are fun.</b>  These exercises have reminded me that, once the responsibilities of software engineering are stripped away, there is a joy to be found in coding for coding&#8217;s sake.
  </li>
</ul>
<p>
All of these applications are <a href="http://github.com/carbonfive/html5-playground">available on GitHub</a>, but it&#8217;s probably easier to right-click on the page and choose <i>view source</i>. <img src='http://blog.carbonfive.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/07/08/a-few-experiments-with-html-5-applications/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Unit testing JavaScript with Blue Ridge</title>
		<link>http://blog.carbonfive.com/2009/11/13/unit-testing-javascript-with-blue-ridge/</link>
		<comments>http://blog.carbonfive.com/2009/11/13/unit-testing-javascript-with-blue-ridge/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 21:19:19 +0000</pubDate>
		<dc:creator>Jonah Williams</dc:creator>
				<category><![CDATA[Process]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JavaScript / AJAX]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=696</guid>
		<description><![CDATA[My current rails project is using Blue Ridge and the tool set it bundles together (Rhino, env.js, Screw.Unit, and Smoke) to write test driven JavaScript. The ability to write tests of my JavaScript, in JavaScript, as efficiently as I can &#8230; <a href="http://blog.carbonfive.com/2009/11/13/unit-testing-javascript-with-blue-ridge/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>My current rails project is using <a href="http://github.com/relevance/blue-ridge">Blue Ridge</a> and the tool set it bundles together (<a href="http://www.mozilla.org/rhino/">Rhino</a>, <a href="http://github.com/thatcher/env-js">env.js</a>, <a href="http://github.com/nkallen/screw-unit">Screw.Unit</a>, and <a href="http://github.com/andykent/smoke">Smoke</a>) to write test driven JavaScript. The ability to write tests of my JavaScript, in JavaScript, as efficiently as I can test other languages has forced me to rethink how I structure my work and I&#8217;m writing better code because of it.</p>
<p>There are a couple of different options for JS testing available at this point but Blue Ridge&#8217;s plugin is the first I have seen which made writing test driven code as easy as I have come to expect while still providing all the functionality I need. In particular;</p>
<ul>
<li>Running my tests in a browser is fast. Refreshing fixture pages to rerun tests is dramatically more efficient than waiting for selenium tests to cycle.</li>
<li>I can debug my tests as they run against their fixtures pages and inspect or manipulate the DOM at any point.</li>
<li>I have mock and fake objects available to test behavior and stub out dependencies.</li>
<li>My JS tests run in continuous integration, just like all the other tests.</li>
</ul>
<p>By writing fixtures pages and tests first I am immediately using all of my code in two locations and running it against slightly different DOMs. That has pushed me to encapsulate most of my code as jQuery plugins and think carefully about how much I depend on the page&#8217;s structure. I end up with terse selectors instead of using whatever attributes are readily available and a clear configuration point for my page&#8217;s behavior as I chain together plugin calls in $(document).ready().</p>
<p>We&#8217;d like to see what other developers have done and share what we have learned so far so Carbon Five is hosting an open discussion of JavaScript testing in our office this week.</p>
<p>Topic: Javascript Testing<br />
When: Tuesday Nov 17<br />
6pm: arrive/network<br />
6:30 &#8211; 8 presentation and discussion<br />
Where: Carbon Five office: <a href="http://maps.google.com/maps?f=q&amp;hl=en&amp;geocode=&amp;q=171+2nd+St+%23+4,+San+Francisco,+CA%E2%80%8E&amp;sll=36.738884,-118.432617&amp;sspn=13.579326,18.632813&amp;ie=UTF8&amp;hq=&amp;hnear=171+2nd+St,+San+Francisco,+California+94105&amp;z=14&amp;iwloc=r0">171 2nd Street, 4th Floor</a></p>
<p>Please <a href="https://spreadsheets.google.com/viewform?formkey=dDg5dl9zbHlhZXNpdzBxdVIzblhjN3c6MA">RSVP</a> if you would like to attend.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2009/11/13/unit-testing-javascript-with-blue-ridge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

