Monthly Archives: May 2011

Google Adds Superstars, Nested Labels, and Advanced IMAP Controls to Gmail’s Settings [In Brief]

Three of our favorite Gmail Labs features have graduated and moved on to out-of-the-box Gmail. Superstars lets you assign different levels of stars to an email, making a killer to-do list based on priority; nested labels creates labels within labels, so you can organize your mail by sub-categories; and if you use a desktop mail client, you can now adjust which labels show up in your client and which don’t. The Google Search Box lab has been removed altogether, since there’s already a “Search the Web” button in Gmail. All features are available from Gmails’ Settings page. Hit the link to read more. [Official Gmail Blog] More »







Picturescue Recovers iPhone Photos from iTunes Backup Files [Download Of The Day]

Mac OS X: Picturescue is a tiny app that quickly finds any and all images stored in old iTunes backup files, which are made whenever an iPhone or other iOS device is synced with with its “home” computer. The full version of the app is available for $4.99 and allows the user to export some or all of the photos found, while a trial version allows viewing of the images but not export. More »







Your iPad’s a Telephone With Google Voice

Out of the box, Apple has you covered on your iPad 2 with FaceTime for video chat with your friends, family and colleagues, so long as they have a FaceTime capable device and a Wi-Fi connection. But let’s face it, not everybody is on FaceTime, and certainly not constantly near a Wi-Fi hot spot. If all you want to do is replicate a phone connection, Google Voice along with a couple of native iOS apps may be just what you’re looking for.

What You Need

Google Voice Account. If you’re not already part of Google Voice, simply log into your Google account and sign-up for Google Voice (google.com/voice, but it’s U.S. only as of this writing). It will walk you through the sign-up process, including setting up a new number.

GV Connect. Google’s strategy for the iPad, including Google Voice, appears to be limited to Safari apps only. Google offers an official iOS-native Google Voice client for the iPhone, but GV Connect is a better option, as it has full support iPad support.

Talkatone. Neither the Safari interface that Google offers, nor GV Connect will make VOIP calls from your iOS device. To enable that functionality, you need to download and install the free, ad-supported Talkatone app.  Yes, this is an iPhone app, but you can control it from the iPad-friendly GV Connect interface.

How to Make a Phone Call

Once you have a Google Voice account, download and install both the GV Connect and Talkatone clients on your iPad, and set up each with your Google Voice account information. Then, in GV Connect, do the following:

  1. Under Settings, set the Start Calls From setting to Google Talk.
  2. Enable the Call using Talkatone setting.
  3. Click on the telephone handset icon in the upper left corner to place a call.

While you are controlling your Google Voice account from within GV Connect, the VOIP call is actually being handled by Talkatone. Talkatone does claim to allow calls over 3G, but the quality of those calls are dependent on the network. I’ve only used it while connected via Wi-Fi.

How to Receive a Phone Call

To direct all your incoming calls to be received on your iPad. In GV Connect on your iPad, do the following:

  1. Under Settings, set the Call Forwarding setting to Google Talk.
  2. Make sure you are logged in to your Google Account in Talkatone.
  3. Wait for an incoming call.

It’s that easy; just make sure you’re not logged in to Google Talk anywhere else. I tend to use the stock earbuds to avoid looking like a fool with the iPad pressed against my face, but unfortunately, Bluetooth headsets aren’t fully supported by either Apple or Talkatone. I have yet to completely dedicate my Google Voice account to exclusive iPad-only calling, but I’d love to hear from you if you end up using the solution described above as a total home or cell phone replacement.

Related content from GigaOM Pro (subscription req’d):

How to Cook Pasta Correctly [Do It Right]

Boiling pasta is supposed to be simple. It’s the perennial college student meal because it involves only about four steps, one of which is boiling water. But is it really that easy? Have you been doing something wrong all along? More »







iPad Usability Study Reveals What We Do and Don’t Like In Apps

iPad users aren’t stingy with their devices, according to a new usability report by the Nielsen Norman Group focusing on Apple’s tablet. In fact, iPad owners who lived with one or more individuals reported that they shared their iPads freely, unlike the iPhone. The report also illuminated many things we like and don’t like about the apps we use on our iPads.

