본문 바로가기
Delphi Tip/컴포넌트

델파이 TChart 설명

by MonoSoft 2021. 11. 3.
728x90
반응형

델파이  TChart 설명

 

 

1. TChart 중요 요소

 

(1) Panel(= TChart)


- 차트 배경. 색이나 바깥 테두리와 간격등을 설정 가능.


- TChart.Color, TChart.MarginLeft등

 

(2) TChart.Title


- 차트 제목. 기본 중앙 상단에 표시되며 위치, 글꼴등 변경 가능.

 


(3) TChart.Legend

- 범례. 기본 버전은 기능이 미약하여 거의 사용하지 않고 필요기능(보이기/감추기, 이름/색상변경등)을 추가하여 따로

만들어서 사용하는것이 좋음.

 

(4) TChart.Left Axis, TChart.BottomAxis

- 차트 축. Left(기본 Y축), Bottom(기본 X축) 외에 Right, Top등이 존재.

 

- (Property) 

   Automatic, AutomaticMinimum, AutomaticMaximum : 데이터에 따른 축 눈금 자동 조절 여부.

 

- (Property) Minimum : 축의 최소 눈금. Maximum보다 크면 Error 발생.

 

- (Property) Maximum : 축의 최대 눈금. Minimum보다 작으면 Error 발생.


- (Property) MinimumOffset, MaximumOffset : 자동 축 조정시 눈금과 데이터간 조절.


  최대 데이터가 10이고 MaximumOffset이 0%면 Maximum은 자동으로 10으로 설정됨.


  최대 데이터가 10이고 MaximumOffset이 20%면 Maximum은 자동으로 12으로 설정됨.


- (Property) AxisValuesFormat : Label의 Format을 결정.


- (Function) AdjustMaxMin : 데이터에 따라 축 눈금 자동 조정.


- (Function) SetMinMax : 축의 최소, 최대 눈금 설정. Property로 설정 할 경우 

                                               직접 데이터가 크거나 작은지 체크해야함.

                                               현재 Y축이 10~20으로 설정되어 있을때,

                                               1~2로 설정하려면 Minimum을 먼저 설정해야 Error가 안나고,

                                                100~200으로 설정하려면 Maximum을 먼저 설정해야 하는데 

                                               이 함수를 사용하면 직접 체크하지 않아도 됨.

 

(5) TChart.Series[]

- 차트의 그래프. Design Time에서 추가한 Series는 자동으로 Source상에 Class가 추가됨.

 

TForm1 = class(TForm)

  Chart1: TChart;

  Series1: TLineSeries;

- 동적으로 생성 가능.

var

  s: TLineSeries;

begin

  s := TLineSeries.Create(Chart1);

  s.ParentChart := Chart1;

 

- 데이터 속성 : 그래프의 데이터 한개에는 총 4가지의 속성이 있습니다. 

   이거 이해못해서 한참 해맸습니다^^

Index : 데이터배열에 필요한 Index 정보. X축 좌측기준 0부터 시작.

Pos : 차트에 데이터가 위치하는 좌표(윈도우 화면 좌표가 아닌 차트 내부좌표). Double 형식. 

       스크롤이나 해당 위치에 선 그릴때 필요.

Value : Y축 데이터 값입니다. Double 형식.

Label : X축 Label 값입니다. Text 형식.

 

- (Property) Color : 그래프 색상.

- (Property) Title : 그래프 이름. 다른 그래프와 중복 가능.

- (Property) ValueList.ValueList[0] : X축 데이터의 Pos List. 하위 Items[]로 접근 가능.

- (Property) ValueList.ValueList[1] : X축 데이터의 Value List. 하위 Items[]로 접근 가능.

- (Property) LabelList : 데이터의 Label List. 하위 Labels[Index]로 접근 가능. 읽기 전용.

 

2. Scroll 기능 만들기

(1) 원리

- 데이터 추가 시, X축 좌표를 직접 입력하여 X축 설정을 통해 Scroll.

 

(2) 방법

1) X축 좌표 입력하여 데이터 추가

s.AddXY(1, 10, '1번', clRed);

s.AddXY(2, 20, '2번', clRed);

s.AddXY(3, 30, '3번', clRed);

s.AddXY(1.5, 15, '1.5번', clRed);

s.AddXY(2.5, 25, '2.5번', clRed);

 

 

2) X축 범위 설정을 통해 Scroll 구현

Chart1.BottomAxis.SetMinMax(1.5, 2.5);

 

 

3. Label 변경

(1) 원리

- 데이터가 추가되고 Label List Class가 있지만 읽기전용으로 수정 불가능.

- GetAxisLabel Event를 통해 LabelText를 바꿀 수 있음.

 

(2) GetAxisEvent

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis;

Series: TChartSeries; ValueIndex: Integer; var LabelText: string);

begin

end;

 

- Sender : 어떠한 축에서 Event가 발생되었는지 알 수 있음.

