はじめに
古くから人々はデータを視覚化させ、情報を分かりやすくする試みを行ってきました。駅の構内案内図やグラフなどが身近なよい例でしょう。
中でも意思決定や判断の材料に有効な可視化手段として、自動車の速度計や温度計のように、即時性があり現状をすばやく把握するのに適したゲージタイプがあります。
2010年6月にリリースされたばかりの.NETアプリケーション向けコンポーネント「NetAdvantage for WPF Data Visualization 2010 Volume 2」を使うと、そのようなゲージを簡単に作成できます。今回は、現在のCPU利用率を表示させるガジェットの作成を例に、その概要を紹介します。
対象読者
Visual Basic 2010またはVisual C# 2010でWindows Forms/WPFアプリケーションを作成したことがある人。
必要環境
Visual Basic 2010、Visual C# 2010以降の開発環境。今回のサンプルは原稿執筆時の最新バージョンであるVisual Studio 2010 Ultimate、.NET Framework 4にて作成しています。また、Windows 7 Ultimate(64ビット)において動作を検証しています。
プログラム実行時の注意環境
あらかじめ.NET Framework 4以降のランタイムが動作環境にインストールされていることを確認してください。
コンポーネントのインストール
はじめてNetAdvantage for WPF Data Visualizationを使用する場合は、事前にソフトウェアをインストールする必要があります。インフラジスティックス社のWebページからインストーラーをダウンロードしてください(サイトへの登録が必要になります)。この製品は有償ですが、20日間すべての機能を使用できるトライアル版としてインストール可能です。
NetAdvantage for WPF Data Visualization
2009年にSilverlight 2ベースのデータ視覚化コンポーネントスイートとして発売され、2010年6月にWPF版が新たに発売されました。原稿執筆時点での日本語版最新バージョンは2010 Volume 2で、Visual Studio 2010、Expression Blend 4に対応しています。
収録されているコントロールは今回のゲージの他に、大量データに対応したハイパフォーマンスチャート、Microsoft Excelのピボットテーブルの機能を実現可能なピボットグリッド、さらにバーコート作成コントロールなどを含んでいます。
このスイートを含め、インフラジスティックス社のコントロールを使用したサンプルについては、サンプルサイトで確認することができます。
ゲージコントロール
NetAdvantage for WPF Data Visualizationでは3種類のゲージがサポートされています。
- xamRadialGauge
- xamLinearGauge
- xamDigitalGauge
円形で示される範囲で現在の値を表示します。例:時計、自動車の速度計など
直線で示される範囲で現在の値を表示します。例:温度計など
デジタル数値表示で現在の値を表示します。例:デジタル時計、カウントダウンタイマーなど
また、ゲージのそれぞれの部分に関して下記のような定義がされています。
スケール
ゲージの値の範囲を定義します。このスケールに針、ラベル、目盛、範囲を追加することでゲージを完成させます。

針
スケールの中で単一の値を指示するポインタとして表示されます。

ラベル
ゲージにn番目ごとの間隔でラベルを表示し、大体の値を示す手助けとなります。

目盛
ゲージにn番目ごとの間隔で線を表示し、現在の値の表示をガイドします。

範囲
スケールの中で指定された値の範囲を強調させる視覚的なエレメントです。

本稿ではxamRadialGaugeを使用します。
新規WPFプロジェクトの作成
まずVisual Studio 2010を起動し、Visual BasicまたはVisual C#を選択したのち、新しいWPFアプリケーションを作成します。ここではプロジェクト名を「NA_CpuGauge」とします。
MainWindow.xamlのカスタマイズ
既定ではアプリケーションの起動時に表示させるウィンドウとしてMainWindow.xaml、MainWindow.xaml.csが設定されています。この項目ではガジェットらしく、ウィンドウの枠の非表示やサイズ指定を行います。また、この際、x:Name属性を「CpuGaugeWindow」と設定します。この段階ではWindow自体のBackgroundはBlueと設定します。
<Window x:Class="NA_CpuGauge.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
x:Name="CpuGaugeWindow"
Height="200" Width="200"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
Background="Blue"
ResizeMode="NoResize"
Topmost="True">
<Grid>
</Grid>
</Window>
実行すると青色の四角が表示されていることを確認できます。

