HOWTO: Use Custom Layout and Drawing with the Office Chart Component (290348)



The information in this article applies to:

  • Microsoft Office 2003 Web Components
  • Microsoft Office XP Web Components

This article was previously published under Q290348

SUMMARY

The Office XP Chart component and the Office 2003 Chart component expose functionality that enables you to position various objects in the Chartspace and to add custom text and drawings to the Chartspace at run time. This article describes how to implement custom layout and drawing with the Office XP Chart component and the Office 2003 Chart component with a code sample.

MORE INFORMATION

To position and size the various objects in a Chartspace, you must first set the AllowLayoutEvents property of the Chartspace to True. This allows you to handle the AfterLayout event, which is triggered after all chart objects have been laid out but before they are rendered. In this event, you can position and size chart objects, such as chart plot areas, legends, and titles.

To draw lines, shapes, and text in a Chartspace, set the AllowRenderEvents property of the Chartspace to True. This enables you to access the chart drawing object (ChChartDraw) in the BeforeRender, AfterRender, and AfterFinalRender events.
  • The BeforeRender event is triggered before each object in the Chartspace is rendered. In this event, you can query the ChartObject parameter to determine which chart object is about to be rendered so that you can add custom drawings to the chart that appears behind the object in the Chartspace but on top of objects already rendered. You can also choose to cancel the rendering of certain objects in the Chartspace by setting the Cancel parameter to True.
  • The AfterRender event is triggered after each object in the Chartspace is rendered. In this event, you can query the ChartObject parameter to determine which chart object was rendered so that you can add custom drawings to the chart that appears on top of the object in the Chartspace; the drawing appears behind any objects rendered later.
  • The AfterFinalRender event is triggered after all objects in the Chartspace have been rendered. Custom drawings that you create in this event appear on top of all other objects in the Chartspace.

Sample

The following sample demonstrates how you can handle the layout and render events to create a customized chart. The sample works in the following manner:
  1. Builds a standard column chart using literal data, and sets both the AllowLayoutEvents and AllowRenderEvents to True.
  2. After the initial chart is laid out, but before any objects in the chart are rendered, the AfterLayout event is handled to position and size the chart's plot area.
  3. Before the plot area is rendered, the BeforeRender event is handled to draw a rectangle with a texture. The rectangle is drawn before the axes, gridlines, and columns are rendered; therefore, the rectangle appears as a backdrop to those objects in the chart.
  4. After the gridlines are rendered, the AfterRender event is handled to draw a horizontal line that represents the average value of the columns in the chart. The line is drawn so that it lies in the correct location with respect to the value axis. Because the line is rendered after the gridlines but before the columns in the chart, the custom line appears behind the columns.
  5. Several additional items are drawn during the AfterFinalRender event so that the items are drawn on top of all other objects in the Chartspace:
    • a "callout" for the data point with the lowest value (the callout is comprised of a line with an arrowhead and an ellipse containing text). The coordinates for the specific data point are retrieved by using the GetValue method.
    • two lines of text at the bottom of the Chartspace. The lines of text are drawn in different font styles and act as a chart title with subtext. The TextWidth property of the drawing object is used to determine the width of the text before it is drawn so that it may be centered in the Chartspace.

Picture of Custom Chart Generated By Sample Code

To try the sample, save the following code as an HTML file, and then browse to the HTML file in Internet Explorer (IE). On the Web page that is rendered, click Build the Chart to create a column chart with drawings and custom text. Click Build the Chart twice more to observe different color schemes for the chart.
<html>

<body>
<p align="center"/>
<button id="BuildChart">Build the Chart</button>
<br/><br/>
<object classid="clsid:0002E556-0000-0000-C000-000000000046" id="WebChart">
</object>
</body>

<script language="VBScript">

Dim oChart, c
Dim aSales(3)
Dim nPlotTop, nPlotLeft, nPlotRight, nPlotBottom
Dim aScheme
Dim Counter

Set c = WebChart.Constants

Function BuildChart_OnClick()
       
    'Choose a color scheme.
    Counter = Counter + 1
    Select Case (Counter Mod 3)
    Case 0: aScheme = Array(c.chTextureCanvas, c.chTextureParchment, "OldLace", "SaddleBrown")
    Case 1: aScheme = Array(c.chTextureDenim, c.chTextureBlueTissuePaper, "MintCream", "Navy")
    Case 2: aScheme = Array(c.chTextureOak, c.chTexturePapyrus, "navajowhite", "black")
    End Select
    
    'Create a column chart with one series.
    WebChart.Clear
    Set oChart = WebChart.Charts.Add
    oChart.PlotArea.Interior.Color = c.chColorNone
    With oChart.SeriesCollection.Add
        .SetData c.chDimCategories, c.chDataLiteral, Array("Qtr1", "Qtr2", "Qtr3", "Qtr4")
        Randomize Time
        Dim i
        For i = 0 To 3
            aSales(i) = Rnd * 100000
        Next
        .SetData c.chDimValues, c.chDataLiteral, aSales
        .Interior.SetTextured aScheme(0)
    End With
    oChart.PlotArea.Border.Color = c.chColorNone
    
    'Allow Render events to get a handle on the ChChartDraw object so that custom lines,
    'shapes and text can be drawn on the chart.
    WebChart.AllowRenderEvents = True
    
    'Allow layout events so that the chart's plot area can be repositioned and resized.
    WebChart.AllowLayoutEvents = True

End Function    