- Series : 어떠한 Series에서 Event가 발생되었는지 알 수 있음. 단, 데이터 등록시 Label을 입력하지 않으면

   Series는 GetAxisLabel Event를 발생하지 않음.

- ValueIndex : 현재 표시되려는 Label의 Index를 알 수 있어 데이터에 접근 가능. 

   단, 데이터 등록시 Label을 입력하지 않으면 ValueIndex는 -1로 전송받음.

- LabelText : 표시 되려는 Label. 이 변수를 변경함으로써 표시되는 Label 변경 가능. 

   실제 내부 Label값은 변하지 않음. 이 LabelText의 Format은 해당 축의 (Property) 

   AxisValuesFormat으로 결정됨.

 

(3) 방법

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis;

Series: TChartSeries; ValueIndex: Integer; var LabelText: string);

begin

  // Y축 Label 변경

  if (Sender = Chart1.LeftAxis) then // Y축인지 검사

  begin

    LabelText := Format('[%s]', [LabelText]);

  end;

 

  // X축 Label 변경

  if (Sender = Chart1.BottomAxis) and (Series = Series1) then // X축인지 검사 

      // Series 검사를 하지 않으    면 예외 Label이 발생 할 수 있음.

  begin

    try

      LabelText := FormatDateTime('hh:nn:ss', StrToDateTime(LabelText));

    except

      LabelText := 'Wrong Format';

    end;

  end;

end;

 

4. 많은 데이터 처리

 

(1) 원리

- 데이터 추가시 Label을 입력하게 되면 데이터 개수가 많아질수록(약 1만개 이상) 

   Chart Class가 전체적으로 느려짐.

- Label의 길이가 길어지면 더 빨리 느려지고, Label을 입력하지 않으면 속도가 아주 빠름.

- 데이터 추가시에는 Label을 입력하지 않고, GetAxisLabel을 통해 표현하는 방법이 

   최고 속도 구현. 이때 GetAxisLabel의 LabelText는 좌표값으로 표시됨.

 

(2) 방법

 

1) 데이터 추가

for i := 1 to 86400

  s.AddXY(i, i * 10, '', clRed);

 

2) Label 변경

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis;

Series: TChartSeries; ValueIndex: Integer; var LabelText: string);

begin

  // X축 Label 변경

  if (Sender = Chart1.BottomAxis) and (Chart1.SeriesCount > 0) then // X축인지 검사

  begin

    LabelText := Format('%s번', [LabelText]);

  end;

end;


5. 시간 형식 Label 사용 및 시간 기준 Scroll

 

(1) 원리

- X축 Label 시간을 표시하는 방법

1) 데이터 추가시 Label에 시간 넣기

2) GetAxisLabel에서 시간 표시하기

- 빠른 속도를 위해 Label을 입력하지 않고 위치값에 TDateTime값을 입력하여 

   Label을 TDateTime으로 변환하여 표시

- 위치값을 시간으로 입력하면 SetMinMax 함수를 통해 시간 기준 Scroll 가능

 

(2) 방법

1) 데이터 추가

dtPivot: TDateTime;

var

  i: integer;

 dtAdd: TDateTime;

begin

  Series1.Clear;

  dtPivot := Now; // 전역변수에 마지막 시간을 입력한다.

  dtAdd := dtPivot;

  for I := 1 to 86400 do // 1초마다 24시간 만큼 추가

  begin

    Series1.AddXY(dtAdd, i, '', clRed);

    dtAdd := dtAdd - (1/24/60/60); // 1초 감소

  end;

end;

 

2) 시간 표시

procedure TForm1.Chart1GetAxisLabel(Sender: TChartAxis;

Series: TChartSeries; ValueIndex: Integer; var LabelText: string);

// Label이 없게 데이터를 추가하면 ValueIndex는 항상 -1로 넘어옴.

var

  dtLabel: TDateTime;

  dDT: double;

begin

  if (Sender = Chart1.BottomAxis) and (Chart1.SeriesCount > 0) then

  begin

    try

      dDT := StrToFloat(LabelText);

      dtLabel := dDT;

      LabelText := FormatDateTime('hh:nn:ss', dtLabel);

    except

      LabelText := 'Error';

    end;

  end;

end;

 

3) Scroll

var

  dtBegin, dtEnd: TDateTime;

begin

  dtBegin := dtPivot - ((1/24/60/60) * 10); // 마지막 시간 기준 10초 전으로 설정

  dtEnd := dtPivot; // 마지막 시간으로 설정

 

  if Chart1.Zoomed = false then // Zoom이 안되어 있을때만 스크롤

    Chart1.BottomAxis.SetMinMax(dtBegin, dtEnd);

 

4) Zoom 해제 시, Scroll 영역 설정

procedure TForm1.Chart1UndoZoom(Sender: TObject);

var

  dtBegin, dtEnd: TDateTime;