このままではガジェット自体の移動ができないので、MouseMoveイベントを定義し、イベントハンドラ内でDragMove()メソッドを使用し、ドラッグ移動を可能にします。
<Window x:Class="NA_CpuGauge.MainWindow"
…
MouseMove="CpuGaugeWindow_MouseMove">
<Grid>
</Grid>
</Window>
private void CpuGaugeWindow_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
DragMove();
}
ここまでのアプリケーションを実行すると枠のないアプリケーションが起動し、マウスでのドラッグが可能になっていることが分かります。
xamRadialGaugeコントロールを追加
xamRadialGaugeコントロールをWindowに追加するにはまず、[ソリューションエクスプローラ]タブで参照設定に以下のアセンブリを追加します。
- InfragisticsWPF4.Controls.Charts.XamGauge.v10.2.dll
- InfragisticsWPF4.DataVisualization.v10.2.dll
- InfragisticsWPF4.v10.2.dll

次にMainWindow.xamlのXML名前空間を指定します。
<Window x:Class="NA_CpuGauge.MainWindow"
…
xmlns:ig=http://schemas.infragistics.com/xaml>
<Grid>
</Grid>
</Window>
最後にxamRadialGaugeを追加します。また、WindowのBackgroundをTransparent、AllowTransparencyプロパティをTrueとしてゲージのみ表示されるように変更します。
<Window x:Class="NA_CpuGauge.MainWindow"
…
Background="Transparent"
AllowsTransparency="True"
xmlns:ig="http://schemas.infragistics.com/xaml">
<Grid>
<ig:XamRadialGauge Name="xamRadialGauge1" />
</Grid>
</Window>

スケール、針、目盛を追加
追加したxamRadialGaugeには何も表示されていないので、スケール、針、目盛をそれぞれ追加します。スケールを追加する場合は[プロパティ]ウィンドウからScalesコレクションエディタを起動することで簡単に追加できます。追加ScaleにはStartAngleを150、EndAngleを390と設定します。

<ig:XamRadialGauge Name="xamRadialGauge1">
<ig:XamRadialGauge.Scales>
<ig:RadialGaugeScale StartAngle="150" EndAngle="390" />
</ig:XamRadialGauge.Scales>
</ig:XamRadialGauge>
続いて、RadialGaugeScaleに針、目盛、ラベル、範囲を追加します。すべてコレクションエディタを使用し追加が可能です。

針を追加する場合はNeedlesコレクションエディタを使用します。この針には明示的に名前を「Needle1」と設定します。
<ig:XamRadialGauge Name="xamRadialGauge1">
<ig:XamRadialGauge.Scales>
<ig:RadialGaugeScale StartAngle="150" EndAngle="390" >
<ig:RadialGaugeScale.Needles>
<ig:RadialGaugeNeedle x:Name="Needle1" >
<ig:RadialGaugeNeedle.Response>
<ig:GaugeMarkerResponse RefreshRate="00:00:00.0100000" />
</ig:RadialGaugeNeedle.Response>
</ig:RadialGaugeNeedle>
</ig:RadialGaugeScale.Needles>
</ig:RadialGaugeScale>
</ig:XamRadialGauge.Scales>
</ig:XamRadialGauge>
ラベルを追加する場合はLabelGroupsコレクションエディタを使用します。
<ig:XamRadialGauge Name="xamRadialGauge1">
<ig:XamRadialGauge.Scales>
<ig:RadialGaugeScale StartAngle="150" EndAngle="390" >
…
<ig:RadialGaugeScale.LabelGroups>
<ig:RadialGaugeLabelGroup />
</ig:RadialGaugeScale.LabelGroups>
</ig:RadialGaugeScale>
</ig:XamRadialGauge.Scales>
</ig:XamRadialGauge>
次に目盛を追加するため、TickMarkGroupsコレクションエディタを使用します。ここでは目盛の間隔を示すIntervalを5、StartExtentを0.5、EndExtentを1と設定します。
<ig:XamRadialGauge Name="xamRadialGauge1">
<ig:XamRadialGauge.Scales>
<ig:RadialGaugeScale StartAngle="150" EndAngle="390" >
…
<ig:RadialGaugeScale.TickMarkGroups>
<ig:RadialGaugeTickMarkGroup Interval="5" StartExtent="0.5" EndExtent="1" />
</ig:RadialGaugeScale.TickMarkGroups>
</ig:RadialGaugeScale>
</ig:XamRadialGauge.Scales>
</ig:XamRadialGauge>
最後に範囲を追加します。今回は80-100の値が危険領域ということを示すため、StartValueを80、EndValueを100、FillをRedと設定しています。
<ig:XamRadialGauge Name="xamRadialGauge1">
<ig:XamRadialGauge.Scales>
<ig:RadialGaugeScale StartAngle="150" EndAngle="390" >
…
<ig:RadialGaugeScale.Ranges>
<ig:RadialGaugeRange StartValue="80" EndValue="100" Fill="Red" InnerExtentEnd="0.7" InnerExtentStart="0.7" OuterExtent="0.8" />
</ig:RadialGaugeScale.Ranges>
</ig:RadialGaugeScale>
</ig:XamRadialGauge.Scales>
</ig:XamRadialGauge>
上記の設定がすべて完了した時点で実行するとゲージが画面に出力されます。

