Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 17-02-2011
McK McK is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 33
Poder: 0
McK Va por buen camino
Selección de una parte de un Chart

Hola delphimaniacos,

Pues hoy vengo con un tema que podría resolverme un buen dilema.
A ver tengo una gráfica, y de la misma tengo que coger solo una parte para grabar esos puntos.

Por poner un ejemplo sencillo. Imaginad que tengo en un ListBox 10 items y necesito grabar (coger para los españoles) solo 5 que se encuentran en medio de la lista. Esto se resolvería con un simple ListBox.Multiselect:= TRUE y listo.

Pues algo así necesito hacer con una gráfica que sale de un archivo de puntos. No controlo mucho de gráficas, lo mismo hay un componente mejor que un TChart....

Si alguien me puede ayudar se lo agradezco desde ya.

Salu2!
Responder Con Cita
  #2  
Antiguo 17-02-2011
rounin rounin is offline
Miembro
 
Registrado: sep 2005
Posts: 43
Poder: 0
rounin Va por buen camino
Hola,

Necesitas seleccionar el diapason de X y despues calcular los
puntos seleccionados?
O seleccionar los puntos en Chart y marcarlos?
Responder Con Cita
  #3  
Antiguo 17-02-2011
McK McK is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 33
Poder: 0
McK Va por buen camino
Cita:
Empezado por rounin Ver Mensaje
Hola,

Necesitas seleccionar el diapason de X y despues calcular los
puntos seleccionados?
O seleccionar los puntos en Chart y marcarlos?
Gracias por la contestación rounin.

Lo suyo sería lo segundo ya que necesito guardar X e Y y se vería más clarito.
Responder Con Cita
  #4  
Antiguo 18-02-2011
rounin rounin is offline
Miembro
 
Registrado: sep 2005
Posts: 43
Poder: 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
  #5  
Antiguo 18-02-2011
McK McK is offline
Miembro
NULL
 
Registrado: oct 2010
Posts: 33
Poder: 0
McK Va por buen camino
Gracias!! Te lo agradezco mucho, ese codigo me va a venir de perlas.

Soy un poco novato con los gráficos...

Última edición por McK fecha: 18-02-2011 a las 12:59:59.
Responder Con Cita
  #6  
Antiguo 08-02-2012
efirvida efirvida is offline
Miembro
 
Registrado: jun 2010
Posts: 12
Poder: 0
efirvida Va por buen camino
hola estoy tratando de utilizar tu codigo y me da unos cuantos errores el primero es que FSelection no esta definido no se si hice bien, pero lo defini como un TSelection,en las variables glovales, pero lo que no me compila es BGetSelectionClick que tampoco esta declarado, bueno despues de declarar el Fselection y borrar el procedimiento de BGetSelectionClick, me compilo bien solo que no me coje los datos para el listbox.
?que me falta por hacer??
Responder Con Cita
  #7  
Antiguo 08-02-2012
efirvida efirvida is offline
Miembro
 
Registrado: jun 2010
Posts: 12
Poder: 0
efirvida Va por buen camino
Cita:
Empezado por efirvida Ver Mensaje
hola estoy tratando de utilizar tu codigo y me da unos cuantos errores el primero es que FSelection no esta definido no se si hice bien, pero lo defini como un TSelection,en las variables glovales, pero lo que no me compila es BGetSelectionClick que tampoco esta declarado, bueno despues de declarar el Fselection y borrar el procedimiento de BGetSelectionClick, me compilo bien solo que no me coje los datos para el listbox.
?que me falta por hacer??
repondiendome a mi mismo, que bruto soy jejeje, defini BGetSelectionClick y ya lo otro si tuve que hacer un oequeño cambio para que funcionara -->

Código Delphi [-]
procedure TTForm1.Chart1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FSelection.HandleMouse(X, Y, evMouseUp, Shift);
  BGetSelectionClick(sender);
end;

ahora mi pregunta es la siguiente si en vez de quere capturar lo svalores lo que quiero es hacerle zoom a esa area que es lo que tendria que hacer???
Responder Con Cita
  #8  
Antiguo 09-02-2012
rounin rounin is offline
Miembro
 
Registrado: sep 2005
Posts: 43
Poder: 0
rounin Va por buen camino
Una manera de hacer esto es herramienta "Zoom" y herramienta "Seleccion" y
dos botones (TSpeedButton o TToolButton) por seleccionar las.

Otra manera es hacer Zoom cuando "Ctrl" o "Alt" botones estan presionado.

He hecho la ejemplo de primera manera.

Código Delphi [-]
unit main;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TeEngine, Series, ExtCtrls, TeeProcs, Chart, StdCtrls,
  XYSel, Buttons;
type
  TForm1 = class(TForm)
    Chart1: TChart;
    Series1: TLineSeries;
    ListBox1: TListBox;
    BGetSelection: TButton;
    BSelectTool: TSpeedButton;
    BZoomTool: TSpeedButton;
    procedure FormCreate(Sender: TObject);
    procedure BGetSelectionClick(Sender: TObject);
    procedure Chart1AfterDraw(Sender: TObject);
    procedure Chart1MouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure Chart1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure Chart1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
    procedure BToolClick(Sender: TObject);
  private
    FSelection: TSelection;
    FMouseHandled: Boolean;
    FZoomMode: Boolean;
  public
    procedure SetZoomMode(ZoomOn: Boolean);
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  BZoomTool.GroupIndex := 1;
  BSelectTool.GroupIndex := 1;
  BSelectTool.AllowAllUp := False;
  BSelectTool.Down := True; 
  BZoomTool.OnClick := BToolClick;
  BSelectTool.OnClick := BToolClick;
  for i := 0 to 30 do
    Series1.AddXY(i, Random(i));
  SetZoomMode(False);
  Chart1.OnAfterDraw := Chart1AfterDraw;
  Chart1.OnMouseDown := Chart1MouseDown;
  Chart1.OnMouseMove := Chart1MouseMove;
  Chart1.OnMouseUp   := Chart1MouseUp;
  BGetSelection.OnClick := BGetSelectionClick;
  FSelection := TSelection.CreateEx(Self, Chart1, Series1);
end;
procedure TForm1.SetZoomMode(ZoomOn: Boolean);
begin
  FZoomMode := ZoomOn;
  if ZoomOn then
  begin
    Chart1.AllowPanning := pmBoth;
    Chart1.AllowZoom := True;
  end
  else
  begin
    Chart1.AllowPanning := pmNone;
    Chart1.AllowZoom := False;
  end;
end;
procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
  FSelection.Draw(Chart1);
end;
procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FMouseHandled := FZoomMode;
  FSelection.HandleMouse(X, Y, evMouseDown, Shift, FMouseHandled);
end;
procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  FMouseHandled := FZoomMode;
  FSelection.HandleMouse(X, Y, evMouseMove, Shift, FMouseHandled);
end;
procedure TForm1.Chart1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FMouseHandled := FZoomMode;
  FSelection.HandleMouse(X, Y, evMouseUp, Shift, FMouseHandled);
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;
procedure TForm1.BToolClick(Sender: TObject);
begin
  SetZoomMode(Sender = BZoomTool);
end;
end.
Responder Con Cita
  #9  
Antiguo 14-03-2012
efirvida efirvida is offline
Miembro
 
Registrado: jun 2010
Posts: 12
Poder: 0
efirvida Va por buen camino
muchisimas gracias esto me servira de mucho, solo permitame hacerle unas observaciones que me dieron error, cuando se utiliza
Código Delphi [-]
FSelection.HandleMouse(X, Y, evMouseDown, Shift, FMouseHandled);

paraque funcionara tuve que dejarlo como

Código Delphi [-]
FSelection.HandleMouse(X, Y, evMouseDown, Shift);
que es asi como esta declarado en XYSel.pas

solo eso muchisimas gracias por todo nuevamente, y disculpenme por no haber respondido antes.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Chart Caro OOP 3 13-06-2008 04:50:37
utilizacion del chart ely15 Gráficos 5 04-04-2008 03:47:49
como mostrar una pagina(html) parte por parte? gabrielflowers PHP 10 02-04-2008 00:37:21
Problema con un chart egbaquela Gráficos 3 18-08-2007 01:47:12
Imprecion con Chart FX agonzalez Gráficos 3 07-04-2004 16:43:52


La franja horaria es GMT +2. Ahora son las 17:13:46.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi