Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 08-02-2012
efirvida efirvida is offline
Miembro
 
Registrado: jun 2010
Posts: 12
Poder: 0
efirvida Va por buen camino
ayuda con un tchart

hola estoy haciendo una aplicacion en la que nececito tener un grafico y poder desplazarme por el comodamente, he cojido la idea del toolbox de matlab de procesamiento de señales y ya tengo hecho mas o menos algo parecido con dos tchart uno para mostrar la señal completa y otro para mostrar el zoom, y para desplazarme por el chart donde muestro la señal completo uso un avdrangeslider y asi puedo seccionar el grafico. el problema esta en que cuando el grafico tiene muchos puntos, el proceso se me hace muy lento, y entonces quiero cambiar el slider y dejarlo esactamenete como lo tiene el de matlab.
en fin la pregunta seria como puedo dibujar rectangulos dentro del chart del tamaño deseado, y luego hacer zoom a esa seleccion en otro tchart
saludos
Responder Con Cita
  #2  
Antiguo 15-02-2012
rounin rounin is offline
Miembro
 
Registrado: sep 2005
Posts: 43
Poder: 0
rounin Va por buen camino
Hola,

>en fin la pregunta seria como puedo dibujar rectangulos dentro del chart del
>tamano deseado, y luego hacer zoom a esa seleccion en otro tchart

Es bastante facil hacer on aguel objeto.
Apariencia no es muy buena, pero se puede cambiar.

