Archive

Monthly Archives: December 2009

Alright, time to add some actual functionality to this thing.  First I want a report showing up on the scorecard page that has already been created.  I don’t really care what it displays, just want to get it working and displaying.  I will get one report working and then pull up others and connect them with actual data from the Model.

First things first I grabbed the MS Charting controls, which you will need to follow along with this section of code.  I assume for the rest of this entry that the charting controls are installed.

First off I created some nice fake data in a DataTable.  The object I created is below.  This is located in the Models path for now.  Just to get this mocked up.

public class ReportSampleData
{
    public ReportSampleData()
    {
        SampleData = new DataTable("Adron's Sample Data");
 
        SampleData.Columns.Add(new DataColumn("Col1"));
        SampleData.Columns.Add(new DataColumn("Col2"));
        SampleData.Columns.Add(new DataColumn("Col3"));
        SampleData.Columns.Add(new DataColumn("Col4"));
 
        DataRow dr1 = SampleData.NewRow();
        dr1[0] = "Sample Set 1";
        dr1[1] = 14;
        dr1[2] = 13;
        dr1[3] = 10;
        DataRow dr2 = SampleData.NewRow();
        dr2[0] = "Sample Set 2";
        dr2[1] = 15;
        dr2[2] = 13;
        dr2[3] = 12;
        DataRow dr3 = SampleData.NewRow();
        dr3[0] = "Sample Set 2";
        dr3[1] = 17;
        dr3[2] = 11;
        dr3[3] = 9;
 
        SampleData.Rows.Add(dr1);
        SampleData.Rows.Add(dr2);
        SampleData.Rows.Add(dr3);
    }
 
