はじめに
前回の記事『マウスイベントに対応したグラフを持つWPFアプリケーションの作成』では、ComponentOne Studio Enterprise 2011J(ComponentOne Studio for WPF 2011J)のChart for WPFコンポーネントに含まれるC1Chartコントロールを使って、東京の8月の気温を表示する折れ線グラフを作成しました。
C1Chartコントロールには、前回紹介したものの他にも豊富な機能が組み込まれているので、多彩なグラフを作成することができます。そこで今回は、8月の東京電力管内のある地点における1日当たりの最高気温と電力消費量を、縦棒グラフと折れ線グラフを組み合わせた複合グラフで表示するアプリケーションを作成してみました。
対象読者
Visual Basic、Visual C# 2010を使ってプログラムを作ったことのある人
必要な環境
Visual Basic 2010、Visual C# 2010、Visual Studio 2010でプログラムが作れる環境。なお、本プログラムはWindows Vista上で動作するVisual Studio 2010を使用して作成し、動作確認を行っています。
動作環境として、あらかじめ.NET Framework 4.0がインストールされている必要があります。動作するOSは、以下を参照ください。
OS | 32ビット(x86) | 64ビット(x64) |
Windows XP 日本語版 | ● | ● |
Windows Vista 日本語版 | ● | ● |
Windows 7 日本語版 | ● | ● |
Windows Server 2003 日本語版 | ● | ● |
Windows Server 2008 日本語版 | ● | ● |
Windows Server 2008 R2 日本語版 | - | ● |
コンポーネントのインストール
この記事の手順を試すには、Visual Studio、Visual Basic、Visual C#の開発環境にComponentOne Studio Enterprise 2011J(または、ComponentOne Studio for WPF 2011J)をインストールする必要があります。インストーラは、グレープシティのWebページからダウンロードできます。
製品のトライアル版一覧ページにてダウンロードしたい製品にチェックを入れ、ページ右上部の[申込フォーム]をクリックしてグレープシティのWebサイトへ必要情報を登録すると、添付トライアルライセンスキーファイルとダウンロードサイトを記載したE-Mailが送られてきますので、ここからダウンロードします。制限事項などの詳細については、インストーラに同梱されているリリースノートを参照ください。
コントロールの追加
ComponentOne Studio Enterprise 2011J(または、ComponentOne Studio for WPF 2011J)をインストールしたら、ツールボックスに専用のタブを作成し、使用するコンポーネントを追加します。追加するコンポーネントは、[WPFコンポーネント]でアセンブリ名が「C1.WPF.C1Chart」の「C1Chart」コントロールです。
WPFアプリケーションの作成
C1Chartコントロールについては、前回の記事『マウスイベントに対応したグラフを持つWPFアプリケーションの作成』で概要を説明しているので、今回はさっそくWPFアプリケーションを作成していきます。
GUIのデザイン
今回作成するのは、東京電力管内のある地点での、8月の最高気温と電力消費量(1日当たり)を、縦棒グラフと折れ線グラフの複合グラフで表示するアプリケーションです。
使用するデータが31日分もあるため、これを1つのページに収めようとすると、とても細かなグラフになってしまうので、見やすいサイズのまま横スクロールしていくグラフに仕上げます。使用するコントロールは、C1ChartコントロールとTextBlockコントロールの2つです。
複合グラフの作成
複合グラフは、各系列ごとにDataSeries.ChartTypeプロパティを設定して実現できますが、ここでは、ベースとなるグラフをC1Chartコントロールで、もう1種類のグラフをテンプレートで作成する方法を紹介します。今回の複合グラフは、1日当たりの電力消費量を縦棒グラフで、その日の最高気温を折れ線グラフで作成します。
ちなみに、各系列ごとにDataSeries.ChartTypeプロパティを設定する場合は、下記のように記載します。
<c1chart:DataSeries ChartType="LineSymbols" Label="Series 1" RenderMode="Default" Values="20 22 19 24 25" />
まず、ページにC1Chartコントロールを配置し、グリッドとウィンドウのサイズを変えます。デフォルトではダミーのデータが設定され、チャートは縦棒グラフになっています。
<Window x:Class="WPF_MultiChart_cs.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="552" Width="996" xmlns:c1chart="http://schemas.componentone.com/xaml/c1chart"> <Grid Height="510" Width="898"> <c1chart:C1Chart Height="455" HorizontalAlignment="Left" Margin="33,43,0,0" Name="c1Chart1" VerticalAlignment="Top" Width="803"> <c1chart:C1Chart.Data> <c1chart:ChartData ItemNames="P1 P2 P3 P4 P5"> <c1chart:DataSeries Label="Series 1" RenderMode="Default" Values="20 22 19 24 25" /> <c1chart:DataSeries Label="Series 2" RenderMode="Default" Values="8 12 10 12 15" /> </c1chart:ChartData> </c1chart:C1Chart.Data> <c1chart:C1ChartLegend DockPanel.Dock="Right" /> </c1chart:C1Chart> </Grid> </Window>
ダミーのデータとX軸の軸ラベルを変更します。X軸の軸ラベルは日付にし、最初のデータに消費電力量を、2番目のデータに最高気温を設定します。
<c1chart:C1Chart.Data> <c1chart:ChartData ItemNames="1日 2日 3日 4日 5日 6日 7日 8日 9日 10日 11日 12日 13日 14日 15日 16日 17日 18日 19日 20日 21日 22日 23日 24日 25日 26日 27日 28日 29日 30日 31日" > <!-- 最初の系列 --> <c1chart:DataSeries Label="日最大需要電力(100万kW)" Values="35.86 37.50 39.65 40.67 41.88 42.00 42.31 46.62 48.17 49.00 48.37 44.61 40.76 39.95 40.80 41.82 45.66 49.22 41.51 33.54 32.57 34.52 39.12 42.63 39.29 41.89 34.95 37.64 40.91 41.22 41.16" /> <!-- 2番目の系列 --> <c1chart:DataSeries Label="最高気温(℃)" Values="27.3 29.1 29.3 31.1 31.2 32.3 34.5 33.2 33.9 34.6 35.2 35.1 34.5 33.6 33.2 33.6 33.8 36.1 30.9 25.8 23.5 22.9 30.9 32.0 29.3 31.9 27.5 29.8 29.8 31.7 30.4 " />
データテンプレートを作成します。<Window.Resorce>要素を作成し、ここに<DataTemplate>要素を作成します。テンプレートは、シンボルとラインの2つを、<Grid>コントロールの前に作成します。<DataTemplate>はキーを設定し、ラインでは線の太さを、シンボルでは形状とサイズを作成します。
<Window.Resources> <!-- 折れ線グラフテンプレート- 太線 --> <DataTemplate x:Key="lines"> <c1chart:Lines StrokeThickness="10" /> </DataTemplate> <!-- 折れ線グラフ シンボルテンプレート --> <DataTemplate x:Key="star"> <c1chart:Star Size="20,20" /> </DataTemplate> </Window.Resources>
作成したテンプレートをデータ系列「最高気温」に設定します。まず、「Connection」プロパティに線のテンプレートを設定し、「Symbol」プロパティにシンボルのテンプレートを設定します。これで、データ「最高気温」が折れ線グラフに変わります。
<!-- 2番目の系列 - --> <c1chart:DataSeries Label="最高気温(℃)" Values="27.3 29.1 29.3 31.1 31.2 32.3 34.5 33.2 33.9 34.6 35.2 35.1 34.5 33.6 33.2 33.6 33.8 36.1 30.9 25.8 23.5 22.9 30.9 32.0 29.3 31.9 27.5 29.8 29.8 31.7 30.4 " Connection="{StaticResource lines}" Symbol="{StaticResource star}"/>
スクロールバーの設定
作成したグラフは、31日分のデータが一度に表示されています。全体の傾向を一度に見るにはこれでもかまいませんが、日にちのラベルが重なったりして見づらいので、チャートのサイズを大きくしスクロールして見ることができるようにします。
チャートをスクロールできるようにするには、スクロールバーを使用します。
まず、Viewクラスを使用して、チャートのX軸の表示スケールを大きくします。グラフの各要素は、図のようにそれぞれオブジェクト(クラス)になっています。
この中で、横軸(X軸)のビューを担当しているのが「c1chart:ChartView.AxisX」クラスです。この下層の「Axis」クラスの「Scale」プロパティを使用すると、X軸の表示サイズを変えることができます。設定値は表示倍率で、数字が小さいほど表示範囲が狭くなり、ズーム表示をしたのと同じ結果になります。ここでは「0.3」を設定します。
また、併せて「Title」プロパティにTextBlockコントロールを配置し、X軸のタイトルも設定しておきます。コードは<c1chart:C1ChartLegend>タグの下に記述します。
<c1chart:C1ChartLegend DockPanel.Dock="Right" /> <c1chart:C1Chart.View> <c1chart:ChartView> <c1chart:ChartView.AxisX> <c1chart:Axis Scale="0.3"> <c1chart:Axis.Title> <TextBlock Text="8月" TextAlignment="Center" Foreground="Crimson"/> </c1chart:Axis.Title> </c1chart:Axis> </c1chart:ChartView.AxisX> </c1chart:ChartView> </c1chart:C1Chart.View>
続いて、スクロールバーを作成します。<c1chart:C1ChartLegend>タグの下に、次のコードを記述します。
<c1chart:C1ChartLegend DockPanel.Dock="Right" /> <ScrollBar Name="Scroll1" DockPanel.Dock="Bottom" Minimum="0" Maximum="1" SmallChange="0.01" LargeChange="0.1" Orientation="Horizontal" ViewportSize="0.1" Value="{Binding ElementName=c1Chart1, Path=View.AxisX.Value}" Height="21" Width="458" />
- DockPanel.Dockプロパティ:スクロールバーの表示位置を指定
- Minimum、Maximumプロパティ:スクロールバーの動作範囲を指定
- SmallChange、LargeChangeプロパティ:ボタンやスライダーの動作量を指定
- Orientationプロパティ:スクロールバーの方向を指定
- ViewportSizeプロパティ:スクロール量のレートを設定
- Valueプロパティ:スクロールバーを連結するコントロールとビューを指定
これらのプロパティを使用して、スクロールバーの動作や外観などを設定します。特に、ElementNameに設定するC1Chartコントロールの名前の、大文字小文字に注意してください。これを間違えるとスクロールバーとC1Chartコントロールが連動しなくなります。
チャートの装飾
次に、チャートを装飾します。グラフの背景と縦棒、折れ線とシンボルの色を変えます。デザイン画面でC1Chartコントロールをクリックし、プロパティウィンドウで[ブラシ]をクリックして展開します。「Background」プロパティでグラデーションブラシを選択します。
<c1chart:C1Chart Height="455" HorizontalAlignment="Left" Margin="33,43,0,0" Name="C1Chart1" VerticalAlignment="Top" Width="803" ChartType="Column"> <c1chart:C1Chart.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFE87341" Offset="0" /> <GradientStop Color="#FFF2E2F1" Offset="1" /> </LinearGradientBrush> </c1chart:C1Chart.Background>
XAMLコードウィンドウで最初のデータ系列をクリックします。プロパティウィンドウが「DataSeries」クラスのプロパティに入れ替わるので、[その他]をクリックして展開し、「SymbolFill」プロパティにグラデーションカラーを設定します。
<c1chart:DataSeries.SymbolFill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFA894EB" Offset="0" /> <GradientStop Color="#FF5AAEE2" Offset="1" /> </LinearGradientBrush> </c1chart:DataSeries.SymbolFill>
同様に、2番目のデータ系列から[その他]をクリックして展開し、「SymbolFill」プロパティにグラデーションカラーを設定します。これで、シンボルの色がグラデーションで塗りつぶされます。
続いて「ConnectionFill」プロパティをクリックし、単色で塗りつぶします。これで、折れ線が塗りつぶされます。
<c1chart:DataSeries Label="最高気温(℃)" Values="27.3 29.1 29.3 31.1 31.2 32.3 34.5 33.2 33.9 34.6 35.2 35.1 34.5 33.6 33.2 33.6 33.8 36.1 30.9 25.8 23.5 22.9 30.9 32.0 29.3 31.9 27.5 29.8 29.8 31.7 30.4 " Connection="{StaticResource lines}" Symbol="{StaticResource star}" ConnectionFill="#FF30D7A0">
軸ラベルの設定
最後に、軸ラベルを設定します。左側に表示しているY軸の軸ラベルに加え、右側にも温度表示用のY軸ラベルを追加します。
まず、今ある左側のY軸に軸ラベルを設定します。すでにX軸のラベルを作成してある「View」要素の中に、<c1chart:ChartView.AxisY>タグを作成し、TextBlockコントロールでラベルを作成します。
<c1chart:C1Chart.View> <c1chart:ChartView> <!-- 既存のY軸ラベルを作成 --> <c1chart:ChartView.AxisY> <c1chart:Axis> <c1chart:Axis.Title> <TextBlock Text="日最大需要電力(100万kW)" TextAlignment="Center" Foreground="Crimson"/> </c1chart:Axis.Title> </c1chart:Axis> </c1chart:ChartView.AxisY>
この下に、右側に表示する温度表示用のY軸ラベルを作成します。既にY軸ラベルは作成してあるので、今度はもう1つ「Axis」オブジェクトを作成し、そのプロパティを設定して新しいY軸ラベルを作成します。右側に表示するには「Position」プロパティを「Far」に設定します。
<c1chart:Axis AxisType="Y" Position="Far" Min="0" Max="49" MajorUnit="3" AutoMin="False" AnnoFormat="00" AnnoAngle="60"> <c1chart:Axis.Title> <TextBlock Text="気温(℃)" TextAlignment="Center" Foreground="BlueViolet" Margin="5"/> </c1chart:Axis.Title> </c1chart:Axis>
TextBlockコントロールでグラフの見出しを作成して、完成です。
<TextBlock Height="25" HorizontalAlignment="Left" Margin="124,12,0,0" Name="TextBlock1" Text="8月の東京電力管内の1日当たりの最高気温と電力消費量" VerticalAlignment="Top" Width="499" FontSize="18" />
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="552" Width="996" xmlns:c1chart="http://schemas.componentone.com/xaml/c1chart"> <Window.Resources> <!-- 折れ線グラフテンプレート- 太線 --> <DataTemplate x:Key="lines"> <c1chart:Lines StrokeThickness="10" /> </DataTemplate> <!-- 折れ線グラフ シンボルテンプレート --> <DataTemplate x:Key="star"> <c1chart:Star Size="20,20" /> </DataTemplate> </Window.Resources> <Grid Height="510" Width="898"> <c1chart:C1Chart Height="455" HorizontalAlignment="Left" Margin="33,43,0,0" Name="C1Chart1" VerticalAlignment="Top" Width="803" ChartType="Column"> <c1chart:C1Chart.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFE87341" Offset="0" /> <GradientStop Color="#FFF2E2F1" Offset="1" /> </LinearGradientBrush> </c1chart:C1Chart.Background> <c1chart:C1Chart.Data> <c1chart:ChartData ItemNames="1日 2日 3日 4日 5日 6日 7日 8日 9日 10日 11日 12日 13日 14日 15日 16日 17日 18日 19日 20日 21日 22日 23日 24日 25日 26日 27日 28日 29日 30日 31日" > <!-- 最初の系列 --> <c1chart:DataSeries Label="日最大需要電力(100万kW)" Values="35.86 37.50 39.65 40.67 41.88 42.00 42.31 46.62 48.17 49.00 48.37 44.61 40.76 39.95 40.80 41.82 45.66 49.22 41.51 33.54 32.57 34.52 39.12 42.63 39.29 41.89 34.95 37.64 40.91 41.22 41.16" ConnectionStroke="{x:Null}" ConnectionStrokeThickness="2" ConnectionFill="{x:Null}"> <c1chart:DataSeries.SymbolFill> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="#FFA894EB" Offset="0" /> <GradientStop Color="#FF5AAEE2" Offset="1" /> </LinearGradientBrush> </c1chart:DataSeries.SymbolFill> </c1chart:DataSeries> <!-- 2番目の系列 --> <c1chart:DataSeries Label="最高気温(℃)" Values="27.3 29.1 29.3 31.1 31.2 32.3 34.5 33.2 33.9 34.6 35.2 35.1 34.5 33.6 33.2 33.6 33.8 36.1 30.9 25.8 23.5 22.9 30.9 32.0 29.3 31.9 27.5 29.8 29.8 31.7 30.4 " Connection="{StaticResource lines}" Symbol="{StaticResource star}" ConnectionFill="#FF30D7A0"> <c1chart:DataSeries.SymbolFill> <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5"> <GradientStop Color="#FFD8458A" Offset="0" /> <GradientStop Color="#FFAD48EB" Offset="1" /> </LinearGradientBrush> </c1chart:DataSeries.SymbolFill> </c1chart:DataSeries> </c1chart:ChartData> </c1chart:C1Chart.Data> <c1chart:C1ChartLegend DockPanel.Dock="Right" Height="57" Width="192" /> <ScrollBar Name="sb" DockPanel.Dock="Bottom" Minimum="0" Maximum="1" SmallChange="0.01" LargeChange="0.1" Orientation="Horizontal" ViewportSize="0.1" Value="{Binding ElementName=C1Chart1, Path=View.AxisX.Value}" Height="21" Width="458" /> <c1chart:C1Chart.View> <c1chart:ChartView> <c1chart:ChartView.AxisY> <c1chart:Axis> <c1chart:Axis.Title> <TextBlock Text="日最大需要電力(100万kW)" TextAlignment="Center" Foreground="Crimson"/> </c1chart:Axis.Title> </c1chart:Axis> </c1chart:ChartView.AxisY> <c1chart:Axis AxisType="Y" Position="Far" Min="0" Max="49" MajorUnit="3" AutoMin="False" AnnoFormat="00" AnnoAngle="60" > <c1chart:Axis.Title> <TextBlock Text="気温(℃)" TextAlignment="Center" Foreground="BlueViolet" Margin="5"/> </c1chart:Axis.Title> </c1chart:Axis> <c1chart:ChartView.AxisX> <c1chart:Axis Scale="0.3"> <c1chart:Axis.Title> <TextBlock Text="8月" TextAlignment="Center" Foreground="Crimson"/> </c1chart:Axis.Title> </c1chart:Axis> </c1chart:ChartView.AxisX> </c1chart:ChartView> </c1chart:C1Chart.View> </c1chart:C1Chart> <TextBlock Height="25" HorizontalAlignment="Left" Margin="124,12,0,0" Name="TextBlock1" Text="8月の東京電力管内の1日当たりの最高気温と電力消費量" VerticalAlignment="Top" Width="499" FontSize="18" /> </Grid> </Window>
まとめ
多彩な機能を持つC1Chartコントロールは、それらの機能を組み合わせて使うことができます。今回は、2つのデータ系列で複合グラフを作成しましたが、さらにチャートを重ね合わせることも可能ですし、違うタイプのチャートで表現することもできます。