Charts (Part II)

All right, as promised, here’s the code that gets rid of the jagged edges of the chart we created using Office Web Components. It's hackish, so if you're against that sort of thing, run away.

What we do is basically get the chart as a very large image (1500×1500, for example) and then create a high-resolution thumbnail out of it (300×300, for example) via GDI+. The over-caffeinated reader would wonder why we bothered with office web components in the first place; why didn’t we simply use GDI+ to create the chart? There’s no good reason, really, other than that I wanted to tinker with office web components, which I’ve never used before. ;-) So, without further ado, here’s the code:

//Get the picture
byte[] imageBuffer =
    (byte[])chartSpace.
    GetPicture(“gif”, 1500, 1500);

MemoryStream ms =
    new
    MemoryStream(imageBuffer);

Bitmap original =
    (Bitmap)Bitmap.FromStream
    (ms, true, true);


//Create the thumbnail
Bitmap thumbnail =
    new Bitmap(300, 300);

Graphics g = Graphics.
    FromImage(thumbnail);

g.InterpolationMode =
    InterpolationMode.HighQualityBilinear;

g.DrawImage(
    original,
    new Rectangle
        (0, 0, 300, 300),
    0,
    0,
    1500,
    1500,
    GraphicsUnit.Pixel);

g.Dispose();

//Send the image to
    the browser
Response.
    ContentType = “image/gif”;

thumbnail.Save
     (Response.OutputStream, ImageFormat.Jpeg);

Pretty self-explanatory, so I won’t bore you with an explanation.

Encrypting Web.Config

I typically store at least one sensitive item in the web.config file: namely, the connection string to my database. There are several ways to protect your web.config file from falling into the wrong hands (for example, you can explicitly forbid ASP .NET from serving .config files or you can redirect users to a “You stink” page using HttpHandlers). But imagine for a moment that the worst happened and that somehow an attacker got hold of your web.config file. Now what? Obviously, we would like it if sensitive parts of the web.config file look like complete gibberish so that the cracker feels like an utter idiot for wasting all the time trying to get the file.

Encrypting the web.config file is, apparently, not only entirely possible but also ridiculously easy. Enter — drumroll please — aspnet_regiis.

All you need to do is type in…

aspnet_regiis -prov DataProtectionConfigurationProvider -pef [the name of the configuration setting that you want to encrypt; for example, connectionStrings] [location of the folder in which your web.config resides; for example, C:Website1]

–prov — what provider to use

–pef [section name] [location of config file] — what section to encrypt (using the provider mentioned above) and the >location of the .config file

...in cmd prompt and wait a couple of seconds while your configuration file gets encrypted. Load up web.config and you should see something like:

<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAM85VV82faE2ocurvYx6Z4gmoreincomprehensiblegarbagehereitg6XOFiehAkVwulqACFAAAAEZTASYdjIvoIiAR3yzotHc6z8E5</CipherValue>

Accessing the connection string, however, is no different after you encrypt than before. That is, you would still get your connection string as follows:

string connStr=ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;

Note that it’s also possible to encrypt web.config programmatically (go down to step5).

Creating Charts with .NET Reports

The Problem

You have a stored procedure that returns the number of products you sold each day from a given date 'til today. You want to allow the user to pick the given date. You're a nice person and figure that you'll make the users' lives easier by showing the data in a nice little graph instead of just dumping the information in an ugly table. But you don't want to spend a lot of time doing this. Oh, and you have to use .NET's Reporting Services because, umm, you have to. ####The Solution

Assuming you already have a shared data source and data set configured and the stored procedure all working:

Drop a chart onto the page from the Toolbox.

Drop the x-axis category (probably the date) into the box below the chart that says "Drop category fields here" and drop your data fields (number of products sold each day, for example) into the box above the chart that says "Drop data fields here."

