Subscribe | Alerts via Email
View All Quotes
“Early in the project you can have firm cost and schedule targets or a firm feature set, but not both.”
-Steve McConnell
<May 2008>
SunMonTueWedThuFriSat
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

©2012 Cal Zant
Sign In
Total Posts: 107
This Year: 0
This Month: 0
This Week: 0
Comments: 0

By Stephen Few
223 Pages
http://www.amazon.com/Information-Dashboard-Design-Effective-Communication/dp/0596100167

This book is really useful.  I picked this up one evening on a regular visit to Barnes and Noble, just because I had seen one of the really talented analysts I worked with reading it.  I started thumbing through it, and was amazed by the meat packed in between the covers.  The term "dashboard" has become a huge buzzword as of late, and seems to be what everybody from line workers to upper executives want ... even though most don't have a clue what it is or what this magical tool would even look like.

Stephen cuts to the heart of this confusion, and gives some practical advice for how to effectively use dashboards in your organization.  Since so many people have varying ideas of what a dashboard is or should be, Stephen starts by looking at what some sources say a dashboard is and combines some of those into what he thinks the best defiinition is:

Dashboard - Visual display of the most important information needed to achieve one or more objectives which fits entirely on a single computer screen so it can be monitored at a glance.

He is very intentional in the exact wording of that definition, and goes into greater detail about why each word or phrase is important and how it ties into the primary goal of the dashboard.  He shows numerous examples of some dashboards currently available from companies like Oracle, Informatica, Cognos, etc. and points out the strengths and weaknesses of each.

The thing I liked the best about this book is the scientific approach to our visual perception.  Stephen presents some concepts that we seem to understand subconsciencely ... but brings them into the light, and explains how we can make better at-a-glance dashboards by making use of things like hue, intensity, 2-D location, orientation, line length, line width, size, shape, added marks, encloser, and the dreaded flicker.  He also explains why/how to tone down the "noise" (and often times the flashiness) of the dashboard so that it can better serve its purpose.

I consider this a must-read for any analyst or developer who designs dashboards for their organization, or tries to represent data visually in any form or fashion.  If you read it and apply the concepts it covers, I really think it could add some serious business value.

Saturday, May 31, 2008 8:25:44 AM (Central Standard Time, UTC-06:00)  # 

Ever noticed that setting the MaxLength for a MultiLine TextBox does absolutely nothing? According to documentation on MSDN "this property is only applicable when the TextMode property is set to TextBoxMode.SingleLine or TextBoxMode.Password." You can just put a RegularExpressionValidator on the textbox that makes sure the length is under a certain threshold, but that isn't always the most user-friendly way.  On single line textboxes, the browser simply doesn't allow the user to insert any more letters once they have reached the max length ... which is pretty intuitive for users to understand "oh, I need to shorten this down a little."  Here is some JavaScript that will create that same type of effect on MultiLine textboxes that users are familiar with on single line textboxes.

Here is the JavaScript function:

function MaxLength(field, maxLength)
{
    if (field.value.length >= maxLength)
        field.value = field.value.substring(0, maxLength - 1);
}

Then you can add an "onKeyDown" event to the TextBox in the aspx file like this:

<asp:TextBox ID="txtMultiLine" TextMode="MultiLine" onKeyDown="MaxLength(this,200);" runat="server" />

... or add it programmatically in the CodeBehind like this:

txtMultiLine.Attributes.Add("onKeyDown", "MaxLength(this,200);");

Note: If it is critical that a user not be able to submit a form with more than the maxLength number of characters in the multiline textbox, then you also need to add a RegularExpressionValidator to double-check the length ... just in case the user has disabled JavaScript on their browser.  This will obviously only work if they have JavaScript enabled, and is more designed to make this a more pleseant and familiar expreience for the end-user.  Here is an example of the RegularExpressionValidator you might drop on the page as well:

<asp:RegularExpressionValidator ID="revMultiLine" ControlToValidate="txtMultiLine" ValidationExpression="(.|\n){1,200}" ErrorMessage="Please enter 200 characters or less" runat="server" />

