2014年02月19日

WPF Chart: INotifyPropertyChangedを実装し、リアルタイムでグラフを変化させる

   このエントリーをはてなブックマークに追加 Clip to Evernote
チャートにおいても、バインドするデータクラスにINotifyPropertyChangedインターフェースを実装することで、データの変更を、チャートに反映ささせるこっとができます。
これにより、データの変更にリアルタイムに追随する動きのあるグラフを作ることができます。
まずは、バインドするデータクラスをC#で定義します。
ここでは、選挙の候補者名とその得票数を表すクラスとしましょう。
変化するのは、得票数だけなので、NotifyPropertyChanged を呼び出すのは、Votesプロパティのみとします。

public class Candidacy : INotifyPropertyChanged {
    public string Name { get; set; }
    private int _votes;
    public int Votes {
        get { return _votes; }
        set {
            if (value != this._votes) {
                this._votes = value;
                NotifyPropertyChanged("Votes");
            }
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info) {
        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

今回のグラフでは、複数の候補者を扱いますので VotesCastList クラスを定義します。

public class VotesCastList {
    public VotesCastList() {
        Candidacies = new ObservableCollection<Candidacy> {
            new Candidacy { Name="候補者A", Votes=12300 },
            new Candidacy { Name="候補者B", Votes=43000 },
            new Candidacy { Name="候補者C", Votes=35000 },
            new Candidacy { Name="候補者D", Votes=58000 },
        };
    }
    public ObservableCollection<Candidacy> Candidacies { get; set; }
}

サンプルプログラムの都合上、初期値は、コンストラクタで与えています。
このデータを横棒グラフで表示しようと思います。

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:chartingToolkit="clr-namespace:System.Windows.Controls.DataVisualization.Charting;assembly=System.Windows.Controls.DataVisualization.Toolkit"
        x:Class="INotifyPropertyChangedSample.MainWindow"
        xmlns:local="clr-namespace:INotifyPropertyChangedSample"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:VotesCastList x:Key="myList" />
    </Window.Resources>
    <Grid>
        <chartingToolkit:Chart
            DataContext="{Binding Source={StaticResource myList}}" 
            Name="chart1" Title="得票数" 
            Margin="10,10,10,50">
            <chartingToolkit:BarSeries
                Title="得票数"
                DependentValuePath="Votes"
                IndependentValuePath="Name"
                ItemsSource="{Binding Candidacies}" >
            </chartingToolkit:BarSeries>
            <chartingToolkit:Chart.Axes>
                <chartingToolkit:LinearAxis
                    Orientation="X"
                    Maximum="100000"
                    Minimum="0"
                    Interval="20000" />
            </chartingToolkit:Chart.Axes>
        </chartingToolkit:Chart>
        <Button Content="Button" HorizontalAlignment="Left" Margin="432,286,0,0"
                VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
    </Grid>
</Window>

ウィンドウに配置したボタンクをリックした時にデータを変化させます。

private void Button_Click_1(object sender, RoutedEventArgs e) {
    VotesCastList vl = this.chart1.DataContext as VotesCastList;
    vl.Candidacies[0].Votes += 1000;
    vl.Candidacies[1].Votes += 5500;
    vl.Candidacies[2].Votes += 9000;
    vl.Candidacies[3].Votes += 3500;
}

これで、ボタンをクリックすると、データが変更されると同時にグラフのバーが伸びていきます。

初期状態
INotifyPropertyChangedSample1

ボタンを2度クリックした後の状態
INotifyPropertyChangedSample2


 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/52347500