[SOLVED] Print Resolution Problem with frReports lazarus / 55-TAChart ---------------------------------------------------------------------- donnie · 2016-04-15 11:05 Hello again, I am drawing some tacharts and use frReport to fix the printings.  At the preview of the printing the resolution is perfect. But when I print them the resolution is not good at all. The same happens when I try to print in a PDF creator. In order to draw a chart I use the same code with the example of lazreports: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  if (Memo[0] = 'MyChart') and (View is TfrPictureView) then  begin    pv := View as TfrPictureView;    bmp := TBitmap.Create;    try      bmp.Width := Round(pv.Width);      bmp.Height := Round(pv.Height);    MyChart.PaintOnCanvas(bmp.Canvas, Rect(0, 0, bmp.Width, bmp.Height));      pv.Picture.Bitmap.Assign(bmp);    finally      bmp.Free;    end;  end I know that with Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  Chart1.Draw(TPrinterDrawer.Create(Printer), ARect);I would have a better result but not with lazreports. I need reports to have a preview. Is there any way to improve the quality of printing using frReports? Thanks, in advance. ---------------------------------------------------------------------- donnie · 2016-04-15 11:49 There is also another 'bug' maybe. At the bottom axes I use a DateTimeIntervalChartSource and I give DateTimeFormat-> dd/mm/yy hh:nn. When I draw my chart the time is ok as seen at the normalchart.jpg. But when I bring it in frReports I have only the Date and the time is 00:00 as seen at the printing chart.jpg. It can't bring the time which is strange as it takes a bitmap of the Tchart. I also tried to save my chart to a bitmap to Desktop  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   else if (Memo[0] = 'ChartXTH') and (View is TfrPictureView) then  begin    pv := View as TfrPictureView;    bmp := TBitmap.Create;    try      bmp.Width := Round(pv.Width);      bmp.Height := Round(pv.Height);    ChartDXTH.PaintOnCanvas(bmp.Canvas, Rect(0, 0, bmp.Width, bmp.Height));      bmp.SaveToFile('C:\Users\Desktop\chartbit.bmp'); //<----new      pv.Picture.Bitmap.Assign(bmp);    finally      bmp.Free;    end;  end and the result is the same with the printing jpg. It brings 00:00 to the hour. So the problem is on taChart to bitmap and not to frReports. ---------------------------------------------------------------------- donnie · 2016-04-15 13:46 Ok, just solved one part of the problem! At the bottom axis the 00:00 is the result of the nicesteps. DateTimeIntervalChartSource1->Params->Options->aipUseNiceSteps= false. The resize of the bitmap at my printing was making these steps much more bigger so it was not possible for the hour to be there and it was taking the start hour(00:00) of the day. The only problem now is the resolution of the printing!!! ---------------------------------------------------------------------- wp · 2016-04-15 18:46 The attached project is a modified version of TAChart's LazReport demo. It contains a new LazReport drawer which implements a Scale method for the distance calculations and a ScaleChart method for scaling of font sizes and line widths. Scaling factor should be the ratio of printer-to-screen resolution. The ScaleChart method is not complete, it only considers line and bar series, please extend it according to your needs. Moreover you must be aware that fonts in TAChart have a default size of 0 - this is not good if this number is multiplied by the scaling factor... Therefore, you must assign a non- zereo size to each font needed. This is probably not the best solution. Therefore, I will not upload the project to the TAChart demos repository. The main problem is that the chart should be rendered in two resolutions, in screen resolution for the preview, and in printer resolution for the print-out. In my understanding (I am not a LazReport expert...), however, the chart is rendered only once. This would not be an issue if this could be a vector graphic file format, but Lazreport accepts only bitmap formats in its picture element. Since finally, the chart will be printed, it is blown up by the above-mentioned scaling routines to printed size; unfortunately these "huge" fonts do not look nice when scaled-down in the preview. If somebody, more experienced with LazReport than me, is reading this: Is it possible to render the chart twice? The first time for the preview (using the standard canvas drawer), and the second time for the print-out (using the new LazReport drawer which scales the screen chart up to printer size)? ---------------------------------------------------------------------- Jurassic Pork · 2016-04-16 09:41 hello, wp , maybe you can try to reload the TfrPictureView in the BeforePrint Event like this :  Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i // var pv : TfrPictureView;  // globale variableprocedure TForm1.frReport1BeforePrint(sender: TfrReport);var bmp: TBitmap;  drawer: TLazReportDrawer;  clonedChart: TChart;  factor: Double;begin  showMessage('beforeprint');  if pv <> nil then    begin     bmp := TBitmap.Create;    try      factor := Max(Printer.XDPI, Printer.YDPI) / Screen.PixelsPerInch;      bmp.Width := Round(pv.Width*factor);    bmp.Height := Round(pv.Height*factor);      drawer := TLazReportDrawer.Create(bmp.Canvas, factor);      clonedChart := Chart1.Clone;      try        drawer.ScaleChart(clonedChart);        clonedChart.Draw(drawer, Rect(0, 0, bmp.Width, bmp.Height));      finally        clonedChart.Free;      end;      pv.Picture.Bitmap.Assign(bmp);    finally      bmp.Free;    end;  end;end; procedure TForm1.frReport1EnterRect(Memo: TStringList; View: TfrView);var  bmp: TBitmap;begin  if Memo.Count = 0 then exit;  if (Memo[0] = 'Chart1') and (View is TfrPictureView) then  begin    pv := View as TfrPictureView;    bmp := TBitmap.Create;    try      bmp.Width := Round(pv.Width);      bmp.Height := Round(pv.Height);    Chart1.PaintOnCanvas(bmp.Canvas, Rect(0, 0, bmp.Width, bmp.Height));      pv.Picture.Bitmap.Assign(bmp);    finally      bmp.Free;    end;  endend;                   Friendly, J.P ---------------------------------------------------------------------- wp · 2016-04-16 10:35 Yes, thank you, that would be a solution, although I have to keep track of the frPictureViews in case that the report contains several of them. And there's another disadvantage which I did not think of: The preview looks perfect at 100% magnification, but awful at 200%. The previous version looked poor (but not "awful") at 100% and better (but not "perfect") at 200%. It's a pity that LazReport does not support vector graphics files. BTW: Are there any plans to interface LazReport with fpvectorial? I think this would allow to paint the chart to svg which should render fine at all magnifications. ---------------------------------------------------------------------- wp · 2016-04-16 15:14 I uploaded a new version to Lazarus trunk which takes account of the Lazreport print resolution issue. It better integrates into the TAChart drawing backend infrastructure than the code posted above. Please see the updated Lazreport sample in the TAChart installation. The basic idea is: Upscale the bitmap into which the chart is rendered for the Lazreport picture view by a factor given by the ratio of printer to screen resolution.Use the new TScaledCanvasDrawer for painting the chart into this bitmap; its constructor gets the scaling factor which is automatically applied for scaling font sizes and line widths.It is no longer necessary to replace zero-valued default font sizes because this is done internally.Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.frReport1EnterRect(Memo: TStringList; View: TfrView);var  bmp: TBitmap;  pv: TfrPictureView;  factor: Double;begin  if Memo.Count = 0 then exit;  if (Memo[0] = 'Chart1') and (View is TfrPictureView) then begin    pv := View as TfrPictureView;    factor := Max(Printer.XDpi, Printer.YDpi) / Screen.PixelsPerInch;    bmp := TBitmap.Create;    try      bmp.Width := Round(pv.Width * factor);      bmp.Height := Round(pv.Height * factor);      Chart1.Draw(        TScaledCanvasDrawer.Create(bmp.Canvas, factor, [scaleFont, scalePen]),        Rect(0, 0, bmp.Width, bmp.Height));      pv.Picture.Bitmap.Assign(bmp);    finally      bmp.Free;    end;  end;end; ---------------------------------------------------------------------- donnie · 2016-04-18 13:35 wp, the last solution is above all expetations....  (until lazreports supports vectors) In my first resolution I just changed the width and height of the Rect to my wished resolutions. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i else if (Memo[0] = 'Chart1') and (View is TfrPictureView) then  begin    pv := View as TfrPictureView;    bmp := TBitmap.Create;    try      bmp.Width := Round(pv.Width);      bmp.Height := Round(pv.Height);     bmp.Width := 1200;       bmp.Height := 800;      Chart1.PaintOnCanvas(bmp.Canvas, Rect(0, 0, bmp.Width, bmp.Height));    pv.Picture.Bitmap.Assign(bmp);    finally      bmp.Free;    end;  end eg. 1200x800. Ofcourse you can make them as properties in order for the user to select the wanted resolution and the printing resolution was much better. You can have any resolution you want. Just changed some properties from my Picture(that loads the chart) at the frreport. Centered->true, KeepAspect->False, Stretched->True. Your solution brings the graph with its origin dimensions which I believe is better. (I changed some files from the component tachart in order to see the TScaledCanvasDrawer. http://svn2.freepascal.org/svn/lazarus/trunk/components/tachart/ and compare the files with the changes at the https://github.com/alriecker t/lazarus/tree/master/components/tachart.And everything is ok!!!!) Thank you very much.