Puedes guardar X y Y en ambos casos.
La differencia es que en segundo caso es posible seleccionar 5, 7, 9
y en primero solo 5, 6, 7, 8, 9.
Segundo caso, ejemplo muy simple:
Código Delphi
[-]
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
for i := 0 to 30 do
Series1.AddXY(i, Random(i));
Chart1.AllowPanning := pmNone;
Chart1.AllowZoom := False;
Chart1.OnAfterDraw := Chart1AfterDraw;
Chart1.OnMouseDown := Chart1MouseDown;
Chart1.OnMouseMove := Chart1MouseMove;
Chart1.OnMouseUp := Chart1MouseUp;
FSelection := TSelection.CreateEx(Self, Chart1, Series1);
end;
procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
FSelection.Draw(Chart1);
end;
procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FSelection.HandleMouse(X, Y, evMouseDown, Shift);
end;
procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
FSelection.HandleMouse(X, Y, evMouseMove, Shift);
end;
procedure TForm1.Chart1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FSelection.HandleMouse(X, Y, evMouseUp, Shift);
end;
procedure TForm1.BGetSelectionClick(Sender: TObject);
var i, idx: Integer;
begin
ListBox1.Items.Clear;
for i := 0 to FSelection.Count-1 do
begin
idx := FSelection.Indexes[i];
ListBox1.Items.Add(
Format('%f %f', [FSelection.Series.XValue[idx], FSelection.Series.YValue[idx]])
);
end;
end;
unit XYSel;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, TeEngine, Series, ExtCtrls, TeeProcs, Chart; type
TEventID = (evNone, evDraw, evMouseDown, evMouseMove, evMouseUp, evKeyDown, evKeyUp);
TSelection = class(TComponent)
private
FSeries: TChartSeries;
FChart: TChart;
FIndexes: TList;
FSelectionInProgress: Boolean;
FDownPt: TPoint;
FPrevPt: TPoint;
function GetCount: Integer;
function GetIndexes(I: Integer): Integer;
public
property Series: TChartSeries read FSeries;
property Chart: TChart read FChart;
property Count: Integer read GetCount;
property Indexes[I: Integer]: Integer read GetIndexes;
constructor Create(AOwner: TComponent); override;
constructor CreateEx(AOwner: TComponent; AChart: TChart; ASeries: TChartSeries);
destructor Destroy; override;
procedure Clear;
procedure Draw(Chart: TChart);
procedure HandleMouse(X, Y: Integer; Event: TEventID; Shift: TShiftState);
end;
implementation
constructor TSelection.Create(AOwner: TComponent);
begin
inherited;
FIndexes := TList.Create;
FSeries := nil;
end;
constructor TSelection.CreateEx(AOwner: TComponent; AChart: TChart; ASeries: TChartSeries);
begin
Create(AOwner);
FSeries := ASeries;
FChart := AChart;
end;
destructor TSelection.Destroy;
begin
FIndexes.Free;
inherited;
end;
procedure TSelection.Clear;
begin
FIndexes.Clear;
end;
function TSelection.GetCount: Integer;
begin
Result := FIndexes.Count;
end;
function TSelection.GetIndexes(I: Integer): Integer;
begin
Result := Integer( FIndexes[i] );
end;
procedure TSelection.Draw(Chart: TChart);
var i: Integer;
procedure DrawSelectedMarker(Idx: Integer);
var xx, yy, hh, ww: Integer;
begin
if Idx >= Series.Count then Exit;
xx := Chart.BottomAxis.CalcPosValue(Series.XValues[Idx]);
yy := Chart.LeftAxis.CalcPosValue (Series.YValues[Idx]);
hh := 7;
ww := 7;
if Series is TCustomSeries then
begin
hh := (Series as TCustomSeries).Pointer.VertSize + 2;
ww := (Series as TCustomSeries).Pointer.HorizSize + 2;
end;
Chart.Canvas.Pen.Style := psSolid;
Chart.Canvas.Pen.Mode := pmCopy;
Chart.Canvas.Pen.Color := clBlack;
Chart.Canvas.Brush.Style := bsClear;
Chart.Canvas.Rectangle(xx-ww, yy-hh, xx+ww+1, yy+hh+1);
Chart.Canvas.Rectangle(xx-ww-1, yy-hh-1, xx+ww+2, yy+hh+2);
end;
begin
if not Assigned(FSeries) then Exit;
for i := 0 to FIndexes.Count-1 do
begin
DrawSelectedMarker( Integer(FIndexes[i]) );
end;
end;
procedure OrientRect(var Rect: TRect);
procedure Swap(var A, B: Integer);
var tmp: Integer;
begin
tmp := A; A := B; B := tmp;
end;
begin
if Rect.Left > Rect.Right then Swap(Rect.Left, Rect.Right);
if Rect.Top > Rect.Bottom then Swap(Rect.Top, Rect.Bottom);
end;
type
TAddMode = (amPlus, amXor, amMinus);
procedure TSelection.HandleMouse(X, Y: Integer; Event: TEventID; Shift: TShiftState);
var
selRect: TRect;
i, xx, yy: Integer;
procedure AddToSelection(Idx: Integer; Mode: TAddMode);
begin
if FIndexes.IndexOf(Pointer(Idx)) > -1 then
begin
if Mode in [amMinus, amXor] then FIndexes.Remove(Pointer(Idx))
end
else
begin
if Mode in [amPlus, amXor] then FIndexes.Add(Pointer(Idx));
end;
end;
begin
if not Assigned(FSeries) then Exit;
if (Event = evMouseDown)and(ssLeft in Shift) then
begin
FSelectionInProgress := True;
FDownPt := Point(X, Y);
FPrevPt := Point(X, Y);
if not (ssShift in Shift) then FIndexes.Clear;
Chart.Invalidate;
end
else
if (Event = evMouseMove)and(FSelectionInProgress) then
begin
Chart.Canvas.Pen.Style := psSolid; Chart.Canvas.Pen.Mode := pmNot;
Chart.Canvas.Brush.Style := bsClear;
Chart.Canvas.Rectangle(FDownPt.X, FDownPt.Y, FPrevPt.X, FPrevPt.Y);
Chart.Canvas.Rectangle(FDownPt.X, FDownPt.Y, X, Y);
FPrevPt := Point(X, Y);
end
else
if (Event = evMouseUp) then
begin
if FSelectionInProgress then
begin
selRect := Rect(FDownPt.X, FDownPt.Y, X, Y);
OrientRect(selRect);
for i := 0 to Series.Count-1 do
begin
xx := Chart.BottomAxis.CalcPosValue(Series.XValues[i]);
yy := Chart.LeftAxis.CalcPosValue (Series.YValues[i]);
if PtInRect(selRect, Point(xx, yy)) then AddToSelection(i, amXor);
end;
end;
Chart.Invalidate;
FSelectionInProgress := False;
end;
end;
end.