OdeToCode IC Logo

Revisiting Charts: HTML5 Attributes

Tuesday, February 15, 2011 by K. Scott Allen

The charting sample I wrote years ago rendered image tags like this:

<img id="topDestinations" src="roller.gif" />

The roller gif was a spinning animation that let the user know some work was happening behind the scenes. JavaScript loaded into the page had the following responsibilities:

1) Identity the image tags to transform into charts.

2) Call a web service to generate the chart asynchronously.

3) Set the src attribute of each image the to image name returned by the web service call.

Although the Microsoft AJAX libraries made it easy to call WCF services, they didn’t provide much in the way of DOM element selection and manipulation. Thus, the client script was a little heavy.

// <reference name="MicrosoftAjax.js" />

function pageLoad() {

    var context =
    {
        index: 0,
        client: new ChartingService(),
        charts: 
        [
            { id: "topDestinations", builder: "TopDestinations" },
            { id: "taxiTime", builder: "TaxiTime" },
            { id: "dayOfWeek", builder: "DayOfWeek" },
            { id: "delaysByDay", builder: "DelaysByDay" }
        ]
    };

    context.client.GenerateChart(
        context.charts[context.index].builder,
        updateChart,
        displayError,
        context);
}

function updateChart(result, context) {
    var img = $get(context.charts[context.index].id);
    img.src = result;

    context.index++;
    if (context.index < context.charts.length) {
        context.client.GenerateChart(
            context.charts[context.index].builder,
            updateChart,
            displayError,
            context);
    }
}

function displayError() {
    alert("There was an error creating the dashboard charts");
}

It’s New, So It Must Be Better

Ah, what a difference a few years makes (especially when jQuery is involved). I rather like the approach Brad Wilson took to unobtrusive JavaScript in ASP.NET MVC using data- attributes. The MVC charting rewrite uses a similar approach  - it renders img tags using data- attributes to indicate the type of chart it should hold.

     <img data-chart="topdestinations" src="/Content/roller.gif"/>

I rather like the data- approach. It’s more explicit than saying class=”topdestinations” or id=”topdestinations”.

Creating the dashboard one asynchronous chart at a time is also considerably easier (not really because of the data- attribute, but because jQuery makes it easy).

/// <reference path="jquery-1.4.4-vsdoc.js" />

$(function () {

    var charts = $.makeArray($("img[data-chart]")).reverse();
    if (charts) {
        getChart($(charts.pop()));
    }

    function getChart(element) {
        if (element.length) {
            $.get("/chart/generate",
                  { name: element.attr("data-chart") },
                  function (result) {
                      element.attr("src", result);
                      getChart($(charts.pop()));
                  });
        }
    }
});

The rewrite also dropped WCF from the solution, since an MVC controller action can generate a chart and return a string with little effort. Here’s the download for the entire solution.

Revisiting Charting with ASP.NET and LINQ

Monday, February 14, 2011 by K. Scott Allen

Once upon a time I wrote an article titled “Charting with ASP.NET and LINQ”. At the time I used a combination of WebForms, WCF, the Microsoft AJAX libraries, and the Microsoft chart control. I had some time to revisit the topic recently and rewrote the sample application using ASP.NET MVC and jQuery. You can download the sample here.

The idea behind the sample is to present a “dashboard” full of charts. I’ve worked on a few dashboards over the years, and they are always notoriously difficult to optimize without aggressive caching and asynchrony. In this sample the view drops placeholder images with enough information for JavaScript to come along and request each chart asynchronously. The result is a page that loads quickly and then fills with information over time.

There are a few interesting pieces to compare and contrast in the sample. We’ll look at them over the coming days.

Data Validation Annotations You Won't See In .NET 5.0

Thursday, February 10, 2011 by K. Scott Allen

I just heard today - the attributes demonstrated below didn't make the cut.

public class EditViewModel
{
    [GoodLooking]
    [NotATerrorist]
    public User CurrentUser { get; set; }  

    [ProperGrammer]
    [Profanity(ProfanityLevel.None)]
    public string Description { get; set; }
}

Stackoverflow Exceptions with Html.Action

Wednesday, February 9, 2011 by K. Scott Allen

If you ever have a stack overflow using Html.Action or Html.RenderAction in a Layout view, then check the return type of your child action.

public class Weather : Controller 
{
    public ActionResult Forecast()
    {
        // ...

        return View();
    }
}

The problem is if you call that action from a Layout view, like so:

@Html.Action(actionName: "Forecast", 
             controllerName: "Weather")

... then the child action is returning a ViewResult (which will pick up a Layout from the default _ViewStart, and the Layout renders the child action, which returns a ViewResult, which picks up a Layout, and so on).

