ComponentOne Studioに収録されている4つのチャートコントロール

 現在発売中のComponentOne Studio Enterprise 2010Jには、Windowsフォーム、ASP.NETWPFSilverlightの各テクノロジに対応した4つのチャートコントロールが収録されています。

コンポーネント 単体販売 Enterprise for Windows Forms for ASP.NET for Silverlight
TrueChart for Windows Forms - -
TrueChart for ASP.NET - -
Chart for WPF - - - -
Chart for Silverlight - - -



 「Chart for WPF」と「Chart for Silverlight」(以下、WPFSilverlight版)は単体販売こそされていませんが、後発ということで他の2つのチャートコンポーネントよりも自由度が増しているのが特徴です。


 「TrueChart for Windows Forms」と「TrueChart for ASP.NET」(以下、Windowsフォーム/ASP.NET版)ではChartGroupという単位でグラフ種が決められており、種類の異なるグラフは2つまでしか重ね合わせて表示させることができませんでした。WPFSilverlight版では、DataSeries毎にグラフ種を設定できるため、種類の異なるグラフをいくつでも重ね合わせて表示させることが可能です。


 ここでは、積層棒グラフが2つと折れ線グラフが1つで、合計3つのグラフを重ね合わせた下記のようなグラフを「Chart for WPF」を使って作成する方法を解説します。





 XAMLとコードは以下のようになります。


XAML

<Window x:Class="Window1"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   xmlns:c1chart="http://schemas.componentone.com/xaml/c1chart"
   xmlns:local="clr-namespace:WpfC1ChartSample"
   Title="Window1" Height="350" Width="525">
    <Grid>
        <c1chart:C1Chart Name="C1Chart1" ChartType="ColumnStacked" c1chart:BarColumnOptions.Size="1.15"
                        Palette="Office" >
 
            <c1chart:C1Chart.Data>
                <c1chart:ChartData ItemNames="1月 2月 3月 4月 5月 6月 7月 8月 9月 10月 11月 12月">
                    <c1chart:DataSeries Label="グロッサリー" Values="226 192 204 212 145 322 228 219 205 172 220 233"
                                       Display="HideLegend" PlotElementLoaded="budget_PlotElementLoaded" />
                    <c1chart:DataSeries Label="鮮魚" Values="109 82 120 162 103 117 123 125 112 88 98 100"
                                       Display="HideLegend" PlotElementLoaded="budget_PlotElementLoaded" />
                    <c1chart:DataSeries Label="精肉" Values="75 43 70 99 57 137 126 69 114 93 125 98"
                                       Display="HideLegend" PlotElementLoaded="budget_PlotElementLoaded" />
                    <c1chart:DataSeries Label="青果" Values="50 46 60 49 24 34 39 33 37 42 42 23"
                                       Display="HideLegend" PlotElementLoaded="budget_PlotElementLoaded" />
 
                    <c1chart:DataSeries Label="グロッサリー" Values="221,174,223,189,318,316,313,274,304,300,317,179"
                                      c1chart:BarColumnOptions.StackGroup="1" PlotElementLoaded="result_PlotElementLoaded"/>
                    <c1chart:DataSeries Label="鮮魚" Values="91,109,162,101,54,67,145,144,146,135,120,139"
                                       c1chart:BarColumnOptions.StackGroup="1" PlotElementLoaded="result_PlotElementLoaded" />
                    <c1chart:DataSeries Label="精肉" Values="80,91,135,157,125,120,107,120,98,87,160,181"
                                       c1chart:BarColumnOptions.StackGroup="1" PlotElementLoaded="result_PlotElementLoaded" />
                    <c1chart:DataSeries Label="青果" Values="34,28,42,50,40,34,25,34,33,44,32,27"
                                       c1chart:BarColumnOptions.StackGroup="1" PlotElementLoaded="result_PlotElementLoaded" />
 
                    <c1chart:DataSeries Label="累計" Values="426, 828, 1390, 1887, 2424, 2961, 3551, 4123, 4704, 5270, 5899, 6425"
                                       ChartType="LineSymbols" AxisY="y2" Display="HideLegend" />
                </c1chart:ChartData>
            </c1chart:C1Chart.Data>
 
            <c1chart:C1Chart.View>
                <c1chart:ChartView>
                    <c1chart:ChartView.AxisX>
                        <c1chart:Axis AxisType="X" MinorUnit="1"/>
                    </c1chart:ChartView.AxisX>
                    <c1chart:ChartView.AxisY>
                        <c1chart:Axis AxisType="Y" AnnoFormat="#,##0">
                            <c1chart:Axis.Title>
                                <TextBlock Text="月別売上" HorizontalAlignment="Left" Margin="-55,-30,0,0">
                                <TextBlock.LayoutTransform>
                                        <RotateTransform Angle="90"/>
                                </TextBlock.LayoutTransform>
                                </TextBlock>
                            </c1chart:Axis.Title>
                        </c1chart:Axis>
                    </c1chart:ChartView.AxisY>
                    <c1chart:ChartView.Axes>
                        <c1chart:Axis Name="y2" AxisType="Y" Min="0" Position="Far" AnnoFormat="#,##0">
                            <c1chart:Axis.Title>
                                <TextBlock Text="累計" HorizontalAlignment="Left" Margin="-25,0,0,-35">
                                    <TextBlock.LayoutTransform>
                                            <RotateTransform Angle="-90"/>
                                    </TextBlock.LayoutTransform>
                                </TextBlock>
                            </c1chart:Axis.Title>
                        </c1chart:Axis>
                    </c1chart:ChartView.Axes>
                </c1chart:ChartView>
            </c1chart:C1Chart.View>
 
            <TextBlock DockPanel.Dock="Top" Text="月別売上推移グラフ&#xd;&#xa;2009年度" TextAlignment="Center"/>
            <c1chart:C1ChartLegend DockPanel.Dock="Bottom" Orientation="Horizontal" />
        </c1chart:C1Chart>
    </Grid>
