動作環境
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
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」と表示された。