Page 1 of 1

Cut and paste of TChart and its content

Posted: Tue Dec 21, 2004 3:21 am
by 9235196
I want to implement cut and paste of a tchart, include all its content.
I see the example from the BCB help. Then i try to apply on TChart.

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
TMetaClass *MetaClassChart = __classid(TChart);
RegisterClasses(&MetaClassChart, 0);

TMetaClass *MetaClassFLS = __classid(TFastLineSeries);
RegisterClasses(&MetaClassFLS, 0);

}

void __fastcall TForm1::ButtonAddClick(TObject *Sender)
{
int i;

for(i = 0; i < 20; i++)
Chart1->Series[0]->AddY(i*10);

for(i = 19; i >= 0; i--)
Chart1->Series[1]->AddY(i*10);
}

void __fastcall TForm1::ButtonCutClick(TObject *Sender)
{
Clipboard()->SetComponent(Chart1);
delete Chart1;
}

void __fastcall TForm1::ButtonPasteClick(TObject *Sender)
{
Clipboard()->GetComponent(this, this);
}

Chart can be paste but, the trace is missing.
How to implement cut and paste for a chart.
My chart contain only fastlineseries and pointseries.

Thank you

Herman


[/quote]

Posted: Tue Dec 21, 2004 7:57 am
by Marjan
Hi, Herman.

I'd use slightly different approach:
1) Create a temporary memory stream
2) Save original chart to this memory stream when copy is performed
3) Load chart from memory stream to target chart when paste is performed.

This way all series, published and some public properties will be copied from source to target chart.

I think there is an example of this (chart templates) available in TeeChart BCB demo.

Posted: Tue Dec 21, 2004 8:57 am
by 9235196
Hi,

Which example? All feature/Exporting/Native binary format?
I can not see the example source. Only a configure button, when i click on the source code. I have download the latest Tee7New from the website.
Can you send me the example?

Thank you

Herman

Posted: Tue Dec 21, 2004 10:25 am
by Pep
Hi Herman,

>Which example? All feature/Exporting/Native binary format?
Yes.

The sources are included in the binaries installer of teeChart Pro without source code.
Here is the copy of the code :

Code: Select all

unit Template_Chart;
{$I TeeDefs.inc}

interface

uses
  {$IFNDEF CLX}
  Windows, Messages, 
  {$ENDIF}
  SysUtils, Classes, 
  {$IFDEF CLX}
  QGraphics, QControls, QForms, QDialogs, QStdCtrls, QExtCtrls, QActnList,
  {$ELSE}
  Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ActnList,
  {$ENDIF}
  Base, TeeProcs, TeEngine, Chart, TeeChartActions;

type
  TTemplateChart = class(TBaseForm)
    TemplateChart: TChart;
    Button1: TButton;
    Button2: TButton;
    ActionList1: TActionList;
    ChartActionEdit1: TChartActionEdit;
    Splitter1: TSplitter;
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$IFNDEF CLX}
{$R *.dfm}
{$ELSE}
{$R *.xfm}
{$ENDIF}

Uses TeeStore;

procedure TTemplateChart.Button2Click(Sender: TObject);
var tmp : TMemoryStream;
    {$IFDEF CLR}
    tmpChart : TCustomChart;
    {$ENDIF}
