Transformation Logic Guide

Transformation logic is written in Javascript. If you're unfamiliar with Javascript, there are many ways to learn it online. Here are just two suggestions for online beginner guides:

To create your own apps, it is particularly usefull to learn about strings, values, variables, loops, arrays, objects and using functions.

The App Object

Out of the box you get one predefined object: the app object. It contains three base objects that you need to work with:

Object Explanation
app.input This contains the exact data structure as is was retrieved from the data source, converted to a Javascript object.
app.format This is an object with several formatting functions, that allows you to easily apply formatting to your text strings.
app.output This is where you write your formatted articles to.

In addition there are the following functions that help you create appropriate objects:

Function Explanation
app.createArticle() Creates an article object that can be added to the output.
app.createTable(relativeColumnWidths, columnHeaders) Creates a table object. Optionally you can pass in:
  • relativeColumnWidths: an array of numbers that represent the relative widths of each column, e.g. [1,3,2] will make column 1 1/6 of the width, column 2 3/6 of the width and column 3 2/6 of the width
  • columnHeaders: an array with column titles, e.g. ["Home team", "Visiting team", "Score"]

Input

You read your data from the app.input object. In many cases this is a list structure, e.g.

[ 
    { home_team: "Boxers", visiting_team: "Jets", score: "6-4" },
    { home_team: "Fiskers", visiting_team: "Blokes", score: "3-4" },
    { home_team: "Patriots", visiting_team: "Angels", score: "3-6" }
]

Format

The app.format object gives you a range of formatting functions that operate both on individual strings, as well as an array of strings.

