Version 1.7Loading Timetable Data From A Remote Source
API Quick Reference
JavaScript is required to use the quick reference
This is a worked example of using a glow.widgets.Timetable and loading the Track and Item data into it from a remote source. The process is divided in to 6 steps.
- Identify the data source.
- Define a transform function to turn the source into Timetable specific data.
- Use glow.net to get the source data
- Use your transformer to turn it into the right format for a glow.widgets.Timetable constructor
- Create a glow.widgets.Timetable with your transformed data.
- draw() the Timetable
Identify the data source.
In this case we have grabbed some TV schedule data from the ION schedule. This comes in a very verbose JSON format (you can look at it at all.json), but, leaving only the bits we are interested in here, it look like this;
{
/* ... */
"blocklist" : [
{
/* ... */
"emp_title" : "Leum is Danns: Episode 21",
"service" : "bbc_alba",
"end" : "2009-03-09T17:10:00",
"service_title" : "³ÉÈËÂÛ̳ ALBA",
"start" : "2009-03-09T17:00:00",
},
{
/* more of the same */
}
],
/* ... */
}
It's worth noting that all the channels with programmes in this data are mixed up, so that each programme has all the channel info we need attached to it.
Define a transform function to turn the source into Timetable specific data.
This function will have several steps. First lets define the shell.
function process(netResponse) {
var list = netResponse.json().blocklist;
return {};
}
This gets the glow.net.Response data as a JSON object, and then accesses the blocklist property, which is an Array. It returns an object because we want to extract several peices of data from this response.
Next, we write a loop that goes through this array. The body of the loop looks like this;
thisService = list[i].service;
services[thisService] = services[thisService] || {title: list[i].service_title, programmes: []};
thisStart = makeDate(list[i].start);
thisEnd = makeDate(list[i].end);
programmes = services[list[i].service].programmes;
programmes[programmes.length] = [
list[i].emp_title,
thisStart,
thisEnd
];
Because the programmes are in one big list, we need to separate them into channels ourselves. The first line of the loop creates (if not already created) an entry in the services
collection, keyed on the channel ("service" in this data) code.
The remaining lines populate the programmes
Array property of this entry with Arrays of properties suitable for passing to glow.widgets.Timetable.Track#addItem.
Note the makeDate
function. This is necessary because the date format in the data is not suitable for creating a Javascript Date, so we need a function to do this transformation.
function makeDate(sDate) {
var adjusted = sDate.replace(/^([0-9]{4})-([0-9]{2})-([0-9]{2}).([0-9]{2}):([0-9]{2}):([0-9]{2})$/,
"$1/$2/$3 $4:$5:$6");
return new Date(adjusted);
}
Next we transform the services collection in to an Array of Track data Arrays, each of which represents suitable arguments for passing to glow.widgets.Timetable#addTrack.
for(var id in services) {
tracks[tracks.length] = [services[id].title, trackSize, {items: services[id].programmes}];
}
Finally we add the results to the return object.
return {
tracks: tracks,
};
Putting it all together and fleshing it out a little (especially to extract the Timetable's start and end points and the view window), we get this;
function makeDate(sDate) {
var adjusted = sDate.replace(/^([0-9]{4})-([0-9]{2})-([0-9]{2}).([0-9]{2}):([0-9]{2}):([0-9]{2})$/,
"$1/$2/$3 $4:$5:$6");
return new Date(adjusted);
}
function process(netResponse) {
var list = netResponse.json().blocklist,
i = list.length,
services = {},
programmes = null,
latest = new Date(0),
earliest = new Date("2099/12/31 23:59:59"),
thisStart = null,
thisEnd = null
thisService = null;
// grab required tracks and transform items
while (i--) {
thisService = list[i].service;
services[thisService] = services[thisService] || {title: list[i].service_title, programmes: []};
programmes = services[list[i].service].programmes;
thisStart = makeDate(list[i].start);
thisEnd = makeDate(list[i].end);
// deduce required Timetable end points
if(thisStart.valueOf() latest.valueOf()) {
latest = thisEnd;
}
programmes[programmes.length] = [
list[i].emp_title,
thisStart,
thisEnd
];
}
// deduce required Timetable view points
var viewStart = new Date(earliest.valueOf() + 3 * 60 * 60 * 1000),
viewEnd = new Date(earliest.valueOf() + 6 * 60 * 60 * 1000),
tracks = []
trackSize = 155;
// transform grabbed tracks
for(var id in services) {
tracks[tracks.length] = [services[id].title, trackSize, {items: services[id].programmes}];
}
// disable all tracks but the first 4. tracks[j][2] is the options object
// this is so we have something that fits the page
for(var j = 4, len = tracks.length; j
Use glow.net to get the source data and Use your transformer to turn it into the right format for a glow.widgets.Timetable constructor
This bit is fairly straighforward glow.net.get
call. The onLoad of the call is a function that calls our process
function on the data before using it to create the Timetable.
glow.net.get("/glow/docs/1.7/furtherinfo/widgets/timetable/all.json", {onLoad: function (response) {
var processed = process(response);
/* create the Timetable */
}});
Create a glow.widgets.Timetable with your transformed data and draw() the Timetable
All that remains is to flesh out the onLoad with the code to create and draw the Timetable. Because we have processed all our data in to one set for passing as an option to the constructor, we can draw it straight away. So the extra code looks like this.
var myTimetable = new glow.widgets.Timetable("#remoteExample",
processed.earliest, processed.latest,
processed.viewStart, processed.viewEnd,
{
size: 600,
tracks: processed.tracks,
}
).setBanding("hour")
.addScale("hour", "left", 83, {template: scaleMe})
.addScrollbar("hour", "right", 50, {template: scaleMe})
.setTrackHeaderTemplate("<h2></h2>")
.draw();
Note that the scale and scrollbar templates are both defined as scaleMe
. This is the following function, which simply gives a 12-hour clock hour only (eg "8am") from a given time.
function scaleMe(data) {
var start = data.start,
hours = Math.floor(start.valueOf() / 3600000) % 24,
ampm = ["am", "pm"][Math.floor(hours / 12)],
hh = ((hours - 24) % 12) + 12;
return hh + ampm;
}
And finally...
Putting all the above together produces a result that looks like this (there is data in ³ÉÈËÂÛ̳ Three, it's just further down...).
If you look at the source code of this page you will see that the code that produces this example, is exactly the code as given above.
What next?
This example has concentrated on the process of getting the Track and Item data from an external source. It could easily be enhanced with more programme data placed in the Item's data object and a nicer Item template to display it. Perhaps it could also use a glow.widgets.InfoPanel to give the user more information about an Item they have clicked on.