And that's pretty much it for creating the chart. To allow the user to pick the date: right-click on the document ("document" as in "not the page" as in "the yellow thing and not the white thing") and select "Report Parameters" and enter the name (same as the parameter in the stored procedure), the data type, and the label and that pretty much is it. Go to the "Preview" section and see your chart.

Creating Charts in ASP .NET with Office Web Components

In this article, we’re going to learn how to create the chart shown above on-the-fly using ASP .NET and Microsoft Office Web Components.###Step 1: Add a Reference to Microsoft Office Web Components to the Project

The very first thing to do to use MS Office to create eye-catching charts is to add a reference to the Microsoft Office Web Components dll. So go ahead and create a brand new web project imaginatively called “OfficeWebComponents.” MS Office means COM, so when you go to add a reference, you need to go over to the COM tab. Scroll down until you find the right dll, select it, and click OK.

If you have Office running on the machine, then you probably have this .dll already installed. If you don’t, you will have to get it from Microsoft.

Step 2: Write the Code

Don’t forget to add using OWC11; to your code-behind.

Before I explain it, here’s the code:

public partial class _Default :
 System.Web.UI.Page
{
 protected void Page_Load(object sender,
  EventArgs e)
 {
  string[] chartCategories = new string[]
  {
   “Luke Skywalker”,
   “Mara Jade”,
   “Leia Organa Solo”,
   “Mace Windu”,
   “Han Solo”,
   “Anakin Skywalker”,
   “Depa Billaba”,
   “Yoda”
  };

  string[] chartValues = new string[]
  {
   “5″,
   “-50″,
   “3.5″,
   “30″,
   “5″,
   “-20″,
   “20″,
   “0″
  };

  //The charting component wants its categories and
  // deliminated values tab.
  string chartCatsAsString = String.Join(“t”, chartCategories);
  string chartValuesAsString = String.Join(“t”, chartValues);

  //Create the charting workspace
  OWC11.ChartSpaceClass chartSpace = new OWC11.ChartSpaceClass();

  //Create the chart itself 
  OWC11.ChChart theChart = chartSpace.Charts.Add(0);

  //Set the type of the chart
  theChart.Type = OWC11.ChartChartTypeEnum.chChartTypeColumnClustered;

  //Add the chart’s title 
  theChart.HasTitle = true;
  theChart.Title.Caption = "Indecipherable Star Wars Graph";

  //Populate the indecipherable data
  theChart.SeriesCollection.Add(0);

  //Add the categories
  theChart.SeriesCollection[0].SetData(
   OWC11.ChartDimensionsEnum.chDimCategories,
   (int)OWC11.ChartSpecial.DataSourcesEnum.chDataLiteral,
   chartCatsAsString);

  //Add the values
  theChart.SeriesCollection[0].SetData(
   OWC11.ChartDimensionsEnum.chDimValues,
   (int)OWC11.ChartSpecial.DataSourcesEnum..chDataLiteral,
   chartValuesAsString);
   //Show the chart to the client as a GIF image (400×400)

  Response.ContentType = “image/gif”;
  Response.BinaryWrite((byte[])chartSpace.GetPicture(“gif”, 400, 400));
  Response.End();
 }
}

The code is actually pretty-self explanatory (with my comments at least ;-) ). Rather than bore you by going through the same code again, here’s some information that’s not in the code:

  • You add the chart’s legend the same way you add the title: you set the HasLegend property to true and then set the legend.

  • There are a number of ways to display your chart — everything from pie-graphs to scatter-plots.

  • Your category names and values can’t have any commas in them — the charting component seems to deliminate the string at commas as well as tabs.

  • You can save the chart as an image, too; you aren’t limited to sending the image back to the browser.

  • If you have fewer or more categories than values, you don’t get an error — the chart gets rendered with the extra category/value.

Real Life Uses

In real life, we’re obviously not going to have hard-coded categories and values in your code-behind. We’re probably going to get them from the database. This works just fine. For example, suppose you want to figure out how much time you spent each day working on a certain project. These numbers might be stored in a database or an XML file. All you do is simply read the numbers into a values array, and the days into a categories array; join them into a string just like we did in the example, and then go on from there.

