Page 1 of 1

Printing Text (&etc) along with Chart

Posted: Thu Aug 04, 2005 4:29 pm
by 9341114
Has anyone had any experience with printing additional text/graphics/etc along with TChart? I can get the text to appear in the previewer, but it never actually prints. I've tried this with several PC's and printers, all the same. The chart prints, but nothing else.

Can anyone help with this?

Thanks

Paul

Posted: Fri Aug 05, 2005 1:35 am
by Pep
Hi Paul,
This is as designed. The problem is all custom positioned object (legend,
text, series marks) use screen pixels coordinates. While this is fine for
screen it does not work for printer. Why ? The reason for this is if you
print, TeeChart will internally change chart size (so that it fits in
specified printer.Canvas region). The result is Chart size will change but
the custom positioned items "positions" on printer canvas will remain the
same (in screen pixel coordinates). This will result in custom items being
drawn at wrong place.
The solutions:

+ To print, use the following code:

var tmpMeta: TMetaFile;
begin
tmpMeta := Chart1.TeeCreateMetafile(true,Chart1.ClientRect);
try
Printer.BeginDoc;
try
Printer.Canvas.StretchDraw(custom_printer_rect_region,tmpMeta);
finally
Printer.EndDoc;
end;
finally
tmpMeta.Free;
end;

Basically you're creating a metafile with the same size as original chart.
The consequence of this is custom positions will be valid for metafile as
well. Then you use StretchDraw method to "paint" this image (with correct
custom items positions) directly onto Printer.Canvas.

+ If possible try using "axis" scale coordinate for mark position position.

Basically, set (an example) custom item position to x=1.0, y=5.2 and then
use Chart1.BottomAxis.CalcPosValue(x), Chart1.LeftAxis.CalcPosValue(y) to
calculate current "screen" or "printer" canvas pixel position (you'll also
have to define an array where you'll store all positions, expressed in axis
values). Now you're defining marks positions in axis scale and using
CalcPosValue method to convert it to screen pixel coordinate. The advantage
of this method is you can use TChartPreviewer and existing print methods.

Posted: Fri Aug 05, 2005 12:57 pm
by 9341114
Hello -

Yes, I understand the problem with screen versus printer coordinates. I guess I just assumed that when it's advertized in "All Features" the ability to place text on the paper in the print previewer, it would actually print. It seems reasonable that the writers of TChart would have resolved the translation problem.

Actually, what is happening is not that the objects get printed in the wrong place or at the wrong size (I specifically looked for that situation), but rather they don't print *at all*.

Thanks for your help.

Paul

Posted: Fri Aug 05, 2005 2:01 pm
by Pep
Hi Paul,

whops..in that case, could you please send me a simple example with which I can reproduce the problem as is here ?
Send me it directly to pep@steema.com

Posted: Mon Aug 15, 2005 10:45 am
by 4209035
Hello,

how do I compute the values for 'custom_printer_rect_region'? I don't really get this.

Thanks!
Mike aka Betaversion

Posted: Wed Aug 17, 2005 2:24 pm
by 8572663
Pep,

Were you able to reproduce and solve this issue? I am having the same problem. I am placing annotation text next to chart that does not get printed at all. Thanks

Posted: Thu Aug 18, 2005 7:43 am
by Pep
Hi leaf,

have you tried the solutions I posted on this post ? I've also posted a txt file into the news://www.steema.net/steema.public.attachments newsgroup (RE: Printing Better) which contains a detailed explanation about the use of TeeChart and the Printers. Could you please take a look at it ?

Posted: Sun Aug 28, 2005 4:59 pm
by 8572663
This is still a problem for me.

I want to go to the link you provided and try your solution but I am unable to get there. Is ther another way other than the link you provided? How do I display your solution?

Thanks

Posted: Sat Sep 03, 2005 5:17 pm
by 9343038
I wrote the following code to print on the default printer using a margin and print my chart proportional as large as possible. I appreciate any feedback (like this is in the library already etc.)
--Paul

Code: Select all

procedure TChartFrame.Print1Click(Sender: TObject);
var
   tmpMeta: TMetaFile;
const
   Margin = 0.5;   //margins in inches
var
   PPIX     ,
   PPIY     : integer; //printer pixels per inch
   OffSetX  ,          //margins
   OffSetY  : integer;
   SizeX    : integer; //size for printer image
   SizeY    : integer;
   PrMaxX   ,          //maximum for printer image
   PrMaxY   : integer;
   Mult     : double;
   ChartX   ,          //size of screen image
   ChartY   : integer;
