@webtrends #wtengage Conference Rocked!

Week before Mardi Gras, the Saints rocked and won the Super Bowl, and @webtrends threw an awesome #wtengage Conference.  Props out to the long list of Webtrends People there;  @DashLavine, @caseycarey, @webtrendspeter, @justinogarrity, @sullybridgetb, @kaykas, @justinkistner, @michelewarther, @mrdiggles, @yodera, @vkenkal, @derekfine, @ekrobi, @mccook, @robinoula, @benfogarty, @noexg, @thomschoenborn, @mediachick, and others!  The event was awesome, great sessions, great knowledge transfer, great food, just great ? period!

Also must say the meetings, meets, and introductions were great.  I'm glad to have met dozens and dozens of people and get those names and faces connected.  Finally caught up with; @seanpower, @johnlovett, @christineconley, @ed1chandler, @bullfrogmedia, @ebeane, @cgrantski, @drcasio, @nadolski, and many others.  Then there are others I met and caught up with and still got more catching up to do; @aknecht and @bosilytics.

Seriously, all of these individuals are rock stars in the analytics community.  The conversations, new ideas, thoughts, and general kicking around New Orleans was a great time.  If you are interested in the next Webtrends Engage (and you ought to be if you do anything with analytics), check out the 2011 Conference coming to San Francisco.

Code Camp Kick Off

In other news, Code Camp is kicking off real soon.  Specifically, the kick off meeting is tonight here at Webtrends.  This year Code Camp is going to be pretty huge.  I am guessing at around 400-500 people, more sessions, more geeking & nerding about, it will be an awesome time for all.  So keep reading and I will be posting more tidbits about the upcoming Code Camp.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: Adron
Posted on: 2/8/2010 at 11:19 AM
Tags: , ,
Categories: WebTrends | Events
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Getting The Bits Swinging in the Business

Read Part 1 & Part 2 of this series if you haven't already. 

Last entry I worked up the basic origins and destinations for the data we have. Now we have to start turning this into something real, something concrete. The following processes include a whole soup of acronyms and other cryptic vocabulary. The most common thing I will probably use is the ETL acronym, which stands for Extract, Transform, and Load. This is the process of bridging the data to the various originations and destination and moving that data appropriately.

In the last entry I finalized the originations and destinations as shown below;