Friday, May 23, 2008 2:38:51 PM (Central Standard Time, UTC-06:00)  # 

I was trying to figure out how to make the rows in a grid alternate background colors in a SQL Server Reporting Services (SSRS) report using Report Builder/Designer in Visual Studio (like the example shown below).  I searched the internet for a little while and pretty much just found people who said Report Designer was a very simple tool and didn't allow you to do "advanced customizations" like this ... bull crap.  It is a simple tool (with a few quirks) ... but it is pretty extendible too.  There are a ton of places where it allows you to use "Expressions", which are extremely powerful.  Thats what I used to make this alternating background thing work.

Alternate backgrounds in SSRS report

First select the table row you would like to apply this type of alternative style to in the designer.  Then in the properties window for that TableRow object you should see a "BackgroundColor" property ... click the drop down and choose "<Expression...>":

Set TableRow BackgroundColor property to alternate color in report

Then, all you have to do is write an expression like this and replace the colors with the ones that you want.  The expression simply evaluates the current row number mod 2, which will be one for row numbers that are odd (e.g. 1,3,5) and zero for row numbers that are even (e.g. 0,2,4).  It compares the result for the current row and returns the appropriate background color ... simple stuff:

Write custom expression to set row background color

Wednesday, May 07, 2008 1:41:41 PM (Central Standard Time, UTC-06:00)  # 

I have our production web servers set up to email me notifications when unhandled exceptions occur, and if a site is publicly accessible crawlers, spiders, and other types of search bots can make this a pain.  Most crawlers try to go through pages they have in their index, and pull new content.  If you have promo-type pages that are only up for a limited amount of time, they will try to access that URL later on after it is gone, and bam ... another email in my box.

There are CAPTCHA components out there, but they aren't really appropriate for this scenario ... I don't want site users to have to read some squiggly letters and type those out before the site sends me an error email.  So I have written some pretty simple code that helps me filter out if the request came from a crawler.  My 10 second Goggle on the subject didn't turn up much, so maybe this will help someone else out there.  If you figure out a way to improve it, please post some comments or contact me.

The solution is two part.  I have a regular expression pattern stored in the web.config, and then a single "IsBot" method that returns true if the current request is from a crawler and false otherwise.  I store the pattern in the web.config because it is still evolving, and probably far from "all encompassing" ... but when an error email slips through that is from a bot, I will look at the agent it presents itself as and then add a new keyword to the pattern to detect that crawler in the future.  If I was to guess, I would say the pattern posted here probably detects over 90% of hits from crawlers ... as of today.

Current pattern in web.config's AppSetting setting section:

<add key="botRegex" value="bot|crawler|spider|slurp|ask|teoma" />

C# IsBot method:

/// <summary>
/// Returns true if the current request is from a bot crawling the site, and false otherwise.
/// </summary>
public static bool IsBot
{
    get
    {
        // If this method can't access the current context that means the executing thread doesn't have access
        // to the current request's properties ... since we can't pull any agent information we have to assume
        // this is not a bot.
        if(HttpContext.Current == null)
            return false;
        
        string HTTP_USER_AGENT = "";
        if (HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"] != null)
            HTTP_USER_AGENT = HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"].ToLower();

        // Check to see if the user agent field contains any of the terms in the botRegex set in the web.config
        string expression = ConfigurationManager.AppSettings["botRegex"];
        Regex botRegex = new Regex(expression);
        return botRegex.IsMatch(HTTP_USER_AGENT);
    }
}
Tuesday, April 29, 2008 2:45:22 PM (Central Standard Time, UTC-06:00)  # 
...
using System.Globalization;
using System.Threading;
...

string thisPhrase = "HELLO WORLD!";
lblOutput.Text = Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(thisPhrase.ToLower());

That's it ... this example would convert the string to "Hello World!"  Pretty easy, huh?

Thursday, April 24, 2008 12:04:48 PM (Central Standard Time, UTC-06:00)  #