    public DataTable SampleData { get; set; }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Once I created the fake data, I dropped in the chart control into the Display.aspx view under the Scorecard Directory of the views.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
 
<%@ Register Assembly="System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
    Namespace="System.Web.UI.DataVisualization.Charting" TagPrefix="asp" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Scorecard
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <form id="form1" runat="server">
    <h2>
        Scorecard
    </h2>
    <%
        using (Chart chartColumns = new Chart())
        {
            chartColumns.Width = 412;
            chartColumns.Height = 296;
            chartColumns.RenderType = RenderType.ImageTag;
           
            chartColumns.Palette = ChartColorPalette.None;
            Title t = new Title("Column Bar Chart",
                Docking.Top,
                new System.Drawing.Font("Verdana, Helvetica, Sans-Serif", 14, System.Drawing.FontStyle.Bold),
                System.Drawing.Color.FromArgb(26, 59, 105));
            chartColumns.Titles.Add(t);
            chartColumns.ChartAreas.Add("Series 1");
 
            // create a couple of series  
            chartColumns.Series.Add("Series 1");
            chartColumns.Series.Add("Series 2");
 
            // add points to series 1  
            foreach (int value in (List<int>)ViewData["Chart"])
            {
                chartColumns.Series["Series 1"].Points.AddY(value + DateTime.Now.Second);
            }
 
            // add points to series 2  
            foreach (int value in (List<int>)ViewData["Chart"])
            {
                chartColumns.Series["Series 2"].Points.AddY(value + DateTime.Now.Minute);
            }
           
            chartColumns.Legends.Add("Legend1");
            chartColumns.BorderSkin.SkinStyle = BorderSkinStyle.None;
            
            // Render chart control  
            chartColumns.Page = this;
            HtmlTextWriter writer = new HtmlTextWriter(Page.Response.Output);
            chartColumns.RenderControl(writer);
        }
    %>
    </form>
</asp:Content>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Once that was finished the final step is to toss in the controller the view data.

public ActionResult Display()
{
    ViewData["Chart"] = new List<int>() {4, 6, 12, 3, 11};
    return View("Display");
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

Now run the app and check out the page.  You should see a chart like that shown below.  (Click for larger image)

That covers the second part of this series.  I will have another addition up soon, tying even more bits together.

Shout it

kick it on DotNetKicks.com

There have been a lot of requests for MVC based scorecards, so I am going to kick off a new series of wiring up an MVC scorecard site.  This first part will simply cover setting up the basic site and skeleton framework using the default ASP.NET MVC Project.

Start off by starting a new ASP.NET MVC Project.  Since I will be creating tests for this walk through, be sure to add a unit test project also.  I am just using the default MS-test libraries for now, but feel free to apply whatever test framework you would like.

To create additional views and controllers we’ll add a unit test for a new controller.  I will name this new controller ScorecardController, so I have added a test file called ScorecardControllerTest.cs.  The first test is just the standard action for the appropriate method actions and returning the view, as follows.  I added a similar test for the Index method also.

[TestClass]
public class ScorecardControllerTest
{
    [TestMethod]
    public void Scorecard()
    {
        ScorecardController scorecardController = new ScorecardController();
        var result = scorecardController.Scorecard() as ViewResult;
        Assert.IsNotNull(result);
    }
 
    [TestMethod]
    public void Index()
    {
        ScorecardController scorecardController = new ScorecardController();
        var result = scorecardController.Index() as ViewResult;
        Assert.IsNotNull(result);
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }Once the skeleton implementation is made to get green lights on these tests, a controller will be created with the following code.

public class ScorecardController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
 
    public ActionResult Scorecard()
    {
        return View();
    }
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

At this point I need to create some tests for what is expected in the view, but I will get to that once a bit more of the skeleton of the site is done.  As soon as I wrote these tests, based on where they are located in my folder structure I decided that I need to do a quick refactor of the name.  Having a Scorecard/Scorecard path just seemed stupid, so I renamed the Scorecard.aspx to Display.aspx and changed the method name appropriately.  If you are following along, the subsequent code will be using the renamed page/method, etc.

The next thing I wanted to do was to get the view coming up appropriately, so first things first, new tests.

[TestMethod]
public void ScorecardViewExists()
{
    ScorecardController scorecardController = new ScorecardController();
    var result = scorecardController.Display() as ViewResult;
    Assert.AreEqual("Display", result.ViewName);
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

First of course it fails, but with the appropriate change shown, all runs green again.

public ActionResult Display()
{
    return View("Display");
}

So after this I added the following tests, controller actions, and views.

[TestMethod]
public void Select()
{
    ScorecardController scorecardController = new ScorecardController();
    var result = scorecardController.Select() as ViewResult;
    Assert.IsNotNull(result);
}
 
[TestMethod]
public void SelectViewNamed()
{
    ScorecardController scorecardController = new ScorecardController();
    var result = scorecardController.Select() as ViewResult;
    Assert.AreEqual("Select", result.ViewName);
}
 
[TestMethod]
public void IndexViewNamed()
{
    ScorecardController scorecardController = new ScorecardController();
    var result = scorecardController.Index() as ViewResult;
    Assert.AreEqual("Index", result.ViewName);
}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

After that I edited the CSS so I could get a better feel to the site relative to what I am working toward.  I will leave you to decide what you want to do with the CSS & such yourself.  One of these days I will be graphic artists worthy, for now I am just happy with a decent looking layout and reasonable colors. ;)

When I was done my Solution Explorer looked like this.

Last I added the following to the Site.Master page for appropriate linkages.  This spot is located in the menucontainer section of the page.

<div id="menucontainer">
    <ul id="menu">
        <li>
            <%= Html.ActionLink("Home", "Index", "Home")%></li>
        <li>
            <%= Html.ActionLink("About", "About", "Home")%></li>
        <li>
            <%= Html.ActionLink("Scorecard", "Display", "Scorecard") %></li>
    </ul>
</div>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

When I run the app I now have a basic skeleton and the initial pages I am going to work with.  Next steps coming soon.

kick it on DotNetKicks.com

Shout it

A recent article The Next Big Bang by our Webtrends CEO, Alex Yoder, was published recently online via Teradata.  It got me thinking toward the technical aspects of what is within our reach in the analytics industry.  The industry as a whole has moved past the mere counting of visits & their respective users as numbers and moved to making the numbers actually represent the people.  That can be a weird statement, but I will clarify a bit more.

Years ago, one would setup a server and start tracking hits on a website.  Often these would be called views or page views.  What did that mean though?  Effectively it meant zero, zilch, nothing of any value.  You know only that a machine, or machines, made X number of views against a website.  One didn't know what kind of browser, device, PC, Apple, screen size, or if the views were even unique to a machine or possibly unique to a user.

Then everything changed, and this is still the past I am speaking about.  We finally started enabling detection of devices, browsers, screens, viewable, and types of visits.  This elaboration of data drastically altered what we could build for a website.  It made good design more measurable by audience participation.

A short time afterwards the industry was able to move forward and get into doing some further pre-analysis of this data.  This enabled more actionable and intelligent decisions being made from web analytics data.  The analytics data started creeping into the realms of business intelligence, general reporting, and actual information.

The next huge leap, which is close to where we are now, is the opening up of these sources of analytics data and bridging the final gaps in the Web, Enterprise, and E-commerce Architectures.  The complete full cycle evolution has occurred from IT, to Engineering, to Marketing and over to Sales.  A company can now integrate their data from analytics with their data from point of sale systems and derive true, daily, value from the decisions that can be made from these sources.

The Future Arrives

Now we are at a point, with the level of services and opening of data, that almost any valuable data point can be tracked and trended with high accuracy.  Gone are the needs for traditional media that leaves one with massive gaps in segmentation and individual directed content.  Today we have vastly greater capabilities.

We can analyze and provide data that helps companies at so many levels, such as tracking game play to pinpoint the fun parts versus the boring parts of a game.  We can derive the dead spaces in a web site, or better yet the hard to navigate areas of an actual brick and mortar storefront.  Even more analytics can provide and correlate tracking against the usage of a car or transit system, an airline boarding flow, and draw causable correlation between the very first steps a consumer takes the the purchase and beyond.  All because the data is open and cross-correlative.

This leads me to my next question.  What architectures have you found valuable?  What combination of data cross-correlated with analytics data have given you actionable measures?  What other devices, sites, and mechanisms provide a value to track, trend, and analyze?  I would love to hear what users have found useful in their own environments, so please leave a comment or three.  : )

Excited!

That is me right now.  I am stoked about the upcoming Engage 2010 for a few reasons.

  1. The main reason is because the analytics industry & this field of technology is really interesting to me.  I dig crunching the numbers, working with our clients, and getting the results and analysis into useful, actionable numbers.  Being able to see & know our clients are able to act on those numbers is awesome.  Attending a conference like this provides an opportunity to talk with clients regarding their use of the technology.
  2. Ideas grow at a rapid rate when this many smart people, with a common interest & goal are in one place.  Just talking with conference goers, thought leaders in the industry, and being able to talk on a one to one basis gives me, them, and everyone involved new ideas.  One never knows what may come out of a conference like this.  Whatever does, it is always exciting to think of the opportunities.
  3. Ignite New Orleans.  If you have ever been to a Portland Ignite, these are really cool events.  Local, human, entertaining, and personal all come to mind to describe how these Ignite Events are.  To have one in New Orleans – or Nawlins' – will be a blast!  :)
  4. I will be there speaking & working a workshop.  This will be the first time I have ever presented or done anything like this in New Orleans.  That adds all the more excitement to it.  I hope to see some familiar faces and many new ones.
  5. I grew up just down the ole' Interstate, so New Orleans or as we often say Nawlins, is kind of a second home to me.  I enjoyed so much driving into this city from the east, over Lake Pontchartrain's Twin Span 5+ mile bridge or the 23+ mile Lake Pontchartrain's Causeway.  Better yet I really enjoyed rolling into the city on the Amtrak Crescent via the Norfolk Southern Lake Pontchartrain Bridge (See the awesome map).

This is shaping up to be a truly awesome event.  If you are going and would like to meetup, discuss some analytics, or just enjoy some music on Bourbon, St Charles, or Decatur just hit me up on Twitter @webtrendsadron.

Ok, so over the last 30 years or so, Microsoft has made a lot of software.  Probably more software than any single entity on the face of the earth.  The first two decades of software was rough when released in beta.  If it was even released in beta, or alpha, or as service packs.  Most IT people, software developers, or anyone using software would almost always steer clear of beta, alpha, or service updates of software.

Why?

That is the easy thing to answer.  Most of the time, the software would not even work.  At least not in any semblance of the way it was supposed to.

Fast Forward to Today. . .

Software works.  Rarely does one download software that is in beta and it doesn't work.  At least on a fundamental, core functional basis.  This is very much apparent at Microsoft.  The competition lit a fire and Microsoft has answered with more frequent releases, more service packs and updates to keep things secure and up to date, more quality packed into every release.  Why did they make this massive transition?

Agility.

Yup, I said it, the firestorm that has been the Agile movement has caused a major upheaval at Microsoft.  Out went the Waterfalls and in came the Maneuvers of Agile.  In all honesty, if someone is still arguing the tenants of this success, they?re lost in a bygone era of questioning agile processes.  Of course, I will admit, many of the processes are up for debate in various ways.  But the core culture of software development has been dragged kicking and screaming.

Gone are the grognards sitting in the corner being anti-social, hacking away on some code that nobody else will ever be able to maintain.  Gone are those days when a development team works in a vacuum, and fails.  Instead we have faster teams, more customer involvement, iterations or sprints, and in the end higher quality software.

The reason I bring this up really has one simple intention.  Stop freaking out over beta software.  Implement things with it.  Use it.  Love the stuff.  I am regularly using beta software, with all sorts of new goodies, and releasing these projects into production environments.  You might say, "really?  that is so dangerous", but I have not had a single failure, crash, or error related to a beta issue in production for at least 5 years.  Back when Agile was really just starting to gain steam to run the course.  So use new software, stay on the bleeding edge, and help everyone by helping yourself keep up to date!

Follow

Get every new post delivered to your Inbox.

Join 3,273 other followers