Sobre anterior pregunta, no he encontrado la respuesta :-(
Tengo que usar mi propia grafica.

Código Delphi [-]
{============================ unit main.pas ===================================}
unit main;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TeEngine, Series, ExtCtrls, TeeProcs, Chart, StdCtrls,
  ChartObj,
  Dpsn,
  XYSel,
  ZoomRect;
type
  TForm1 = class(TForm)
    Chart1: TChart;
    ListBox1: TListBox;
    BGetSelection: TButton;
    BGetDiapasonSelection: TButton;
    Chart2: TChart;
    Series1: TFastLineSeries;
    Series2: TFastLineSeries;
    procedure FormCreate(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);
  private
    FZoomRect: TZoomRect;
    FActiveObject: TChartObject;
    FMouseHandled: Boolean;
    FExclusiveZoomMode: Boolean;
    procedure ZoomRectChanged(Sender: TObject);
  public
    procedure SetExclusiveZoomMode(ZoomOn: Boolean);
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  for i := 0 to 300 do
  begin
    Series1.AddXY(i, Random(i));
    Series2.AddXY(i, Series1.YValue[i]);
  end;
  SetExclusiveZoomMode(False);
  Chart1.OnAfterDraw := Chart1AfterDraw;
  Chart1.OnMouseDown := Chart1MouseDown;
  Chart1.OnMouseMove := Chart1MouseMove;
  Chart1.OnMouseUp   := Chart1MouseUp;
  Chart2.AllowZoom := False;
  Chart2.AllowPanning := pmNone;
  Chart2.LeftAxis.AutomaticMaximum := False;
  Chart2.LeftAxis.AutomaticMinimum := False;
  Chart2.BottomAxis.AutomaticMaximum := False;
  Chart2.BottomAxis.AutomaticMinimum := False;
  FZoomRect := TZoomRect.CreateEx(Self, Chart1);
  FZoomRect.Rect := RectF(50, 50, 200, 200);
  FZoomRect.OnChange := ZoomRectChanged;
    {?}
    FZoomRect.AllowRectBody := True;
    FZoomRect.AllowStandardZoom := True;
    Chart1.AllowPanning := pmBoth;
    Chart1.AllowZoom := True;
  FActiveObject := FZoomRect;
end;
procedure TForm1.SetExclusiveZoomMode(ZoomOn: Boolean);
begin
  FExclusiveZoomMode := ZoomOn;
  if ZoomOn then
  begin
    Chart1.AllowPanning := pmBoth;
    Chart1.AllowZoom := True;
  end
  else
  begin
    Chart1.AllowPanning := pmNone;
    Chart1.AllowZoom := False;
  end;
end;
procedure TForm1.ZoomRectChanged(Sender: TObject);
begin
  with (Sender as TZoomRect).Rect do
  begin
    if Chart2.BottomAxis.Maximum < XMin
      then Chart2.BottomAxis.Maximum := XMin;
    Chart2.BottomAxis.Minimum := XMin;
    Chart2.BottomAxis.Maximum := XMax;
    if Chart2.LeftAxis.Maximum < YMin
      then Chart2.LeftAxis.Maximum := YMin;
    Chart2.LeftAxis.Minimum := YMin;
    Chart2.LeftAxis.Maximum := YMax;
  end;
  Chart2.Invalidate;
end;
procedure TForm1.Chart1AfterDraw(Sender: TObject);
begin
  FActiveObject.Draw(Chart1);
end;
procedure TForm1.Chart1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FMouseHandled := FExclusiveZoomMode;
  FActiveObject.HandleMouse(X, Y, evMouseDown, Shift, FMouseHandled);
end;
procedure TForm1.Chart1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  FMouseHandled := FExclusiveZoomMode;
  FActiveObject.HandleMouse(X, Y, evMouseMove, Shift, FMouseHandled);
end;
procedure TForm1.Chart1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FMouseHandled := FExclusiveZoomMode;
  FActiveObject.HandleMouse(X, Y, evMouseUp, Shift, FMouseHandled);
end;
end.
{======================== unit ChartObj.pas ===================================}
unit ChartObj;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TeEngine, Series, ExtCtrls, TeeProcs, Chart;
type
  PRectF = ^TRectF;
  TRectF = packed record
    XMin, XMax, YMin, YMax: Double;
  end;
  TEventID = (evNone, evDraw, evMouseDown, evMouseMove, evMouseUp, evKeyDown, evKeyUp);
  TChartObject = class(TComponent)
  private
    FChart: TChart;
  public
    property Chart: TChart read FChart;
    procedure Draw(Chart: TChart); virtual; abstract;
    procedure HandleMouse(X, Y: Integer; Event: TEventID; Shift: TShiftState; var Handled: Boolean); virtual; abstract;
    constructor Create(AOwner: TComponent); override;
    constructor CreateEx(AOwner: TComponent; AChart: TChart);
  end;
function RectF(XMin, YMin, XMax, YMax: Double): TRectF;
procedure OrientRect(var Rect: TRect);
procedure OrientRectF(var Rect: TRectF);
implementation
{------------------------------ TChartObject ----------------------------------}
constructor TChartObject.Create(AOwner: TComponent);
begin
  inherited;
  FChart := nil;
end;
constructor TChartObject.CreateEx(AOwner: TComponent; AChart: TChart);
begin
  Create(AOwner);
  FChart := AChart;
end;
{------------------------------------------------------------------------------}
function RectF(XMin, YMin, XMax, YMax: Double): TRectF;
begin
  Result.XMin := XMin;
  Result.XMax := XMax;
  Result.YMin := YMin;
  Result.YMax := YMax;
end;
procedure OrientRectF(var Rect: TRectF);
    procedure Swap(var A, B: Double);
    var tmp: Double;
    begin
      tmp := A; A := B; B := tmp;
    end;
begin
  if Rect.XMin > Rect.XMax then Swap(Rect.XMin, Rect.XMax);
  if Rect.YMin > Rect.YMax then Swap(Rect.YMin, Rect.YMax);
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;
end.
{======================== unit ZoomRect.pas ===================================}
unit ZoomRect;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, TeEngine, Series, ExtCtrls, TeeProcs, Chart, 
  ChartObj; 
type
  TZoomRectElement = (elNone, elRectBody,
    elLeftBorder, elRightBorder, elTopBorder, elBottomBorder,
    elLeftTopCorner, elRightTopCorner, elLeftBottomCorner, elRightBottomCorner);
  TZoomRect = class(TChartObject)
  private
    FRect: TRectF;
    FActiveElememt: TZoomRectElement;
    FOnChange: TNotifyEvent;
    //FDownPt: TPoint;
    FPrevPt: TPoint;
    FAllowStandardZoom: Boolean;
    FAllowRectBody: Boolean;
    procedure SetRect(const Value: TRectF);
    function GetRect: TRectF;
 protected
    function CalcScreenRect(const R: TRectF): TRect;
    function CalcLogicRect(const R: TRect): TRectF;
    procedure Changed;
  public
    property Rect: TRectF read GetRect write SetRect;
    property AllowStandardZoom: Boolean read FAllowStandardZoom write FAllowStandardZoom;
    property AllowRectBody: Boolean read FAllowRectBody write FAllowRectBody;
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
    procedure Draw(Chart: TChart); override;
    procedure HandleMouse(X, Y: Integer; Event: TEventID; Shift: TShiftState; var Handled: Boolean); override;
  end;
implementation
{----------------------------- TZoomRect --------------------------------------}
procedure TZoomRect.Draw(Chart: TChart);
var scrRect: TRect;
begin
  scrRect := CalcScreenRect({!FRect} Rect);
  Chart.Canvas.Pen.Style := psSolid;
  Chart.Canvas.Pen.Mode := pmCopy;
  Chart.Canvas.Pen.Color := clBlack;
  Chart.Canvas.Pen.Width := 2;
  Chart.Canvas.Brush.Style := bsClear;
  Chart.Canvas.Rectangle(scrRect.Left, scrRect.Top, scrRect.Right+1, scrRect.Bottom+1);
  // Zoom Icon
  Chart.Canvas.Pen.Width := 1;
  Chart.Canvas.Ellipse(scrRect.Left+3, scrRect.Top+3, scrRect.Left+16, scrRect.Top+16);
  Chart.Canvas.MoveTo(scrRect.Left+9, scrRect.Top+6);
  Chart.Canvas.LineTo(scrRect.Left+9, scrRect.Top+13);
  Chart.Canvas.MoveTo(scrRect.Left+6, scrRect.Top+9);
  Chart.Canvas.LineTo(scrRect.Left+13, scrRect.Top+9);
  Chart.Canvas.MoveTo(scrRect.Left+14, scrRect.Top+13);
  Chart.Canvas.LineTo(scrRect.Left+19, scrRect.Top+17);
end;
procedure TZoomRect.HandleMouse(X, Y: Integer; Event: TEventID; Shift: TShiftState; var Handled: Boolean);
const SENS = 3;
var scrRect, newScrRect: TRect;
    function GetElementUnderMouse(const R: TRect): TZoomRectElement;
    var orientedR: TRect;
    begin
      Result := elNone;
      orientedR := R;
      OrientRect(orientedR);
      if (X < orientedR.Left - SENS)or(X > orientedR.Right  + SENS) then Exit;
      if (Y < orientedR.Top  - SENS)or(Y > orientedR.Bottom + SENS) then Exit;
      if      (Abs(X - R.Left)  < SENS)and(Abs(Y - R.Top)    < SENS) then Result := elLeftTopCorner
      else if (Abs(X - R.Left)  < SENS)and(Abs(Y - R.Bottom) < SENS) then Result := elLeftBottomCorner
      else if (Abs(X - R.Right) < SENS)and(Abs(Y - R.Top)    < SENS) then Result := elRightTopCorner
      else if (Abs(X - R.Right) < SENS)and(Abs(Y - R.Bottom) < SENS) then Result := elRightBottomCorner
      else if Abs(X - R.Left)   < SENS then Result := elLeftBorder
      else if Abs(X - R.Right)  < SENS then Result := elRightBorder
      else if Abs(Y - R.Top)    < SENS then Result := elTopBorder
      else if Abs(Y - R.Bottom) < SENS then Result := elBottomBorder
      else if PtInRect(orientedR, Point(X, Y)) then Result := elRectBody;
      if (not FAllowRectBody) and (Result = elRectBody) then Result := elNone;
    end;
    function GetProperCursor(Element: TZoomRectElement): TCursor;
    begin
      case Element of
        elNone:                               Result := crDefault;
        elRectBody:                           Result := crHandPoint;
        elLeftBorder, elRightBorder:          Result := crSizeWE;
        elTopBorder, elBottomBorder:          Result := crSizeNS;
        elLeftTopCorner, elRightBottomCorner: Result := crSizeNESW;
        elRightTopCorner, elLeftBottomCorner: Result := crSizeNWSE;
        else                                  Result := crDefault;
      end;
    end;
    
begin
  if Handled then Exit;
  scrRect := CalcScreenRect(FRect);
  {Chart.}Screen.Cursor := crDefault;
  if Event = evMouseDown then
  begin
    //FDownPt := Point(X, Y);
    FPrevPt := Point(X, Y);
    FActiveElememt := GetElementUnderMouse(scrRect);
    if FActiveElememt <> elNone then Chart.AllowZoom := False;
    Screen.Cursor := GetProperCursor(FActiveElememt);
  end
  else
  if Event = evMouseMove then
  begin
    if (ssLeft in Shift) then
    begin
      newScrRect := scrRect;
      if FActiveElememt = elRectBody then OffsetRect(newScrRect, X - FPrevPt.X, Y - FPrevPt.Y); {!else}
      if FActiveElememt in [elLeftBorder, elLeftTopCorner, elLeftBottomCorner]    then newScrRect.Left := X;
      if FActiveElememt in [elRightBorder, elRightTopCorner, elRightBottomCorner] then newScrRect.Right := X;
      if FActiveElememt in [elTopBorder, elLeftTopCorner, elRightTopCorner]       then newScrRect.Top := Y;
      if FActiveElememt in [elBottomBorder, elLeftBottomCorner, elRightBottomCorner] then newScrRect.Bottom := Y;
      Rect := CalcLogicRect(newScrRect);
      Screen.Cursor := GetProperCursor(FActiveElememt);
      Chart.Invalidate;
      FPrevPt := Point(X, Y);
    end
    else
      {Chart.}Screen.Cursor := GetProperCursor(GetElementUnderMouse(scrRect));
  end
  else
  if Event = evMouseUp then
  begin
    FActiveElememt := elNone;
    //Chart.AllowZoom := True;
    Chart.AllowZoom := AllowStandardZoom;
    Chart.Invalidate;
  end;
end;
function TZoomRect.GetRect: TRectF;
begin
  Result := FRect;
  {!}OrientRectF(Result);
end;
procedure TZoomRect.SetRect(const Value: TRectF);
begin
  FRect := Value;
  //{!}OrientRectF(FRect);
  Changed;
  Chart.Invalidate;
end;
procedure TZoomRect.Changed;
begin
  if Assigned(FOnChange) then FOnChange(Self);
end;
function TZoomRect.CalcScreenRect(const R: TRectF): TRect;
begin
  Result.Left := Chart.BottomAxis.CalcPosValue(R.XMin);
  Result.Right := Chart.BottomAxis.CalcPosValue(R.XMax);
  Result.Top := Chart.LeftAxis.CalcPosValue(R.YMax);
  Result.Bottom := Chart.LeftAxis.CalcPosValue(R.YMin);
end;
function TZoomRect.CalcLogicRect(const R: TRect): TRectF;
begin
  Result.XMin := Chart.BottomAxis.CalcPosPoint(R.Left);
  Result.XMax := Chart.BottomAxis.CalcPosPoint(R.Right);
  Result.YMin := Chart.LeftAxis.CalcPosPoint(R.Bottom);
  Result.YMax := Chart.LeftAxis.CalcPosPoint(R.Top);
end;
end.
{==============================================================================}
Responder Con Cita
  #3  
Antiguo 14-03-2012
efirvida efirvida is offline
Miembro
 
Registrado: jun 2010
Posts: 12
Poder: 0
efirvida Va por buen camino
ahora es que viendo las respuestas entre este y el otro post me doy cuenta que me ayuda la misma persona, muchas gracias rounin por todo, me has sido de gran ayuda, aqui tambien tengo unas observaciones que fueron necesarias para que me funcionara.

en ChartObj.pas tuve que eliminar la declaracion de TEventID, y agregar XYSel en las uses para que funcionara al igual que en zoomrect.pas, y ya todo funciono al quilo, muchas gracias por esas units que aunque no entiendo muy bien su funcionamiento todavia me seran de mucha ayuda, por lo menos estos ejemplos son los que estoy buscando en estos momentos.

por otra parte, ahora me hace falta tener dos tchart y poder sincronizarlos, o mejor si se puede hacer que un solo tchart muestre dos series que no esten superpuestas, ejemplo, mostrar una funcion seno y una funcion coseno una encima de otra, como si fueran dos graficos separados, sino se puede.
Responder Con Cita
  #4  
Antiguo 17-03-2012
rounin rounin is offline
Miembro
 
Registrado: sep 2005
Posts: 43
Poder: 0
rounin Va por buen camino
Hola,

El hecho es que cuando yo estaba haciendo el utlimo ejemplo, he separado
la clase basica de TSelection y TZoomRect, y declaracion de TEventID se va a ChartObj.pas.
Eso permite sustituir un objeto con otra o usar unas aquellos objetas.
En adjunto hay la ultimas versiones de objetos.

Sobre dos charts sincronizados, necesitas usar
eventos OnZoom, OnUndoZoom, OnScrol:

Código Delphi [-]
function TForm1.AnotherChart(Chart: TChart): TChart;
begin
  if Chart = Chart1
    then Result := Chart2
    else Result := Chart1;
end;
procedure TForm1.ChartZoomChanged(Sender: TObject);
begin
  AnotherChart(Sender as TChart).LeftAxis.Automatic := (Sender as TChart).LeftAxis.Automatic;
  AnotherChart(Sender as TChart).BottomAxis.Automatic := (Sender as TChart).BottomAxis.Automatic;
  AnotherChart(Sender as TChart).LeftAxis.Minimum := (Sender as TChart).LeftAxis.Minimum;
  AnotherChart(Sender as TChart).LeftAxis.Maximum := (Sender as TChart).LeftAxis.Maximum;
  AnotherChart(Sender as TChart).BottomAxis.Minimum := (Sender as TChart).BottomAxis.Minimum;
  AnotherChart(Sender as TChart).BottomAxis.Maximum := (Sender as TChart).BottomAxis.Maximum;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Chart1.OnZoom := ChartZoomChanged;
  Chart1.OnUndoZoom := ChartZoomChanged;
  Chart1.OnScroll := ChartZoomChanged;
  Chart2.OnZoom := ChartZoomChanged;
  Chart2.OnUndoZoom := ChartZoomChanged;
  Chart2.OnScroll := ChartZoomChanged;
end;
Archivos Adjuntos
Tipo de Archivo: zip ChartObj.zip (11,8 KB, 14 visitas)
Responder Con Cita
  #5  
Antiguo 05-04-2012
efirvida efirvida is offline
Miembro
 
Registrado: jun 2010
Posts: 12
Poder: 0
efirvida Va por buen camino
hola de nuevo :)