Function Explanation
app.format.bold(singleOrMultipleStrings) Make the single or multiple text strings bold and return that as its result.
app.format.italic(singleOrMultipleStrings) Make the single or multiple text strings italic and return that as its result.
app.format.fontType(singleOrMultipleStrings, fontName) Set the font type of the single or multiple text strings and return that as its result.
app.format.relativeTextSize(singleOrMultipleStrings, value) Set the relative text size of the single or multiple text strings and return that as its result. The text size is relative to its parent container, but in most cases this is relative to the base text size. For example, a value of 2 will render the text twice as tall as its parent, whereas a value of 0.5 will render it half as tall.
app.format.textColor(singleOrMultipleStrings, cssColorValue) Set the color of the single or multiple text strings to the cssColorValue and return that as its result.
app.format.textShadow(singleOrMultipleStrings) Set a text shadow for the single or multiple text strings and return that as its result.
app.format.alignLeft(singleOrMultipleStrings) Set the single or multiple text strings to be aligned left (only works when it's added to a paragraph or table cell) and return that as its result.
app.format.alignCenter(singleOrMultipleStrings) Set the single or multiple text strings to be aligned to the center (only works when it's added to a paragraph or table cell) and return that as its result.
app.format.alignRight(singleOrMultipleStrings) Set the single or multiple text strings to be aligned right (only works when it's added to a paragraph or table cell) and return that as its result.

Here's an example of how you apply the above functions:

var game = input[0];
var gameDescription = game.home_team + " against " + game.visiting_team + " ended in " + app.format.bold(game.score);
var descriptionInRed = app.format.textColor(gameDescription, "#FF0000");

Article

When you have formatted your data, you need to compile the formatted text strings into an article. You start of with creating a new article object:

var article = app.createArticle();

Next can add one or more (formatted) text strings with any of the following functions:

Function Explanation
addLine(textString) Add a text string as a line. When multiple lines are added, then there will be a line break between them but no empty line.
addParagraph(textString) Add a text string as a paragraph. A paragraph is similar to a line, but in addition is has an empty line underneath it.
addTable(tableObject) Add a table object.

For example:

var game = input[0];
var gameDescription = game.home_team + " against " + game.visiting_team + " ended in " + app.format.bold(game.score);

var article = app.createArticle();
article.addLine(app.format.bold("Latest game"));
article.addParagraph(gameDescription);

Table

A table object enables you to visualize a list of data as a table. The app object has the function that easily lets you create a new table, optionally initialized with relative column widths and column headers:

var table = app.createTable([2,2,1], ["Home team", "Visiting team", "Score"]);

As mentioned with the format function, you can also format arrays of text strings. This is especially convenient for formatting arrays with texts for multiple columns, e.g.

var boldHeaders = app.format.bold(["Home team", "Visiting team", "Score"]);
var table = app.createTable([2,2,1], boldHeaders);

The table object itself supports the following functions:

Function Explanation
addRow(columnTexts) Add an array of text strings as a new row to the table.
relativeColumnWidths(relativeColumnWidths) If you haven't set the relative column widths during creation of the table, then you can still do it after the fact using this function. You need to pass in an array of numbers that represent the relative widths of each column, e.g. [1,3,2] will make column 1 1/6 of the width, column 2 3/6 of the width and column 3 2/6 of the width.
headerRow(columnHeaders) If you haven't set the column headers during creation of the table, then you can still do it after the fact using this function. You need to pass in an array with text strings to be shown in the header of each column, e.g. ["Home team", "Visiting team", "Score"].
padding(amount) Sets the cell padding. If you pass in a number, then the unit is "pixels", but you can also enter relative padding by passing in a string like "2%".
borderWidth(width) Sets the border width in pixels.
borderColor(cssColorValue) Set the color of the borders to the passed in cssColorValue.
headerRowColor(cssColorValue) Set the background color of the header row to the passed in cssColorValue.
headerRowBackground(cssBackgroundValue) Set the background of the header row to the passed in cssBackgroundValue value.
rowColor(cssColorValue) Set the background color of all regular rows to the passed in cssColorValue.
rowBackground(cssBackgroundValue) Set the background of all regular rows to the passed in cssBackgroundValue value.
evenRowColor(cssColorValue) Set an alternate background color for all even rows to the passed in cssColorValue.
evenRowBackground(cssBackgroundValue) Set an alternate background for all even rows to the passed in cssBackgroundValue value.

For example:

var table = app.createTable([2,2,1], ["Home team", "Visiting team", "Score"]);
table.addRow([input[0].home_team], input[0].visiting_team, input[0].score);
table.borderWidth(2);
table.borderColor("#CDCDCD");
table.headerRowBackground("linear-gradient(#F0F0F0, #E0E0E0)");

Output

Now that we have seen all ways to format data into visualizable structures there is on thing left to do: write the created visualization to the app.output object. Only then will the newly created article be shown either upon each single article refresh or in the ticker. There is only one function you need to do this:

Function Explanation
addArticle(article) Add an article object to the output set so that it will be shown in the article playback cycle.

Complete "Single Article" Example

It's time for a complete example. Let's starts with one in which we create just one article to be shown as a single article, like so:

Data View

First there is the input we used in the previous examples as well:

[ 
    { home_team: "Boxers", visiting_team: "Jets", score: "6-4" },
    { home_team: "Fiskers", visiting_team: "Blokes", score: "3-4" },
    { home_team: "Patriots", visiting_team: "Angels", score: "3-6" }
]

Let's turn that into a title and some lead in text, followed by a table created by iterating over every entry in the input data.

var article = app.createArticle();
var title = app.format.relativeTextSize(app.format.bold("Last played games"), 1.5);
var leadIn = app.input.length + " games have been played recently. Here are the results.";

article.addLine(title);
article.addParagraph(leadIn);

var table = app.createTable([2,2,1], ["Home team", "Visiting team", app.format.alignCenter("Score")]);
table.borderColor("#333");
table.borderWidth(1);
table.headerRowBackground("linear-gradient(#101010, #101010)");
table.rowColor("rgba(15,15,15,0.6)");
table.evenRowColor("rgba(5,5,5,0.6)");

for (var i = 0; i < app.input.length; i++) {
  var game = app.input[i];

  table.addRow([
    game.home_team,
    game.visiting_team,
    app.format.alignCenter(app.format.fontType(game.score, "Anonymous Pro"))
  ]);
}

article.addTable(table)

app.output.addArticle(article);

Since we'll be creating one big table, we will create just one article. Next we create a nicely formatted title, followed by a lead in text. The title is added to the article as a single line and the lead in text as a paragraph.

Next we compile the table. We start of with a new table with some relative column widths and a header row, followed by formatting the table. Note the different ways you can specify colors:

  • by common names, like white, red, yellow, etc.
  • by RGB hexadecimal string, e.g. #FF8810, #421
  • with RGB decimals, e.g. rgb(250, 249, 128)
  • with RGBA numbers, where the A is the alpha (or opacity) value ranging from 0 to 1, e.g. rgba(15,15,15,0.6)
  • by setting the background (not the background color) to a linear-gradient creating a nice gradient effect, e.g. linear-gradient(#101010, #101010)

We iterate over the input and for each game found we create new row with game information. When the table is complete, we add it to the article. Finally, the one article is added to the output.

Complete "Ticker" Example

Here's another example in which we create a ticker with the game results, using the same input from the previous examples.

for (var i = 0; i < app.input.length; i++) { 
  var game = app.input[i];

  var article = app.createArticle();
  article.addLine(game.home_team + " vs. " + game.visiting_team + ": " + app.format.bold(game.score) + "   |   ");
  app.output.addArticle(article);
}

In this example we iterate over every entry in the input data again, but this time we create an article per game. The article contains just one line mentioning both teams followed by the score and an article seperator.

Tips

Writing the transformation logic can be tricky and it is easy to make a mistake or two. To monitor if there are any errors in your logic, you can use the development tools of you browser in which you can see the network requests that retrieve the data from your data source as well as errors that occur when running your transformation logic. Here are the links to the descriptions of how you open these tools in Chrome, Firefox and Safari.

You can also debug your transition logic by placing a breakpoint in your code and then stepping through it. You can add a breakpoint by putting the debugger; command in your logic. Then make sure that your browser's development tools are open. The next time your transition logic is run, it will stop on the line with the debugger; statement. From here you can inspect the values of variables and step through your code.

For example:

for (var i = 0; i < app.input.length; i++) { 
  var game = app.input[i];
  debugger;
  var article = app.createArticle();
  article.addLine(game.home_team + " vs. " + game.visiting_team + ": " + app.format.bold(game.score) + "   |   ");
  app.output.addArticle(article);
}