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

델파이 TChart 마커 이동하기

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

델파이 TChart 마커 이동하기

 

 

procedure TFrm_Mng_014.Chart_PriceAfterDraw(Sender: TObject);

 function ChartSeriesValueIndexByXValue(ASeries: TChartSeries; AXValue: Double): Integer;

  var

    i: Integer;

    LastValue: Double;

    dMinDiff, dMaxDiff: Double;

  begin

    Result := -1;

    try

      if ASeries.XValues.Count > 0 then

        begin

        LastValue := ASeries.XValue[ASeries.XValues.Count - 1];

        if AXValue > LastValue then

        begin

          Result := ASeries.XValues.Count - 1;

          Exit;

        end;

 

        LastValue := ASeries.XValue[0];

        if AXValue < LastValue then

        begin

          Result := 0;

          Exit;

        end;

 

        for i := 1 to ASeries.XValues.Count - 1 do

        begin

          if (AXValue = ASeries.XValue[i]) then

          begin

            Result := i;

            Exit;

          end

          else if ((AXValue > LastValue) AND (AXValue < ASeries.XValue[i])) then

          begin

            dMinDiff := Abs(AXValue - LastValue);

            dMaxDiff := Abs(AXValue - ASeries.XValue[i]);

            if dMinDiff < dMaxDiff then

              Result := i - 1

            else

              Result := i;

            Exit;

          end;

          LastValue := ASeries.XValue[i];

        end;

      end;

    except

    end;

  end;

var

  x, y, i, v, j:integer;

  dtTime: TDateTime;

  sText: String;

  rT: TRect;

  ChartToken: TChart;

  dValue: Double;

begin

  try

    ChartToken := (Sender As TChart);

    if Assigned(ChartToken) then

    begin

      // 1. 마우스 X좌표

      x := MousePosInChart.X;

      // 2. X좌표가 Chart의 영역일때만 수행

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

      begin

        // 3. 마우스 X축에 해당하는 세로선 그리기

        ChartToken.Canvas.Pen.Color := clRed;

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

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

        // 4. Chart의 모든 Series를 검사하여 현재 X축에 해당하는 값 추출

        for i := 0 to ChartToken.SeriesCount - 1 do

        begin

          // 5. Series가 보일때만 실행

          if ChartToken.Series[i].Visible then

          begin

            // 6. X축의 현재 값 추출

            dtTime := ChartToken.Series[i].XScreenToValue(x);

            // 7. X축 현재 값의 순서 추출

            //    정확한 순서를 구해야 Y축에 해당하는 값을 얻을 수 있음

            //    실제 6번으로 추출된 값은 단순 Label값

            v := ChartSeriesValueIndexByXValue(ChartToken.Series[i], dtTime);

            try

              // 8. 순서를 제대로 찾았는지 검사

              if v >= 0 then

              begin

                // 8. 실제 입력된 데이터의 Y값, X값, 시간, 실제값을 구한다.

                x := ChartToken.Series[i].CalcXPos(v);

                dtTime := ChartToken.Series[i].XValue[v];

                y := ChartToken.Series[i].CalcYPos(v);

                dValue := ChartToken.Series[i].YValue[v];

 

                // 9. 값 위치에 표시될 Mark 크기, 위치 설정

                rT.Left := x - 2;

                rT.Right := x + 2;

                rT.Top := y - 2;

                rT.Bottom := y + 2;

 

                // 10. 값 위치에 Mark 표시

                ChartToken.Canvas.Pen.Color := ChartToken.Series[i].Color;

                ChartToken.Canvas.Brush.Style := bsClear;

                ChartToken.Canvas.Brush.Color := ChartToken.Series[i].Color;

                ChartToken.Canvas.Rectangle(rT);

 

                // 10. 값 주변에 정보 표시 (Series Title : [시간] [값])

                ChartToken.Canvas.Pen.Color := ChartToken.Series[i].Color;

                ChartToken.Canvas.Brush.Style := bsSolid;

                ChartToken.Canvas.Brush.Color := ChartToken.Series[i].Color;

                // 10-1. 폰트 색상, 글꼴, 크기 지정

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

                ChartToken.Canvas.Font.Color := clRed; //ChartToken.Series[i].Color;

                ChartToken.Canvas.Font.Size := 10;

                ChartToken.Canvas.Font.Style := [fsBold];

                // 10-2. 텍스트 출력

                sText := FormatFloat('0.0', dValue);

                ChartToken.Canvas.TextOut(x + 10, y - 25, sText);

                // 11. 텍스트에 언더바(밑줄) 그리기

                ChartToken.Canvas.Pen.Color := clRed;

                ChartToken.Canvas.MoveTo(x + 7, y - 10);

                ChartToken.Canvas.LineTo(x + 7 + (Trunc(Length(sText) * 5.5)), y - 10);
                // 12. 언더바와 값 Makr 사이에 선긋기

                ChartToken.Canvas.Pen.Color := clRed;

                ChartToken.Canvas.MoveTo(x, y);

                ChartToken.Canvas.LineTo(x + 7, y - 10);

              end;

            except

            end;

          end;

        end;

      end;

    end;

  except

  end;

end;

 

procedure TFrm_Mng_014.Chart_PriceGetAxisLabel(Sender: TChartAxis;

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

var

  dtLabel: TDateTime;

  dDT: double;

begin

  try

    if Sender = Chart_Price.BottomAxis then

    begin

      if (Chart_Price.SeriesCount > 0) then

      begin

        try

          if LabelText = '' then LabelText := '0';

 

          dDT := StrToFloat(LabelText);

          dtLabel := dDT;

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

        except

          LabelText := 'Error';

        end;

      end;

    end;

  except

  end;

end;

 

procedure TFrm_Mng_014.Chart_PriceMouseMove(Sender: TObject; Shift: TShiftState;

  X, Y: Integer);

begin

  try

    MousePosInChart.X := X;

    MousePosInChart.Y := Y;

    (Sender as TChart).Repaint;

  except

  end;

end;

 

======================================두번째

var i: Integer; 

begin 

for i := 0 to Series1.Marks.Positions.Count - 1 do 

with Series1.Marks.Positions.Position[i] do begin 

Custom := true; 

LeftTop.x := Series1.CalcXPos(i); 

end; 

Series1.Repaint; 

end; 

728x90
반응형

댓글