司道光
【摘 要】WPF為Windows Presentation Foundation縮寫(xiě) ,是微軟新一代圖形系統(tǒng),運(yùn)行在.NET Framework 3.0架構(gòu)下,為用戶界面、2D/3D 圖形、文檔和媒體提供統(tǒng)一的描述和操作方法?;赪PF技術(shù)雷達(dá)動(dòng)畫(huà)設(shè)計(jì),動(dòng)畫(huà)演變時(shí)間進(jìn)度與軟件節(jié)點(diǎn)狀態(tài)同步響應(yīng)設(shè)計(jì),可實(shí)現(xiàn)雷達(dá)掃描實(shí)時(shí)性。異步方式節(jié)點(diǎn)狀態(tài)監(jiān)測(cè),利用線程獨(dú)立于雷達(dá)進(jìn)程運(yùn)行,為其提供后臺(tái)監(jiān)測(cè)服務(wù),完成對(duì)雷達(dá)節(jié)點(diǎn)數(shù)據(jù)轉(zhuǎn)換要求。
【關(guān)鍵詞】WPF,XAML語(yǔ)言 雷達(dá)模型 動(dòng)畫(huà)
1 WPF技術(shù)簡(jiǎn)介
基于DirectX 9/10技術(shù)的WPF不僅帶來(lái)前所未有的3D界面,且其圖形向量渲染引擎也大大改進(jìn)傳統(tǒng)2D界面,如Vista中半透明效果窗體等都得益于WPF。 WPF相對(duì)于Windows客戶端開(kāi)發(fā)來(lái)說(shuō),向前跨出很大一步,它提供了超豐富的.NET UI 框架,集成矢量圖形,豐富流動(dòng)文字支持flow text support,3D視覺(jué)效果和強(qiáng)大無(wú)比的控件模型框架。
2 WPF技術(shù)雷達(dá)實(shí)現(xiàn)
XAML標(biāo)記語(yǔ)言是WPF技術(shù)特色,設(shè)計(jì)人員利用它能構(gòu)建絢麗多彩UI界面。實(shí)際開(kāi)發(fā)中,設(shè)計(jì)人員利用Microsoft Expression Blend 工具來(lái)設(shè)計(jì)界面,并生成XAML用戶界面,下面例子是利用XAML構(gòu)建雷達(dá)模型,實(shí)現(xiàn)雷達(dá)動(dòng)畫(huà),利用C#語(yǔ)言完成監(jiān)控業(yè)務(wù)邏輯,實(shí)現(xiàn)C#與XAML語(yǔ)言完美結(jié)合,為用戶創(chuàng)建震撼效果的雷達(dá)監(jiān)控功能。本案例使用了Mircosoft Visual Studio.NET 2008開(kāi)發(fā)工具和Microsoft Expression Blend 2設(shè)計(jì)工具,采用C/S架構(gòu)模式,使用C#語(yǔ)言和Xaml語(yǔ)言。
2.1 雷達(dá)監(jiān)控功能描述
雷達(dá)圖的圖形界面分三個(gè)區(qū)域:區(qū)一表示業(yè)務(wù)系統(tǒng)運(yùn)行正常;區(qū)二表示業(yè)務(wù)系統(tǒng)部分關(guān)鍵指標(biāo)出現(xiàn)告警,系統(tǒng)運(yùn)行受到影響;區(qū)三表示業(yè)務(wù)系統(tǒng)關(guān)鍵指標(biāo)不可用,系統(tǒng)運(yùn)行不可用;各系統(tǒng)監(jiān)測(cè)狀態(tài)主要通過(guò)探針?lè)?wù)器直接進(jìn)行可用性探測(cè),并參考各業(yè)務(wù)核心關(guān)鍵指標(biāo),各系統(tǒng)圖標(biāo)依據(jù)以上三種狀態(tài)進(jìn)行顏色變化。當(dāng)某個(gè)系統(tǒng)出現(xiàn)問(wèn)題后(區(qū)域二或區(qū)域三)進(jìn)行告警,據(jù)問(wèn)題嚴(yán)重程度排序顯示。并展示各業(yè)務(wù)系統(tǒng)運(yùn)行狀態(tài)統(tǒng)計(jì)圖。
2.2 雷達(dá)建模
這里主要使用Expression Blend工具來(lái)生成XAML語(yǔ)言雷達(dá)模型,設(shè)計(jì)時(shí)將Canvas元素作為模型容器,內(nèi)部使用大小不同Ellipse元素,轉(zhuǎn)換成路徑,通過(guò)漸變填充構(gòu)建出雷達(dá)效果背景。
2.3 雷達(dá)動(dòng)畫(huà)驅(qū)動(dòng)
創(chuàng)建雷達(dá)動(dòng)畫(huà),動(dòng)畫(huà)主要針對(duì)上述指針模型,圍繞雷達(dá)中心點(diǎn),周而復(fù)始進(jìn)行360度旋轉(zhuǎn)。下面代碼是雷達(dá)動(dòng)畫(huà)故事版代碼,每一圈動(dòng)畫(huà)速率為10秒。
//加載雷達(dá)故事板Story = (Storyboard)this.Resources["EllipseAnimation"];
//觸發(fā)時(shí)間線過(guò)度事件Story.CurrentTimeInvalidated += new EventHandler(story_CurrentTimeInvalidated);Story.Begin();
2.4 雷達(dá)掃描同步
雷達(dá)掃描同步是動(dòng)畫(huà)演變時(shí)間進(jìn)度與軟件節(jié)點(diǎn)狀態(tài)同步響應(yīng)設(shè)計(jì),利用Storyboard類中故事板對(duì)象CurrentTimeInvalidated事件,實(shí)現(xiàn)掃描進(jìn)度與實(shí)際監(jiān)控狀態(tài)響應(yīng)同步。
///節(jié)點(diǎn)狀態(tài)同步監(jiān)測(cè)服務(wù)類PCTK.App_Code.SystemSoftAnimation Syssoft;
//時(shí)間線事件 void story_CurrentTimeInvalidated(object sender, EventArgs e){Clock myClock = (Clock)sender; if (myClock.CurrentTime != null)
double TotalSeconds =Math.Round(myClock.CurrentTime.Value.TotalMilliseconds, 4);
CountAnimation = (int)TotalSeconds / 10000;
double NowIndex = Math.Round((TotalSeconds - CountAnimation * 10000) / avgtime, 4);Syssoft.SetSoftState(NowIndex); Syssoft.SetSoftXY(); }}
2.5 節(jié)點(diǎn)狀態(tài)異步監(jiān)測(cè)
節(jié)點(diǎn)狀態(tài)監(jiān)測(cè)主要是獨(dú)立于雷達(dá)動(dòng)畫(huà)進(jìn)程節(jié)點(diǎn)狀態(tài)監(jiān)測(cè),是雷達(dá)中表現(xiàn)的被監(jiān)控對(duì)象。在本案例中節(jié)點(diǎn)是各應(yīng)用系統(tǒng),用獨(dú)立線程從中間庫(kù)提取應(yīng)用系統(tǒng)運(yùn)行狀態(tài), Thread DataServiceProcess = new Thread(new ThreadStart(GetState)); // GetState狀態(tài)檢測(cè)過(guò)程DataServiceProcess.IsBackground = true;DataServiceProcess.Start();
在本案例中自定義了節(jié)點(diǎn)狀態(tài)監(jiān)測(cè)服務(wù)類NodeDataService 主要完成節(jié)點(diǎn)狀態(tài)監(jiān)測(cè)和節(jié)點(diǎn)分布變化邏輯,是雷達(dá)監(jiān)控業(yè)務(wù)核心邏輯,通過(guò)動(dòng)畫(huà)演變引發(fā)時(shí)間線事件,來(lái)調(diào)用內(nèi)部方法,實(shí)現(xiàn)雷達(dá)掃描狀態(tài)實(shí)時(shí)變化。本案例中還構(gòu)建一個(gè)節(jié)點(diǎn)Model對(duì)象類,并在NodeDataService 類中定義了該對(duì)象泛型集合,實(shí)現(xiàn)監(jiān)控進(jìn)程與動(dòng)畫(huà)UI進(jìn)程數(shù)據(jù)通信。
2.6 節(jié)點(diǎn)分布
節(jié)點(diǎn)分布是雷達(dá)中為各應(yīng)用系統(tǒng)生成的標(biāo)點(diǎn),即圖標(biāo),圖標(biāo)據(jù)系統(tǒng)狀態(tài)進(jìn)行顏色變化及區(qū)域跳轉(zhuǎn),所有標(biāo)點(diǎn)在雷達(dá)圓中按排列規(guī)則計(jì)算標(biāo)點(diǎn)坐標(biāo),實(shí)現(xiàn)均勻分布。
double iangle = Math.Round(n * angle, 3);
///采用三角計(jì)算公式 勾股定理,角度正弦值求標(biāo)點(diǎn)的半徑長(zhǎng)度
Point p = new Point(); if (iangle <= 90){p.X = AVGP + Math.Round(dc * Math.Sin(iangle * (Math.PI / 180)), 2) - widths / 2; p.Y = AVGP - Math.Round(dc * Math.Sin((90 - iangle) * (Math.PI / 180)), 2) - 12;}
else{if (iangle <= 180){ p.X = AVGP + Math.Round(dc * Math.Sin((180 - iangle) * (Math.PI / 180)), 4) - widths / 2; p.Y = AVGP + Math.Round(dc * Math.Sin((90 - (180 - iangle)) * (Math.PI / 180)), 2) - 12; }
else{if (iangle <= 270){
p.X = AVGP - Math.Round(dc * Math.Sin((iangle - 180) * (Math.PI / 180)), 2) - widths / 2;
p.Y = AVGP + Math.Round(dc * Math.Sin((270 - iangle) * (Math.PI / 180)), 2) - 12; }
else{if (iangle <= 360) {
p.X = AVGP - Math.Round(dc * Math.Sin((90 - (iangle - 270)) * (Math.PI / 180)), 2) - widths ;
p.Y = AVGP - Math.Round(dc * Math.Sin((90 - (360 - iangle)) * (Math.PI / 180)), 2) - 12;
}return p;}