Cut and paste of TChart and its content
Cut and paste of TChart and its content
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]
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]
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.
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.
Marjan Slatinek,
http://www.steema.com
http://www.steema.com
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 :
>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.
Pep Jorge
http://support.steema.com
http://support.steema.com
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
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
Hi, Herman.9235196 wrote:sorry..do you have bcb version?
I'm not familiar with delphi code.
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;
}
}
//---------------------------------------------------------------------------
Marjan Slatinek,
http://www.steema.com
http://www.steema.com
LoadChartFromStream notice
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 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
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?
Do you have any explanation?
-
- Newbie
- Posts: 14
- Joined: Wed Apr 05, 2006 12:00 am
Error on LoadChart
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???
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???
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
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.
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.
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Newbie
- Posts: 14
- Joined: Wed Apr 05, 2006 12:00 am
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
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.
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.
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Newbie
- Posts: 14
- Joined: Wed Apr 05, 2006 12:00 am
I have posted the files at news://www.steema.net/steema.public.attachments newsgroup under "Export-Import of TChart".
I hope this can help!
I hope this can help!
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;
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;
Pep Jorge
http://support.steema.com
http://support.steema.com