There is a simple fix - make sure you return a PartialViewResult from the child action.

public class WeatherController : Controller
{
    public ActionResult Forecast()
    {
        // ...

        return PartialView();
    }
}

Once More In Defense Of The var Keyword

Tuesday, February 8, 2011 by K. Scott Allen

Even today there are those of you who doubt the power of the var keyword in C#! Or rather, there are those of you who steadfastly refuse to use it.

I think the var keyword provides a nice symmetry for local variable declarations. No one variable appears more important than another just because it has a type name with more capital letters.

var newPatient = new Patient();
var surgicalProcedure = Procedures.Rhinoplasty;
var lengthOfStay = TimeSpan.FromDays(2);

We can also talk about readability, type inference - blah blah blah. But, I think the following generalization is the real benefit of the var keyword.

Developers who use the var keyword tend to take greater care in naming their variables.

I think the carefulness is a natural reaction to the lack of type information.  I've seen quite a bit of code like this:

Procedure proc = Procedures.Rhinoplasty;

But, rarely do I see abbreviations and shortcuts with var.

var surgicalProcedure = Procedures.Rhinoplasty;

If you are still wary of var, give it a try for the day. I think your variable names will thank you.

The Value of Symmetry

Monday, February 7, 2011 by K. Scott Allen

Pablo Picasso. Girl before a Mirror. Boisgeloup, March 1932Symmetry in code is valuable, and often subtle. When I find symmetry in code, I feel it's a positive sign that the design is working well.

I like temporal symmetry. When something opens at the very beginning of a request, I'll expect it to close at the very end of a request.

I like conceptual symmetry. Milan Negovan has a discussion about symmetry on an old blog post (Achieving Code Symmetry), and includes examples from Kent Beck's Implementation Patterns book.

I also like structural symmetry. It sounds silly to judge code based on it's visual representation in a text editor, but I was recently thrown by a bit of code that looked like this.

if (widget.IsRegular)
{
    service.Process(widget);
}
else
{
    var result = widget.Calculation();
    widget.ApplyResult(result);
    service.ProcessSpecial(widget);
}

When you get down to look at the detail of the code you might find it violates any number of principles and object oriented design goals, but with just a glance something appears amiss. One path appears more complex than the other. Why? The asymmetry breaks my concentration and makes the code harder to read.

After a bit of refactoring, the code could look like this:

if (widget.IsRegular)
{
    service.Process(widget);
}
else
{
    service.ProcessSpecial(widget);
}

Now there is a balance in the code, and any additional problems might be easier to see.

If Software Was Like The Super Bowl

Thursday, February 3, 2011 by K. Scott Allen

We'd have cheerleaders, fans, and of course . . .  reporters to write about it all.

V-TPS Team Defeats Milestone 6 in Overtime

imageKen Hoethlisberger came out of the project war room with a huge smile and a fist pump. "We did it!", he shouted. "We shipped!"

When asked about the victory, Ken gave credit to his hard working team. "All the sprints, the analysis, the design - it all paid off in the end." The release was a sweet redemption for project manager Hoethlisberger, who missed the first four weeks of the year after being forced to take a leave of absence following a charge of sexual misconduct at the office holiday party.

Rookie phenom developer Mawiya Lakshanya played a crucial role in the final stretch.  Lakshanya, the team's #1 pick from the West Miami College of Culinary Arts and Computers, knocked out 156 defects on just 14 system change requests - a feat not seen since Billy "Broccoli" Nagurski's 151 fixed defects during the ill fated "Project Enterprise Reporting" campaign of 1998.

"It's easy", says a humble Lakshanya. "QA does all the hard work of finding the gaping security holes, and I just follow their lead." Her flamboyant counterpart, Mandy Ross, was a little more assertive. "They need to give me more SCRs - we could've been done a week ago and I'd spend tonight in the hot tub with a bottle of Merlot instead of eating cold pizza in a break room full of dorks." Unnamed sources inside the team say Ross is looking for another job.

The final nail biting moments once again came down to the foot of veteran IT manager Sebastian Lockitdownski. "Yeah - sometimes the CPU fan on that server doesn't spin up after a reboot and the BIOS just halts." Lockitdownski's kick in the dimly lit server closet looked errant at first. "I thought I shanked it", he says, "but seconds after I made contact on the side panel the disk lights started to flicker and I knew it was a good kick".

Senior Developer A.J. Butler left with an injury halfway through the iteration. Doctors say Butler suffered a repetitive stress injury in his mouse hand and should return to coding action in 2 to 4 weeks - in time to face the heavily favored Milestone 8.