Getting All the Links on a Page

One thing I keep having to do again and again (why???) is extract links from a webpage. I recently created a tiny application that gives you the list of all the links on a given web page, and I thought I’d share it with everyone. Given the url of the page, the first thing to do is to get the source code of the page so that we can screen it for links. There are a couple of ways to do this, but the easiest way, as far as I’m aware of, is to use a WebClient object:

WebClient webClient = new WebClient();

//Get the HTML from the given page byte[] response_html = webClient.DownloadData(url);

UTF8Encoding utf8 = new UTF8Encoding();

string html = utf8.GetString(response_html);

Read more about the WebClient class at MSDN.

Now that we have the source code, the next thing to do is search for all the links. You can do this the hard way — i.e., use the String class’ IndexOf function and hack your way out of the predicaments that come your way (and trust me, there are quite a few of them).

The easy way is to use regular expressions.

The pattern for matching the href = "wherever.whatever" (i.e., the url) part of a link is: href\s=\s(?:"(?<1>[^"]*)"|(?<1>\S+)). Looks a little ugly, but the point is that it works in 90% of the cases. What that regular expression actually means is the subject of another article, but suffice to say, it works.

So, the code then:

private void GetLinks(string url) { //using System.Net WebClient webClient = new WebClient();

     //Get the HTML from the given page
     byte[] response_html = webClient.DownloadData(url);

     //using System.Net
     UTF8Encoding utf8 = new UTF8Encoding(); 

     string html = utf8.GetString(response_html);

//using System.Text.RegularExpressions Regex r = new Regex ("hrefs=s(?:"(?<1>[^"]*)"|(?<1>S+))", RegexOptions.IgnoreCase | RegexOptions.Compiled);

     //using System.Text.RegularExpressions
     //Get all the matches
     MatchCollection mcl = r.Matches(html);

     //using System.Collections
     ArrayList a = new ArrayList(); 

     foreach (Match m in mcl)
         a.Add(m.Value);

//A gridview object grdLinks.DataSource = a; grdLinks.DataBind(); }

Changing Windows Icons Without 3rd Party Applications

Today, we’re going to learn such vitally important things as changing the folder icons in Windows XP. And no, you don’t actually need to install 3rd party applications to tweak your icons. You just need to know where to go to change most of the icons; changing the default folder icon, however, is a bit more complicated, but not much.

Let’s start with the easy part:

Changing Desktop Icons

Right click on your My Computer icon and select Properties. Go to the Desktop tab and click the Customize Desktop button (below the list of wallpapers you can choose for your background). As might be self-evident from the screen, you basically click on each unhappy icon in the middle, click the Change Icon button and point the file browser to the proper location of your new happy icon.

Changing Other Icons

What if you want to change the Microsoft Word Document icon or your mp3 icon or maybe even your open folder icon? It’s very easy. Double click on your My Computer folder (or practically any other folder, for that matter). Go to Tools » Folder Options » File Types. Once again what you need to do is rather obvious. If you scroll down the list of the registered files, you find that there’s practically everything in there, including the open folder one and the normal folder one. To change the icon, you basically do the same thing you do above: click the icon that you want to change, click the Advanced button, click the Change Icon button in the dialog that pops up and point to your new icon.

Changing the Default Folder Icon

If you tried to follow the method mentioned just above this paragraph to change the default folder icon, you might have noticed that the method…err, failed. For some odd reason, Windows doesn’t give you an easy way to change the default folder icon, which kind of sucks, because I rather dislike the default folder icon. It looks particularly ugly when compared to all my new icons. So, after some researching and much head-banging, I found out that there was a pretty easy way to change the default folder icon.

Open up your registry editor(Start » Type in "regedit" in the textbox of the dialog that pops up). Navigate to HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Windows / Current Version / Explorer / Shell Icons. Find the registry file called 3. Right-click on it and select Modify in the menu. Type in the path to the location of your new icon, click OK, and restart the computer. That’s it! You have a new default folder icon. :-) (Sometimes, though, you might need to refresh the icon cache for your new icon to turn up.)

