LoginSignup
0
1

More than 5 years have passed since last update.

C++ Builder XE4 > TeeChart > クリックした点に近い系列データの明示 > 点と値の表示 > v0.1..v0.2

Last updated at Posted at 2018-11-16
動作環境
C++ Builder XE4
TeeChart Lite v2013.08.130414 32bit VCL

処理

  • 系列データがある
  • マウスクリックした時、以下のいずれかをする
    • A. 点がない時に、点を追加する
    • B. 点がある時に、点を削除する

関連

仕組み

  • クリック場所のX,Yから系列データのインデックスを取得
  • Pointとして定義した別系列データとしてAdd()やDelete()する

v0.1 > クリック:追加、再度クリック: 消す

実装

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.TeEngine.hpp>
#include <VCLTee.TeeProcs.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE で管理されるコンポーネント
    TChart *Chart1;
    TFastLineSeries *Series1;
    TPointSeries *Series2;
    TEdit *E_xvalue;
    TEdit *E_yvalue;
    TLabel *Label1;
    TLabel *Label2;
    void __fastcall FormCreate(TObject *Sender);
    void __fastcall Chart1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y);
private:    // ユーザー宣言
public:     // ユーザー宣言
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
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::Chart1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{
    // A. すでにポインタがある場合 > 消す
    if (Series2->Count() > 0) {
        Series2->Delete(0);
        E_xvalue->Text = L"";
        E_yvalue->Text = L"";
        return;
    }

    // B. ポイントがない場合 > 追加する
    int index = Series1->Clicked(X, Y);

    if (index == -1) {
        return;
    }

    double xval = Series1->XValue[index];
    double yval = Series1->YValue[index];
    Series2->AddXY(xval, yval);

    E_xvalue->Text = String().sprintf(L"%.3f", xval);
    E_yvalue->Text = String().sprintf(L"%.3f", yval);
}
//---------------------------------------------------------------------------

動作

クリック後(矢印の先をクリック)
2018-11-16_18h15_39.png

さらにクリック
2018-11-16_18h16_09.png

さらにクリック(矢印の先をクリック)
2018-11-16_18h16_22.png

備考 (v0.1, v0.2共通)

  • インデックスはクリック場所の左側のポイントになる (右側の近いポイントは選ばれない)
  • 最後のポイントはインデックス取得できなさそう

注意点

シリーズの名前を変更するとインデックス取得に失敗する。
(例として、凡例表示をしていて、凡例に任意の文字列を表示したい場合など)

デフォルトの凡例表示を使うのではなく、凡例そのものを自前で表示するなどの工夫は必要。

v0.2 > クリック:表示、再度クリック > 表示または消す

処理

  • クリック
    • 表示
  • 再度クリック
    • 線上であれば表示
    • それ以外は消す

こちらの方が自然な操作になりそう。

実装

  • Unit1.hppはv0.1と同じ
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::Chart1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{
    int index = Series1->Clicked(X, Y);

    // A. クリックが外れていたときに消す
    if (index == -1) {
        if (Series2->Count() > 0) {
            Series2->Delete(0);
            E_xvalue->Text = L"";
            E_yvalue->Text = L"";
        }
        return;
    }

    // B. クリックが線上の時に表示

    // 既存のものは消す
    if (Series2->Count() > 0) {
        Series2->Delete(0);
    }

    // 点の追加
    double xval = Series1->XValue[index];
    double yval = Series1->YValue[index];
    Series2->AddXY(xval, yval);

    E_xvalue->Text = String().sprintf(L"%.3f", xval);
    E_yvalue->Text = String().sprintf(L"%.3f", yval);
}
//---------------------------------------------------------------------------
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1