ChartDirector 7.0 (ASP/COM/VB Edition)
Histogram with Bell Curve
Source Code Listing
<%@ language="vbscript" %>
<%
Set cd = CreateObject("ChartDirector.API")
'
' This example demonstrates creating a histogram with a bell curve from raw data. About half of the
' code is to sort the raw data into slots and to generate the points on the bell curve. The
' remaining half of the code is the actual charting code.
'
' Generate a random guassian distributed data series as the input data for this example.
Set r = cd.RanSeries(66)
samples = r.getGaussianSeries(200, 100, 10)
'
' Classify the numbers into slots. In this example, the slot width is 5 units.
'
slotSize = 5
' Compute the min and max values, and extend them to the slot boundary.
Set m = cd.ArrayMath(samples)
minX = Int(m.min() / slotSize) * slotSize
maxX = Int(m.max() / slotSize) * slotSize + slotSize
' We can now determine the number of slots
slotCount = Int((maxX - minX) / slotSize + 0.5)
ReDim frequency(slotCount - 1)
' Count the data points contained in each slot
For i = 0 To UBound(samples)
slotIndex = Int((samples(i) - minX) / slotSize)
frequency(slotIndex) = frequency(slotIndex) + 1
Next
'
' Compute Normal Distribution Curve
'
' The mean and standard deviation of the data
mean = m.avg()
stdDev = m.stdDev()
' The normal distribution curve (bell curve) is a standard statistics curve. We need to vertically
' scale it to make it proportion to the frequency count.
scaleFactor = slotSize * (UBound(samples) + 1) / stdDev / Sqr(2 * 3.1416)
' In this example, we plot the bell curve up to 3 standard deviations.
stdDevWidth = 3.0
' We generate 4 points per standard deviation to be joined with a spline curve.
bellCurveResolution = Int(stdDevWidth * 4 + 1)
ReDim bellCurve(bellCurveResolution - 1)
For i = 0 To bellCurveResolution - 1
z = 2 * i * stdDevWidth / (bellCurveResolution - 1) - stdDevWidth
bellCurve(i) = Exp(-z * z / 2) * scaleFactor
Next
'
' At this stage, we have obtained all data and can plot the chart.
'
' Create a XYChart object of size 600 x 360 pixels
Set c = cd.XYChart(600, 360)
' Set the plotarea at (50, 30) and of size 500 x 300 pixels, with transparent background and border
' and light grey (0xcccccc) horizontal grid lines
Call c.setPlotArea(50, 30, 500, 300, cd.Transparent, -1, cd.Transparent, &Hcccccc)
' Display the mean and standard deviation on the chart
Call c.addTitle("Mean = " & c.formatValue(mean, "{value|1}") & ", Standard Deviation = " & _
c.formatValue(stdDev, "{value|2}"), "Arial")
' Set the x and y axis label font to 12pt Arial
Call c.xAxis().setLabelStyle("Arial", 12)
Call c.yAxis().setLabelStyle("Arial", 12)
' Set the x and y axis stems to transparent, and the x-axis tick color to grey (0x888888)
Call c.xAxis().setColors(cd.Transparent, cd.TextColor, cd.TextColor, &H888888)
Call c.yAxis().setColors(cd.Transparent)
' Draw the bell curve as a spline layer in red (0xdd0000) with 2-pixel line width
Set bellLayer = c.addSplineLayer(bellCurve, &Hdd0000)
Call bellLayer.setXData2(mean - stdDevWidth * stdDev, mean + stdDevWidth * stdDev)
Call bellLayer.setLineWidth(2)
' No tooltip is needed for the spline layer
Call bellLayer.setHTMLImageMap("{disable}")
' Draw the histogram as bars in blue (0x6699bb) with dark blue (0x336688) border
Set histogramLayer = c.addBarLayer(frequency, &H6699bb)
Call histogramLayer.setBorderColor(&H336688)
' The center of the bars span from minX + half_bar_width to maxX - half_bar_width
Call histogramLayer.setXData2(minX + slotSize / 2.0, maxX - slotSize / 2.0)
' Configure the bars to touch each other with no gap in between
Call histogramLayer.setBarGap(cd.TouchBar)
' Use rounded corners for decoration
Call histogramLayer.setRoundedCorners()
' Tool tip for the histogram
Call histogramLayer.setHTMLImageMap("", "", "title='{value}'")
' ChartDirector by default will extend the x-axis scale by 0.5 unit to cater for the bar width. It
' is because a bar plotted at x actually occupies (x +/- half_bar_width), and the bar width is
' normally 1 for label based x-axis. However, this chart is using a linear x-axis instead of label
' based. So we disable the automatic extension and add a dummy layer to extend the x-axis scale to
' cover minX to maxX.
Call c.xAxis().setIndent(False)
Call c.addLineLayer2().setXData(minX, maxX)
' For the automatic y-axis labels, set the minimum spacing to 40 pixels.
Call c.yAxis().setTickDensity(40)
' Output the chart
Set viewer = cd.WebChartViewer(Request, "chart1")
Call viewer.setChart(c, cd.SVG)
' Include tool tip for the chart
viewer.ImageMap = c.getHTMLImageMap("")
%>
<!DOCTYPE html>
<html>
<head>
<title>Histogram with Bell Curve</title>
<!-- Include ChartDirector Javascript Library to support chart interactions -->
<script type="text/javascript" src="cdjcv.js"></script>
</head>
<body style="margin:5px 0px 0px 5px">
<div style="font:bold 18pt verdana;">
Histogram with Bell Curve
</div>
<hr style="border:solid 1px #000080; background:#000080" />
<div style="font:10pt verdana; margin-bottom:1.5em">
<a href="viewsource.asp?file=<%= Request("SCRIPT_NAME") %>">View Chart Source Code</a>
</div>
<!-- ****** Here is the chart image ****** -->
<%= viewer.renderHTML() %>
</body>
</html>
Public Sub createChart(viewer As Object, chartIndex As Integer)
Dim cd As New ChartDirector.API
'
' This example demonstrates creating a histogram with a bell curve from raw data. About half of
' the code is to sort the raw data into slots and to generate the points on the bell curve. The
' remaining half of the code is the actual charting code.
'
' Generate a random guassian distributed data series as the input data for this example.
Dim r As RanSeries
Set r = cd.RanSeries(66)
Dim samples()
samples = r.getGaussianSeries(200, 100, 10)
'
' Classify the numbers into slots. In this example, the slot width is 5 units.
'
Dim slotSize As Long
slotSize = 5
' Compute the min and max values, and extend them to the slot boundary.
Dim m As ArrayMath
Set m = cd.ArrayMath(samples)
Dim minX As Double
minX = Int(m.min() / slotSize) * slotSize
Dim maxX As Double
maxX = Int(m.max() / slotSize) * slotSize + slotSize
' We can now determine the number of slots
Dim slotCount As Long
slotCount = Int((maxX - minX + 0.5) / slotSize)
ReDim frequency(slotCount - 1)
' Count the data points contained in each slot
Dim i As Long
For i = 0 To UBound(samples)
Dim slotIndex As Long
slotIndex = Int((samples(i) - minX) / slotSize)
frequency(slotIndex) = frequency(slotIndex) + 1
Next
'
' Compute Normal Distribution Curve
'
' The mean and standard deviation of the data
Dim mean As Double
mean = m.avg()
Dim stdDev As Double
stdDev = m.stdDev()
' The normal distribution curve (bell curve) is a standard statistics curve. We need to
' vertically scale it to make it proportion to the frequency count.
Dim scaleFactor As Double
scaleFactor = slotSize * (UBound(samples) + 1) / stdDev / Sqr(6.2832)
' In this example, we plot the bell curve up to 3 standard deviations.
Dim stdDevWidth As Double
stdDevWidth = 3.0
' We generate 4 points per standard deviation to be joined with a spline curve.
Dim bellCurveResolution As Long
bellCurveResolution = Int(stdDevWidth * 4 + 1)
ReDim bellCurve(bellCurveResolution - 1)
For i = 0 To UBound(bellCurve)
Dim z As Double
z = (2 * i - UBound(bellCurve)) * stdDevWidth / UBound(bellCurve)
bellCurve(i) = Exp(-z * z / 2) * scaleFactor
Next
'
' At this stage, we have obtained all data and can plot the chart.
'
' Create a XYChart object of size 600 x 360 pixels
Dim c As XYChart
Set c = cd.XYChart(600, 360)
' Set the plotarea at (50, 30) and of size 500 x 300 pixels, with transparent background and
' border and light grey (0xcccccc) horizontal grid lines
Call c.setPlotArea(50, 30, 500, 300, cd.Transparent, -1, cd.Transparent, &Hcccccc)
' Display the mean and standard deviation on the chart
Call c.addTitle("Mean = " & c.formatValue(mean, "{value|1}") & ", Standard Deviation = " & _
c.formatValue(stdDev, "{value|2}"), "arial.ttf")
' Set the x and y axis label font to 12pt Arial
Call c.xAxis().setLabelStyle("arial.ttf", 12)
Call c.yAxis().setLabelStyle("arial.ttf", 12)
' Set the x and y axis stems to transparent, and the x-axis tick color to grey (0x888888)
Call c.xAxis().setColors(cd.Transparent, cd.TextColor, cd.TextColor, &H888888)
Call c.yAxis().setColors(cd.Transparent)
' Draw the bell curve as a spline layer in red (0xdd0000) with 2-pixel line width
Dim bellLayer As SplineLayer
Set bellLayer = c.addSplineLayer(bellCurve, &Hdd0000)
Call bellLayer.setXData2(mean - stdDevWidth * stdDev, mean + stdDevWidth * stdDev)
Call bellLayer.setLineWidth(2)
' No tooltip is needed for the spline layer
Call bellLayer.setHTMLImageMap("{disable}")
' Draw the histogram as bars in blue (0x6699bb) with dark blue (0x336688) border
Dim histogramLayer As BarLayer
Set histogramLayer = c.addBarLayer(frequency, &H6699bb)
Call histogramLayer.setBorderColor(&H336688)
' The center of the bars span from minX + half_bar_width to maxX - half_bar_width
Call histogramLayer.setXData2(minX + slotSize / 2.0, maxX - slotSize / 2.0)
' Configure the bars to touch each other with no gap in between
Call histogramLayer.setBarGap(cd.TouchBar)
' Use rounded corners for decoration
Call histogramLayer.setRoundedCorners()
' Tool tip for the histogram
Call histogramLayer.setHTMLImageMap("", "", "title='{value}'")
' ChartDirector by default will extend the x-axis scale by 0.5 unit to cater for the bar width.
' It is because a bar plotted at x actually occupies (x +/- half_bar_width), and the bar width
' is normally 1 for label based x-axis. However, this chart is using a linear x-axis instead of
' label based. So we disable the automatic extension and add a dummy layer to extend the x-axis
' scale to cover minX to maxX.
Call c.xAxis().setIndent(False)
Call c.addLineLayer2().setXData(minX, maxX)
' For the automatic y-axis labels, set the minimum spacing to 40 pixels.
Call c.yAxis().setTickDensity(40)
' Output the chart
Set viewer.Picture = c.makePicture()
' Include tool tip for the chart
viewer.ImageMap = c.getHTMLImageMap("clickable")
End Sub