Wading for Answers

As of December 2011, this topic has been archived. As a result, it is no longer actively maintained. For more information, see Archived Content. For information, recommendations, and guidance regarding the current version of Internet Explorer, see Internet Explorer Developer Center.

Mark Davis, Heidi Housten, Dan Mohr, and Kusuma Vellanki
Microsoft Corporation

July 5, 2001

There is much denial in our offices this month. Not about who sent that crate of water balloons—we will uncover that yet—but we are sad to say that Kusuma will be leaving the Web Team. We will miss her quick wit, thoughtful answers, and tales of terrorizing the slopes of Steven's Pass. Unfortunately for the poor souls on the slopes, she will still be living in Redmond. Fortunately for us, she will still be working at Microsoft, so we can still send pranks through interoffice mail.

This month, we return to a little more traditional fare with a couple of answers in DHTML and one on using VML to make line charts. Enjoy the column, savor the summer, and good luck Kusuma!

Contents

Drawing the Line—charting progress with VML
Made in the Shade—shadowing DHTML Menus

Web Team in Short

Drawing the Line

Dear Web Team:

Is there a way (and I'm sure there is!) to display a line graph on an ASP page? Please shed some light on this.

Thanks in advance,
Jay

The Web Team replies:

There sure is a way to draw line charts and it goes by a three-letter acronym (okay, what doesn't?)—VML (Vector Markup Language). It's a markup language with an XML-like syntax that you can use to declaratively create vector images on Web pages. For a good starter sample of creating line graphs with VML, check out Michael Wallent's DHTML Dude column from June 1999. A cool thing to do with something like a VML chart generator would be to wrap it up into a DHTML behavior so it could serve as a handy reusable component. We offered Dan a lifetime supply of Diet Mountain Dew if he could come up with a solution that showed off IE's new viewLink behaviors and met these criteria:

  • It has to be resizable at run-time (that is, it has to work at both large and small sizes and be able to shift between them dynamically).
  • It has to have the capability to correctly clip lines whose data points exceeded its bounds.
  • It has to be able to render points (for the data points), as well as the lines.
  • It has to be performant (within reason).

Though we won't bore you with a line-by-line retelling of how Dan coded the behavior, we'd like to briefly focus on how he went about fulfilling these requirements for the benefit of anyone writing their own behavior from scratch or modifying the sample code below.

When dealing with the issues of VML and size, it is important to pay careful attention to the size of your coordinate space. In most cases, you'll have all your VML elements contained inside a group element for housekeeping purposes. For this group element, there are three logical ways that you could set up a coordinate space: (a) have it be a fixed size (like 10000,10000) for every graph, (b) have it be the extents of the coordinates you'll be graphing, or (c) have it be the same as the pixel dimensions of your chart. With (a) and (b) you run the risk of having fewer coordinates than pixels, which means that you can't draw anything that's one pixel tall—not good. With (c) you wind up having to do a little more work to resize, but the added precision is worth it.

To get the clipping equations correct, it's time to get the high school geometry book out of storage and get ready for some serious SOHCAHTOA action.

The third and fourth requirements are pretty much diametrically opposed because the added work of drawing all the data points severely impacts performance. So, Dan allowed the data points to be toggled on or off and then began optimizing all of the drawing code. First, he ensured that his code was following the tips offered in both Building High Performance HTML Pages and Mark's excellent article A Dozen Tips for Faster DHTML. Next, he rewrote the drawing code to take advantage of window.setTimeout. Not only is setTimeout asynchronous (a perceived performance increase), but it can also be used to batch the drawing so that consecutive modifications to the chart (such as a script which sets the height, as well as the maximum value) do not result in multiple passes through the main drawChart() routine.

Here are links to both the source code for the behavior and a demo page that populates the chart with multiple series of random data points. Note that since this is a viewLink behavior, it will only work in IE 5.5 and above. Also, note that implementation of axis labels and a legend is left as an exercise to the reader.

http://samples.msdn.microsoft.com/workshop/samples/dhtmltechcol/dnwebteam/webteam07022001/Linechart.htc. View the code:

http://samples.msdn.microsoft.com/workshop/samples/dhtmltechcol/dnwebteam/webteam07022001/demoPage.htm. View the sample:

Made In the Shade

Dear Web Team:

Love the column! Real world advice with examples, not too often you see that. The Microsoft Australia Homepage has little menus on the left margin. No rocket science there. The rad thing is that when a menu is selected the child items appear in a box with a shadow on the bottom and right sides. A semi-transparent shadow to boot. This can't be an image because the menus vary in size... or could it? So my question is, how does one implement a similar feature (the shadow, not the menu)?

Clinton 'Bamboozeled' Greer

The Web Team replies:

We got out our rubber boots and went wading through the Microsoft Australia site's source code to unravel this one. This is an elegant bit of code that is implemented using a behavior. The shadow is not some trickery with graphics; it's created by dynamically drawing and cascading DIV tags behind the menu table using document.createElement and setting the size properties to those of the menu table. This method could be used to apply shadows to just about anything. The ShowShadowMenu function accepts three parameters: the item to shadow, the color to shadow with, and the depth of the shadow to draw. The transparency is done by using filters. There is a little clean up code to keep from leaving a trail of shadows. We extracted the key bits that we found and put together the following sample for your reading pleasure. We also tossed in an example of how to place the table where the mouse click occurred using the event object. We hope you enjoy the elegance of this solution as much as we enjoyed fishing it out.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<TITLE>Shadowy Tables</TITLE>
<STYLE>
BODY {color:#FF0000;font-size:20}
.menubar { background-color: #0000FF; position:absolute; color:"white";}
</STYLE>
<SCRIPT LANGUAGE=javascript>

var global = window.document
global.shadows = new Array

function ShowShadowMenu(el, color, depth)
{
   var i;

    // Tidy up any previous shadows
   for (i=0; i<global.shadows.length; i++)
      global.shadows[i].removeNode(true);
   global.shadows = new Array();

   //place the menu where the mouse is and show it
   el.style.left = window.event.x
   el.style.top = window.event.y
   el.style.display = "block"

   //draw a series of cascading rectangles to create shadow
   for (i=depth; i>0; i--)
   {
      var rect = document.createElement('div');
      var rs = rect.style
      rs.position = 'absolute';

      //offset this shadow from the table
      rs.left = (el.style.posLeft + i) + 'px';
      rs.top = (el.style.posTop + i) + 'px';
      rs.width = el.offsetWidth + 'px';
      rs.height = el.offsetHeight + 'px';

      //put rectangle behind the table
      rs.zIndex = el.style.zIndex - i;
      rs.backgroundColor = color;

      //make the shadow transparent
      var opacity = 1 - i / (i + 1);
      rs.filter = 'alpha(opacity=' + (100 * opacity) + ')';

      //add shadow to document
      el.insertAdjacentElement('afterEnd', rect);

      //save this shadow for later removal
      global.shadows[global.shadows.length] = rect;
   }
}

</SCRIPT>

</HEAD>

<BODY BGCOLOR="#FFFFFF" >
<DIV STYLE="width:250" ONCLICK="ShowShadowMenu(TMenu,'#0000AA',4)">
<B> click me! click me! click me! click me! click me! click me!</B>
</DIV>
<TABLE CLASS="menubar" ID="TMenu" STYLE="display:none" >
<TR ALIGN="left" VALIGN="middle">
   <TD>Peek a boo!</TD>
</TR>
</TABLE>
</BODY>
</HTML>

Web Team in Short

Take Me Home

Q: Debby would like to create a link on her Web site that has the same functionality as the home button.

A: Use HREF="about:home" or check out the default homePage behavior provided by Internet Explorer 5 and greater.

Supreme Combo

Q: Matt Jay wants to create a combo box like in Visual Basic.

A: You can find not one, but two solutions in our previous issue.

Drop a Line

Q: Sriram Parthasarathy wants to send formatted text as a body using the mailto protocol, and would also like to know the limit of the mailto URL.

A: Per RFC 2368, the mailto URL is primarily intended for generation of short text messages that are actually the content of automatic processing (such as "subscribe" messages for mailing lists), not general MIME bodies. If using CDONTS is an option, check out Q189945.

Plug for Plug-ins

Q: Greg Banse is wondering why the document.plugins collection does not work in Internet Explorer

A: The plug-ins collection is only present for compatibility with other browsers, but there is no public standard for plug-ins. Use the embeds collection instead in Internet Explorer.

Managing Security

Q: George Loo wants to prevent scripting and ActiveX® controls from running in the Web browser object hosted in an MFC application.

A: You can achieve this by implementing a custom security manager and responding to the ProcessUrlAction method appropriately. Refer to the sample in Q246227.

Save Me Not

Q: Paul Fahey wants to prevent users from saving images on his site.

A: The simplest solution is to cancel the oncontextmenu event of the document by setting window.event.returnValue to false if the srcElement is an image. This way you don't have to handle this event for every image tag. Make sure your check for the image tag is case insensitive. For example, using JavaScript,
if (window.event.srcElement.tagName.toUpperCase() == "IMG").

The Web Team

Mark Davis is a software design engineer on the Internet Explorer SDK team. Mark originates from England and is currently training to climb the major summits in the Northwest.

Heidi Housten works as a Consultant with Microsoft Consulting Services in Sweden after spending some time in Developer Support and MSDN. It is only a rumor that she moved there to escape the drizzle of Seattle; she really went for the traditional crayfish parties in August.

Dan Mohr, an engineer with Microsoft Developer Support's Internet Client team, spends his free minutes recording bands in his basement, programming his Commodore 64, and extolling the virtues of late '70s punk rock.

Kusuma Vellanki is one of the few people who likes winters in Washington better than summers. When not working as a developer for the Internet Client team, she can be found skiing down the slopes of Washington.


The Web Team's Greatest Hits

List of Web Team Topics


  
Show: