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 2019-01-08
動作環境
C++ Builder XE4

関連

概要

  • TChart上をクリックする
  • クリックした地点の日時を計算する

実装 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::FormShow(TObject *Sender)
{
    Chart1->Series[0]->XValues->DateTime = true;
    Chart1->BottomAxis->DateTimeFormat = L"mm/dd hh:nn";

    TDateTime dt;

    dt = Now();

    double yval;
    for (int idx=0; idx < 1000; idx++) {
        yval = (1+ idx) % 200;
        Series1->AddXY(dt, yval, "", clRed);
        dt = IncMinute(dt, 1);
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Chart1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{
    String msg;

    // 1. 開始日時と終了日時の表示
    TDateTime startdt = Chart1->BottomAxis->Minimum;
    TDateTime enddt = Chart1->BottomAxis->Maximum;

    msg = L"[" + startdt.FormatString(L"yyyy/mm/dd hh:nn");
    msg += L" to " + enddt.FormatString(L"yyyy/mm/dd hh:nn") + L"]";
    Memo1->Lines->Add(msg);

    // 2. クリックしたXから日時を計算
    int xrange = Chart1->ChartRect.Width();  // 日時の幅
    int xclick = X - Chart1->ChartRect.Left; // クリック地点の開始日時からの幅 [単位:Xに基づく]
    double ratio = (double)xclick / (double)xrange;

    int elapsed = SecondsBetween(Chart1->BottomAxis->Maximum, Chart1->BottomAxis->Minimum) * ratio;
    TDateTime dtclick;  // クリック地点の日時

    dtclick = IncSecond(Chart1->BottomAxis->Minimum, elapsed);
    msg = L"Click:" + dtclick.FormatString(L"yyyy/mm/dd hh:nn");
    Memo1->Lines->Add(msg);
}
//---------------------------------------------------------------------------

動作例

任意の5箇所をクリック後
2019-01-08_18h03_20.png

それぞれクリック地点の日時を計算できているようだ。

実装 v0.2

  • 変更
    • calcClickedDateTime()に処理をまとめた
    • クリック地点がグラフ範囲外の時には処理を中断
Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <DateUtils.hpp>
#include "Unit1.h"
#include "UtilListSearch_double.h" // 自前実装の探索処理
//
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
    Chart1->Series[0]->XValues->DateTime = true;
    Chart1->BottomAxis->DateTimeFormat = L"mm/dd hh:nn";

    TDateTime dt;

    dt = Now();

    double yval;
    for (int idx=0; idx < 1000; idx++) {
        yval = (1+ idx) % 200;
        Series1->AddXY(dt, yval, "", clRed);
        dt = IncMinute(dt, 1);
    }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Chart1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
          int X, int Y)
{
    String msg;

    // 1. 開始日時と終了日時の表示
    TDateTime startdt = Chart1->BottomAxis->Minimum;
    TDateTime enddt = Chart1->BottomAxis->Maximum;

    msg = L"[" + startdt.FormatString(L"yyyy/mm/dd hh:nn");
    msg += L" to " + enddt.FormatString(L"yyyy/mm/dd hh:nn") + L"]";
    Memo1->Lines->Add(msg);

    // 2. クリックしたXから日時を計算
    TDateTime dtclick = calcClickedDateTime(X, Chart1);
    if (SecondsBetween(dtclick, 0) == 0) { // 範囲外
        return;
    }
    msg = L"Click:" + dtclick.FormatString(L"yyyy/mm/dd hh:nn");
    Memo1->Lines->Add(msg);
}

TDateTime __fastcall TForm1::calcClickedDateTime(int Xpos, TChart *chrPtr)
{
    if (chrPtr == NULL) {
        return 0;  // error
    }

    if (Xpos < chrPtr->ChartRect.left) {
        return 0;  // error
    }
    if (Xpos > chrPtr->ChartRect.right) {
        return 0;  // error
    }

    int xrange = chrPtr->ChartRect.Width();  // 日時の幅
    int xclick = Xpos - chrPtr->ChartRect.Left; // クリック地点の開始日時からの幅 [単位:Xに基づく]
    double ratio = (double)xclick / (double)xrange;

    int elapsed = SecondsBetween(chrPtr->BottomAxis->Maximum, chrPtr->BottomAxis->Minimum) * ratio;
    TDateTime dtclick;  // クリック地点の日時

    dtclick = IncSecond(chrPtr->BottomAxis->Minimum, elapsed);
    return dtclick;
}
//---------------------------------------------------------------------------
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