折れ線グラフ、棒グラフ
WPF-Toolkit、Silverlight Toolkit に、System.Windows.Controls.DataVisualization があり、折れ線グラフや棒グラフが描けます。
インストールしたら、プロジェクトの参照に System.Windows.Controls.DataVisualization を加えます。
Visual Studio のデザイナで、Chart を張り付けると以下のような表示になります。
XAMLには、必要な変更が加えられます。
Chartの描画自体の表現は、概ね以下のような内容が追加されます。
ColumnSeries と言うのが、棒グラフを指すようです。
- <toolkit:Chart Grid.Column="0" Name="chart1"
- HorizontalAlignment="Left" VerticalAlignment="Top">
- <toolkit:ColumnSeries DependentValuePath="X" IndependentValuePath="Y">
- <toolkit:ColumnSeries.ItemsSource>
- <PointCollection>
- <Point>1,10</Point>
- <Point>2,20</Point>
- <Point>3,30</Point>
- <Point>4,40</Point>
- </PointCollection>
- </toolkit:ColumnSeries.ItemsSource>
- </toolkit:ColumnSeries>
- </toolkit:Chart>
これを、LineSeries に変えると、折れ線グラフになります。
- <toolkit:Chart Grid.Column="1" Name="chart2"
- HorizontalAlignment="Left" VerticalAlignment="Top">
- <toolkit:LineSeries DependentValuePath="X" IndependentValuePath="Y"
- >
- <toolkit:LineSeries.ItemsSource>
- <PointCollection>
- <Point>1,10</Point>
- <Point>2,20</Point>
- <Point>3,30</Point>
- <Point>4,40</Point>
- </PointCollection>
- </toolkit:LineSeries.ItemsSource>
- </toolkit:LineSeries>
- </toolkit:Chart>
これをスタート地点に、思い通りの図が書けるようになりたいと思います。
意図するのは、綺麗な図と言うよりエンジニアリング用の緻密な図です。
いろいろ試して、以下のようなSilverlightアプリケーションで使って見ました。
ToolKitのChartは大変高機能で、なんでもカスタマイズできますが、同じような折れ線グラフを簡便に描くには覚えることが多すぎます。
仕組みを理解できたら、ToolKitのChartを使ったカスタムなライブラリにしておくことにします。
Silverlightでのxapのサイズ
Silverlight4で、新たに作成したプロジェクトで作られる何もしない xap のサイズは4KBでした。
これに単にChartを張り付けてビルドすると 377KB になりました。
この機能は、Silverlight の ランタイムに含まれるものではなく、個々の .xap にリンクされるもののようです。
チャートの種類
ToolKitのChartは、以下のようなチャートが描けるようです。
ここでは、Line だけを考えます。
-
Area
-
Bar
-
Bubble
-
Column
Rectangleで描かれる。
-
Line
PolyLine で描かれる。
-
Pie
-
Scatter
レイアウト
表示されるチャートは、左図のような構成になっています。
チャートを使うには、XAMLで <Chart … とChartタグを必要な位置に記述することになりますが、このChartコントロールのデフォルトのテンプレートが以下のようになっているものと思います。
-
Chartタグで、図にあるプロパティを設定すればカスタマイズできます。
-
Chartタグで、Chartのテンプレートを記述すると任意のレイアウトになります。
この場合、ChartArea、Legend の名前を使う必要があり、その型は、EdgePanel、Legendであることが必要です。
Chartの構成
折れ線グラフを描く観点で見ると以下のような構成になっています。
- 折れ線グラフのデータは、Point の列で表されます。
- 線は複数引くことがあるので、Chartは、Point の列である LineSeries のコレクションを持ちます。
- データを表す線以外の要素として、Chartには、タイトル、凡例、軸があります。
- タイトルは、文字列に限らず、コントロールを表示できます。
- タイトルを非表示にすると、タイトルが占めていた表示領域は解放され、チャートが大きくなります。
- 凡例には、タイトルが付けられます。
- 凡例のLegendItemsは、LineSeries の追加に連動しています。
- 凡例を非表示にすると、タイトルが占めていた表示領域は解放され、チャートが大きくなります。
- 軸は、Chartの軸と、LineSeriesごとの軸の2か所にあります。
- 折れ線上のPointの示す位置には丸などのマークが描かれます。これは、DataPointStyleでカスタマイズできます。
軸の構成
軸には、目盛りを表示することと、データをスケーリングして表示することの2つの目的があります。
特に指定しない場合、自動的にデータ値の最大値、最小値から適切な軸、スケーリングが行われます。
しかし、複数の線を引く場合、体重と伸長のようなケースでは、単に最大値、最小値から軸やスケーリングを決めることはできません。
toolkit の Chart は、軸にMinimun、Maximunプロパティを持ち、この値は目盛りを決めると同時に、データのスケーリングにも使われます。
したがって、Chartにある軸ではなく、LineSeriesにある軸を使うのが普通そうです。
軸は、次のような構成です。
- Minimun、Maximunプロパティは、軸の目盛りの最大、最小を設定します。
- 同時に、データがスケーリングされ、範囲外のデータは見えないことになります。
- 指定しない場合は、データの最大値、最小値が使われます。
- 軸は、水平方向、垂直方向でことなります。
- 軸の表示位置は、上下、左右、4か所から指定できます。
- 水平、または垂直の補助線(GridLine)の表示、非表示が設定できます。
- そのStyleを設定できます。
- 軸には、そのタイトルを設定できます。これは文字列に限らず、コントロールが設定できます。
- 軸に表示される数値は、AxisLabelと言うようで、この文字列化はStringFormatで変更できます。
- デフォルトは、"{0}"となり、C#のランタイムが適宜丸めた数字になります。軸に同じ数字が並ぶことも起きます。
ライブラリ化
Chartは高機能でなんでもできますが、折れ線グラフを描こうと思ったときに発想することとは、だいぶ距離があります。
わたしのイメージするところを書きます。上の目次から、「ベクターにアップしたプログラム」
「SimpleChart(WPF,Silverlight)」以下を参照ください。
サイズ
Gridで確保した空間に配置したいと思います。デフォルトでは、中央にこじんまりと表示されます。
タイトル と 凡例の Visibility を Collapsed に設定すると最大サイズで表示できます。
さらに軸のラベルを非表示にした状態が最大だと思います。
タイトル
Title の Visibility を Collapsed に設定すると、表示スペースが割り当てられません。設定方法は、「サイズ」を参照。
デフォルトでは、常に割り当てられていて、文字が割り当てられると、それに合わせて、さらに大きな表示スペースが割り当てられます。
デザイナでは、Chart.Title を指定しないか、空文字列の場合、小さな表示スペースが割り当てられます。一度、文字列を設定すると、文字列に合わせて大きなスペースが割り当てられます。これは、Titleを空にしたり削除してもそのままにです。
ビハインドコードからも同様で、一度割り当てた表示スペースは、Title を null にしても解放されません。
凡例
凡例の非表示
「サイズ」参照。
凡例の位置
表示非表示同様、LegendStyle で設定します。Margin を使を使います。
どこが、基準なのかは良くわかりません。
LegendStyle で設定すると、他の項目もStyleのデフォルト状態になり、指定しなかった場合とは異なる表示になります。(すべての項目を自前で設定する必要があります。)
「凡例項目の設定」に例。
凡例項目の設定
- <toolkit:Chart Grid.Column="1" Name="chart2"
- HorizontalAlignment="Left" VerticalAlignment="Top" Width="154">
- <toolkit:Chart.LegendStyle>
- <Style TargetType="toolkit:Legend">
- <Setter Property="Margin" Value="0,0"/>
- <Setter Property="VerticalAlignment" Value="Center"/>
- <Setter Property="BorderBrush" Value="Gray"/>
- <Setter Property="Background">
- <Setter.Value>
- <LinearGradientBrush EndPoint="0.4,0.005" StartPoint="0.5,0.9">
- <GradientStop Color="Gray"/>
- <GradientStop Color="White" Offset="1"/>
- </LinearGradientBrush>
- </Setter.Value>
- </Setter>
- </Style>
- </toolkit:Chart.LegendStyle>
マーク
線上のマークを非表示
- <toolkit:LineSeries DependentValuePath="X" IndependentValuePath="Y"
- Foreground="blue" Background="Cyan">
- <toolkit:LineSeries.DataPointStyle>
- <Style TargetType="toolkit:LineDataPoint">
- <!-- マークなし -->
- <Setter Property="Template" Value="{x:Null}"/>
- </Style>
- </toolkit:LineSeries.DataPointStyle>
線上のマークの形状設定
近傍のGridなどでテンプレートを定義します。
- <Grid.Resources>
- <ControlTemplate x:Key="mark_template">
- <Rectangle Width="6" Height="6" Stroke="Red"/>
- </ControlTemplate>
- </Grid.Resources>
これを設定すればマークの形状は変わります。
- <DVC:LineSeries.DataPointStyle>
- <Style TargetType="DVC:LineDataPoint">
- <Setter Property="Template"
- Value="{StaticResource ResourceKey=mark_template}"/>
- </Style>
- </DVC:LineSeries.DataPointStyle>
マークは、線と同じ色とか、凡例と同期があるので、もう少し工夫が必要です。
参照
最上部の目次から、「ベクターにアップしたプログラム」「SimpleChart(WPF,Silverlight)」以下にあるようなライブラリを作りました。
折れ線に付与するマークの設定は、いろいろな要素があって以下のようなことを調べました。
「カスタムコントロールのXAMLとコード」
「Styleとプロパティ」
「Styleとバインディング」
「DataContextとインスタンス」
「XAML記述とVisualの変換」
「1つのStyle記述から複数のインスタンス」
「FrameworkElementFactory(コードでTemplateを作る)」
-
XAMLを分割して記述する方法
-
記述1つから複数のインスタンスを得る方法
が、必要です。 |