C++ Builder 10.2 Tokyo + TeeChart > AddNullXY()した切断線をTChart*から知る > IsNull(ValueIndex)

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3
TeeChart Standard v2016.17.160129 32bit VCL
```

### 背景

- TeeChartのグラフのSVG出力処理の実装
- 切断線を処理する
    - AddNullXY()にて追加される
    - AddNullXY()実行時には「同じ点」のX,Y座標が追加される
- 同一点と切断線の識別問題
    - 同一点: 同じX,Y座標が二つ
    - 切断線: 同じX,Y座標が二つ
    - => X,Y座標情報のみでは二者の判別は不可能

### IsNull関数

あまり読みやすいとは言えないドキュメントに記載の関数を色々試した結果、IsNull()を使うと良いと分かった。

- TChartSeries.IsNull
    - http://teechart.net/docs/teechart/vclfmx/lib/html/TChartSeries.IsNull.html

> Returns True if ValueIndex value is Null.

この説明だけで「切断線の判別に使える」と分かるユーザは一体何人いるのだろうか。
自分は分からなかった。

### 実装

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ExtCtrls.hpp>
#include <VCLTee.Chart.hpp>
#include <VCLTee.Series.hpp>
#include <VclTee.TeeGDIPlus.hpp>
#include <VCLTee.TeEngine.hpp>
#include <VCLTee.TeeProcs.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TChart *Chart1;
	TFastLineSeries *Series1;
	TButton *Button1;
	TMemo *Memo1;
	TButton *Button2;
	void __fastcall Button1Click(TObject *Sender);
	void __fastcall Button2Click(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	Series1->TreatNulls = tnDontPaint;

	Series1->AddXY(2.5, 2.0);
	Series1->AddXY(3.5, 3.5);
	Series1->AddXY(3.5, 2.0);
	Series1->AddXY(4.5, 2.0);
	Series1->AddNullXY(4,5, 2.0);
	Series1->AddXY(5.0, 2.5);

	Chart1->LeftAxis->SetMinMax(0, 5.0);
	Chart1->BottomAxis->SetMinMax(0, 5.0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
    Memo1->Lines->Clear();

	String msg;
	for(int idx=0; idx < Series1->Count(); idx++) {
		if (Series1->IsNull(idx)) {
			msg = L"Don't Draw";
		} else {
			msg = L"Do Draw";
		}
		Memo1->Lines->Add(msg);
    }
}
//---------------------------------------------------------------------------
```


### 実行例

Button1押下、Button2押下後の結果。

切断すべきところは「Don't Draw」と表示された。

![2019-09-11_16h34_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/534b7064-4fed-2e9e-a362-efea26d50c04.png)


### 関連

- [2016-01-22 c++ builder XE4, 10.2 Tokyo > TeeChart > 折れ線グラフにてデータがないところの線を切る (+ データ欠損処理)](https://qiita.com/7of9/items/8e112537905dc59d8caf)
- [C++ Builder XE4 > TeeChart > 折れ線グラフ > 時系列データの欠損期間の線を切断する](https://qiita.com/7of9/items/f196a49ae9e21a64e396)
- [TChartSeries Methods](http://teechart.net/docs/teechart/vclfmx/lib/html/TChartSeries.0Methods.html)
    - 様々なAPIがあるが、説明は不十分