グラフ。リアルタイムに波形を生成描画 shinano_cake.. forked:3favorite:4lines:409license : MIT License modified : 2010-03-15 22:17:57 Embed Tweet package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Shape; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageQuality; import flash.display.StageScaleMode; import flash.events.Event; import flash.events.TimerEvent; import flash.text.AntiAliasType; import flash.text.TextField; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; import flash.utils.Timer; [SWF (width=465, height=465, backgroundColor="#666666")] public class GraphSprite extends Sprite { /*======================================================================================*/ /* データ用 */ /*======================================================================================*/ private var data:Array = new Array(); private var xAxisData:Array = null; private var line:Sprite = new Sprite(); /*======================================================================================*/ /* Variables */ /*======================================================================================*/ /* ------------- グラフの幅、高さなど -------------- */ private var _graphWidth:int = 400; /* グラフの幅 */ private var _graphHeight:int = 250; /* グラフの高さ */ private var _graphPaddingLeft:int = 60; /* グラフの余白(左)*/ private var _graphPaddingRight:int = 40; /* グラフの余白(右)*/ private var _graphPaddingTop:int = 40; /* グラフの余白(上)*/ private var _graphPaddingBottom:int = 40; /* グラフの余白(下)*/ /* ---------- 表示するテキストの値など ------------ */ private var _title:String = "title"; /* タイトル */ /* --------- 色など、描画オブジェクトの設定値 -------- */ /* #public */ /** 背景色 */ public var bgColor:int = 0xFFFFFF; /** 軸の色 */ public var baseLineColor:int = 0xAA0000; /** 補助線の色 */ public var auxLineColor:int = 0xBBBBBB; /* #private */ private const scaleTextColor:int = 0x555555; /* 目盛のテキストの色 */ private const titleTextColor:int = 0x333333; /* タイトルのテキストの色 */ private const labelTextColor:int = 0x333333; /* 軸ラベルのテキストの色 */ private const titleFontSize:int = 16; /* タイトルのフォントサイズ */ private const scaleFontSize:int = 12; /* 目盛のフォントサイズ */ private const labelFontSize:int = 12; /* 軸ラベルのフォントサイズ */ private var _scaleTextFormat:TextFormat; /* 目盛用のテキストフォーマット */ private var _titleTextFormat:TextFormat; /* タイトル用のテキストフォーマット */ private var _xLabelTextFormat:TextFormat; /* x軸ラベル用のテキストフォーマット */ private var _yLabelTextFormat:TextFormat; /* y軸ラべル用のテキストフォーマット */ /* ----------- 座標などのパラメータ -------------- */ private var graphAxisX:int = 0; /* x軸の位置 */ private var graphAxisY:int = ((_graphHeight/2)-_graphPaddingTop); /* y軸の位置 */ private var base_sx:int; /* x軸方向描画始点(左) */ private var base_ex:int; /* x軸方向描画終点(右) */ private var base_sy:int; /* y軸方向描画始点(上) */ private var base_ey:int; /* y軸方向描画終点(下) */ private var gl_x:int; /* 描画開始地点を考慮した、軸 の位置 (x)*/ private var gl_y:int; /* 描画開始地点を考慮した、軸 の位置 (y)*/ private var stepX:int = 0; /* 目盛の間隔(データの間隔) (x軸方向) */ private var stepY:int = 0; /* 目盛の間隔(ピクセル間隔) (y軸方向) */ private var _autoScaleX:Number = 1.0; /* x軸方向倍率(セットされたデータに対して自動的にリスケールを実施するための倍率) */ private var _autoScaleY:Number = 1.0; /* y軸方向倍率(セットされたデータに対して自動的にリスケールを実施するための倍率) */ /* ---------- 描画のためのオブジェクト ------------ */ private var axisLine:Shape = new Shape(); /* 軸線 */ private var auxLineX:Shape = new Shape(); /* 補助目盛線 (x座標) */ private var auxLineY:Shape = new Shape(); /* 補助目盛線 (y座標) */ private var base:Shape = new Shape(); /* 背景 */ private var scaleTexts:Array = new Array(); /* 目盛用のテキストを保持する配列 */ private var xLabelText:TextField; /* x軸に付ける名前 */ private var yLabelText:TextField; /* y軸に付ける名前 */ private var titleText:TextField; /* グラフのタイトル */ /*======================================================================================*/ /* Public function */ /*======================================================================================*/ /** コンストラクタ */ public function GraphSprite() { initSetting(); /* 初期設定 */ initPosVal(); /* 座標の初期化 */ createBackGround(); /* 背景の描画 */ createTitle(); /* タイトルの描画 */ createAxisLabel(); /* 軸のラベルの描画 */ createBaseLine(); /* 軸などの描画 */ exec(); /* データの生成 */ } /*======================================================================================*/ /* Internal function */ /*======================================================================================*/ /*======================================================================================*/ /* 初期化関数 */ /*======================================================================================*/ /** スプライトの初期化 */ private function initSetting():void { //stage.quality = StageQuality.HIGH; //stage.frameRate = 60; stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP; } /** 座標系の変数の初期化 */ private function initPosVal():void { base_sx = _graphPaddingLeft + 10; /* x軸方向描画始点(左) */ base_ex = _graphWidth - _graphPaddingRight+ 10; /* x軸方向描画終点(右) */ base_sy = _graphPaddingTop + 10; /* y軸方向描画始点(上) */ base_ey = _graphHeight - _graphPaddingBottom + 10; /* y軸方向描画終点(下) */ gl_x = base_sx + graphAxisX; /* 描画開始地点を考慮した、軸 の位置 (x)*/ gl_y = base_sy + graphAxisY; /* 描画開始地点を考慮した、軸 の位置 (y)*/ } /*======================================================================================*/ /* オブジェクトの追加、作成など */ /*======================================================================================*/ /** 背景の作成 */ private function createBackGround():void { /* base */ this.addChild(base); this.drawBackGround(); } /** 軸、メモリなどの作成 */ private function createBaseLine():void { this.addChild(auxLineX); this.addChild(auxLineY); this.addChild(axisLine); this._scaleTextFormat = new TextFormat(); this._scaleTextFormat.color = this.scaleTextColor; this._scaleTextFormat.size = this.scaleFontSize; drawBaseLine(); } /** タイトルの作成 */ private function createTitle():void { this.titleText = createTextField(this._title,0,0); /* テキストフィールドの作成 */ this._titleTextFormat = new TextFormat(); /* テキストフォーマットの作成 */ this._titleTextFormat.color = this.titleTextColor; /* テキストの色 */ this._titleTextFormat.size = this.titleFontSize; /* フォントサイズ */ this.titleText.setTextFormat(this._titleTextFormat);/* テキストフィールドに適用 */ this.addChild(titleText); /* 追加 */ this.drawTitle(); /* タイトルの描画 */ } /** 軸のラベルを作成 */ private function createAxisLabel():void { /* x軸のラベル */ this.xLabelText = createTextField("Time(sec)",0,0);/* テキストフィールドの作成 */ this._xLabelTextFormat = new TextFormat(); /* テキストフォーマットの作成 */ this._xLabelTextFormat.color = this.labelTextColor; /* テキストの色 */ this._xLabelTextFormat.size = this.labelFontSize; /* フォントサイズ */ this.xLabelText.setTextFormat(this._titleTextFormat);/* テキストフィールドにフォーマットの適用 */ this.addChild(xLabelText); /* y軸のラベル */ this.yLabelText = createTextField("Amplitude",0,0);/* テキストフィールドの作成 */ this._yLabelTextFormat = new TextFormat(); /* テキストフォーマットの作成 */ this._yLabelTextFormat.color = this.labelTextColor; /* テキストの色 */ this._yLabelTextFormat.size = this.labelFontSize; /* フォントサイズ */ this.yLabelText.setTextFormat(this._titleTextFormat);/* テキストフィールドにフォーマットの適用 */ /* ビットマップにして回転 */ var yLabelTextBmpData:BitmapData = new BitmapData(this.yLabelText.textWidth+5,this.yLabelText.textHeight+5,true); yLabelTextBmpData.draw(this.yLabelText); var yLabelTextBmp:Bitmap = new Bitmap(yLabelTextBmpData,"auto",true); yLabelTextBmp.rotation = -90; /* 真ん中になるようにする */ yLabelTextBmp.x = ((this._graphPaddingLeft - yLabelTextBmpData.height) >>1) - (yLabelTextBmpData.height>>1) + 10; yLabelTextBmp.y = ((this._graphHeight - yLabelTextBmpData.width) >>1) + (yLabelTextBmpData.width) + 10; this.addChild(yLabelTextBmp); this.drawAxisLabel(); } /*======================================================================================*/ /* 背景の描画 */ /*======================================================================================*/ private function drawBackGround():void { base.graphics.clear(); base.graphics.beginFill(bgColor,1); base.graphics.drawRoundRect(10,10,_graphWidth,_graphHeight,10,10); base.graphics.endFill(); } /*======================================================================================*/ /* 軸の描画 */ /*======================================================================================*/ /** 軸の描画 */ private function drawBaseLine():void { /* 初期化 */ this.axisLine.graphics.clear(); this.axisLine.graphics.lineStyle(1,baseLineColor,100,true); this.auxLineX.graphics.clear(); this.auxLineX.graphics.lineStyle(1,auxLineColor,100,true); this.auxLineY.graphics.clear(); this.auxLineY.graphics.lineStyle(1,auxLineColor,100,true); /* 以前追加した目盛のラベルを削除 */ while(scaleTexts.length > 0){ this.removeChild(this.scaleTexts.pop()); } /* 描画処理 */ this.drawAxis(); /* 軸の描画 */ this.drawScale(); /* 軸の目盛の描画 */ this.drawAuxScaleX(); /* x軸方向の補助目盛の描画 */ this.drawAuxScaleY(); /* y軸方向の補助目盛の描画 */ } /** x軸,y軸の描画 */ private function drawAxis():void { axisLine.graphics.moveTo(base_sx ,gl_y); /* x軸の描画 */ axisLine.graphics.lineTo(base_ex ,gl_y); axisLine.graphics.moveTo(gl_x ,base_sy); /* y軸の描画 */ axisLine.graphics.lineTo(gl_x ,base_ey); } /** 目盛の描画 */ private function drawScale():void { /* ----------- x軸の目盛の描画 --------------*/ var l_StepX:int = stepX; /* 軸の間隔 */ if(l_StepX == 0){ /* 軸の間隔が設定されていないとき */ l_StepX = this.data.length / 10; /* 自動設定 する*/ } var i:int = 0; for(i = 1; i < (this._graphWidth - (this._graphPaddingLeft+this._graphPaddingRight )-1) ; i++ ){ if( i % int(this._autoScaleX*l_StepX) == 0){ axisLine.graphics.moveTo(gl_x+i ,gl_y-7); /* 軸の線を描画 */ axisLine.graphics.lineTo(gl_x+i ,gl_y); /* 軸の文字列を描画 */ if(xAxisData != null){ /* 文字列用データがセットしてあるとき */ addScaleTextX(xAxisData[int(i/this._autoScaleX)]+"",gl_x+i,gl_y); }else{ addScaleTextX(i+"",gl_x+i,gl_y); } } } /* ----------- y軸の目盛の描画 --------------*/ var l_StepY:int = stepY; /* 軸の間隔 */ if(l_StepY == 0){ /* 軸の間隔が設定されていないとき */ /* 自動設定する */ l_StepY = (this._graphHeight-(this._graphPaddingTop+this._graphPaddingBottom))/10; } var labelVal:Number; /* GLより上 */ for(i = 0; i <= Math.abs(base_sy-gl_y) ; i++ ){ labelVal = Math.round((i/this._autoScaleY)*100.0)/100.0; /* 自動スケール時の計算 */ if( i % l_StepY == 0){ axisLine.graphics.moveTo(gl_x-7,gl_y-i); axisLine.graphics.lineTo(gl_x,gl_y-i); addScaleTextY(labelVal+"",gl_x,gl_y-i); } } /* GLより下 */ for(i = 1 ; i <= Math.abs(base_ey-gl_y) ; i++ ){ labelVal = Math.round((-i/this._autoScaleY)*100.0)/100.0; if( i % l_StepY == 0){ axisLine.graphics.moveTo(gl_x-7,gl_y+i); axisLine.graphics.lineTo(gl_x,gl_y+i); addScaleTextY(labelVal+"",gl_x,gl_y+i); } } } /** x軸方向の軸の項目を描画 */ private function addScaleTextX(val:String,x:int,y:int):void { var t:TextField = this.createTextField(val,x,y); /* テキストの作成 */ t.defaultTextFormat = this._scaleTextFormat; /* テキストフォーマットの設定 */ t.setTextFormat(this._scaleTextFormat); t.x = x - t.textWidth/2; /* x座標(軸の中心 */ this.addChild(t); /* 追加 */ scaleTexts.push(t); /* 削除用にとっておく */ } /** y軸方向の軸の項目を描画 */ private function addScaleTextY(val:String,x:int,y:int):void { var t:TextField = this.createTextField(val,x,y); /* テキストの作成 */ t.defaultTextFormat = this._scaleTextFormat; /* テキストフォーマットの設定 */ t.setTextFormat(this._scaleTextFormat); t.x = x - t.textWidth-10; /* x座標(軸の左に寄せる) */ t.y = y - t.textHeight/2; /* y座標(軸の中心) */ this.addChild(t); /* 追加 */ scaleTexts.push(t); /* 削除用にとっておく */ } /** 軸目盛用テキストの作成 */ private function createTextField(val:String,x:int,y:int):TextField { var t:TextField = new TextField(); t.antiAliasType = AntiAliasType.ADVANCED; t.autoSize = TextFieldAutoSize.NONE; t.text = val; t.x = x; t.y = y; return t; } /*======================================================================================*/ /* 補助目盛線の描画 */ /*======================================================================================*/ /** 補助目盛線を描画(X軸) */ private function drawAuxScaleX():void { var l_StepX:int = stepX; /* 軸の間隔 */ if(l_StepX == 0){ /* 軸の間隔が設定されていないとき */ l_StepX = this.data.length / 10; /* 自動設定 する*/ } /* 描画の終点 */ var endX:int = (this._graphWidth - /* 幅 */ (this._graphPaddingLeft+this._graphPaddingRight) /* 余白 */ -1) ; for(var i:int = 1; i < endX; i++ ){ if( i % int(this._autoScaleX*l_StepX) == 0){ /* 指定した間隔ごとに */ auxLineX.graphics.moveTo(base_sx+i ,base_sy); /* 軸の線を描画 */ auxLineX.graphics.lineTo(base_sx+i ,base_ey); } } } /** 補助目盛線を描画(Y軸) */ private function drawAuxScaleY():void { var l_StepY:int = stepY; /* 軸の間隔 */ if(l_StepY == 0){ /* 軸の間隔が設定されていないとき */ /* 自動設定する */ l_StepY = (this._graphHeight-(this._graphPaddingTop+this._graphPaddingBottom))/10; } var i:int = 0; /* GLより上 */ for(i = 1; i <= Math.abs(base_sy-gl_y) ; i++ ){ if( i % l_StepY == 0){ auxLineY.graphics.moveTo(base_sx,gl_y-i); auxLineY.graphics.lineTo(base_ex,gl_y-i); } } /* GLより下 */ for(i = 1 ; i <= Math.abs(base_ey-gl_y) ; i++ ){ if( i % l_StepY == 0){ auxLineY.graphics.moveTo(base_sx-7,gl_y+i); auxLineY.graphics.lineTo(base_ex,gl_y+i); } } } /*======================================================================================*/ /* その他の描画 */ /*======================================================================================*/ /** タイトルの描画 */ private function drawTitle():void { this.titleText.autoSize = TextFieldAutoSize.CENTER; this.titleText.x = ((this._graphWidth - titleText.textWidth) >>1) + 10; /* 真ん中になるようにする */ this.titleText.y = ((this._graphPaddingTop - titleText.textHeight) >>1) + 10 ; this.titleText.text = this._title; this.titleText.setTextFormat(this._titleTextFormat); } /** 軸のラベルの描画 */ private function drawAxisLabel():void { this.xLabelText.autoSize = TextFieldAutoSize.CENTER; this.xLabelText.x = ((this._graphWidth - xLabelText.textWidth) >>1) + 10 ;/* 真ん中になるようにする */ this.xLabelText.y = this._graphHeight - this._graphPaddingBottom + ((this._graphPaddingBottom - xLabelText.textHeight) >>1) + 10; this.xLabelText.setTextFormat(this._titleTextFormat); } /*======================================================================================*/ /* その他描画関連 */ /*======================================================================================*/ /** 自動スケール処理を行う */ public function doAutoScale():void { /* 自動スケールのための倍率を計算 */ var max:Number = getMaxValue(); var min:Number = getMinValue(); /* y軸方向の倍率 */ var upper:Number = Math.abs(this.base_sy-gl_y); var under:Number = Math.abs(this.base_ey-gl_y); var tArea:Number = (upper) < (under) ? upper : under; max = max > Math.abs(min) ? max : Math.abs(min); if(max != 0){ this._autoScaleY = tArea / Math.abs(max); }else{ this._autoScaleY = 1; } /* x軸方向の倍率 */ this._autoScaleX = Number(this._graphWidth) / Number(this.data.length) ; } /** 再描画 */ public function refleshLines():void { this.drawBaseLine(); this.drawGraph(); } /** 再描画 */ public function refleshAll():void { this.initPosVal(); /* 座標再調整 */ this.doAutoScale(); /* 自動拡大縮小 */ this.drawBackGround(); /* 背景の描画 */ this.drawTitle(); /* タイトルの描画 */ this.drawAxisLabel(); /* 軸のラベルの描画 */ this.refleshLines(); /* 線の再描画 */ } /*======================================================================================*/ /* その他 */ /*======================================================================================*/ /** データの最大値を得る */ private function getMaxValue():Number { var max:Number = data[0]; /* 最大値 */ for(var i:int = 1; i < data.length; i++){ if(max < data[i]){ /* 一番大きなデータを探す */ max = data[i]; } } return max; } /** データの最小値を得る */ private function getMinValue():Number { var min:Number = data[0]; /* 最小値 */ for(var i:int = 1; i < data.length; i++){ if(min > data[i]){ /* 一番大きなデータを探す */ min = data[i]; } } return min; } /** 表示するデータの変更 */ public function setData(data:Array):void { if( data == null || data.length == 0){ return ; } this.data = data; this.doAutoScale(); } /** x軸方向の軸用データ */ public function setXAxisData(data:Array):void { this.xAxisData = data; } /*======================================================================================*/ /* 作業用 */ /*======================================================================================*/ public function exec():void { /* データ の作成 */ var data:Array = new Array(); /* サイン波初期化 */ initSinGen(2,250,1); /* x軸方向のデータ */ var xdata:Array = new Array(); for(var i:int = 0;i < 400 ; i++){ data[i] = nextWave(); xdata[i] = Number(i)/Number(250); } /* データのセット */ this._title = "Sine Wave"; this.setData(data); this.setXAxisData(xdata); this.refleshAll(); /* タイマー起動 */ var timer:Timer = new Timer(30); timer.addEventListener(TimerEvent.TIMER,onTimer); timer.start(); this.addChild(line); } /** タイマ関数 */ private function onTimer(e:Event):void { /** グラフのシフト */ for(var j:int = 0; j < 4 ; j++){ for(var i:int = 0;i < 400 ; i++){ data[i] = data[i+1]; } data[400-1] = nextWave(); } this.setData(data); this.refleshLines(); } /** グラフの描画 */ private function drawGraph():void { line.graphics.clear(); line.graphics.lineStyle(1,0x5c3f4b,100,true); for(var i:int = 0; i*this._autoScaleX < this._graphWidth - (this._graphPaddingLeft+this._graphPaddingRight) -1 ; i++ ){ var startX:int = base_sx + (i) *this._autoScaleX; var endX:int = base_sx + (i+1) *this._autoScaleX; var startY:int = gl_y - data[i] *this._autoScaleY; var endY:int = gl_y - data[i+1] *this._autoScaleY; line.graphics.moveTo(startX ,startY); line.graphics.lineTo(endX ,endY); } } /*======================================================================================*/ /* 信号生成 */ /*======================================================================================*/ private var siny:Array = new Array(3); /* サイン波生成用 バッファ */ private var angle:Number = 0; /* 角度(ラジアン) */ private var a1:Number = 0.0; /* 係数1 */ private var a2:Number = 0.0; /* 係数2 */ private var freq:int = 0; /* 周波数 */ private var amp:Number = 1; /* 振幅 */ private var sample:int = 250; /* サンプリングレート */ /** * サイン波生成のための変数の初期化処理をする * @param freq 生成するサイン波の周波数 * @param sample サンプリング周波数 * @param amp 生成するサイン波の振幅 */ public function initSinGen(freq:int,sample:int,amp:Number):void{ /* 一回あたりに変化する角度の量 */ angle = (2 * Math.PI * Number(freq)) / Number(sample); siny[0] = 0.0; siny[1] = Math.sin(angle); siny[2] = 0.0; a1 = 2.0 * Math.cos(this.angle); a2 = -1.0; } /** * つぎのサイン波を返す * @return つぎのサイン波 */ public function nextWave():Number{ var wave:Number = (siny[0]*amp); siny[0] = a1 * siny[1] + a2 * siny[2]; //シフト siny[2] = siny[1]; siny[1] = siny[0]; return wave; } } } Code Fullscreen Preview Fullscreen Mingchoi matacat hidrodixtion.. : chartsin newmh : Math.sin Math.sin chart graph realtime sin sine wave Math.max Math.abs Math.min TextFormat exec Math.round Array addEventListener pop StageScaleMode.NO_SCALE start push align Timer String TimerEvent.TIMER size color Math.cos text sort new page view favorite forked pv201 forked from: グラフ。リアルタイムに波形を生成描.. hacker_a81ed2g9 forked:1 favorite:1lines:409 (diff:1) pv0 forked from: グラフ。リアルタイムに波形を生成描.. mattypang forked:0 favorite:0lines:409 (diff:1) pv279 forked from: グラフ。リアルタイムに波形を生成描.. mattypang forked:0 favorite:2lines:409 (diff:1)