For example, the study found that users aren’t crazy about using their iPad devices to deal with complicated forms that require lots of user input, especially if those forms are found in non-optimized websites, rather than housed in an app. Users would skip registrations processes rather than deal with inputting information in many cases. The solution to such a problem would be to make forms simpler, requiring less information, and reduce the need for repeat entry of information (so apps that offer to remember login details are better, for example).

iPad users also aren’t as able to decipher non-obvious control systems as some developers might think. In cases where it wasn’t made clear what tapping an item that wasn’t obviously a button (i.e., a logo) would do, users often missed the functionality. Examples cited in the report include the logo in the top left of The Daily app, which returns users to the app’s home screen. USA Today  originally used a similar mechanism, but changed their logo to include a “Sections” label to tell users that it was in fact designed to be tapped and tied to a function.

Likewise, gestures in apps can sometimes cause trouble when there are no visual cues to provide information about how they work. Don’t think that placing an instructional video or graphic at the beginning of the app will solve the problem, either. Many users don’t read instructions, though visual instructions that are incredibly obvious, like those used by Bing for iPad, tested well with those participating in the study, since users couldn’t avoid grasping their meaning even when they quickly dismissed them. Nielsen Norman Group advises developers that they’re much better off including visual markers throughout, indicating that swipes and other gestures can be used. For example, magazine apps like Wired include arrows that show the direction a user should swipe to unveil more content.

Another alternative is to provide explicit tips in the form of dialog boxes, like Adobe Photoshop Express does. The iPad Photoshop app uses gestures to control effects like “soft focus,” and pops up notifications to alert users of what to do. Tips can be hidden at any time, so they won’t become annoying.

What users find very annoying according to the report are splash or loading screens. No matter how clever, or how easy on the eye, splash screens and animations become annoying very quickly. Startup sounds, in particular, are singled out as especially bad, because of the potential they have for unpleasantly surprising people who open apps in surroundings where noise might not be appreciated.

Also, almost universally, apps will benefit from having back buttons on nearly every page, and should aim for a simple homepage-like table of contents over more complicated navigation schemes. Users prefer a home base from which to operate without having to hunt through carousels or wade through long columns of thumbnails, and they always want the option to go one step back from their current position, because of accidental taps or to refer back to something they just saw.

As mentioned above, iPads tend to be communal devices, at least within the household. But the report also highlighted some other interesting points regarding how we use the Apple tablet. Generally, we use it for gaming, checking email and communicating via social networking, watching videos/movies and reading news. We also tend to shop, but the participants in the study generally preferred shopping on their desktops, and some even perceived iPad shopping to be more risky from a security perspective. iPads also tend to be carried around by many users, or at least taken along for the ride when long waits or trips are expected.

Now that the iPad is more than a year old, it’s interesting to see how people are using it, and what is and isn’t working when it comes to app usability design. No doubt there’s still plenty of innovation left in iPad app interface design, but this report illustrates that some things never go out of style when it comes to user experience.

How does your experience with the iPad either agree or disagree with the findings described above?

Related content from GigaOM Pro (subscription req’d):

Prototypes

The number one feature request I get for my iPhone mockup tool is to allow linking different screens into interactive prototypes. I’m not sure when — or even if — I’ll find the time to continue working on the iPhone mockup tool, but at least I now have an answer for these requests: use Prototypes.

Prototypes

Prototypes is a totally awesome new project by Duncan Wilcox and Keith Lang.1 Basically, it’s a tool that lets you create interactive prototypes based on your static mockups, wireframes, or even sketches.

You create a new prototype, add the pictures of your screens, create «hotspots» by clicking and dragging on a screen, and then link the hotspots to other screens. You can even set transition animations.

Hotspot properties

You can then run the prototype on your Mac, and klick through it.

All of this is already incredibly useful.

But the real killer feature is that you can upload your prototype to an online service, and then run it on an iPhone as a web app. Yes, this tool allows you to easily create interactive prototypes that run on actual iPhones.

Uploading a prototype

So what can you use this for? Well, for me, the most obvious use would be to do prototype usability testing.2 Or you could use it to explain an interaction to a programmer. Or you could use it to test the «flow» of your app. Or make sure the colors look right on an actual iPhone, and that the touchable areas are big enough for people’s fingers.

