
概要
複数の折れ線シリーズを持つグラフでは、シリーズによって「データが存在する期間」が異なる場合があります。
Infragistics の XamDataChart と LineSeries は、値プロパティに null(nullable 型)をセットすると、その期間の線を自動的に描画しないという動作をします。
この特性を活用することで、共通の日時軸に複数のシリーズを載せながら、各シリーズが存在する期間のみ線を表示できます。
問題
複数の折れ線シリーズを共通の日時軸上に表示するケースで、シリーズごとに「データが存在する期間」が異なる場合、次のような要件が発生します。
- すべてのシリーズを同じ日時範囲のデータとしてまとめて管理したい。
- シリーズごとに「データが存在する期間」のみを線として描画し、存在しない期間は線を切断したい。
- 「データなし」の状態と「値が 0」の状態を区別して表現したい。
解決策
値プロパティを double?(nullable double)で定義し、データが存在しない期間は null をセットします。
XamDataChart の LineSeries は null 値を「ブレーク(切断)」として扱うため、その区間は線を描画しません。
なぜ nullable double を使うのか
値プロパティを double(非 nullable)で定義した場合、データを設定しない期間は既定値の 0 が入ります。その結果、本来「データなし」であるべき区間に Y=0 の点が描画され、「データなし」と「値が 0」の区別ができません。
nullable 型にしておけば、未設定の期間は null となり、LineSeries はその区間を描画しません。コード上は値プロパティの型が double? か double かを見れば、どちらの設計を採用しているか判別できます。
実装手順
1. データモデルの作成
日付と各シリーズの値を持つデータクラスを作成します。値プロパティはすべて double? にします。
// Data/ChartData.cs
namespace WpfApp1.Data
{
class ChartData
{
public DateTime Date { get; set; }
public double? SeriesA { get; set; }
public double? SeriesB { get; set; }
public double? SeriesC { get; set; }
}
}
ポイント:
| プロパティ | 型 | 説明 |
|---|---|---|
| Date | DateTime | X 軸にマッピングされる日時 |
| SeriesA / SeriesB / SeriesC | double? | 各シリーズの値。null の場合は線を描画しない |
2. XAML の設定の要点
X 軸には CategoryDateTimeXAxis を使用し、DateTimeMemberPath に日付プロパティ名を指定します。各 LineSeries の ValueMemberPath には、データモデルの対応する値プロパティ名を指定します。
<ig:CategoryDateTimeXAxis x:Name="xAxis" DateTimeMemberPath="Date" />
<ig:NumericYAxis x:Name="yAxis" />
<ig:LineSeries Title="シリーズA"
XAxis="{Binding ElementName=xAxis}"
YAxis="{Binding ElementName=yAxis}"
ValueMemberPath="SeriesA" />
3. データのセット方法の要点
データリスト内で、値が存在しない期間は null を明示的にセットします。LineSeries は null の区間を「ブレーク(切断)」として扱い、線を描画しません。
軸と各シリーズに同じデータコレクションを ItemsSource にセットします。
var data = new List<ChartData>
{
new() { Date = new DateTime(2024, 1, 1), SeriesA = 100, SeriesB = null },
new() { Date = new DateTime(2024, 4, 1), SeriesA = 130, SeriesB = 80 },
new() { Date = new DateTime(2024, 7, 1), SeriesA = null, SeriesB = 110 },
// ...
};
xAxis.ItemsSource = data;
seriesA.ItemsSource = data;
seriesB.ItemsSource = data;
結果
各シリーズはそれぞれデータが存在する期間のみ折れ線として描画され、データなしの期間は線が切断されて表示されます。(冒頭の画像を再掲します。)
