有没有真正的方法可以隐藏 TeeChart 中的系列的一部分?
Is there a real way to hide part of a series in TeeChart?
Delphi 10 个带有嵌入式 TeeChart。
我想隐藏 tLineSeries 的一部分并仅检测 CalcClickedPart 的可见部分。
假设一条未排序的 XY 线,其中有许多交叉点,一些点可能会被用户选择为不可见。我通过将 "hidden" 点的颜色设置为 clNone 来实现。当用户移动鼠标时,在 MouseMove 事件上,调用 CalcClickedPart,但它也是对 "hidden" 点的响应,因为它不是真正的隐藏方式。
图表创建:
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;
Chart 的 MouseMove 事件中的 CalcClickedPart 代码
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。
我可以遍历所有系列点并找到其他更近的点,但是有 "clean" 隐藏部分系列的方法吗?
整个系列可见:
前两个点是 "hidden",请参阅标题,点索引为 1 而不是 4(红色圆圈)
我决定编写自己的 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 应该是这样的:
另一种选择是将一个系列分成多个系列,但我不喜欢它。
Delphi 10 个带有嵌入式 TeeChart。 我想隐藏 tLineSeries 的一部分并仅检测 CalcClickedPart 的可见部分。
假设一条未排序的 XY 线,其中有许多交叉点,一些点可能会被用户选择为不可见。我通过将 "hidden" 点的颜色设置为 clNone 来实现。当用户移动鼠标时,在 MouseMove 事件上,调用 CalcClickedPart,但它也是对 "hidden" 点的响应,因为它不是真正的隐藏方式。
图表创建:
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;
Chart 的 MouseMove 事件中的 CalcClickedPart 代码
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。 我可以遍历所有系列点并找到其他更近的点,但是有 "clean" 隐藏部分系列的方法吗?
整个系列可见:
我决定编写自己的 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 应该是这样的:
另一种选择是将一个系列分成多个系列,但我不喜欢它。