begin

  // Zoom이 풀릴때 스크롤중이라면 범위를 맞춘다.

  if IsScroll then

  begin

    dtBegin := dtPivot - ((1/24/60/60) * 9);

    dtEnd := dtPivot;

    Chart1.BottomAxis.SetMinMax(dtBegin, dtEnd);

  end;

 

6. 선긋기

 

(1) 원리

- CalcXPosValue, CalcYPosValue 함수를 통해 축의 위치값에 해당하는 화면 좌표를 얻을 수 있음.

- 해당 좌표를 이용하여 가로선, 세로선, 사각형, 글자를 AfterDraw 이벤트에서 Draw.

 

(2) 방법

procedure TFrameLine.Chart2AfterDraw(Sender: TObject);

var

  x, y, i, xcc, ri, j:integer;

  dtBegin, dtEnd: TDateTime;

  sChamber: String;

  sLabel, sLabel2: String;

  // 범위용

  rT: TRect;

begin

  // 가로선

  if IsHorzLine then

  begin

    // Y축 5에 해당하는 좌표얻기

    y := Chart2.LeftAxis.CalcYPosValue(5);

    if (y >= Chart2.ChartRect.Top) and (y <= Chart2.ChartRect.Bottom) then

    begin

      // 선 색상 지정

      Chart2.Canvas.Pen.Color := clPurple;

      // 폰트 색상, 글꼴, 크기 지정

      Chart2.Canvas.Font.Name := 'Arial';

      Chart2.Canvas.Font.Color := clPurple;

      Chart2.Canvas.Font.Size := 8;

 

      // Y축 왼쪽부터 오른쪽까지 선긋기

      Chart2.Canvas.MoveTo(Chart2.ChartRect.Left,y);

      Chart2.Canvas.LineTo(Chart2.ChartRect.Right,y);

      Chart2.Canvas.TextOut(Chart2.ChartRect.Right + 2, y - 6, 'This is 5'); 

      // +2, -6은 적절한 위치 설정은 위함

    end;

  end;

 

// 세로선

if IsVertLine then

begin

// X축 3초전 좌표얻기

dtBegin := dtPivot - ((1/24/60/60) * 3);

x := Chart2.BottomAxis.CalcXPosValue(dtBegin);

if (x >= Chart2.ChartRect.Left) and (x <= Chart2.ChartRect.Right) then

begin

// 선 색상 지정

Chart2.Canvas.Pen.Color := clBlue;

// 폰트 색상, 글꼴, 크기 지정

Chart2.Canvas.Font.Name := 'Arial';

Chart2.Canvas.Font.Color := clBlue;

Chart2.Canvas.Font.Size := 8;

 

// X축 위부터 아래까지 선긋기

Chart2.Canvas.MoveTo(x, Chart2.ChartRect.Bottom);

Chart2.Canvas.LineTo(x, Chart2.ChartRect.Top);

Chart2.Canvas.TextOut(x, 10, Format('This is %s', [FormatDateTime('hh:nn:ss', dtBegin)]));

end;

end;

 

// 범위

if IsRange then

begin

// X축 6초전 좌표얻기

dtBegin := dtPivot - ((1/24/60/60) * 6);

// X축 3초전 좌표얻기

dtEnd := dtPivot - ((1/24/60/60) * 3);

 

// 사각 좌표 얻기

rT.Left := Chart2.BottomAxis.CalcXPosValue(dtBegin);

rT.Right := Chart2.BottomAxis.CalcXPosValue(dtEnd);

 

rT.Top := Chart2.ChartRect.Top;

rT.Bottom := Chart2.ChartRect.Bottom;

 

// Zoom 상태를 감안하여 표시 여부 설정

if (rT.Left <= Chart2.ChartRect.Right) and (rT.Right >= Chart2.ChartRect.Left) then

begin

if rT.Left <= Chart2.ChartRect.Left then rT.Left := Chart2.ChartRect.Left; // 좌측을 넘어가는 범위 자르기

if rT.Right >= Chart2.ChartRect.Right then rT.Right := Chart2.ChartRect.Right; // 우측을 넘어가는 범위 자르기

 

// 선 색상

Chart2.Canvas.Pen.Color := clGreen;

// 채우기 색상, 스타일

Chart2.Canvas.Brush.Style := bsDiagCross;

Chart2.Canvas.Brush.Color := clGreen;

// 상자 그리기

Chart2.Canvas.Rectangle(rT);

 

// 상단 중간에 글자 표시

Chart2.Canvas.Font.Name := 'Arial';

Chart2.Canvas.Font.Color := clGreen;

Chart2.Canvas.Font.Size := 8;

Chart2.Canvas.TextOut(rT.Left, 0, Format('This is %s ~ %s', [FormatDateTime('hh:nn:ss', dtBegin), FormatDateTime('hh:nn:ss', dtEnd)]));

end;

end;

end;

 

 

728x90
반응형

댓글