一、先看图:
这是一个用Flash做的动态曲线图,请将鼠标移动那些绿色的小点上看看。
这个示例可以结合asp、asp.net、php、jsp等后台语言,显示你想要的数据曲线。其实是与后台语言无关的,只要按一定的格式传递数据给它就可以。另外,这仅仅是个示例程序,您在使用时,有可能得按照自己的需求重新修改,但本例基本上已涉及了Flash绘制曲线图的各个技术方面。
二、在制作此例前,我假设您已了解以下Flash知识点:
1.使用this.createEmptyMovieClip动态创建MovieClip;
2.使用AS绘制线条或矩形;
3.对Flash中“深度”的理解;
4.使用this.createTextField动态创建文本框;
三、正式开始
1)创建一个空白文档,有三个层:
看上图,三个层:
script:放置一些脚本;
鼠标跟随:当鼠标放置在曲线的点上时,会有一个提示,这个提示其实是一个MovieClip,这个层就放它;
坐标曲线: 放置一个MovieClip,即生成的曲线;
2).按Ctrl+F8新建一个影片剪辑(MovieClip),里面放置一个动态文本框,实例名称为:tips,如下图:
3).返回场景,将刚才制作的mc坐库中托至场景(放在可视区域外),并且命名为:mouse_mc,如图:
4).按Ctrl+F8新建一个影片剪辑(MovieClip):坐标曲线,有三个层:,如下图:
script:放置一些脚本;
文字:放置x,y轴的说明文字;
xy轴: 放置x,y坐标轴;
5).在影片剪辑“坐标曲线”的“xy轴”层上画x,y坐标线:
这步就是注意坐标轴的中心点,画在影片剪辑的注册点上,即_x=0,_y=0处;
6).在坐标轴附近,创建二个动态文本框,分别指定变量名为:txt_x,txt_y,如下图:
这二个文本框用来显示坐标轴的说明文字;
6).接着在的“script”层的第一帧,加入如下代码:
影片剪辑"坐标曲线"的"script"层的代码
//
txt_x = _root.xtxt;
txt_y = _root.ytxt;
//x轴单位刻度的像素数
var xspace = Math.floor(400/_root.xtotal);
//trace("xspace:"+xspace);
//y轴单位刻度的像素数
var yspace = Math.floor(400/_root.ytotal);
//trace("yspace:"+yspace);
//
//画X轴刻度
DrawScalX(_root.xtotal);
//画Y轴刻度
DrawScalY(_root.ytotal);
//画曲线
DrawLine(_root.piont);
//
//画X轴刻度
function DrawScalX(total:Number) {
createEmptyMovieClip("scalX_mc", 1);
scalX_mc.lineStyle(1, 0x000000, 80);
var i:Number;
for (i=1; i<total+1; i++) {
if (i%5 == 0) {
scalX_mc.lineStyle(1, 0x000000, 70);
scalX_mc.moveTo(xspace*i, 0);
scalX_mc.lineTo(xspace*i, -6);
CreateText(i/5, xspace*i-14-5*xspace, 5);
//CreateText(i/5, xspace*i-14, 5);
} else {
scalX_mc.lineStyle(1, 0x000000, 30);
scalX_mc.moveTo(xspace*i, 0);
scalX_mc.lineTo(xspace*i, -4);
}
}
}
//画Y轴刻度
function DrawScalY(total:Number) {
createEmptyMovieClip("scalY_mc", 2);
var i:Number;
for (i=1; i<total+1; i++) {
if (i%10 == 5) {
scalY_mc.lineStyle(1, 0x000000, 50);
scalY_mc.moveTo(0, 0-(yspace*i));
scalY_mc.lineTo(7, 0-(yspace*i));
} else if (i%10 == 0) {
scalY_mc.lineStyle(1, 0x000000, 80);
scalY_mc.moveTo(0, 0-(yspace*i));
scalY_mc.lineTo(8, 0-(yspace*i));
CreateText(i, -30, 0-(yspace*i)-9);
} else {
scalY_mc.lineStyle(1, 0x000000, 30);
scalY_mc.moveTo(0, 0-(yspace*i));
scalY_mc.lineTo(4, 0-(yspace*i));
}
}
}
//建立x,y轴的坐标文本
function CreateText(txt:Number, X:Number, Y:Number) {
var my_txt = createTextField("my_txt"+txt, Math.floor(Math.random()*100000), X, Y, 30, 30);
//trace(my_txt);
my_txt.multiline = false;
my_txt.wordWrap = true;
my_txt.selectable = false;
var my_fmt:TextFormat = new TextFormat();
my_fmt.color = 0x999999;
my_fmt.align = "center";
my_txt.text = txt;
my_txt.setTextFormat(my_fmt);
}
//
//画坐标曲线
function DrawLine(point:String) {
createEmptyMovieClip("curve_mc", 3);
//曲线填充色
curve_mc.beginFill(0xFFFFCC, 50);
//曲线颜色
curve_mc.lineStyle(1, 0xFF6600, 100);
curve_mc.moveTo(0, 0);
//
var point_arr:Array = point.split("|");
for (var i = 0; i<point_arr.length; i++) {
curve_mc.lineTo(point_arr[i].split(",")[0]*xspace, 0-point_arr[i].split(",")[1]*yspace);
DrawCircle((point_arr[i].split(",")[0]), 0-(point_arr[i].split(",")[1]));
}
curve_mc.lineTo((point_arr[point_arr.length-1].split(",")[0]*xspace), 0);
curve_mc.lineStyle(1, 0x000000, 0);
curve_mc.lineTo(0, 0);
curve_mc.endFill();
}
//画坐标点
function DrawCircle(X:Number, Y:Number) {
var tempInt:Number = 100000+Math.floor(Math.random()*100000);
var circle_mc = this.createEmptyMovieClip("circle_mc"+tempInt, tempInt);
circle_mc.onRollOver = function() {
_root.mouse_mc._x = _root._xmouse;
_root.mouse_mc._y = _root._ymouse;
if (Math.abs(X)%5 == 0) {
_root.mouse_mc.tips.text = " "+_root.xtxt+":"+((Math.abs(X)/5))+"-5,"+_root.ytxt+":"+Math.abs(Y)+" ";
} else {
_root.mouse_mc.tips.text = " "+_root.xtxt+":"+(Math.floor(Math.abs(X)/5)+1)+"-"+Math.abs(X)%5+","+_root.ytxt+":"+Math.abs(Y)+" ";
}
//刷新舞台以使光标的移动看起来顺畅
updateAfterEvent();
};
circle_mc.onRollOut = function() {
_root.mouse_mc._x = -500;
_root.mouse_mc._y = -500;
};
//圆点的填充色
circle_mc.beginFill(0x00FF00, 100);
//圆点的线条色
circle_mc.lineStyle(0, 0x00FF00);
//画圆线
Circle(circle_mc, X*xspace, Y*yspace, 2);
circle_mc.endFill();
}
//==============画圆形线==============
//x,y为圆心坐标
//r为圆半径
function Circle(mc:MovieClip, x:Number, y:Number, r:Number):Void {
mc.moveTo(x+r, y);
mc.curveTo(r+x, Math.tan(Math.PI/8)*r+y, Math.sin(Math.PI/4)*r+x, Math.sin(Math.PI/4)*r+y);
mc.curveTo(Math.tan(Math.PI/8)*r+x, r+y, x, r+y);
mc.curveTo(-Math.tan(Math.PI/8)*r+x, r+y, -Math.sin(Math.PI/4)*r+x, Math.sin(Math.PI/4)*r+y);
mc.curveTo(-r+x, Math.tan(Math.PI/8)*r+y, -r+x, y);
mc.curveTo(-r+x, -Math.tan(Math.PI/8)*r+y, -Math.sin(Math.PI/4)*r+x, -Math.sin(Math.PI/4)*r+y);
mc.curveTo(-Math.tan(Math.PI/8)*r+x, -r+y, x, -r+y);
mc.curveTo(Math.tan(Math.PI/8)*r+x, -r+y, Math.sin(Math.PI/4)*r+x, -Math.sin(Math.PI/4)*r+y);
mc.curveTo(r+x, -Math.tan(Math.PI/8)*r+y, r+x, y);
}
7)返回场景,在场景的第一帧加入如下代码:
场景的script代码
//让鼠标提示内容的宽度根据内容的多少自动调整
mouse_mc.tips.autoSize = true;
//System.useCodepage = true;
//
//网页传入的值为String类型的,如_root.xtotal = "60",在此转换为Number类型,否则会有点问题.
//x轴刻度总长
_root.xtotal = parseInt(_root.xtotal);
//y轴刻度总长
_root.ytotal = parseInt(_root.ytotal);
8).将库中的“坐标曲线”影片剪辑托至场景中,命名为:mc,如下图:
9).参数说明:
在代码中,使用到了以下变量:
//x轴刻度总长
_root.xtotal = 60;
//y轴刻度总长
_root.ytotal = 100;
//x轴说明文本
_root.xtxt = "月份";
//y轴说明文本
_root.ytxt = "成绩";
//依次的坐标点
_root.piont = "1,80|2,70|3,90|4,88|5,100|6,90|7,90|8,35|9,99|30,60|50,80";
“1,80”代表x坐标为1,y坐标为80的一个点,多个点依次以“|”分隔,选传到Flash后,使用AS的
String.split("|")再拆分出来。
另外,这些变量从那儿来呢?就是从外部动态传入的参数了。传入方法很简单,在嵌入Flash的Html页中,注意下面代码:
嵌入swf的Html代码
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="550" height="470" id="Flash_curve" align="middle">
<param name="allowScriptAccess" value="sameDomain" />
<param name="movie" value="Flash_curve.swf?xtotal=60&ytotal=100&xtxt=month&ytxt=score&piont=1,80|2,70|3,90|4,88|5,100|6,90|7,90|8,35|9,99|30,60|50,80" /><param name="quality" value="high" /><param name="bgcolor" value="#ffffff" /><embed src="Flash_curve.swf?xtotal=60&ytotal=100&xtxt=month&ytxt=score&piont=1,80|2,70|3,90|4,88|5,100|6,90|7,90|8,35|9,99|30,60|50,80" quality="high" bgcolor="#ffffff" width="550" height="470" name="Flash_curve" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />
</object>
注意加粗的那部分,跟在swf文件名后边,以?开头,后边参数类似我们“WebForm1.aspx?QueryString1=1&QueryString2=aaaa”的形式,各值/对参数以“&”符分隔,这样在Flash中可以直接使用此变量,如果含有汉字,请以urlEncode编码,Flash会自动解析出来,否则汉字可能乱码。
还有特别注意第7)步中,说到场景中的代码,有如下二句:
//网页传入的值为String类型的,如_root.xtotal = "60",在此转换为Number类型,否则会有点问题.
//x轴刻度总长
_root.xtotal = parseInt(_root.xtotal);
//y轴刻度总长
_root.ytotal = parseInt(_root.ytotal);
因为外部传入的值默认将是String类型,所以这里做了类型转换,以免后边运算时出错。
四、完整源码下载
点此下载(11K)>>说明:具体代码,里面基本上都加了注释,我在文章里没有再作太多说明,有不明白地方的请回复。