Ver Mensaje Individual
  #4  
Antiguo 18-02-2011
rounin rounin is offline
Miembro
 
Registrado: sep 2005
Posts: 43
Reputación: 0
rounin Va por buen camino
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;            // RTypes RCore RDiapason
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
{ TSelection }
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; //psDot;
    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.
 
{-------------------------------------------------------------------}
Responder Con Cita