begin
  { 1) Save the template into a Stream... }
  tmp:=TMemoryStream.Create;
  try
    { save only Chart and Series formatting, NOT including data }
    SaveChartToStream(TemplateChart,tmp,False);

    { 2) Load the template into other Chart... }
    tmp.Position:=0; { <-- set stream position to beggining of stream }

    {$IFDEF CLR}

    tmpChart:=TCustomChart(Chart1);
    LoadChartFromStream(tmpChart,tmp);
    Chart1:=TChart(tmpChart);

    {$ELSE}
    LoadChartFromStream(TCustomChart(Chart1),tmp);
    {$ENDIF}

    { restore the chart alignment (in this example) }
    Chart1.Align:=alClient;

    { repaint the Chart }
    Chart1.Repaint;
  finally
    { remove the stream, it's no longer necessary... }
    tmp.Free;
  end;
end;

procedure TTemplateChart.FormCreate(Sender: TObject);
begin
  inherited;
  { global variable, to add sample random points at runtime,
    automatically when adding a new series to Chart }
  TeeRandomAtRunTime:=True;
end;

procedure TTemplateChart.FormDestroy(Sender: TObject);
begin
  TeeRandomAtRunTime:=False; { disable adding sample random points at runtime }
  inherited;
end;

initialization
  RegisterClass(TTemplateChart);
end.

Posted: Tue Dec 21, 2004 10:42 am
by 9235196
sorry..do you have bcb version?
I'm not familiar with delphi code. :(

Posted: Wed Dec 22, 2004 2:23 am
by 9235196
I use BCB6.
I convert the posted code into bcb.
Must be something wrong in convertion.
When press button2, error happen.
error message: ChartException 'Wrong *.tee file format'

Another thing is I want to implement cut and paste for
an mdi application. So the memory stream method still can work?
Where should i place the memory stream?
If i use the clipboard, i just use the standard clipboard to store and get
from the clipboard.

//Unit1.h
class TForm1 : public TForm
{
__published: // IDE-managed Components
TChart *TemplateChart;
TButton *Button1;
TButton *Button2;
TActionList *ActionList1;
TChart *Chart1;
TAction *Action1;
TChartEditor *ChartEditor1;
void __fastcall Button2Click(TObject *Sender);
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall Button1Click(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;

//Unit1.cpp
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
/*
* Save the template into a Stream
*/
void __fastcall TForm1::Button2Click(TObject *Sender)
{
TMemoryStream *tmp = new TMemoryStream();
TCustomChart *tmpChart;

try
{
//save only Chart and Series formatting, NOT including data
SaveChartToStream(TemplateChart, tmp, false);

//Load the template into other Chart
tmp->Position = 0; // set stream position to beggining of stream

tmpChart = (TCustomChart*)Chart1;
LoadChartFromStream(tmpChart,tmp);
Chart1 = (TChart*)tmpChart;

LoadChartFromStream((TCustomChart*)Chart1,tmp);

//restore the chart alignment
Chart1->Align = alClient;

//repaint the Chart
Chart1->Repaint();
}
__finally
{
//remove the stream, it's no longer necessary...
tmp->Free();
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
TeeRandomAtRunTime = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
TeeRandomAtRunTime = false;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
ChartEditor1->Execute();
}
//---------------------------------------------------------------------------

Thank you

Herman

Posted: Wed Dec 22, 2004 8:57 am
by Marjan
9235196 wrote:sorry..do you have bcb version?
I'm not familiar with delphi code. :(
Hi, Herman.

Here is the C++ Builder equivalent code (copied from BCB demo, the Template_Chart.cpp unit):

Code: Select all

void __fastcall TTemplateChart::Button2Click(TObject *Sender)
{
  // 1) Save the template into a Stream...
  TMemoryStream *tmp = new TMemoryStream();
  try
  {
    // save only Chart and Series formatting, not data
    SaveChartToStream(TemplateChart,tmp,false);

    // 2) Load the template...

    // Reset stream position to begin:
    tmp->Position=0;

    // Load chart reference from stream:
    LoadChartFromStream(dynamic_cast<TCustomChart*>(Chart1),tmp);

    // restore the chart alignment (in this example)
    Chart1->Align = alClient;
    // repaint the Chart
    Chart1->Repaint();
  }
  __finally
  {
    // remove the stream, it's no longer necessary...
    delete tmp;
  }
}
//---------------------------------------------------------------------------

LoadChartFromStream notice

Posted: Tue Dec 28, 2004 2:45 pm
by 9234468
My experience:

LoadChartFromStream procedure have unpredicable result if applied on non empty Chart.
It is better to initialize Chart to defined state before LoadChartFromStream. Simply use helper Chart (global variable), initialized once anywhere in application starting section. Modified code (only Delphi version):


var
dummyChart: TChart; //global variable


procedure TForm1.FormCreate(Sender: TObject);
begin
dummyChart := tchart.Create(Self);
...
end;


...
Chart1.Assign(dummyChart); //!!start from initial state of TChart
LoadChartFromStream(TCustomChart(Chart1),tmp);
...

LoadChartFromStream issue

Posted: Thu Dec 30, 2004 8:00 am
by 9234468
I discovered that unit TeeEdit must be included in uses clause, otherwise runtime error "Class XXXseries not found" appears during LoadChartFromStream if Chart consists series (with or without data).

Do you have any explanation?

Error on LoadChart

Posted: Tue Sep 26, 2006 1:32 pm
by 9345939
I have added an popupmenu to an chart.
When I save the chart to an file the popupmenu
and the datasource is included. (In the file)

After Import of this file neigher the popupmenu nor
the datasource is in the chart. (I have saved it again to an other file)

What can I do???

Posted: Tue Sep 26, 2006 1:40 pm
by narcis
Hi Miroslav,

When exporting TChart's settings to a native template file datasources are not exported, only the chart's data. You'll have to manually re-assign the datasouces when loading the chart.

Regarding the pop-up menu, I'm afraid TeeChart doesn't export objects external to it.

Posted: Tue Sep 26, 2006 1:45 pm
by 9345939
You can try it!

If you export an Chart with popupmenu
you can see in the exported file that there
is an popupmenu included.

Posted: Tue Sep 26, 2006 1:53 pm
by narcis
Hi Miroslav,

Could you please send us an example we can run "as-is" to reproduce the problem here?

You can post your files at news://www.steema.net/steema.public.attachments newsgroup.

Thanks in advance.

Posted: Wed Sep 27, 2006 7:44 am
by 9345939
I have posted the files at news://www.steema.net/steema.public.attachments newsgroup under "Export-Import of TChart".

I hope this can help!

Posted: Mon Oct 02, 2006 2:24 pm
by Pep
Hi,

When saving/loading chart and series settings there are several limitations you must be aware of:

#1 : The events and particularly events "code" cannot be saved to a stream
i.e. you *must* set all events to nil before you save chart and reassign them manually after you load chart:

Chart1->OnScroll = NULL;
SaveChartToFile(Chart1,"c:\\temp\\test.tee",false);

and then reassign these events after you load chart:

LoadChartFromFile(dynamic_cast<TCustomChart*>(Chart1),"c:\\temp\\test.tee");

Chart1->OnScroll = Chart1OnScroll;

#2 : if you save some series type and then load it again in different form then you must manually register this series type before calling LoadFromChart procedure. Two ways how to do this:

a) register series by calling the RegisterTeeSeries(...) procedure

or (better)

b) Dropping TChartEditor component on the form (this automatically registers all series types).

#3 : Loading TDBChart series does not reconnect them to datasources (datasets) - you must do it manually after the LoadChartFromFile call.

The same happens for popupmenus, you must reconnect them manually :
PopupMenu:= pm;