Reron
Reron

Reputation: 191

Is there a real way to hide part of a series in TeeChart?

Delphi 10 with an Embedded TeeChart. I would like to hide a partial of tLineSeries and detect ONLY the visible parts by CalcClickedPart.

Assume a non sorted XY line with many cross among them, some of the points could be selected by user as not visible. I'm doing so by setting the color of the "hidden" points to clNone. When the user is moving the mouse, on MouseMove event, a CalcClickedPart is called, but it is response to the "hidden" points too, since it is not a real hidden way.

The chart creation:

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;

The CalcClickedPart code in Chart's MouseMove event

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;

In the above example, when the mouse on the middle (50,50) the shown point is #1 (which is hidden) instead of 4. I could go through all series points and find other closer points, but is there a "clean" way to hide partial series?

The entire series is visible: enter image description here First two points are "hidden", see title with point index 1 instead 4 (round red circle) enter image description here

Upvotes: 1

Views: 527

Answers (1)

Reron
Reron

Reputation: 191

I decided to write my own CalcClickedPart function which go through all series and value index and checking if series' ValueColor[Inx] <> clNone as follow:

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;

Now the cursor in the example shows point #4 as should be: enter image description here

Another option is to split a series to many series, but I don't like it.

Upvotes: 1

Related Questions