在 web 页面中使用图表(chart)表现数据
在 web 编程中经常需要做的一件事情就是把从数据库中查出的数据(数字)
使用图表(chart)的形式在页面中表现出来。下面我们简单总结几种常见的做法。
1. 如果图表的样式只需要柱形图(bar)就可以的话,有一种非常简单,偷懒的
方法,即使用某些 tag 的 width 属性来表现就可以。举例如下:
<img height=5 width=<%= 数值 %> src="小方块.gif">
用这种思路,要是不嫌难看的话,你干脆用 for 循环控制 * 号的显示个数也未尝
不可。;-)
如果想比较美观的话,可以把 css 设计的好一些,再和 dhtml 结合。
这种方法的一个完整的例子见:
http://www.microsoft.com/workshop/database/datavis/datavis.asp
2. 一些老兄喜欢直接把图片放在数据库中,那我们看看怎么把它们调出来。
(如果这些图片正好是图表的话,我就不算离题。;-))
iis 的在线帮助中有这么个例子:
http://localhost/iissamples/sdk/asp/docs/codebrws.asp?source=/iissamples/sdk/asp/database/blob_vbscript.asp
其核心代码:
<%
声明回传的是 gif 文件,不是平常的 html
response.buffer = true
response.contenttype = "image/gif"
连数据库
set oconn = server.createobject("adodb.connection")
oconn.open "dsn=localserver;uid=sa;pwd=;database=pubs"
查出存好的图片
set ors = oconn.execute("select logo from pub_info where pub_id=0736")
取值要显得专业些 😉
picsize = ors("logo").actualsize
pic = ors("logo").getchunk(picsize)
再次强调回传的是 gif 图片,view source 是什么都看不到的
response.binarywrite pic
response.end
%>
好,仔细看注释的老兄(我可没这好习惯;-))会问:这支程序 mypic.asp 在浏览器中最后的效果
相当于 http://host/foo/mypic.gif,我想要有文字怎么办?
很简单,写个 web page 中间加上 <img src=mypic.asp> 不就完了。 😉
3. 还有些老兄更甚,这些大侠的机器多半是 8 cpu 的 p iii,他们使用 server-side 软件,
比如 excel,现做一个 chart 图片,然后以 gif 格式传给浏览器。多见于 cgi 高手。;-)
我们来看一个这样的 cool demo。
核心代码:
<%
set excel = getobject("","excel.application")
if err.number <> 0 then
response.write("could not create excel document. " + err.description+"")
err.clear
end if
excel.displayalerts = false
set workbooks = excel.workbooks
set wb = workbooks.add
set sheets = wb.sheets
set wstotal = sheets.add( ,,,-4167)
wstotal.name = "total_expenses"
set range = wstotal.range("b1")
range.formular1c1 = "1"
set range = wstotal.range("c1")
range.formular1c1 = "2"
set range = wstotal.range("d1")
range.formular1c1 = "3"
wstotal.activate
wstotal.select
set range = wstotal.range("b1:d1")
excel.charts.add
excel.activechart.charttype = 51
excel.activechart.setsourcedata range,2
excel.activechart.export "d:\test\exceltest"+".gif","gif"
response.write "<img src=d:\test\exceltest.gif>"
%>
真正的懒人在写这段代码时还利用 excel 的 vba(:-p),绝对代码快枪手,
可是运行效率—-呸!;-)
4. 好了,该看一看专业运动员的做法了—-使用 chart control。
哪种控件更好大家见仁见智,(比如有些老兄喜欢 java applets 😉 还有些老兄
喜欢自己用 c/c++ 开发)为简化起见,这里我推荐微软(;-))的—-
office 2000 web component。;-)
在前面一文中我介绍过控件与数据结合的几种方式,我们来一一分析
用 excel 2000 的 chart control 如何实现。
a. 逐行赋值法
excel 2000 chart control 有两种赋值方法:数组,字符串。
数组法:
代码示例:
———————————-
<object id=chartspace1 classid=clsid:0002e500-0000-0000-c000-000000000046 style="width:100%;height:350"></object>
<script language=vbs>
sub window_onload()
dim categories(3), values(3)
4 个分类
categories(0) = "white"
categories(1) = "black"
categories(2) = "asian"
categories(3) = "latino"
准备活动 😉
chartspace1.clear
chartspace1.charts.add
set c = chartspace1.constants
添加三个系列的值
chartspace1.charts(0).seriescollection.add
chartspace1.charts(0).seriescollection.add
chartspace1.charts(0).seriescollection.add
锦上添花 😉
chartspace1.charts(0).seriescollection(0).caption = "perot"
设置
chartspace1.charts(0).seriescollection(0).setdata c.chdimcategories, c.chdataliteral, categories
values(0) = 0.2 the white value.
values(1) = 0.06 the black value.
values(2) = 0.17 the asian value.
values(3) = 0.13 the latino value.
chartspace1.charts(0).seriescollection(0).caption = "perot"
chartspace1.charts(0).seriescollection(0).setdata c.chdimcategories, c.chdataliteral, categories
chartspace1.charts(0).seriescollection(0).setdata c.chdimvalues, c.chdataliteral, values
series two contains election data for clinton.
update the values array, then set the chart data.
values(0) = 0.38 the white value.
values(1) = 0.82 the black value.
values(2) = 0.28 the asian value.
values(3) = 0.62 the latino value.
chartspace1.charts(0).seriescollection(1).caption = "clinton"
chartspace1.charts(0).seriescollection(1).setdata c.chdimcategories, c.chdataliteral, categories
chartspace1.charts(0).seriescollection(1).setdata c.chdimvalues, c.chdataliteral, values
series two contains election data for bush.
update the values array, and then set the chart data.
values(0) = 0.42 the white value.
values(1) = 0.12 the black value.
values(2) = 0.55 the asian value.
values(3) = 0.25 the latino value.
chartspace1.charts(0).seriescollection(2).caption = "bush"
chartspace1.charts(0).seriescollection(2).setdata c.chdimcategories, c.chdataliteral, categories
chartspace1.charts(0).seriescollection(2).setdata c.chdimvalues, c.chdataliteral, values
make the chart legend visible, format the left value axis as percentage,
and specify that value gridlines are at 10% intervals.
chartspace1.charts(0).haslegend = true
chartspace1.charts(0).axes(c.chaxispositionleft).numberformat = "0%"
chartspace1.charts(0).axes(c.chaxispositionleft).majorunit = 0.1
end sub
</script>
字符串法:
代码示例:
————————–
<script language=vbs>
sub window_onload()
dim categories, values
原来的注释很无聊,被我删掉了 😉
chartspace1.clear
chartspace1.charts.add
set c = chartspace1.constants
以 tab 为分隔符的字符串拼凑
categories = "white" & chr(9) & "black" & chr(9) & "asian" & chr(9) & "latino"
add three series to the chart.
chartspace1.charts(0).seriescollection.add
chartspace1.charts(0).seriescollection.add
chartspace1.charts(0).seriescollection.add
series one contains election data for perot.
set the series caption (the text that appears in the legend).
chartspace1.charts(0).seriescollection(0).caption = "perot"
set the categories for the first series (this collection is zero-based).
chartspace1.charts(0).seriescollection(0).setdata c.chdimcategories, c.chdataliteral, categories
以 tab 为分隔符的字符串拼凑
values = "0.2" & chr(9) & "0.06" & chr(9) & "0.17" & chr(9) & "0.13"
chartspace1.charts(0).seriescollection(0).setdata c.chdimvalues, c.chdataliteral, values
series two contains election data for clinton.
update the values string, and then set the chart data.
values = "0.38" & chr(9) & "0.82" & chr(9) & "0.28" & chr(9) & "0.62"
chartspace1.charts(0).seriescollection(1).caption = "clinton"
chartspace1.charts(0).seriescollection(1).setdata c.chdimcategories, c.chdataliteral, categories
chartspace1.charts(0).seriescollection(1).setdata c.chdimvalues, c.chdataliteral, values
series two contains election data for bush.
update the values string, and then set the chart data.
values = "0.42" & chr(9) & "0.12" & chr(9) & "0.55" & chr(9) & "0.25"
chartspace1.charts(0).seriescollection(2).caption = "bush"
chartspace1.charts(0).seriescollection(2).setdata c.chdimcategories, c.chdataliteral, categories
chartspace1.charts(0).seriescollection(2).setdata c.chdimvalues, c.chdataliteral, values
make the chart legend visible, format the left value axis as percentage,
and specify that value gridlines are at 10% intervals.
chartspace1.charts(0).haslegend = true
chartspace1.charts(0).axes(c.chaxispositionleft).numberformat = "0%"
chartspace1.charts(0).axes(c.chaxispositionleft).majorunit = 0.1
end sub
</script>
————————-
无论是数组法还是字符串法,你都可以在 client-side 逐行插入 <%=value%>。
对于字符串法,你也可以在 server-side 就拼好一个字串,然后直接传过来。
chartspace1.charts(0).seriescollection(1).setdata c.chdimvalues, c.chdataliteral, <% =stringvalues%>
(好象要加引号哦。"<% =stringvalues%>",意思到了就中)
b. client-side recordset 法
excel 2000 chart 这么 cool 的 control 当然支持直接的 recordset 绑定。
代码示例:
————————-
<html>
<body>
第一步:创建 chart 和 ado connection object
<object id=chartspace1 classid=clsid:0002e500-0000-0000-c000-000000000046 style="width:100%;height:480"></object>
<object id=adoconnection1 classid=clsid:00000514-0000-0010-8000-00aa006d2ea4></object>
<script language=vbs>
sub window_onload()
dim rs, categories, values
找个英文 access 97 里的 nwind.mdb 试试
categories = ""
values = ""
adoconnection1.open "driver={microsoft access driver (*.mdb)};dbq=c:\nwind.mdb"
set rs = adoconnection1.execute("select * from [category sales for 1995]")
rs.movefirst
while not rs.eof
categories = categories & rs.fields(0).value & chr(9)
values = values & rs.fields(1).value & chr(9)
rs.movenext
wend
rs.close
adoconnection1.close
多拼了个 tab,去了它
categories = left(categories, len(categories) – 1)
values = left(values, len(values) – 1)
很容易看懂吧
chartspace1.clear
chartspace1.charts.add
chartspace1.charts(0).seriescollection.add
chartspace1.charts(0).seriescollection(0).caption = "sales"
chartspace1.charts(0).seriescollection(0).setdata chartspace1.constants.chdimcategories,
chartspace1.constants.chdataliteral, categories
chartspace1.charts(0).seriescollection(0).setdata chartspace1.constants.chdimvalues,
chartspace1.constants.chdataliteral, values
— as a final step, we turn this into a bar chart (instead of a column chart), and
— format the axis as us $.
chartspace1.charts(0).type = chartspace1.constants.chcharttypebarclustered
chartspace1.charts(0).axes(chartspace1.constants.chaxispositionbottom).numberformat = "$#,##0"
end sub
</script>
</body>
</html>
———————————–
c. 目前 excel 2000 的 chart control 还没有用于 vi6 的 design time control 版,恨恨!
