In this example, we will create a bar chart that displays annual revenue for a
company for the last 10 years. When a bar is clicked, the browser will load a
line chart showning the monthly revenue for the selected year. When the line
chart is clicked, the browser will load a pie chart showing the breakdown of the
revenue for the selected month. When the pie chart is clicked, it will show the
data in detail in an HTML page.
The capability is often called "drill-down", because the user can "zoom-in" to
get more details by clicking on the chart.
[The following is available as "pythondemo_cgi/clickbar.py".]
#!/usr/bin/python
from pychartdir import *
#
#For demo purpose, we use hard coded data. In real life, the following data
#could come from a database.
#
revenue = [4500, 5600, 6300, 8000, 12000, 14000, 16000, 20000, 24000, 28000]
labels = ["1992", "1993", "1994", "1995", "1996", "1997", "1998", "1999",
"2000", "2001"]
#Create a XYChart object of size 450 x 200 pixels
c = XYChart(450, 200)
#Add a title to the chart using Times Bold Italic font
c.addTitle("Annual Revenue for Star Tech", "timesbi.ttf")
#Set the plotarea at (60, 25) and of size 350 x 150 pixels
c.setPlotArea(60, 25, 350, 150)
#Add a blue (0x3333cc) bar chart layer using the given data. Set the bar border
#to 1 pixel 3D style.
c.addBarLayer(revenue, 0x3333cc, "Revenue").setBorderColor(-1, 1)
#Set x axis labels using the given labels
c.xAxis().setLabels(labels)
#Add a title to the y axis
c.yAxis().setTitle("USD (K)")
#Create the image and save it in a temporary location
chart1URL = c.makeTmpFile("/tmp/tmpcharts")
#Create an image map for the chart
imageMap = c.getHTMLImageMap("clickline.py", "",
"title='{xLabel}: USD {value|0}K'")
print "Content-type: text/html\n"
print """
Simple Clickable Bar Chart
View Source Code
""" % vars() |
In the above code, the chart is created and saved in a temporary
file in the "/tmp/tmp_chart" directory using
BaseChart.makeTmpFile. This
function also simultaneously removes old temporary files (default lifetime = 600
seconds) to avoid temporary files from building up.
Note: For the above code to run correctly, please verify the web server
anonymous user has sufficient privileges to read and write to "/tmp/tmp_chart".
An <IMG> tag is used to retrieve the chart with
"myimage.py?img=/tmp/tmpcharts/%(chart1URL)s"
as the URL. "myimage.py" is a simple utility that
comes with ChartDirector for retrieving images files. The "myimage.py" is
needed because the "/tmp/tmp_chart" directory is not under the web server root
directory. If your scripts use a temporary directory that is under the web server
root directory, you may put the temporary file URL directly in the <IMG> tag
instead of using "myimage.py".
The image map for the chart is created using the following code:
imageMap = c.getHTMLImageMap("clickline.py", "",
"title='{xLabel}: USD {value|0}K'")
|
As seen above, only one line of code is needed.
BaseChart.getHTMLImageMap will
generate the image map for the entire chart. The image map will use "clickline.py"
as the handler when the user clicks on the bars.
If you right click on the browser and choose "View Source" to look at the HTML
of the web page as received by the browser, you can see that the image map
generated above will be something like:
...... (one tag for each bar) ...... |
The image map generated by ChartDirector will contain one area tag for each of
the bars. The "href" attribute of the
tag will invoke "clickline.py"
with a some query parameters to describe the bar. In this way, the
"clickline.py" will know which bar the user has clicked.
The
tag also includes the "title" attribute, which will become the "tool
tip" text when the mouse moves over the bar. In this particular example, the
"tool tip" text is in the format:
"title='{xLabel}: USD {value|0}K'"
which is specified as the third argument of
BaseChart.getHTMLImageMap.
As mentioned above, the "myimage.py" is a simply utility used to retrieve
the image from a file and
returns it to the browser.
[The following is available as "pythondemo_cgi/myimage.py".]
#!/usr/bin/python
import cgi, sys
#get HTTP query parameters
query = cgi.FieldStorage()
f = open(query["img"].value, "rb")
#output the chart as a PNG stream.
print "Content-type: image/png\n"
try :
#Make sure we use binary mode if we are running on windows
import msvcrt, os
msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
except :
pass
#use stdout instead of print because print will add an extra new line character at the end
sys.stdout.write(f.read())
f.close() |
In the last example Clickable Bar Chart, when a bar is clicked, the handler
"clickline.py" will be invoked.
The code for the image map handler "clickline.py" is listed below. The
"clickline.py" determines which year the user has clicked from the query
parameters. It then draws a line chart based on selected year. To produce a
clickable line chart, it generates and saves the chart in a
temporary file
using
BaseChart.makeTmpFile, and generates the image map using
BaseChart.getHTMLImageMap, with "clickpie.py" as the handler.
As "clickline.py" is very similar to "clickbar.py", it will not be explained
further here.
[The following is available as "pythondemo_cgi/clickline.py".]
#!/usr/bin/python
from pychartdir import *
import cgi
#get HTTP query parameters
query = cgi.FieldStorage()
#Get the selected year.
selectedYear = query["xLabel"].value
#Get the total revenue
totalRevenue = float(query["value"].value)
#
# In this demo, we just split the total revenue into 12 months using random
# numbers. In real life, the data can come from a database.
#
import whrandom
ran = whrandom.whrandom((int(selectedYear)) % 256)
data = [0] * 12
for i in range(0, 11) :
data[i] = totalRevenue * (ran.random() * 0.6 + 0.6) / (12 - i)
totalRevenue = totalRevenue - data[i]
data[11] = totalRevenue
#
# Now we obtain the data into arrays, we can start to draw the chart using
# ChartDirector
#
#Create a XYChart object of size 450 x 200 pixels
c = XYChart(450, 200)
#Add a title to the chart
c.addTitle("Month Revenue for Star Tech for %s" % (selectedYear), "timesbi.ttf")
#Set the plotarea at (60, 5) and of size 350 x 150 pixels. Enable both
#horizontal and vertical grids by setting their colors to grey (0xc0c0c0)
c.setPlotArea(60, 25, 350, 150).setGridColor(0xc0c0c0, 0xc0c0c0)
#Add a line chart layer using the data
dataSet = c.addLineLayer().addDataSet(data, 0x993399)
#Set the line width to 3 pixels
dataSet.setLineWidth(3)
#Use a 11 point triangle symbol to plot the data points
dataSet.setDataSymbol(TriangleSymbol, 11)
#Set the x axis labels. In this example, the labels must be Jan - Dec.
labels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct",
"Nov", "Dec"]
c.xAxis().setLabels(labels)
#Add a title to the x axis to reflect the selected year
c.xAxis().setTitle("Year %s" % (selectedYear))
#Add a title to the y axis
c.yAxis().setTitle("USD (K)")
#Reserve 10% margin at the top of the plot area just to make sure the line does
#not go too near the top of the plot area
c.yAxis().setAutoScale(0.1)
#Create the image and save it in a temporary location
chart1URL = c.makeTmpFile("/tmp/tmpcharts")
#Create an image map for the chart
imageMap = c.getHTMLImageMap("clickpie.py?year=%s" % (selectedYear), "",
"title='{xLabel}: USD {value|0}K'")
print "Content-type: text/html\n"
print """
Simple Clickable Line Chart
View Source Code
""" % vars() |
In the last example Clickable Line Chart, when a line is clicked, the handler
"clickpie.py" will be invoked.
The code for "clickpie.py" is listed below. It determines which year and month
the user has clicked from the query parameters. It then draws a pie chart based
on those parameters. To produce a clickable pie chart, it generates and saves
the chart in a
temporary file using
BaseChart.makeTmpFile,
and generates the image map using
BaseChart.getHTMLImageMap. method, with
"piestub.py" as the handler.
As "clickpie.py" is very similar to "clickbar.py" and "clickline.py", it will
not be explained further here.
[The following is available as "pythondemo_cgi/clickpie.py".]
#!/usr/bin/python
from pychartdir import *
import cgi
#get HTTP query parameters
query = cgi.FieldStorage()
#Get the selected year and month
selectedYear = int(query["year"].value)
selectedMonth = int(query["x"].value) + 1
#Get the monthly revenue
monthlyRevenue = float(query["value"].value)
#
# In this demo, we just split the total revenue into 3 parts using random
# numbers. In real life, the data probably can come from a database.
#
import whrandom
ran = whrandom.whrandom((selectedMonth * 2000 + selectedYear) % 256)
data = [0] * 3
data[0] = (ran.random() * 0.1 + 0.5) * monthlyRevenue
data[1] = (ran.random() * 0.1 + 0.2) * monthlyRevenue
data[2] = monthlyRevenue - data[0] - data[1]
#The labels for the pie chart
labels = ["Services", "Hardware", "Software"]
#Create a PieChart object of size 360 x 260 pixels
c = PieChart(360, 260)
#Set the center of the pie at (180, 140) and the radius to 100 pixels
c.setPieSize(180, 130, 100)
#Add a title to the pie chart using 13 pts Times Bold Italic font
c.addTitle("Revenue Breakdown for %s/%s" % (selectedMonth, selectedYear),
"timesbi.ttf", 13)
#Draw the pie in 3D
c.set3D()
#Set the pie data and the pie labels
c.setData(data, labels)
#Create the image and save it in a temporary location
chart1URL = c.makeTmpFile("/tmp/tmpcharts")
#Create an image map for the chart
imageMap = c.getHTMLImageMap("piestub.py", "", "title='{label}:USD {value|0}K'")
print "Content-type: text/html\n"
print """
Simple Clickable Pie Chart
View Source Code
""" % vars() |
In the last example Clickable Pie Chart, when a sector is clicked, the handler
"piestub.py" will be invoked. Its code is listed below. In this example, for
demo purposes the "piestub.py" simply displays data about the sector clicked.
[The following is available as "pythondemo_cgi/piestub.py".]
#!/usr/bin/python
import cgi, os
#get HTTP query parameters
query = cgi.FieldStorage()
print "Content-type: text/html\n"
print """
Simple Clickable Pie Chart Handler
View Source Code
You have clicked on the following sector :
- Sector Number : """, query["sector"].value, """
- Sector Name : """, query["label"].value, """
- Sector Value : """, query["value"].value, """
- Sector Percentage : """, query["percent"].value, """%
""" |
© 2003 Advanced Software Engineering Limited. All rights reserved.