TChartのマークに日付データを表示させるには?

解決


老かも  2009-10-11 06:37:37  No: 35865

いつも参考にさせて頂いております。
Delphi初心者です。
DELPHI2007付属のTCHARTで、2次元データ(1〜100の数値、日付データ)の数値を使って折れ線を描き、そのプロット点のマークに付対応する日付データを表示させたいのですが上手く出来ません。折れ線グラフ自体は描けるのですが。Delphi2007のどこを捜してもHELPが見あたらず困っております。
よろしくお願いいたします。


老かも  2009-10-11 06:42:09  No: 35866

済みません、文章が間違っておりました。
>そのプロット点のマークに付対応する日付データを表示させた・・・
そのプロット点のマークに、数値に対応する日付データを表示させた・・・

です。よろしくお願いいたします。


3K  2009-10-12 03:06:21  No: 35867

Series名.Marks.Visible := true;
Series名.Marks.Style :=  smsXValue;
って事?


老かも  2009-10-12 07:54:54  No: 35868

K3さん、早速有り難うございます。
すみません、私の書き方が足りませんでした。
X軸のラベルには0,1,2,3...とデータ順番を表示させ、プロット点のマークにソースデータの日付部分を表示させたいのです。
自分なりにいろいろ検索したり、SteemaSoftのSupportサイトを調べてみたのですが、英文でなかなかよく判りません。

よろしくお願いいたします。


3K  2009-10-12 19:10:44  No: 35869

2次元データ(1〜100の数値、....って書いてありましたね。
申し訳ないです。

下記にて、X軸5番目のY軸のデータプロットの所に文字を表示することが出来ます。
procedure TForm1.Button1Click(Sender: TObject);
begin
 with Chart1 do
 begin
  Canvas.Brush.Style := bsClear;
  Canvas.TextOut(BottomAxis.CalcXPosValue(5),LeftAxis.CalcYPosValue(Series1.YValue[5]),'yy/mm/dd');
 end;
end;

PS
TeeChartに関しては、こちらも参考になるかと
http://www.newtone.co.jp/support/suqatc8vcl.html


老かも  2009-10-13 01:31:19  No: 35870

3Kさん、有り難うございます。前回の投稿でお名前を間違ってしまいました。申し訳ありません。
早速教えてて頂いたコードを試したところ、上手くいきました。
ところが、条件の後出しで大変恐縮なのですが(浅はかにも関係ないと思っておりましたものですから)、今回のプログラムは通信データを自動取り込みしてグラフに表示する予定のものでした。そこで、下記の通りテストプログラムに教えて頂いたコードを追加して実行したところ、プロットの瞬間日付データを表示するのですが、瞬間で消えてしまいます。いろいろ試したのですが解決出来ません。拙いコードですが、テストコードは以下の通りです。

タイマイベントでランダムデータを作り、システム日付時刻を表示するだけです。(本来はデータは2次元の予定ですが、テストの為こうしています。)

var
   n     : Integer;   
   RDate : TDateTime;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
   inc(n);
   Rdate := Now;
   AddPoint(n-1,Random(100),clRed);
end;

procedure TForm1.AddPoint(const x, y :Integer; Acolor: TColor);
begin
   Series1.AddXY(x,y,' ',clRed);
   with Chart1 do
      begin
     Canvas.Brush.Style := bsClear;
    Canvas.TextOut(BottomAxis.CalcXPosValue(n-1),LeftAxis.
         CalcYPosValue(Series1.YValue[n-1]),DateTimeToStr(Rdate));
      end;
end;


3K  2009-10-13 06:56:23  No: 35871

Chart1のイベント「AfterDraw」にTextOutの処理(100個分)を書けばOKですが
通信データの量が短時間に大量にあると問題が発生するかも知れません。


老かも  2009-10-13 17:34:29  No: 35872

3Kさん、早速有り難うございます。ほんとに感謝しております。
アドバイスの通り(?)AfterDrawイベントに
begin
 with Chart1 do
 begin
  Canvas.Brush.Style := bsClear;
  Canvas.TextOut(BottomAxis.CalcXPosValue(5),LeftAxis.CalcYPosValue(Series1.YValue[5]),'yy/mm/dd');
 end;
end;
とやってみたのですが、コンパイルは通るのですが、実行すると読込違反のエラーが発生してしまいます。
多分私がよく判ってないので、考え方が間違っているのでは?と思っております。もう少し自分で研究して解決したいと思います。
どうしても解らない場合、またアドバイスをお願いするかもしれませんが、そのときはどうぞよろしくお願いいたします。
なお、短時間での大量データ処理はありません。

以上、取り急ぎまずはお礼を申し上げます。


3K  2009-10-13 19:37:24  No: 35873

どのような仕様かわかりませんが
AfterDrawイベントの最初に
if Series1.count = 0 then
   exit;
で回避できるかも?


tor  2009-10-14 01:00:44  No: 35874

OnGetMarkTextというイベントがあるけど、これは使えないのかな?
オブジェクトインスペクタからは直接設定できなかったと思うので
Series1.OnGetMarkText := Self.Series1GetMarkText;
みたいな感じで割り当てて、実装の方は
procedure TForm1.Series1GetMarkText(Sender: TChartSeries; ValueIndex: Integer; var MarkText: String);
begin
  MarkText := ValueIndexから求めた日付;
end;
といった感じで。


老かも  2009-10-14 09:17:18  No: 35875

3Kさん、torさん、貴重なアドバイス有り難うございました。私が無い知恵を搾る間もなく、アドバイスを頂き感謝しております。

3Kさん、ご指摘の通り見事解決しました。今回のテクニックはこれからもいろいろ応用できそうです。何度もつきあって下さりほんとに有り難うございました。

torさん、アドバイスの通りのままで上手くいきました。ダメもとでやってみたらオブジェクトインスペクタからも直接設定できました。

今回いろいろ教えて頂いた内容、まだほんとに自分のものにできていません。これから、じっくり解るまで研究したいと思います。ほんとに有り難うございました。改めてお二人のご厚意に感謝致します。それと当サイトの管理者の方にも深くお礼を申し上げます。

これで、解決とさせて頂きます。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加