Repairing Corrupted Registry File (If It Gets Corrupted, That Is)

As I was doing this, however, I encountered a strange problem — whenever I double-clicked on a folder, instead of opening the folder, Windows opened the search page instead?? Bizarre. I thought I had unrepairably screwed my operating system until I found out that sometimes the responsible registry gets corrupted. The site provides a fix [.vbs file] and how to go about using said file, but in case you don’t want to run the file, you can also repair your registry file manually:

Open up your registry editor (Start » Type in "regedit" in the textbox of the dialog that pops up). Navigate to HKEY_CLASSES_ROOT/Directory/shell. Now right-click on the Default registry file you can see in the right panel and select Modify from the menu. For the Value Data, set the value to be none. This worked for me.

Now, if this tutorial means that you’ve run out of excuses to not go icon-hunting… ;-)

Sql Transactions 101

Transactions allow you to batch a set of SQL so that all of them either succeed or fail together.

In .NET, it's especially easy to create transactions — using SqlTransaction.Suppose you have a monkey object and a fingers object. When you create a monkey, you would of course want to create the monkey’s fingers, as well. And so, you first create the monkey object, get the ID of that object, and then go create the fingers.

The code might go something like this:

public void CreateMonkey() { Monkey monkey = new Monkey();

monkey.Id = Guid.NewGuid();

//Set other monkey data here

bool result = Insert(monkey);

if (result) { Fingers fingers = new Fingers(10);

monkey.Hand.Fingers = fingers;

result = Insert(monkey.Hand.Fingers);

if (result) Console.WriteLine("Success! Good job!");

else Console.WriteLine("Failure! Dismal, just dismal!"); } }

You’ll run into problems when you use this kind of code, as might be obvious to you already. Suppose you successfully created the monkey, but for some odd reason, creating the fingers failed. What now? You have a monkey without fingers running around, which is sad for the monkey and creepy for us humans.

Yes, this is exactly where transactions come in. Transactions let you batch SQL statements together so that either all of them succeed or all of them fail. So, if you were using transactions, you’d either get “no monkey and no fingers” or “a monkey with fingers.”

.NET 2.0 makes it especially easy to use transactions. ;-) I recently had to work with them, and I was impressed with how intuitive they were.

When you want to use a transaction, you basically need to follow the following steps:

  1. Create a SqlTransaction object
  2. Create a SqlTransaction object
  3. Link the transaction to the SqlConnection before running the first SQL statement of the batch.
  4. Link the transaction to the SqlCommand object of each of the SQL statement of the batch.
  5. If everything succeeds, commit the transaction. If there’s an error, rollback the transaction.

So, the modified code:

public void CreateMonkey() { //Need to initialize it to null because otherwise .NET will // complain that we're using an uninitialized object. SqlTransaction tr = null;

SqlConnection cn = new SqlConnection ("ConnectionString");

try { cn.Open();

tr = cn.BeginTransaction();

string sqlInsertMonkey = "Insert Monkey into database";

SqlCommand cmd = new SqlCommand(sqlInsertMonkey, cn, tr);

if (cmd.ExecuteNonQuery() == 0) throw new Exception("Failed to insert monkey");

string sqlInsertFingers = "Insert Monkey's fingers into database";

cmd = new SqlCommand(sqlInsertFingers, cn, tr);

if (cmd.ExecuteNonQuery() == 0) throw new Exception("Failed to insert fingres");

cmd.ExecuteNonQuery();

//Everything executed successfully, so commit the //transaction tr.Commit();

//Close the SqlConnection cn.Close(); }

catch (Exception ex) { //We need to check this, because the exception might //not be SQL related at all; i.e., the transaction //could have completed successfully and we could //be here because of some other problem. if (tr != null) { tr.Rollback(); cn.Close(); }

//Show the appropriate error message here } }

It’s that easy! :-)

Tips to Make Tabular Data More Readable

An unstyled table is like nails on blackboard, more so than any other part of the web page. It’s especially important to style the table in a pleasant manner when you have lots of data to present. Imagine if your table contains a couple of hundred elements. Pretty soon all the rows start to blur together. It’s extremely frustrating to the user, and frustrated users are bad for business.###Zebra Tables

One common method used to increase table-readability-and-usability is by highlighting the alternate rows with a different color:

Zebra Tables Example

I use this technique quite a lot, and one of the frustrating things is that when you hard-code which rows are alternate (by adding the class = “alt” directive to the row itself), it becomes a nightmare if you have to change the order of the rows for some reason. This is something that happens a lot to me while the application is still in development. One easy way to “fix” this is by using javascript to add the “alt” class to the alternate rows on the fly:

function highlightAlt()
{
    var theTable = document.getElementById("theTableId");

    var theTRs = theTable.getElementsByTagName("tr");

    for(var i = 0; i &lt; theTRs.length; i += 2)
    {
        var currTR = theTRs<i>;

        //The space is here to set it off from any other
        //classes the tr might belong to
        currTR.className += " alt";
    }

}

Highlighting Row When User Clicks On It

Suppose you have a table that has a hundred elements. The user selects whatever rows he wants (via checkboxes) and then clicks a button at the bottom to perform an action. While the checked checkboxes in the row might provide clue to what rows she selected, it pays to make it more obvious by highlighting it. Javascript to rescue again:

function highlightOnClick()
{
    var theTable = document.getElementById("theTableId");

    var theTRs = theTable.getElementsByTagName("tr");

    for(var i = 0; i &lt; theTRs.length; i++)
    {
        var currTR = theTRs<i>;

        currTR.onclick = function()
        {
            if(this.active == true)
            {
                var index = this.className.indexOf(" clicked");
                this.className = this.className.substr(0, index);
                this.active = false;
            }

            else
            {
                this.className += " clicked";
                this.active = true;
            }
        }
    }
}

I’m sure there’s a much easier way to replace “clicked” with an empty string. But as I’m a newbie javascript coder, I couldn’t make anything else to work. I wasted a lot of time with the Replace() function but that refused to work.

Allow User to Select a Row By Clicking Anywhere on the Row

The checkbox is a small tiny thing that’s stuck somewhere at the very left or right of the row. It makes the users’ life a lot simpler and happier if they can select the checkbox by clicking anywhere on the row, and I’m all for making users happier, especially as I need to add only 4 extra lines to the code in Listing 2 to make it everything work.

The updated code, then:

function highlightOnClick()
{
    var theTable = document.getElementById("theTableId");

    var theTRs = theTable.getElementsByTagName("tr");

    for(var i = 0; i &lt; theTRs.length; i++)
    {
        var currTR = theTRs<i>;

        currTR.onclick = function()
        {
            if(this.active == true)
            {
                var index = this.className.indexOf(" clicked");
                this.className = this.className.substr(0, index);
                this.active = false;

                var chk = this.getElementsByTagName
                            ("input")[0];
                chk.checked = false;

            }

            else
            {
                this.className += " clicked";
                this.active = true;

                var chk = this.getElementsByTagName
                            ("input")[0];
                chk.checked = true;
            }
        }
    }
}

It’s a good idea to keep in mind accessibility rules as you create your tables. I’m not going to mention styling the headers, because that’s something most people do by themselves. For alternate row color, it’s a good idea to use faded colors so that it doesn’t get in the user’s way. #dddddd and eeeeee are my favorite. ;-)

16 of 16 pages « First  <  14 15 16

On the Side