Есть ли реальный способ скрыть часть серии в TeeChart? - PullRequest
0 голосов
/ 06 января 2019

Delphi 10 со встроенным TeeChart. Я хотел бы скрыть часть tLineSeries и обнаруживать ТОЛЬКО видимые части с помощью CalcClickedPart.

Предположим, что несортированная линия XY со множеством перекрестков между ними, некоторые точки могут быть выбраны пользователем как невидимые. Я делаю это, устанавливая цвет «скрытых» точек на clNone. Когда пользователь перемещает мышь, при событии MouseMove вызывается CalcClickedPart, но он также является ответом на «скрытые» точки, поскольку это не настоящий скрытый путь.

Создание диаграммы:

procedure TForm1.FormCreate(Sender: TObject);
const
  clHideColor = {clDefault}clNone; // clNone, clDefault
begin
  Chart1.View3D := false;
  with Chart1.AddSeries(TLineSeries) as TLineSeries do
    begin
      // AddXY(Const AXValue, AYValue: TChartValue; Const ALabel: String; AColor: TColor):
      XValues.Order := loNone;
      YValues.Order := loNone;
      AddXY(  0,   0, '', clHideColor); // Origin point
      AddXY( 50,  50, '', clHideColor); // /    Cross point
      AddXY(100, 100);                  // /
      AddXY(100,   0);                  // |
      AddXY( 50,  50);                  // \    Cross point
      AddXY(  0, 100);                  // \ End point
    end;
 end;

Код CalcClickedPart в событии MouseMove диаграммы

procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
Var
  ClickedPart: tChartClickedPart;
  sCursorText: string;
begin
  sCursorText := '';

  Chart1.CalcClickedPart(Point(X, Y), ClickedPart); // Return information about the TeeChart component below the Mouse pointer at an X,Y location.
  Case ClickedPart.Part of
    cpNone          : sCursorText := 'cpNone';
    cpLegend        : sCursorText := 'cpLegend';
    cpAxis          : sCursorText := 'cpAxis';
    cpSeries        : sCursorText := 'cpSeries';
    cpTitle         : sCursorText := 'cpTitle';
    cpFoot          : sCursorText := 'cpFoot';
    cpChartRect     : sCursorText := 'cpChartRect';
    cpSeriesMarks   : sCursorText := 'cpSeriesMarks';
    cpSeriesPointer : sCursorText := 'cpSeriesPointer' + 
                                      ClickedPart.PointIndex.ToString;
    cpSubTitle      : sCursorText := 'cpSubTitle';
    cpSubFoot       : sCursorText := 'cpSubFoot';
    cpAxisTitle     : sCursorText := 'cpAxisTitle';
  end;

  Chart1.Title.Text.Text := sCursorText;
end;

В приведенном выше примере, когда указатель мыши находится посередине (50, 50), показанная точка будет # 1 (которая скрыта) вместо 4. Я мог бы пройти через все точки серии и найти другие более близкие точки, но есть ли «чистый» способ скрыть частичные серии?

Вся серия видна: enter image description here Первые две точки «скрыты», см. Заголовок с индексом точки 1 вместо 4 (круглый красный круг) enter image description here

1 Ответ

0 голосов
/ 12 января 2019

Я решил написать свою собственную функцию CalcClickedPart, которая просматривает все серии и индекс значений и проверяет, является ли серия ValueColor [Inx] <> clNone следующим образом:

function CalcClickedPartHidenPoints(aChart: tChart; Pos: TPoint; Out Part: tChartClickedPart): boolean;
var
  nSeriesInx, nValueInx: integer;
  aSeries: TCustomSeries;
begin
  Result := false;
  for nSeriesInx := 0 to aChart.SeriesCount-1 do // Go through all series
    begin
      aSeries := aChart[nSeriesInx] as TCustomSeries;
      if aSeries.Visible then // Series is selected in Legend
        begin
          for nValueInx := 0 to aSeries.Count-1 do
            if (abs(aSeries.CalcXPos(nValueInx) - Pos.X) <= aSeries.ClickTolerance) and
               (abs(aSeries.CalcYPos(nValueInx) - Pos.Y) <= aSeries.ClickTolerance) then
              if aSeries.ValueColor[nValueInx] <> clNone then // A "visible" point
                begin
                  Part.ASeries    := aSeries;
                  Part.Part       := cpSeriesPointer;
                  Part.PointIndex := nValueInx;
                  Result := true;
                  Break; // Stop searching for a visible point under the mouse
                end;
        end;
      if Result then
        Break;
    end;
end;

Теперь курсор в примере показывает точку # 4 следующим образом: enter image description here

Другой вариант - разделить серию на множество, но мне это не нравится.

...