begin
//Chart1.Print;  //does not print text boxes etc
tmpMeta := Chart1.TeeCreateMetafile(true,Chart1.ClientRect);
ChartX := (Chart1.ClientRect.Right - Chart1.ClientRect.Left);
ChartY := (Chart1.ClientRect.Bottom - Chart1.ClientRect.Top);

Printer.PrinterIndex := -1;  //default printer

   try
   Printer.BeginDoc;

   PPIX := GetDeviceCaps(Printer.Handle, LOGPIXELSX);
   PPIY := GetDeviceCaps(Printer.Handle, LOGPIXELSY);

   OffSetX := Round(Margin * PPIX);
   OffSetY := Round(Margin * PPIY);

   PrMaxX := Printer.PageWidth - 2 * OffSetX;
   PrMaxY := Printer.PageHeight - 2 * OffSetY;

   SizeX := PrMaxX;
   Mult := prMaxX / ChartX / PPIX;
   SizeY := Round(ChartY * Mult * PPIY);

   if SizeY > PrMaxY
   then
      begin
      SizeY := PrMaxY;
      Mult := prMaxY / ChartY / PPIY;
      SizeX := Round(ChartX * Mult * PPIX);
      end;

      try
      Printer.Canvas.StretchDraw(Rect( OffSetX, OffSetY, OffSetX + SizeX, OffSetY + SizeY ), tmpMeta);
      finally
      Printer.EndDoc;
      end;
   finally
   tmpMeta.Free;
   end;
end;

Posted: Tue Sep 06, 2005 7:37 am
by narcis
Hi leaf,

To get to the attachments newsgroup you need a newsreader, set up a new news server being www.steema.net with all default settings and subscribe to steema.public.attachments newsgroup. Depending on your machine settings, clicking in the following link may also bring you directly to the newsgroups [url]news://www.steema.net/steema.public.attachments[/url]

In case you have any problem accessing to the newsgroups please let us know and we will send you the mentioned document.

Posted: Tue Sep 06, 2005 9:12 am
by Marc
Hello,

To position Custom Canvas elements on a Chart (eg. such a Canvas.TextOut) then they should be done so relatively.

For example an item to be printed at the Bottom Axis at value 3 should use:

Code: Select all

m_Chart1.GetCanvas().TextOut(m_Chart1.GetAxis().GetBottom().CalcXPosValue(3),m_Chart1.GetAxis().GetBottom().GetPosition(),"Hello world");
The above codeline should be added in the OnAfterDraw or other Chart paint event or it will not appear on the Chart.

Regards,
Marc

Posted: Tue Sep 06, 2005 5:20 pm
by Marc
Hello,

Whoops, syntax from the last post is from the AX version for custom element output. The principle is similar with the VCL version (ie. Chart1->BottomAxis->CalcXPosValue(3)).

With respect to Chart location on the printed page please remember the availability of the Chart PrintPartial and PrintPartialCanvas methods to output the Chart to a determined rectangle size/location.

Regards,
Marc Meumann

Posted: Thu Sep 29, 2005 7:01 pm
by 8572663
OK, I have gotten a couple of print routines working. Now that I am able to print both the annotation and chart together, how can I call my print routine from the TChartPreviewer control? Your control does not print the text in the annotation tool.

Posted: Mon Oct 03, 2005 10:48 am
by Pep
Hi,

if you want to print the Chart with custom objects from a preview you should use the TPreviewPanel component and then print directly using similar code to the following :

Code: Select all

procedure TForm1.TeePreviewPanel1AfterDraw(Sender: TObject);
begin
  with TeePreviewPanel1,Canvas do
  begin
    Font.Color:=clRed;
    Font.Size:=12;
    TextOut(PaperRect.Left+10,PaperRect.Top+6,'Some text');
  end;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
var tmpMeta: TMetaFile;
OldColor : TColor;
begin
    Chart1.BevelOuter := bvNone;
    OldColor := Chart1.Color;
    Chart1.Color := clNone;
    tmpMeta := TeePreviewPanel1.TeeCreateMetafile(true,TeePreviewPanel1.ClientRect);
    try
        Printer.Orientation := poLandscape;
        Printer.BeginDoc;
        try
            Printer.Canvas.StretchDraw(Rect(1,1,Printer.PageWidth - 1,
Printer.PageHeight - 1),tmpMeta);
        finally
            Printer.EndDoc;
        end;
    finally
        tmpMeta.Free;
        Chart1.BevelOuter := bvRaised;
        Chart1.Color := OldColor;
    end;
end;
Using the TPreviewPanel component you can create your custom form Prevewer form.