Honestly, I’m totally freaking out about how incredibly cool and useful this is. This makes me actually wish that I still worked on iPhone apps. Which I don’t. But I want a copy of Prototypes in my Applications folder anyway. And so should you.


  1. Disclaimer: Duncan and Keith are friends of mine. But Prototypes would be amazing even if we were mortal enemies. back

  2. If you don’t know how that works, feel free to preorder my upcoming book, which, among a ton of other useful stuff, explains how to do usability tests with static or slightly interactive prototypes. back

If you require a short url to link to this article, please use ignco.de/371

Creating a Line Chart using the HTML 5 Canvas

The HTML 5 canvas is capable of rendering lines, shapes, images, text and more without relying on a plugin. Although the canvas element isn’t supported by older browsers, the latest version of all major browsers (IE, Safari, Chrome, Firefox and Opera) now support the canvas making it an option for rendering charts, graphs and other types of visual data. In cases where a browser doesn’t support the canvas, a fallback can be provided that renders data using Silverlight, Flash or another type of plugin.

In a previous post I walked through the fundamentals of using the HTML 5 canvas to render different types of shapes. In this post I’ll discuss how the canvas can be used to render a line chart using JavaScript. An example of the chart that will be discussed is shown next:

 

To render the chart a JavaScript object named CanvasChart was created that handles rendering all of the lines, shapes and text shown above. An example of defining CanvasChart settings and calling its render() function is show next. The render() function accepts the canvas element ID as well as a JSON object that defines chart properties and data to be used in the rendering process.

<!DOCTYPE html> <html> <head>     <title>Canvas Chart Demo</title>     <script src="Scripts/jquery-1.6.min.js" type="text/javascript"></script>     <script src="Scripts/canvasChart.js" type="text/javascript"></script>     <script type="text/javascript">          $(document).ready(function () {             var dataDef = { title: "US Population Chart",                             xLabel: 'Year',                              yLabel: 'Population (millions)',                             labelFont: '19pt Arial',                              dataPointFont: '10pt Arial',                             renderTypes: [CanvasChart.renderType.lines, CanvasChart.renderType.points],                             dataPoints: [{ x: '1790', y: 3.9 },                                           { x: '1810', y: 7.2 },                                           { x: '1830', y: 12.8 },                                           { x: '1850', y: 23.1 },                                          { x: '1870', y: 36.5 },                                          { x: '1890', y: 62.9 },                                           { x: '1910', y: 92.2 },                                          { x: '1930', y: 123.2 },                                          { x: '1950', y: 151.3 },                                           { x: '1970', y: 203.2 },                                          { x: '1990', y: 248.7 },                                           { x: '2010', y: 308.7}]                            };             CanvasChart.render('canvas', dataDef);         });      </script> </head> <body style="margin-left:50px;margin-top:50px;">     <canvas id="canvas" width="800" height="600"></canvas> </body> </html> 


While the CanvasChart object is only a prototype at this point, it demonstrates several key features of the canvas element that can be used in applications including rendering lines, shapes, gradients, text and even transformed text. Let’s take a look at how the CanvasChart object was created.

Rendering Gradients and Text

The code for the CanvasChart object is located in a file named canvasChart.js. The code starts by defining a CanvasChart object that exposes two members named renderType and render. renderType is used to define what will be rendered on the chart (currently it supports rendering lines and points) while render() is used to render the data on the canvas as well as the associated labels for the x and y axes. The skeleton code for CanvasObject is shown next:

var CanvasChart = function () {     var ctx;     var margin = { top: 40, left: 75, right: 0, bottom: 75 };     var chartHeight, chartWidth, yMax, xMax, data;     var maxYValue = 0;     var ratio = 0;     var renderType = { lines: 'lines', points: 'points' };       return {         renderType: renderType,         render: render     }; } ();

 

The render() function accepts the canvas ID within the page as well as a JSON object that defines details about labels, font sizes, data points and more:

var render = function(canvasId, dataObj) {     data = dataObj;     getMaxDataYValue();     var canvas = document.getElementById(canvasId);     chartHeight = canvas.attr('height');     chartWidth = canvas.attr('width');     xMax = chartWidth - (margin.left + margin.right);     yMax = chartHeight - (margin.top + margin.bottom);     ratio = yMax / maxYValue;     ctx = canvas.getContext("2d");     renderChart(); }

 

The function starts by assigning the dataObj parameter to a variable within the CanvasChart object and then calls an internal function named getMaxDataYValue(). The getMaxDataYValue() function determines the maximum Y value for the data points. From there, the render() function locates the target canvas element within the page, calculates width and height values, and accesses the canvas’s 2D context that will be used to draw. Finally, a call is made to renderChart() to start the rendering process.

The renderChart() function orchestrates different drawing functions and handles rendering the background, lines, labels and data by calling the respective functions:

var renderChart = function () {     renderBackground();     renderText();     renderLinesAndLabels();      //render data based upon type of renderType(s) that client supplies     if (data.renderTypes == undefined || data.renderTypes == null) data.renderTypes = [renderType.lines];     for (var i = 0; i < data.renderTypes.length; i++) {         renderData(data.renderTypes[i]);     } }

 

Different canvas features are used such as gradients and transforms in the CanvasChart object. For example, the renderBackground() function shows how linear gradients can be created:

var renderBackground = function () {     var lingrad = ctx.createLinearGradient(margin.left, margin.top, xMax - margin.right, yMax);     lingrad.addColorStop(0.0, '#D4D4D4');     lingrad.addColorStop(0.2, '#fff');     lingrad.addColorStop(0.8, '#fff');     lingrad.addColorStop(1, '#D4D4D4');     ctx.fillStyle = lingrad;     ctx.fillRect(margin.left, margin.top, xMax - margin.left, yMax - margin.top);     ctx.fillStyle = 'black'; }

 

The renderBackground() function uses the 2D context’s createLinearGradient() function to define a gradient that has 4 gradient stops. Once the gradient is defined it is assigned to the fillStyle property and then rendered to a rectangular area using the fillRect() function.

CanvasChart also demonstrates how text can be manipulated using transforms. The text displayed on the Y axis is rotated so that it displays vertically:

 

image

 

This is accomplished by using the canvas element’s rotate transform functionality which is found in the renderText() function:

var renderText = function renderText() {     var labelFont = (data.labelFont != null) ? data.labelFont : '20pt Arial';     ctx.font = labelFont;     ctx.textAlign = "center";      //Title     var txtSize = ctx.measureText(data.title);     ctx.fillText(data.title, (chartWidth / 2), (margin.top / 2));      //X-axis text     txtSize = ctx.measureText(data.xLabel);     ctx.fillText(data.xLabel, margin.left + (xMax / 2) - (txtSize.width / 2), yMax + (margin.bottom / 1.2));      //Y-axis text     ctx.save();     ctx.rotate(-Math.PI / 2);     ctx.font = labelFont;     ctx.fillText(data.yLabel, (yMax / 2) * -1, margin.left / 4);     ctx.restore(); }

 

The key section of this code is the call to ctx.save() (toward the bottom of the function shown above) which saves the current state of the canvas so that it can be restored. This is necessary so that the entire canvas isn’t rotated. Once the current canvas state is saved, a call to the rotate() function is made to rotate the canvas. The text is then drawn for the vertical axis using the fillText() function. Once the rotated text is rendered the canvas is restored back to its saved state (the state before the rotate transform was applied and the text was rendered).

After the x and y axis text is rendered, the CanvasChart object makes a call to renderLinesAndLabels() to handle rendering the horizontal and vertical lines.

var renderLinesAndLabels = function renderLinesAndLabels() {     //Vertical guide lines     var yInc = yMax / data.dataPoints.length;     var yPos = 0;     var yLabelInc = (maxYValue * ratio) / data.dataPoints.length;     var xInc = getXInc();     var xPos = margin.left;     for (var i = 0; i < data.dataPoints.length; i++) {         yPos += (i == 0) ? margin.top : yInc;         //Draw horizontal lines         drawLine(margin.left, yPos, xMax, yPos, '#E8E8E8');          //y axis labels         ctx.font = (data.dataPointFont != null) ? data.dataPointFont : '10pt Calibri';         var txt = Math.round(maxYValue - ((i == 0) ? 0 : yPos / ratio));         var txtSize = ctx.measureText(txt);         ctx.fillText(txt, margin.left - ((txtSize.width >= 14)?txtSize.width:10) - 7, yPos + 4);          //x axis labels         txt = data.dataPoints[i].x;         txtSize = ctx.measureText(txt);         ctx.fillText(txt, xPos, yMax + (margin.bottom / 3));         xPos += xInc;     }      //Vertical line     drawLine(margin.left, margin.top, margin.left, yMax, 'black');      //Horizontal Line     drawLine(margin.left, yMax, xMax, yMax, 'black'); }

 

Lines are normally drawn using the 2D context’s moveTo() and lineTo() functions which I wrapped in a function named drawLine() to simplify the process:

var drawLine = function drawLine(startX, startY, endX, endY, strokeStyle, lineWidth) {     if (strokeStyle != null) ctx.strokeStyle = strokeStyle;     if (lineWidth != null) ctx.lineWidth = lineWidth;     ctx.beginPath();     ctx.moveTo(startX, startY);     ctx.lineTo(endX, endY);     ctx.stroke();     ctx.closePath();     }


At this point the canvas looks like the following:

image

Rendering Data

Once the labels and lines are rendered, CanvasChart handles rendering the data points by calling a function named renderData(). This function handles iterating through the JSON   data points and drawing lines, points or both depending upon the settings passed to CanvasChart’s render() function. Lines are drawn to connect the different data points through calls to the drawLine() function shown earlier while circles are drawn for specific data points by making calls to the 2D context’s arc() function. The circles that are rendered have a radial gradient applied to them using the createRadialGradient() function:

 

var renderData = function renderData(type) {     var xInc = getXInc();     var prevX, prevY = 0;      for (var i = 0; i < data.dataPoints.length; i++) {         var pt = data.dataPoints[i];         var ptY = (maxYValue - pt.y) * ratio;         if (ptY < margin.top) ptY = margin.top;         var ptX = (i * xInc) + margin.left;          if (i > 0 && type == renderType.lines) {             //Draw connecting lines             drawLine(ptX, ptY, prevX, prevY, 'black', 2);         }          if (type == renderType.points) {             var radgrad = ctx.createRadialGradient(ptX, ptY, 8, ptX - 5, ptY - 5, 0);             radgrad.addColorStop(0, 'Green');             radgrad.addColorStop(0.9, 'White');             ctx.beginPath();             ctx.fillStyle = radgrad;             //Render circle             ctx.arc(ptX, ptY, 8, 0, 2 * Math.PI, false)             ctx.fill();             ctx.lineWidth = 1;             ctx.strokeStyle = '#000';             ctx.stroke();             ctx.closePath();         }          prevX = ptX;         prevY = ptY;     } }

 

Once the data points are rendered the chart looks like the following:

 

Conclusion

You can see that there’s a fair amount of JavaScript code required to use the canvas object. However, once the different API functions are understood it’s simply a process of calling the appropriate functions to render lines, text or shapes. Although the CanvasChart object shown here is only a prototype at this point, I hope it provides insight into what the HTML 5 canvas is capable of rendering and how some of the features it provides can be used.

Download Canvas Demo

xACT Is a Lightweight Bulk Audio Conversion Tool for the Mac [Download Of The Day]

Mac OS X: You can convert audio files on your Mac with iTunes or a few other third-party applications, but there are often unnecessary steps involved and certain formats aren’t supported. xACT is a very simple app without those problems and just gets the job done. More »







Compare the Cost and Time of Driving Versus Flying for Your Next Trip [Saving Money]

With both gas and airline ticket prices skyrocketing, it may be hard to tell whether driving or flying is the better value (in terms of both money and time). This “Fly or Drive Calculator” can help you wisely plan your next trip. More »







Open Hidden Menu Options with the Shift and Right-Click Shortcut [Shortcut Of The Day]

Right-clicking on a file or folder brings up a context-sensitive menu, but sometimes that menu doesn’t show all your options. Hold down the Shift key when you right-click to find hidden but useful commands like copying a file path or expanding the Send To options. More »







WP Like Button Plugin by Free WordPress Templates