muchisimas gracias por tus aportes de verdad me han servido mucho, ya casi tengo todo lo que quiero, pero todavia me faltan algunas cosas relacionadas con esto mismos que hemos estado conversando.

ya tengo los dos Chart sincronizados perfectamente pero ahora no me funciona lo seleccionar y copiar datos, al principio me lo hacia mas o menos, pero luego se me ocurrio crear dos FSelection uno para cad chart, y crear todos los eventos necesarios en cada chart, y no se que me paso que ahora no me hace nada de nada ni siquiera dibuja el rectangulo en ninguno de los dos chart, no se si ese es el procedimiento y meti la pata en algo o ademas de eso me falto algo por hacer.

y lo otro un poco alejado del tema, aunque esa en zona, me gustaria, poder dibujar rectangulos en el chart, y poder guardarlos en un fichero de forma tal que pueda seleccionar las zonas en el grafico que me interesan y guardarlas para usos posteriores, ¿que deberia hacer para esto?
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
TChart Dos escalas rjtostado Gráficos 0 09-11-2010 23:02:05
Ayuda con Elipses en un TChart lol Gráficos 8 25-02-2008 16:58:25
Ayuda con TChart Punzo Gráficos 0 17-10-2007 02:49:27
Tchart marlulipe Gráficos 2 15-08-2007 01:32:04
Ayuda con TChart pelaorb68 Gráficos 0 02-09-2006 00:41:02


La franja horaria es GMT +2. Ahora son las 15:37:30.


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