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.

Tuesday, 24 June 2008

Calendar screenshot

Always trying to do something to stimulate the grey cells, I have started applying the slide demo I developed a few weeks ago to a calendar object. I'm going to be using it in a personal application I'm developing to help track my finances (The green box denotes a bit, should be red).

 

The screenshot is in fact just a fireworks mockup. When it's finished I'm going to integrate it into the blog navigation, sweet.



Tags: Javascript Blog Calendar Slide Fireworks Date Time Cal Demo Mockup

Monday, 09 June 2008

I've been looking at evvective and stylish ways to show off room bookings and came up with this.

Screenshot of room booking page

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.



Tags: Javascript css HTML Room Booking Resource Div Sliding Horizontal Framework Scriptaculous

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.

Screenshot of my bar graph solution

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.



Tags: Javascript Tutorial HTML Canvas Charting Graphing Chart Tabulated Bar Graph Guide Low_Bandwidth Reporting Visualisation Data Table

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.

Screenshot of my bar graph solution

I'll upload the source code once I've streamilined it a bit, the features are:

  • Dynamically builds background and adjusts based on canvas size. tiny or full screen the proportions of the graph are retained.
  • Positions values dynamically.
  • Builds dynamically from tabulated data.

Source should be up later in the week, good night all.



Tags: Javascript HTML Canvas Charting Chart Bar Graph Bar-Graph Component Free Source Code

Friday, 11 April 2008

After spending some time today looking into ways to insert HTML tags into textareas on iPhone, I decided to knock up a quick editor for this site based around the insert at cursor position model as discussed in the previous article.

This post is the first real test of it's function. The biggest problem is scrolling up and down the textarea, it's extremely difficult.

To accentuate the positives however, it can insert the tags I mainly use, such as paragraph, bold, and code. Also it's better than typing it manually. I'm going to try using a two finger scroll to move the textarea.

Roll on firmware 2.0 and the copy and paste feature. For now though, here's how it's done.

function insertAtCursor(myField, myValue) {

if (myField.selectionStart || myField.selectionStart == '0') {

var startPos = myField.selectionStart;

var endPos = myField.selectionEnd;

myField.value = myField.value.substring(0, startPos)

+ myValue

+ myField.value.substring(endPos, myField.value.length);

} else {

myField.value += myValue;

}

}

To call the function, I pass in a reference to my textarea object, followed by the text to insert.

<span onClick="insertAtCursor(document.getElementById('articleBody'), '<p></p>');">P</span>



Tags: Javascript iPhone Content Rich Text Editor Textarea Function

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:

  • Use a rich text editor
  • Add buttons to insert common tags
  • Dynamically add paragraph tags based on carriage returns

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.



Tags: Javascript Safari iPhone Apple HTML Rich Text Editor Webkit

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.

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:

 

  • HTML
  • JavaScript
  • CSS
  • VBScript / ASP

 

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.

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:

 

  1. Define what we want to achieve
  2. Sketch how we want it to look
  3. Define the process the user will go through.
  4. Work out how to achieve these steps programatically.

 

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. 

Summary

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.

 



Tags: Javascript css Plan HTML Demetrie Developer Training Learning ASP VBScript Education Thinking

Monday, 18 February 2008

Due to a failure in the heating system in work today, we were all sent home early. In fairness it was bloody freezing.

After a 3 hour power nap, I got up and finally completed the tagging system for the blog.

It works simply though an onBlur function on an input box, splitting the tags into an array and inserting them into the database. Each keyword is passed separately so that I can check if it already exists in the database, in increment the usage accordingly so that I can later create a tag list, sized around popularity.  

It's a start anyway, and it works well, which is all I want. Off on holiday tomorrow, and hoping to be off Wednesday to help Lisa.



Tags: Javascript PHP Cold Work Temperature Tags Blog Split

Wednesday, 13 February 2008

When developing applications with AJAX functionality, it is common to pull a value from a text area and pass in into a url for processing.

When doing this, always be sure to add the escape() function around your variables, to ensure they are URL Encoded, otherwise you'll loose parts of your text and your code will fall apart.

If you've escaped a variable, for passing between  functions rather than a url, you can remove the formatting with the unescape() function.



Tags: Ajax Javascript Tips Escape Syntax
Featured Articles
Recent Articles