CPUの使用率を測定する
今回、CPUの使用率を測定する方法として、パフォーマンスカウンタを使用します。MSDNのCodeRecipe逆引きサンプルコードに実装例が記載されていますので、[C#]CPUの使用率を特定の間隔で測定する方法、[VB]CPUの使用率を特定の間隔で測定する方法を参照し、ロード時にパフォーマンスカウンタの値を定期的に取得するコードを作成します。
まず、Windowがロードされた時点でイベントを発生させます。
<Window x:Class="NA_CpuGauge.MainWindow"
…
Loaded="CpuGaugeWindow_Loaded">
<Grid>
…
</Grid>
</Window>
イベントハンドラー内でPerformanceCounter、DispatcherTimerを初期化し、CPUの現在の使用率を取得するように設定します。
private PerformanceCounter pc;
private DispatcherTimer timer;
private void CpuGaugeWindow_Loaded(object sender, RoutedEventArgs e)
{
// パフォーマンス カウンタを初期化します。
pc = new PerformanceCounter("Processor", "% Processor Time", "_Total", true);
// タイマーの初期化を行います。
timer = new DispatcherTimer();
// 1 秒単位で繰り返し処理を行います。
timer.Interval = TimeSpan.FromMilliseconds(1000);
// 処理の内容はこのデリゲートに記述します。
timer.Tick += new EventHandler(timer_Tick);
// タイマーを開始します。
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
// 現在の値を取得し、ゲージの値を設定します。
Needle1.Value = pc.NextValue();
}
このPerformanceCounterはアンマネージリソースであるため、使用後に明示的に解放する必要があります。今回は暫定的にClosingイベント内でDisposeメソッドを呼び出すことにします。
<Window x:Class="NA_CpuGauge.MainWindow"
…
Closing="CpuGaugeWindow_Closing">
<Grid>
…
</Grid>
</Window>
private void CpuGaugeWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
// パフォーマンス カウンタを解放します。
pc.Dispose();
}
実行すると現在のCPU使用率が表示されます。

滑らかにアニメーション
このゲージは1秒おきに値の変更が即座に反映されるため、動きがスムーズではありません。値の変更を滑らかにする場合、Needle.Responseプロパティを設定します。
<ig:XamRadialGauge Name="xamRadialGauge1">
<ig:RadialGaugeScale.Needles>
<ig:RadialGaugeNeedle x:Name="Needle1">
<ig:RadialGaugeNeedle.Response>
<ig:GaugeMarkerResponse RefreshRate="00:00:00.0100000" Enabled="True" ResponseTime="00:00:03" />
</ig:RadialGaugeNeedle.Response>
</ig:RadialGaugeNeedle>
</ig:RadialGaugeScale.Needles>
</ig:RadialGaugeScale>
</ig:XamRadialGauge.Scales>
</ig:XamRadialGauge>
まとめ
今回はVisual Studio 2010を用いてCPU利用率を計測するガジェットの作成を行いました。データ視覚化の活用は今後他社のソリューションとの差別化において非常に有用ではないでしょうか。ぜひNetAdvantage WPF Data Visualizationを使用しリッチなデータ表現を実現してください。







