動作環境
C++ builder XE4
TeeChart Lite v2013.08.130414
RAD Studio 10.2 Tokyo Update 2 (追記 2018/01/10)
TeeChart v2016.17.160129 32bit VCL
TeeChartにて描画した折れ線グラフにおいて、ある範囲だけ線を切りたいことがある。
そのための実装
Unit1.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <DateUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
Chart1->Series[0]->XValues->DateTime = true;
Chart1->BottomAxis->DateTimeFormat = L"nn:ss";
TDateTime dt;
dt = Now();
double yval;
for (int idx=0; idx < 10; idx++) {
yval = (1+ idx) % 2;
Series1->AddXY(dt, yval, "", clRed);
dt = IncSecond(dt, 1);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::breakLine()
{
double xvals[2000];
double yvals[2000];
Series1->TreatNulls = tnDontPaint;
int serCnt = Series1->Count();
for(int sidx = 0; sidx < serCnt; sidx++) { // sidx: series index
xvals[sidx] = Series1->XValue[sidx];
yvals[sidx] = Series1->YValue[sidx];
}
Series1->Clear();
for(int sidx = 0; sidx < serCnt; sidx++) { // sidx: series index
if (sidx >= 3 && sidx < 5) {
Series1->AddNullXY(xvals[sidx], yvals[sidx]);
continue;
}
Series1->AddXY(xvals[sidx], yvals[sidx]);
}
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
breakLine();
}
//---------------------------------------------------------------------------
breakLine()
において条件if (sidx >= 3 && sidx < 5) {
により線を切るようにしている。
結果
切る前
切った後
補足
基本的にはAddXY()する処理すべてにAddNullXY()関連の処理を実装すればいいが、それが色々な機能で使われているときに、個々のAddXY()にそれぞれ実装するのはメンテの点からまずい。
ふと、「一度描画したグラフを線を切って再描画すればいいのでは」と思い、この実装を試した。
double[]を使っているが、このあたりはSTLのvectorなりlistなりを使う方がいいかもしれない。