Originations
Excel & Access (Office 2007) *.mdb, *.xlsx, and *.csv/*.txt data stores
Internal Account Software (IAS) This one is a prospective can of worms.  Proprietary layouts, de-normalized & normalized data, and all sorts of redundant, non-atomic data.  This sounds like an accounting package right?  :p
Webtrends Analytics Data Exchange Web Services (DX) Webtrends web services provide REST style architecture, with the ability for data to be retrieved in XML, JSON, HTML, or other formats (we can add more if need be, just let us know).
Point of Sale System (POS) This system provides two daily exports, one at 6:00am and one at noon for processing.  The export format is *.csv.

Destination
SSRS SQL Server Reporting Services, with the core underlying data stored in SQL Server.

In my previous entry you may have noticed that I had posted SSIS with the Destination list.  Being one that corrects themselves when mistaken, I took it out, as it does not belong there.  The SSIS is our tool that will perform the ETL functionality for this project.

At this point we are finally going to get into the dirty bits of these pieces of technology, and how we need to tie them together.  I am going to attack them over the next few entries based on the order in the lists above.  The first item, is the Excel & Access 2007 customer relations listings from sales.  Here?s a description and a few shots of what this thing looks like.

The access database is setup with a very simple relational data schema.  This is shown below (click image for larger view).

You can see there are pretty standard pieces of data, in a generally normalized (3rd form for the most part) structure.  This is fine.

Next is a shot of the data entry screen for adding opportunities.  There are respective screens for customers and employees.  Everything needed for a basic customer list & tracking basic things.  Nothing too extravagant here either.  Again, all is fine.

Below is a simple report that shows the available opportunities that are open.

Another report showing the forecasts.

Below is another forecast sliced grid.

So all that seems normal enough.  But the processes are what makes things tricky.  If everyone just managed sales from the database, all would be right in the world.  The first thing that breaks this is that each sales person enters their sales during the day and other information in a spreadsheet that is not linked to the underlying database.  Someone each morning puts the previous days sales information.  This of course, breaks down data integrity.  Below is a sample sheet that is used each day.

One thing that Excel is used for, that doesn?t break reports is the lists of prospective customers to call.  As shown below.

Now that we have a break down of the Excel & Access Customer Relations Management Software, I will move onto the other pieces of technology in the next entry.  This is the data point that has the most prospective data risk, so I put it at the top of the list to cover first.  After I cover each of the systems, we will move into the architecture of the system overall.  So keep reading, more juicy bits to come.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

My Webtrends Engage Speaking Engagements?

So here is the lowdown on what I will be presenting, demoing, and showing to the attendees & anyone who is interested at Engage 2010.  If you are attending and have not signed up on the Engage Crowdvine Site, please do so.  There are some great conversations going on there.

One other thing I wanted to point out, is that you MUST attend the Ignite in New Orleans.  Ignite events are a blast!  Portland, Oregon regularly has some of the largest Ignite Events, and since we are bringing a whole lotta Portland love, and NOLA is well known for some great parties, I know the NOLA Ignite will be awesome!  So make sure to attend.

First off, Brian Gallagher and myself will be showing off some awesome technology for video tracking at the science fair break out sessions.  There will be a Tuesday Science Fair and a Wednesday Science Fair, and I will be there with Brian going over the tracking.  So if you miss us one day make sure to check it out the next day!

The next speaking session is the enterprise & business intelligence topic I have mentioned in some of my previous blog entries.  The session is titled Make Analytics Work across your Enterprise.  Our topic summarized is, The nerd of the Enterprise;  ETL, EPM, ERP, BI, CRM, and how the alphabet soup works together for real Enterprise Business Intelligence and Insight.

The final engagement I have is a topic near a dear to my work here at Webtrends.  Over a year ago a rock star team of developers; Rob D, James K, and myself started working on the Data Exchange, REST Web Services for Webtrends.  Of course now those have been in production and are now on v2.0 already!  Rob has gone on to rock the current iPhone Webtrends Application (Check out the Webtrends Blog Post Too) & James is coding away at some of the awesome infrastructure that keeps all the data flowing smoothly on the back end (to the web services, to the Insight UI, the whole thing ? James is awesome at that).  So we built these services many months ago and now I get to present them as a workshop session at Engage.  Open web services based on good clean REST Architecture Principles have always been an interest of mine and I have been and will continue to be stoked that we at Webtrends have these available for customers!  So be sure, if interested, to check out the Workshop:  The RESTful Way ? How to Use Webtrends REST Services.

Also for further reading, check out some of my past entries on REST Services;

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: Adron
Posted on: 1/26/2010 at 4:30 PM
Tags: , , , , ,
Categories: WebTrends | Web Analytics
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (2) | Post RSSRSS comment feed

Web Analytics Leadership, Social Media Leadership, and Correlations

Alright.  Here I am working through some analytics trending of my Twitter, Facebook, www.adronbhall.com, LinkedIn, and other various sources of traffic.  Here's the frustrating part.  I don't mean a little frustrating, I am talking about a-grade I almost want to break something frustrating.  I have bit.ly, Webtrends Analytics, a database with cross-correlated results, a Twitter monitor in another window, and other little apps to track what is going on.  Where does most of this data come together?  In my head.  Why do I have to manage everything this way, it is damn frustrating!

So here is an idea, and I am just thinking outside the box here (as I always do since nobody will let me in the box anyway :p ).  How about these things get merged into a good solid single interface.  Maybe even some of the environments get rolled together in addition to the tracking analytics and reports.  How about a solid dashboard that allows drilldown into the various mediums to allow actual interaction with the data and platforms?  Imagine a dashboard, that reports the analytics for all these things but then lets you just kick in and start tweeting or posting the latest bits to Facebook.  Why have a half dozen or more applications and web sites open.

What we need here is some technology leadership.

Others have discussed this recently and are looking for some results.  Ok, some of you readers may be thinking, "do you not work for Webtrends Adron?  Go build this stuff!"  Well maybe others and I am, but I am still frustrated at not having it right now.  It seems this is something that is slowly slipping by in this industry and we need a centralizing effort for all these data points to help in actually making sense of them.

A fellow analytics & marketing professional, Rodica Buzescu writes in her blog Morphing Through Time a post titled Web Analytics ? Leaving a Lot to Be Desired.  She lays out the current analytics situation very clearly.  There is no tool that really bridges the data together easily.  Some BI Pros out there may say "oh but I have all that stuff together".  This may be true, but how much time and effort did that take?  What we need is a centralized management solution for this data.  Something to bridge the data together to make it actual, usable, and actionable information.

I have also had a number of conversations with Eric Peterson about various analytics on various platforms.  One such paltform is Twitalyzer (@twitalyzer), that he and @katzpdx have put together.  This is a prime example however, of a very useful tool, but something that lies outside of other tools.  The question is, how to integrate and what to integrate.

As an analytics advocate, practitioner, and developer myself I have one huge issue with a lot of my analytics that I use.  Webtrends Analytics & Data Mart help me bring most of those together.  However there are a number of things that are still disparate and segmented in the wrong areas.

So with this post as it stands, what do people want joined?  Where are all these data points that people want?  I think something good just may come out of this desire, but the ideas do have to come together solidly.  I have things I can?t disclose, but I know there are minds here at Webtrends thinking about bridging this gap right here and right now.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: Adron
Posted on: 1/26/2010 at 9:43 AM
Tags: , , ,
Categories: Discussion Points or Ideas | Web Analytics | WebTrends
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (10) | Post RSSRSS comment feed

Brainstorming Into the Business Intelligence Clouds

Part II of my Business/Enterprise Intelligence Series, check out part 1.

In the previous part of this ongoing series of getting the business intelligence and analytics pieces of the enterprise intelligence world figure out, I hit on the first step of the entire process. Collection of available data points. Not the desired data points, nice to haves, or might haves, but the available data points.

In this entry I will step past that and get into a little more of the technical depth of how these data points will be connected in the enterprise systems. More to the point, how they are not connected and will need to be in the enterprise.

A Quick Review, The Systems

  • Point Of Sale (POS) w/ 300+ stores
  • Webtrends Analytics tracking the Awe Widgets Inc Website
  • Internal Accounting Software (IAS)
  • In-house Built Customer Lists for Sales w/ Excel & Access

With the four systems we have a huge amount of actionable data points. So how do we connect all of these data points? That is the thorny question that comes up. Again, just like during the discovery of what data is available, we have a simple first step for this process.

Figure out the origin and destination!

That is really it. Of course, as anyone would concede, there is a lot in between. Without knowing where we are starting and where we need to end up though, finding the in between is in vain. Sure, one can make the mistake as many business intelligence projects do, and start building architecture before anyone knows or actually can use the architecture. This is a severe mistake, and I myself have literally seen millions of dollars get wasted only to have to start a project over, right in the middle of the original project. Do NOT become one of those projects, find the origin and destination!

In this case I am again, going to use my creative side and determine the operations of this company. Awe Widgets Incorporated is currently using SQL Server and has in house skills developed among their staff. That provides an easy option of moving towards SQL Server Reporting Services (SSRS) and working with SQL Server Integration Services (SSIS) for the ETL bits. Whatever other platforms are in between will be easily connected with these two tool stacks. So now I know my multiple originations, and my single point destination.

Moving on to the fun bits.

Now we have to figure out how we're going to get from our origination to our destination. This is where the trip becomes interesting. Just to make sure things stay clear, and list out what we have that we are working with.

Originations
Excel & Access (Office 2007) *.mdb, *.xlsx, and *.csv/*.txt data stores
Internal Account Software (IAS) This one is a prospective can of worms.  Proprietary layouts, de-normalized & normalized data, and all sorts of redundant, non-atomic data.  This sounds like an accounting package right?  :p
Webtrends Analytics Data Exchange Web Services (DX) Webtrends web services provide REST style architecture, with the ability for data to be retrieved in XML, JSON, HTML, or other formats (we can add more if need be, just let us know).
Point of Sale System (POS) This system provides two daily exports, one at 6:00am and one at noon for processing.  The export format is *.csv.

Destination
SSIS & SSRS SQL Server Integration Services used to connect SQL Server Reporting Services, with the core underlying data stored in SQL Server.

So now we are starting to get somewhere.  We now where we are, what we have, and where we want to go.  Time to wire some things up, so stay tuned.  That will be in the next entry.  Also, if you are planning on attending Webtrends Engage in New Orleans, but sure to look up the Enterprise Intelligence session that I will be presenting with Heather Crince of Webtrends and Tony G. of Orbitz?

If you missed the previous entry in this series, check out Where is the Other Data Tracking?!  Where are My Acronyms?!?!

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Just Tidbits of Technical Tenaciousness

IE6/Windows XP

Microsoft wants users to give up IE6 & Windows XP.  I want users to give up IE6 & XP.  Please, please, please give those things up.  IE6 of course more than XP.  With what Windows 7 is though, go ahead, get on the bandwagon.  Win XP is moving the way of Win98/95 finally so let's keep that movement going.

Free SEO Toolkit from ole' Microsoft

So this looks interesting.  The thing is, as stated above, one has to kick the Windows XP Habit!  So drop it and check this out.  I am keen to see what anybody is coming up with as for these platforms these days.  Especially companies like Microsoft who have vast resources to put toward it.

Adbrite Switches to Webtrends

I see this regularly these days, as we are gaining tons of switchers, since our analytics generally rocks.  But this one really brings it home for me since I have worked with the Adbrite Team on the Implementation.  Great team at Adbrite, excellent implementation if I might say so myself.  If you are looking for a company to do advertisements on the web with, this is definitely a company to take a look at.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: Adron
Posted on: 1/19/2010 at 2:50 PM
Tags: , , , , ,
Categories: Website and Application Write-Ups | Keeping Up | Just Stuff
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Encryption and Decryption Code Bits

I recently had to do some simple encryption and decryption for password storage.  I wanted to document this so a blog entry seemed in order.  So without any yammering here's the simple class I created.

public static class EncryptionHelper
    {
        private const string CryptographyKey = "CryptKey";
 
        // The Initialization Vector for the DES encryption routine
        private static readonly byte[] iv =
            new byte[] { 220, 13, 41, 29, 1, 63, 73, 9 };
 
        /// <summary>
        /// Encrypts provided string parameter
        /// </summary>
        public static string Encrypt(string s)
        {
            if (string.IsNullOrEmpty(s)) return string.Empty;
 
            byte[] buffer = Encoding.ASCII.GetBytes(s);
            var des = new TripleDESCryptoServiceProvider();
            var md5 = new MD5CryptoServiceProvider();
 
            des.Key = md5.ComputeHash(Encoding.ASCII.GetBytes(CryptographyKey));
            des.IV = iv;
 
            string result = Convert.ToBase64String(
                des.CreateEncryptor().TransformFinalBlock(
                    buffer, 0, buffer.Length));
 
            return result;
        }
 
        /// <summary>
        /// Decrypts provided string parameter
        /// </summary>
        public static string Decrypt(string s)
        {
            if (string.IsNullOrEmpty(s)) return string.Empty;
 
            byte[] buffer = Convert.FromBase64String(s);
            var des = new TripleDESCryptoServiceProvider();
            var md5 = new MD5CryptoServiceProvider();
 
            des.Key = md5.ComputeHash(Encoding.ASCII.GetBytes(CryptographyKey));
            des.IV = iv;
 
            string result = Encoding.ASCII.GetString(
                des.CreateDecryptor().TransformFinalBlock(
                    buffer, 0, buffer.Length));
 
            return result;
        }
    }

So simple enough.  Hope that is helpful to anyone interested in a super easy encrypt & decrypt example.  : )

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: Adron
Posted on: 1/15/2010 at 5:33 AM
Tags: , ,
Categories: How-To, Samples, and Such
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

Where Is The Other Data Tracking?! Where Are My Acronyms?!

Where is the business intelligence?

This blog entry may instigate just a bit.  It will also be a little long for a blog entry. You've been warned.  I suppose though, if you know me & the work I do, that is not really something new.  I see something wrong, broken, or otherwise and I am likely to point it out and describe it in detail.

As I roll into 2010 coding, implementing, and rocking with Webtrends, I have noticed something lacking in the analytics industry.  I will add the clause that obviously Webtrends has people thinking about these things and actively working on this topic, but what I want to point out is a general issue.  Where is the other data, where is the existing data?

It seems, even though some company's kind of get to a certain point in connecting data points, not many really do.  The biggest reason is that most companies are just a few steps away from actually being able to do so.  The other even larger reason is, many do not realize what data should or should not be connected.

When someone starts pulling CRM (Customer Relationship Manager/Management), Analytics, POS (Point of Sale), ERP (Enterprise Resource Planning) data, and other sources into a single reporting repository we finally have real business intelligence.  Otherwise so many entities stumble through the land mines of data confusion.  I see this so much it really drives me crazy sometimes.

So how can a company or entity identify and connect these points of data?  It often starts with a ridiculously simple step.  At risk of oversimplifying things, let me just state the first step in getting out of the data confusion land mines is to first figure out your data.  Ask these things:

  • What data does the business have?
  • What data is currently used and available?

Do NOT ask what data you want, do NOT ask what may not be.  What you want to know first, and so many companies make this mistake, is to know what you know.  Do not, at the early stage of business intelligence information gathering start asking too many hypotheticals.  I promise the risk of failure increases exponentially for every hypothetical data point added.

Once you have identified what data is available, start figuring out how the data is related.  Once you understand the data you can then, and only then, make the huge leap to determining what data you want and how to get it to where you want.

Let me draw this out in a real world example.  Beware; I am using my creative mind now!

What we have so far, for Awe Widgets Incorporated, is several data points.

  • Point of Sale/POS Systems in 300+ stores.
  • Web Analytics (by Webtrends of course) tracking all sorts of great data points on the Awe Widgets Incorporated Website.
  • Internal Accounting Software (Almost ERP, not really)
  • In-house Built Customer Lists for Sales.

So there we go, four key pieces of tracking.  So how would they work together?  With a little further analysis (my key creative side now analyzes Awe Widgets Incorporated internal structure) and we find a few connections.

Correlation, POS to Webtrends Analytics

The POS System has a tracking identifier for customers which we can use to sync up with logged in users tracked via Webtrends Analytics.  This data can be used to derive who is and is not in stores purchasing.  In addition trending could follow the user flow to derive some actionable decisions on how to encourage online or store front shopping.  Just these two data points being connected add a lot of value.

Correlation, Internal Account Software ties to POS

Another data point tie in with the aforementioned POS & Webtrends data is the Internal Accounting Software (IAS).  The IAS holds information related to each sale, and other correlated information about how sales are going for the quarter, year, and other performance indicators.

Correlation, In-house Customer Lists for Sales

The sales department, in aggressive technical fashion has built a number of customer lists in Excel & Access.  The Access Application has a partially updated data store with a server based Excel file holding the updated piece of data about each of the sales person's current sales.  I know, I hear it now, every developer that is familiar with this scenario screaming, "OMG, you have your data in Excel AND Access, and it is supposed to have integrity, and be aaaaaaaaaaaaaaaaggggggggggggggggghhhhhhhhhhh noooooo!"  But you know, this @#$% happens.  : )  When things are like this, solutions get creative.

Tying Together the Pieces

Alright, this is when the awesome nerd bits start to happen.  But I have covered enough for this entry.  In the following entries on this topic I will step through this first data finding mission and start discussions on how to connect these sources and get that data mart, warehouse, or other middle tier piece into action.   I will continue on and lead into how the data can finally start telling a real story.  Because in the end, the real story is, somebody needs actionable data to act upon.  Does it really matter where it is?

Check out Part II of this series

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

A Flash Evangelist Goes to the Dark Side

On Tuesday the 12th, from 6-8:30pm, make sure to get yourself to downtown Portland to the Webtrends Office.  Not only will you get to enjoy the awesome views from the 16th floor you'll be treated to awesome information from the upcoming speaker.  Who is the speaker?

Mike Downey is a Director of Platform Evangelism at Microsoft.  Mike was previously the Principal Evangelist for the Platform Business at Adobe Systems.  His primary focus was on Flash, Flex, and AIR.  Needless to say, the ensuing presentation and conversation should be quit interesting.

If you're interested, and you ought to be, check out the calagator event.

Last piece of advice, don?t drive, park at one of the transit centers and take the MAX downtown.  Life is exponentially simpler that way, and parking is then free and MAX only costs $2 bucks.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: Adron
Posted on: 1/11/2010 at 10:26 AM
Tags: ,
Categories: Events
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (0) | Post RSSRSS comment feed

ASP.NET MVC Scorecard Web Application - Part 3

In this entry I want to cover a helper I wrote and some other bits to simplify creating charts for the scorecard application.

One of the things I wanted to do was get rid of the excessive amount of code needed in the view to generate various charts.  Since at some point I wanted to be able to dynamically create charts based on user input, I figured what better time than now to start chiseling out a helper class for displaying the charts.

Take the pie chart I created in the last entry.  The code in the view looked like this.

using (Chart chartPie = new Chart())
{
    double[] yValues = (double[])ViewData["TopCountryCounts"];
    string[] xValues = (string[])ViewData["TopCountries"];
 
    Title t = new Title("Pie Chart Representation",
        Docking.Top,
        new System.Drawing.Font("Verdana, Helvetica, Sans-Serif", 14, System.Drawing.FontStyle.Bold),
        System.Drawing.Color.FromArgb(26, 59, 105));
    chartPie.Titles.Add(t);
    chartPie.ChartAreas.Add("Default");
 
    // create a couple of series
    chartPie.Series.Add("Default");
    chartPie.Series["Default"].Points.DataBindXY(xValues, yValues);
 
    // Set Doughnut chart type
    chartPie.Series["Default"].ChartType = SeriesChartType.Pie;
 
    // Set labels style
    chartPie.Series["Default"]["PieLabelStyle"] = "Inside";
    // Set Doughnut radius percentage
    chartPie.Series["Default"]["DoughnutRadius"] = "40";
    // Explode data point with label "USA"
    chartPie.Series["Default"].Points[3]["Exploded"] = "true";
 
    chartPie.Width = 400;
    chartPie.Height = 300;
    chartPie.Page = this;
    HtmlTextWriter writer = new HtmlTextWriter(Page.Response.Output);
    chartPie.RenderControl(writer);
}

At 31 lines of code, I was not really stoked about this.  A lot of this, such as creating the title, the chart area, and having a series was something that would be needed by most charts.  With that I went to work writing a set of tests to test the helper class.

public const string title = "Chart Title";
public double[] YValues = {3};
public string[] XValues = {"X Value"};
 
[TestMethod]
public void InstantiateChartHelper()
{
    ChartHelper chartHelper = new ChartHelper("title", YValues, XValues, SeriesChartType.Pie);
    Assert.IsNotNull(chartHelper);
}

This first test and default values, that I assumed I would use for the other tests, got me a nice skeleton class & constructor.  I used ReSharper to flesh it out a little and then went to writing the other tests.  Each contributing a bit more functionality to the overall class.  I have excluded the remaining tests from this blog entry, but they will be available when I provide the solution for download (that means keep reading and stay tuned).  The class however, that ended up with is below.

public class ChartHelper
{
    public ChartHelper(string chartTitle, IEnumerable<double> seriesValues, IEnumerable<string> seriesKeys, SeriesChartType chartType)
    {
        // Setup defaults.
        System.Drawing.Font font = new System.Drawing.Font("Verdana, Helvetica, Sans-Serif", 14, System.Drawing.FontStyle.Bold);
        System.Drawing.Color color = System.Drawing.Color.FromArgb(26, 59, 105);
 
        // Title
        Title title = new Title(chartTitle, Docking.Top, font, color);
       
        // Chart Area
        ChartArea chartArea = new ChartArea("DefaultChartArea");
        chartArea.Area3DStyle.Enable3D = true;
        
        // Series
        Series series = new Series("DefaultSeries");
        series.Points.DataBindXY(seriesKeys, seriesValues);
        series.ChartType = chartType;
 
        ResultingChart = new Chart();
        ResultingChart.Titles.Add(title);
        ResultingChart.ChartAreas.Add(chartArea);
        ResultingChart.Series.Add(series);
        
    }
 
    public Chart ResultingChart { get; set; }
}

As you can see, a nice simple class.  With this class I was then able to use to reduce my lines of code to 9 lines (including the multi-line instantiation, which I suppose could be one line, leaving me with 6).

Scorecard.Views.ChartHelper chartHelper = new Scorecard.Views.ChartHelper("Pie Chart Representation",
   (double[])ViewData["TopCountryCounts"],
   (string[])ViewData["TopCountries"],
   SeriesChartType.Pie);
Chart chartPieTwo = chartHelper.ResultingChart;
 
chartPieTwo.Page = this;
HtmlTextWriter writer1 = new HtmlTextWriter(Page.Response.Output);
chartPieTwo.RenderControl(writer1);

This now generates the following pie chart.

There are a few more defaults I want to set though, so I went ahead and added a logic section for pie charts as shown below, with the switch view to provide a bit of factory style magic.

ResultingChart = new Chart();
 
// Setup defaults.
System.Drawing.Font font = new System.Drawing.Font("Verdana, Helvetica, Sans-Serif", 14, System.Drawing.FontStyle.Bold);
System.Drawing.Color color = System.Drawing.Color.FromArgb(26, 59, 105);
 
// Title
Title title = new Title(chartTitle, Docking.Top, font, color);
ResultingChart.Titles.Add(title);
 
// Chart Area
ChartArea chartArea = new ChartArea("DefaultChartArea") {Area3DStyle = {Enable3D = true}};
ResultingChart.ChartAreas.Add(chartArea);
 
// Series
Series series = new Series("DefaultSeries");
series.Points.DataBindXY(seriesKeys, seriesValues);
series.ChartType = chartType;
ResultingChart.Series.Add(series);
 
// Legend
Legend legend = new Legend("DefaultLegend");
ResultingChart.Legends.Add(legend);
 
switch (chartType)
{
    case SeriesChartType.Bar:
        break;
    case SeriesChartType.Column:
        break;
    case SeriesChartType.Pie:
        series["PieLabelStyle"] = "Inside";
        ResultingChart.Legends[0].Docking = Docking.Bottom;
        ResultingChart.Legends[0].Enabled = true;
        break;
    case SeriesChartType.Funnel:
        break;
    case SeriesChartType.Line:
        break;
    default:
        throw new ArgumentOutOfRangeException("chartType");
}
 
ResultingChart.Width = 400;
ResultingChart.Height = 300;

Notice I also reorganized where some things where instantiated, such as the Chart Object, and organized the order according to each thing I needed to have for the chart.  Once I did this I ran and rendered the chart, which I was happy with for now.

At this point I went back in and added some more charts to my scorecard view.  While I did this I noticed one last thing I ought to refactor.

<table>
<tr>
<td>
    <%
        Scorecard.Views.ChartHelper chartHelper = new Scorecard.Views.ChartHelper("Top Countries",
           (double[])ViewData["TopCountryCounts"],
           (string[])ViewData["TopCountries"],
           SeriesChartType.Pie);
        Chart chartPieTwo = chartHelper.ResultingChart;
 
        // Explode data point with label "USA"
        chartPieTwo.Series["DefaultSeries"].Points[3]["Exploded"] = "true";
 
        chartPieTwo.Page = this;
        HtmlTextWriter writer = new HtmlTextWriter(Page.Response.Output);
        chartPieTwo.RenderControl(writer);
    %>
</td>
<td>
    <%
        chartHelper = new Scorecard.Views.ChartHelper("View Cart Trend",
           (double[])ViewData["LineValues"],
           (string[])ViewData["TopEngines"],
           SeriesChartType.Line);
 
        Chart lineChart = chartHelper.ResultingChart;
 
        lineChart.Page = this;
        lineChart.RenderControl(writer);
    %>
</td>
</tr>
<tr>
<td>
    <%
        chartHelper = new Scorecard.Views.ChartHelper("Yesterday's Page Views",
         (double[])ViewData["ColumnStats"],
         (string[])ViewData["ColumnStatHeaders"],
         SeriesChartType.Column);
 
        Chart columnChart = chartHelper.ResultingChart;
 
        columnChart.Page = this;
        columnChart.RenderControl(writer);
    %>
</td>
<td>
    <%
        double[] theValues = (double[]) ViewData["ColumnStats"];
        double[] newValues = new double[]{0,0,0,0};
        int count = 0;
        foreach(double d in theValues)
        {
            newValues[count] += d*DateTime.DaysInMonth(DateTime.Now.Year, DateTime.Now.Month) +
                                DateTime.Now.Month + DateTime.Now.Millisecond;
            
            count++;
        }
 
        chartHelper = new Scorecard.Views.ChartHelper("Current Month Page Views",
    newValues,
    (string[])ViewData["ColumnStatHeaders"],
    SeriesChartType.Bar);
 
        Chart barChart = chartHelper.ResultingChart;
 
        barChart.Page = this;
        barChart.RenderControl(writer);
    %>
</td>
</tr>
</table>

I was assigning the page and rendering the control at every single section within my table.  I didn't need to do that, so I went back and added a render method to the ChartHelper Class.

public void RenderChart(Page page)
{
    ResultingChart.Page = page;
    HtmlTextWriter writer = new HtmlTextWriter(page.Response.Output);
    ResultingChart.RenderControl(writer);
}

With a small change to the view I can now render each chart with one line of code.

chartHelper.RenderChart(this);

Now that puts everything in a better situation.  Until the next part.  Happy coding.

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Posted by: Adron
Posted on: 1/6/2010 at 5:02 AM
Tags: , , , , ,
Categories: How-To, Samples, and Such
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (4) | Post RSSRSS comment feed