Function WebChart_AfterLayout(drawObject)

    'Resize the chart's plot area to provide room at the top, bottom, and
    'right of the chart for custom drawn shapes and text.
    nPlotTop = oChart.PlotArea.Top + 50
    oChart.PlotArea.Top = nPlotTop
    nPlotBottom = oChart.PlotArea.Bottom - 80
    oChart.PlotArea.Bottom = nPlotBottom
    nPlotRight = oChart.PlotArea.Right - 100
    oChart.PlotArea.Right = nPlotRight
    nPlotLeft = oChart.PlotArea.Left + 20
    oChart.PlotArea.Left = nPlotLeft
    
End Function

Function WebChart_BeforeRender(drawObject, chartObject, Cancel)

    'Draw a textured rectangle for the backdrop of the chart before the plot area is rendered.
    If TypeName(chartObject) = "ChPlotArea" Then
        drawObject.Interior.SetTextured aScheme(1)
        drawObject.Border.Weight = 2
        drawObject.Border.Color = aScheme(3)
        drawObject.DrawRectangle 10, 10, oChart.Right - 10, oChart.Axes(c.chAxisPositionBottom).Bottom
    End If
    
End Function

Function WebChart_AfterRender(drawObject, chartObject)

    'After the gridlines are rendered, draw a line in the plot area that represents the average
    'of the data points. Note: The line is drawn after the gridlines but before the data points
    'are drawn so that the line appears behind the data points.
    
    If TypeName(chartObject) = "ChGridlines" Then
        Dim nAvg
        nAvg = (aSales(0) + aSales(1) + aSales(2) + aSales(3)) / 4
        Dim nIncrement, nAvgLineY
        nIncrement = (nPlotBottom - nPlotTop) / ( _
            oChart.Scalings(c.chDimValues).Maximum - oChart.Scalings(c.chDimValues).Minimum)
        nAvgLineY = nPlotBottom - nIncrement * nAvg
        drawObject.Line.DashStyle = c.chLineDashDotDot
        drawObject.Line.Color = aScheme(3)
        drawObject.Line.Weight = 4
        drawObject.DrawLine nPlotLeft + 1, nAvgLineY, nPlotRight - 1, nAvgLineY
        
        'Add text at the right of the drawn line to display the value it represents.
        drawObject.Font.Color = aScheme(3)
        Dim sText
        sText = "Avg = " & CLng(nAvg)
        drawObject.DrawText sText, nPlotRight + 10, nAvgLineY - drawObject.TextHeight(sText) / 2   
    End If
    
End Function

Function WebChart_AfterFinalRender(drawObject)

    Dim sText
    
    'Draw a vertical line at the data point with the smallest value (the minimum).
    Dim oPoint, oCoord
    Dim nMinPoint
    nMinPoint = 0
    Dim i
    For i = 1 To 3
        If aSales(i) < aSales(nMinPoint) Then nMinPoint = i
    Next
    Set oPoint = oChart.SeriesCollection(0).Points(nMinPoint)
    Set oCoord = oChart.SeriesCollection(0).ValueToPoint( _
        oPoint.GetValue(c.chDimCategories), oPoint.GetValue(c.chDimValues))
    drawObject.DrawLine oCoord.x, nPlotTop - 10, oCoord.x, oCoord.y
    
    'Draw an arrowhead for the line.
    drawObject.Interior.Color = "black"
    drawObject.DrawPolygon Array(oCoord.x, oCoord.x + 5, oCoord.x - 5, oCoord.x), _
                           Array(oCoord.y, oCoord.y - 12, oCoord.y - 12, oCoord.y)
                           
    'Draw an ellipse with text inside of it (a callout for the line with the arrowhead).
    Dim nWidth, nHeight, nPaddingX, nPaddingY
    sText = "The Minimum"
    nWidth = drawObject.TextWidth(sText)
    nHeight = drawObject.TextHeight(sText)
    nPaddingX = 20
    nPaddingY = 5
    drawObject.Interior.Color = aScheme(2)
    drawObject.DrawEllipse oCoord.x - nWidth / 2 - nPaddingX, nPlotTop - 10 - nHeight - nPaddingY, _
                           oCoord.x + nWidth / 2 + nPaddingX, nPlotTop - 10 + nPaddingY
    drawObject.DrawText sText, oCoord.x - nWidth / 2, nPlotTop - 10 - nHeight
    
    'Draw two separate lines of custom text beneath the plot area and center the text.
    'with the chart space
    drawObject.Font.Size = 16
    drawObject.Font.Bold = True
    sText = "Custom Chart Text"
    drawObject.DrawText sText, _
        (WebChart.object.Right - WebChart.object.Left) / 2 - drawObject.TextWidth(sText) / 2, _
        nPlotBottom + 40
    drawObject.Font.Size = 9
    drawObject.Font.Bold = False
    drawObject.Font.Color = aScheme(3)
    sText = "Additional custom chart text that is a subtitle"
    drawObject.DrawText sText, _
        (WebChart.object.Right - WebChart.object.Left) / 2 - drawObject.TextWidth(sText) / 2, _
        nPlotBottom + 70
    
End Function

</script>
</html>
				

REFERENCES

For more information about the Office Web components, see the following Microsoft Web sites:

Using Office Web Components

Microsoft Office Developer Center

(c) Microsoft Corporation 2001, All Rights Reserved. Contributions by Lori B. Turner, Microsoft Corporation.


Modification Type:MinorLast Reviewed:8/23/2005
Keywords:kbgraphxlinkcritical kbhowto kbOfficeWebChart KB290348