This site is a self-contained low down on what's going on in my life, what I'm working on, what I'm thinking about, and how I'm feeling about life in general.
Monday, 09 June 2008
I've been looking at evvective and stylish ways to show off room bookings and came up with this.

The room list is static, while the internal content slides smoothly based on the timeframe selected.
I didn't use a framework, instead coding this myself.
As such I haven't had time to streamline the code yet (as usual) but it's free to use if anyone wants it.
All that's missing is adding your own code to reflect the bookings.
The full source code is available here.
Friday, 25 April 2008
I recently wrote about how to create a bar graph using the <canvas> tag in html. This was more of a theory article, so as promised, here is the substance.

Start by creating your html body as follows:
<body onload="buildChart();">
<div class="chart">
<div id="label_container" style="position: relative; margin: 20px auto; display: inline-block;">
<canvas id="canvas" width="400" height="200"></canvas>
</div>
</div>
<table id="mydata">
<tr> <th>Customers</th><th>Value</th> </tr>
<tr><td>Design</td> <td>2</td> </tr>
<tr><td>Enquiries</td> <td>5</td> </tr>
<tr><td>Home Screen</td> <td>1</td> </tr>
<tr><td> Navigation</td> <td> 4</td> </tr>
<tr><td> Projects</td> <td> 6</td> </tr>
<tr><td> To-do</td> <td> 9</td> </tr>
</table>
</body>
The table contains the data used to build the chart, this can be built dynamically which is really useful for reports etc.
Now lets start on the javascript to build our chart. Firstly, lets start working with our buildChart function.
function buildChart(){
// source data table and canvas tag
var data_table = document.getElementById('mydata');
var canvas = document.getElementById('canvas');
var td_index = 1; // which TD contains the data
var max_value = 0;
var ySegmentCount = 5;
Here, we've defined our variables for the table, the canvas and specified the column that contains the values for our graph. max_value will be set to the largest of the values, and ySegmentCount contains the number of values to be listed horizontally.
I've defined a fixed pallet for this example, however you can easily adapt this to use a dynamic pallet, I just like to control the colours used.
var myPallet = new Array();
myPallet[0] = "#2A416A";
myPallet[1] = "#39588E";
myPallet[2] = "#4572AD";
myPallet[3] = "#688BC3";
myPallet[4] = "#8EA6D2";
myPallet[5] = "#B2C3DF";
myPallet[6] = "#CCD8EA";
myPallet[7] = "#DDDBFB";
myPallet[8] = "#F0F0F0";
myPallet[9] = "#2A416A";
myPallet[10] = "#39588E";
myPallet[11] = "#4572AD";
myPallet[12] = "#688BC3";
myPallet[13] = "#8EA6D2";
myPallet[14] = "#B2C3DF";
myPallet[15] = "#CCD8EA";
myPallet[16] = "#DDDBFB";
myPallet[17] = "#F0F0F0";
Next we retrieve the chart values and calculate some parameters.
var tds, data = [], color, colors = [], value = 0;
var trs = data_table.getElementsByTagName('tr'); // all TRs
for (var i = 0; i < trs.length; i++) {
tds = trs[i].getElementsByTagName('td'); // all TDs
if (tds.length === 0) continue; // no TDs here, move on
// get the value, update total
value = parseFloat(tds[td_index].innerHTML);
if(value > max_value){ max_value = value; }
data[data.length] = value;
// Assign color
color = myPallet[i];
colors[colors.length] = color; // save for later
trs[i].style.backgroundColor = color; // color this TR
}
var itemCount = trs.length-1;
var yIncrement = max_value / ySegmentCount; //determine increment between y axis increments
var barWidth = (canvas.width - (10 * (itemCount * 2))) / itemCount;
var yIncrementPixels = (canvas.height - (2 * (ySegmentCount * 2))) / ySegmentCount;
We now know how wide to make the bars based on the canvas width and number of items, and also the distance between value markers.
We now need to prepare to draw our bar graph, we start by preparing the variables.
var ctx = canvas.getContext('2d');
var canvas_size = [canvas.width, canvas.height];
var backSoFar = 2;
var ySpanPosition = 0;
var yTotal = max_value;
backSoFar contains the vertical (y) start position of each background block. This starts at 2 to create a slight gap at the top. ySpanPosition contains the vertical position of the span containing the axis value.
Lets render the background.
for(i=0; i<ySegmentCount+1; i++){
if(i==ySegmentCount){
yTotal = canvas.height-8;
var labelContainer = document.getElementById('label_container');
var oSpan = document.createElement('span');
var oLabelText = document.createTextNode('0');
oSpan.setAttribute('style','left: -50px; top: '+yTotal+'px; position: absolute; font-size: 60%; z-index: 100; background: none; width: 45px; display: block; text-align: right;');
oSpan.appendChild(oLabelText);
labelContainer.insertBefore(oSpan, labelContainer.lastChild);
}else{
backSoFar += 2;
ySpanPosition = backSoFar -8;
ctx.fillStyle = '#E7EEF6';
ctx.fillRect(0,backSoFar,canvas.width,yIncrementPixels);
var labelContainer = document.getElementById('label_container');
var oSpan = document.createElement('span');
var oLabelText = document.createTextNode(yTotal.toFixed(2));
//var oLabelText = document.createTextNode('sdfsg');
oSpan.setAttribute('style','left: -50px; top: '+ySpanPosition+'px; position: absolute; font-size: 60%; z-index: 100; background: none; width: 45px; display: block; text-align: right;');
oSpan.appendChild(oLabelText);
labelContainer.insertBefore(oSpan, labelContainer.lastChild);
yTotal += -yIncrement;
backSoFar += yIncrementPixels;
backSoFar += 2;
}
}
Change the value of ctx.fillStyle to set the background colour. Now for our final block for javascript in this function, we render the bars themselves.
var sofar = 0; // keep track of progress
// loop the data[]
for (var piece in data) {
var percentHeight = (data[piece]/max_value)*100;
var pixelHeight = (canvas.height-4)*(percentHeight/100);
var barFloor = canvas.height - pixelHeight; //subtract bar height from canvas height to get ground level;
sofar += 10; //add left margin
//ctx.beginPath();
ctx.fillStyle = colors[piece]; // color
ctx.lineWidth = 4;
ctx.strokeStyle = '#FFF';
ctx.shadowBlur = 3;
ctx.shadowColor = "#999";
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.strokeRect(sofar,barFloor,barWidth,pixelHeight);
ctx.shadowBlur = 0;
ctx.shadowColor = "#333";
ctx.fillRect(sofar,barFloor,barWidth,pixelHeight);
//Add labels
var xLabelPosition = sofar;
var yLabelPosition = canvas.height + 10; //add span height
var labelContainer = document.getElementById('label_container');
var oSpan = document.createElement('span');
var oLabelText = document.createTextNode(data[piece]);
//var oLabelText = document.createTextNode('sdfsg');
oSpan.setAttribute('style','left: '+xLabelPosition+'px; top: '+yLabelPosition+'px; position: absolute; font-size: 60%; z-index: 100; background: none; width: '+barWidth.toFixed(0)+'px; display: block; text-align: center;');
oSpan.appendChild(oLabelText);
labelContainer.insertBefore(oSpan, labelContainer.lastChild);
sofar += barWidth;
sofar += 10;
}
}
After calculating the positioning of the bar, we create 2 rectangles, the first is white and has drop shadow, the second is the coloured bar. Then we access the DOM to create the span labels and position them appropriately. The 10 value added to the sofar variable spaces the bars 10 pixels.
Finally, some css to make sure everything displays as required.
canvas { background: #fff; border-bottom: 1px solid #ccc; }
.chart {
position: relative;
display: block;
text-align: center;
background: #FFF;
padding-bottom: 10px;
padding-top: 10px;
}
span { font-family: Arial, Helvetica, sans-serif;}
So there we have it, a low bandwidth bar graph that looks great and is totally dynamic. I haven't had time to make the code as efficient as possible but it definitely does the job. I hope you find this useful.
Sunday, 13 April 2008
I recently wrote about how I'd modified a great example of creating a pie chart using the canvas tag and javascript. I've now written a bar graphing function based on the same principal of dynamically building the chart from tabulated data and building it to the size of the canvas tag.
This will form part of a charting component I'm writing, and although this example only builds a simple bar graph, the finished product will let you compare multiple bar values, plot trend lines, line graphs and scatter graphs. It's just a matter of doing it and making it more flexible.

I'll upload the source code once I've streamilined it a bit, the features are:
Source should be up later in the week, good night all.
Sunday, 06 April 2008
I've been looking around for a rich text editor that works with the iPhone / iPod Touch Safari browser. I sometimes make posts when I'm out and about and manually creating html tags is a real bind, so my options, at a high level are:
The problem with the iPhone is that the keyboard is only displayed when the cursor is inside a textarea, which rules out rich text editing, beside the fact that you can't currently highligh a block of text.
The next reasonable option would invove a textarea and using javascript to insert html tags at the cursor point. The only problem with this approach is that although it works it removes focus from the textarea and the keyboard disapears. This is an inconvenience but is the best available option available currently.
Dynamically adding paragraph tags is a time saver, as you just need to focus on typing. The problem occurs when you don't want to automatically add paragraph tags, say around a block of code.
A solution we haven't discussed, which would be ideal, is a custom key / keyboard feature. If you could have a keyboard set aside for custom, complex phrases, that were user programmable, then you could add your html syntax this was. Alternatively, a html key, which when held down, lists 5 / 6 common html tags.
Hopefully, within the next year or so this issue will be addressed for Safari, otherwise, native os html editors will need to be used and the content pasted into the web page, which is far from ideal.
Tuesday, 01 April 2008
I'm in the process of developing a project management web app for the iPhone / iPod Touch, and I wanted to build a canvas based charting component to reflect time spent, resource use, etc.
I knew I could code bar graphs quite easily, but pie charts were a different matter, it'd been a few years since I'd needed PI for anything, so I had a look around for some direction.
There are a couple of ready made solutions out there, notably plotKit, which I really liked the look of, but it is dependent on another framework. I wanted some bare bones code so that I could build upon it easily, and most importantly, understand what was happening at each stage.
I found this example, which was perfect, a well written article with clearly written code. I quickly incorporated it into my application, but wanted it to be more like the plotKit example in appearance, with some additional visuals that was absent from both examples. Only a small thing, but I wanted a line from just inside each segment of the pie, leading to the label. Below is the result of my labours.

It was quite a job to achieve but I'm happy to share how I got there.
Firstly though, a disclaimer, I have not gone through tidying up the code yet this is a rough and ready block of javascript. Now that's out the way, on to the code. You should insert this into the for loop where the segments are built.
//Attempt to get label position
var sliceStart = Math.PI * (2 * sofar);
var sliceEnd = Math.PI * (2 * (sofar + thisvalue));
var angle = (sliceStart + sliceEnd)/2;
// normalize the angle
var normalisedAngle = angle;
if (normalisedAngle > Math.PI * 2){
normalisedAngle = normalisedAngle - Math.PI * 2;
}else if (normalisedAngle < 0){
normalisedAngle = normalisedAngle + Math.PI * 2;
}
What I've done is define the start and end position of the slice, please note I've removed the -0.5 from the calculation for the labels, otherwise they appear at the wrong positions. I then add the two values and devide by two to find the mid point of the arc.
var labelx = center[0] + Math.sin(normalisedAngle) * (radius + 10);
var labely = center[1] - Math.cos(normalisedAngle) * (radius + 10);
var labelBack = '';
var labelAlign = '';
Now that I have the correct angle, I use sine and cosine to determine the x,y pixel reference for the labels.
if (normalisedAngle <= Math.PI * 0.5) { //Top Left
labelx = (labelx - 10) + "px";
labely = labely + "px";
labelBack = 'none';
labelAlign = 'right';
}
else if ((normalisedAngle > Math.PI * 0.5) && (normalisedAngle <= Math.PI)) { //Bottom Right Quarter
labelx = (labelx + 15) + "px";
labely = labely + 10 + "px";
labelBack = 'none';
labelAlign = 'left';
}
else if ((normalisedAngle > Math.PI) && (normalisedAngle <= Math.PI*1.5)) { //Bottom Left Quarter
labelx = (labelx - 30) + "px";
labely = (labely + 10 )+ "px";
labelBack = 'none';
labelAlign = 'right';
}
else { //Top Right
// text on top and align right
labelx = (labelx - 20) + "px";
labely = (labely) + "px";
labelBack = 'none';
labelAlign = 'left';
}
Depending on which quarter of the pie chart the label falls into the is some adjusting to be done, see comments to understand which quarter is being addressed. I also included a variable for background colour and another one for text direction.
//Create Label
var percentage = thisvalue * 100;
var labelContainer = document.getElementById('label_container');
var oSpan = document.createElement('span');
var oLabelText = document.createTextNode(percentage.toFixed(2)+'%');
oSpan.setAttribute('style','left: '+labelx+'; top: '+labely+'; position: absolute; font-size: 60%; z-index: 100; background:'+labelBack+'; width: 45px; display: block; text-align: '+labelAlign+';');
oSpan.appendChild(oLabelText);
labelContainer.insertBefore(oSpan, labelContainer.lastChild);
//End of create label
Finally I output the labels to a div that surrounds my canvas tag, and hey presto, the tags are on the form. Note that I've positioned the elements absolute, therefore the enclosing div tag must be set to position: relative. So that's the labels out of the way, now I render the pie segment. Now, after that the relatively simple task of adding the indicator lines.
// Draw label line
var labelLineFromX = center[0] + Math.sin(normalisedAngle) * (radius * 0.9);
var labelLineFromY = center[1] - Math.cos(normalisedAngle) * (radius * 0.9);
var labelLineToX = center[0] + Math.sin(normalisedAngle) * (radius + 10);
var labelLineToY = center[1] - Math.cos(normalisedAngle) * (radius + 10);
ctx.beginPath();
ctx.shadowBlur = 0;
ctx.moveTo(labelLineFromX,labelLineFromY);
ctx.lineTo(labelLineToX,labelLineToY);
ctx.lineWidth = 1;
ctx.strokeStyle = '#000';
ctx.stroke();
To get the start point, I go one tenth into the segment, and go 10 pixels outside of it, adjust the values to suit your needs.
That's it, simple looking back at it but took me a couple of days tinkering at it getting it the way I wanted it. Feel free to use this code as you will, and my sincerest thanks to the guy who came up with the original code, you saved me a lot of work, and this isn't meant as disrespect, merely a desire to customise and take your work further.
Thursday, 27 March 2008
Today in work I spent some time with one of the guys from our office, a knowledge manager, who wants to upskill and become a developer.
We program our web based apps in ASP, but he has very little experience programming, really only a little html knowledge, but he is a very intelligent person. A few month ago he mentioned to me that he wanted to upskill, and wanted guidance on a learning path.
This is actually very difficult to guide on because if you want to start developing while learning, as he does, then you need elements from 4 key families:
The order I recommended he focus on these items was HTML, CSS, JavaScript, ASP. The reasoning being is that once you can design the end product, then you can start to substitute static elements for dynamic elements.
Today, he had a task he wanted to complete, add a "Rate this article" feature to an existing application, and wanted me to help him though it.
As I thought about how I was going to teach him how to program this feature, which combined all four programming areas, I came to the conclusion that for a first lesson, trying to teach syntax for four different languages was a pointless exercise for the time we had (about half a day), so I decided that I would focus on what I consider the hardest thing to master as a developer, non-linear thinking.
One of the comments I had during our lesson was that it was quite hard for him to wrap his head around developing in a non-linear fashion. Indeed, you call functions from separate documents, use sub routines, pull data from databases, it's a lot to think about.
As an asp developer, developing a standard asp data-driven solution, if I really think about it, there are probably no more that 10 / 15 different vbscript functions and objects or operators that are actually used. Consequentially vbscript becomes one of the simplest components of the education package, but if you cannot wrap your head around how you're going to achieve your programming objective, then the task becomes huge.
The way we approached the project was not on a computer, but in a meeting room, with a pen and paper. our approach was as follows:
For step three, we decided that the user would firstly see greyed out stars, would click the star rating they want to give the article (1-6) which highlights the rating with gold stars. Finally the user would click submit to save the rating, without reloading the page.
For step four we looked at what we'd just detailed in terms of user interaction, and I helped him detail how we would achieve each item.
Firstly, I drew the containers for each of the 6 stars, and then outlined the syntax that would create that:
<a href="javascript:void(0);" onClick="ratingFunction('1')">
<img src.......>
</a>
Then I explained the need for a javascript function to accept and set the rating, one to submit the form, and a variable to set to show that the rating had been set (Not essential but makes it easier to understand what is happening).
I implemented an AJAX call for him to send the rating to an asp page that inserted into the DB, and we created the table in sql.
From a programming perspective, we agreed that this was a fairly ambitious task for the timeframe, and whilst he picked up bits and pieces, the important thing is he started to learn how to think as a developer, and that sometimes, finding the correct syntax is a lot easier if you clearly understand what you are trying to achieve.
Sunday, 09 March 2008
Sad I know but some times you come across a rare bit of syntax that most people just don't know about.
Take, for instance <optgroup>.
I recently came across this on a random website, and when I mentioned it in work, no one had heard of it. Now these are all, including myself, guys with 14+ years experience at writing HTML amongst other things.
The annoying thing was the number of times we'd needed something to perform the function of this simple tag, yet floundered and compromised, using some work around or other.
What optgroup does, is simply create a heading within a select list. A non-selectable element that categorises the values below it.To implement this within your select list, just add the following code:
<optgroup label="GMT-10:00"></optgroup>
It's that simple, give it a try.