</Window>


Visual Basic
Imports C1.WPF.C1Chart
 
Class Window1
 
    Private Sub budget_PlotElementLoaded(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim pe = CType(sender, PlotElement)
        pe.Margin = New Thickness((pe.ActualWidth / 6), 0, 0, 0)
        pe.Opacity = 0.4
    End Sub
 
    Private Sub result_PlotElementLoaded(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim pe = CType(sender, PlotElement)
        pe.Margin = New Thickness(-(pe.ActualWidth / 2), 0, 0, 0)
    End Sub
 
End Class


 ポイントとなる部分を挙げて説明していきます。


グラフデータの設定について
 ChartDataにDataSeriesを追加していくことでグラフが表示されます。今回のようにグラフデータをXAMLからハードコーディングする場合には、DataSeriesクラスのValuesプロパティを使います。Bindingを使って設定する場合にはValueBindingプロパティ、コードから設定する場合にはIEnumerableなValuesSourceプロパティが便利です。


チャート種について
 チャート種はDataSeriesのChartTypeプロパティで設定することができますが、今回のコードではLineSymbolsとなっている最後のDataSeriesしか設定されていません。ChartTypeが設定されていないDataSeriesは、C1ChartコントロールのChartTypeプロパティの設定値が適用されるようになっています。


軸について
 今回の例では、X軸を1つとY軸を2つ使っています。Windowsフォーム/ASP.NET版と異なり軸も独立しているため、いくつでも軸を追加することができます。DataSeriesと軸の関連付けは、DataSeriesのAxisXプロパティ、AxisYプロパティを使用して設定します。
 また、軸のタイトルはデフォルトでは軸に対して水平方向に表示されますが、今回はY軸の上部に垂直に表示させたかったので、RotateTransformなどを使って向きと位置を調整しています。


X軸の注釈(項目名)について
 DataSeriesは、X軸の値も指定できるXYDataSeriesというクラスも用意されています。この場合には当然ながら指定したXValuesの値がX軸の注釈となります。今回のようにX軸の値がないDataSeriesの場合、X軸の値は自動的に0から割り当てられます。任意のX軸の注釈を設定する場合には、ChartData.ItemNamesプロパティを使用します。


複数の積層グラフを表示させる方法について
 積層グラフの場合、1つの積層グラフが複数のDataSeriesから構成されます。そのため、2つ以上の積層グラフを表示させたい場合にはBarColumnOptions.StackGroup添付プロパティを使って、DataSeriesに対してグループ情報を設定します。最初のグループは自動的に0が割り当てられているため、1以降の値を割り当てます。


積層グラフの表示位置について
 2つの積層棒グラフを単純に表示させた場合、X軸の中心点は2つの積層棒グラフの間となります。





 今回のように1つの積層をX軸の中心に、もう1つの積層をそれに少し重ねた位置にするためには、位置を移動させる必要があります。DataSeriesのPlotElementLoadedイベントを使うと、各PlotElementを取得できますのでここで位置や外観を調整することができます。
 なお、同様の処理をXAMLで行いたい場合には、DataTemplateを作成しDataSeriesのSymbolプロパティに設定します。


XAML
<c1chart:C1Chart.Resources>
    <local:BarTranslateXConverter x:Key="transXConv"/>
    <DataTemplate x:Key="budgetSymbol">
        <c1chart:Bar x:Name="budgetBar" Opacity="0.4">
            <c1chart:Bar.RenderTransform>
                <TranslateTransform X="{Binding ActualWidth, ElementName=budgetBar,
                   Converter={StaticResource transXConv}, ConverterParameter=budget}"/>
            </c1chart:Bar.RenderTransform>
        </c1chart:Bar>
    </DataTemplate>
    <DataTemplate x:Key="resultSymbol">
        <c1chart:Bar x:Name="resultBar">
            <c1chart:Bar.RenderTransform>
                <TranslateTransform X="{Binding ActualWidth, ElementName=resultBar,
                   Converter={StaticResource transXConv}, ConverterParameter=result}"/>
            </c1chart:Bar.RenderTransform>
        </c1chart:Bar>
    </DataTemplate>
</c1chart:C1Chart.Resources>


Visual Basic
Public Class BarTranslateXConverter
    Implements IValueConverter
 
    Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
        Dim formatString As String = TryCast(parameter, String)
        Select Case formatString
            Case "result"
                Return -(DirectCast(value, Double) / 2)
            Case "budget"
                Return (DirectCast(value, Double) / 6)
            Case Else
                Return 0
        End Select
    End Function
 
    Public Function ConvertBack(ByVal value As Object, ByVal targetType As System.Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
        Throw New NotImplementedException()
    End Function
End Class


チャートタイトルと凡例について
 凡例は、C1ChartコントロールにC1ChartLegendを追加するだけで表示されます。そのままですとすべての凡例が表示されてしまうため、凡例を表示させたくないDataSeriesについてはDisplayプロパティをHideLegendに設定します。
 C1Chartコントロール内のUIElementには、DockPanel.Dock添付プロパティを使用できます。TextBlockを使ったチャートタイトルを上部に、凡例を下部に表示させています。


 「Chart for Silverlight」でも、ほぼ同様のXAMLで今回のグラフを表示させることができます。





 変更の必要がある箇所は以下の2つです。

  • SilverlightではLayoutTransformがないため、軸ラベルを回転させる部分を削除する。
  • DockPanel.Dock添付プロパティを使用できないため、凡例はC1ChartLegend.Positionプロパティを使って下部に表示し、チャートタイトルはC1Chartコントロールの外に表示させるようする。



 今回のサンプルプロジェクト(Visual Studio 2008形式)は、以下からダウンロードできます。

WpfC1ChartSample.zip(12.1 KB )
SilverlightC1ChartSample.zip(6.87 KB)



 本サンプルプロジェクトの動作には、ComponentOne Studio Enterpries 2010Jが必要です。無償のトライアル版は以下からダウンロードできます。

ComponentOne Studio 2010J ダウンロード | グレープシティ株式会社