ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Creating PDF Report
Posted by Medic89 on Sep-25-2021 19:54
Attachments:
Hello Peter,

I implemented the create PDF report code into my app, it works so far, but when I try to print the pdf report, my Adobe DC reports a graphic error. Is there anything I missed to implement? Please see the created pdf attached to this post.
chartdirector_report.pdf
chartdirector_report.pdf

48.77 Kb

  Re: Creating PDF Report
Posted by Peter Kwan on Sep-28-2021 01:23
Hi Medic89,

I have just tried myself. The Adobe DC can view the PDF normally, but when I printed it using Adobe DC on Windows, it reports a graphics error as you mentioned. I can print it successful using Adobe DC only if I choose "Print as Image" in Adobe DC print dialog.

I have tried to display and print using other viewers, like using various browsers, and the "Preview" app on macOS (the default viewer on macOS). They all work normally.

I also found some unusual features in your PDF report. There are two pages. In the second page, there is the "unregistered" yellow bar, but in the first page there is no such bar. Normally, the "unregistered" message will either not display at all, or it will display on every page.

Is it possible to create a simple source code example that can create a PDF with this problem? You can use hard coded data like in most of our sample code. I suspect there is some configuration in the report which may cause the interaction between Adobe DC and the printer driver to malfunction. If I can reproduce the problem from the source code, I can determine exactly what is inside the PDF and this would help to find out the cause the problem. I can also be a bug in Adobe DC (since it can display it, it should be able to print it, and all other programs can print and display it), in which case I can find out which feature triggers the problem.

Regards
Peter Kwan

  Re: Creating PDF Report
Posted by Medic89 on Sep-30-2021 19:44
Hi Peter,

here is my code:

void CMFCApplication2Dlg::createPdfReport(const char* filename)
{
MultiPagePDF doc;
const char* pageConfig = "pagewidth = 1123; pageHeight = 794";

PieChart firstPage(720, 960);
CDMLTable* Tabelle = firstPage.addTable(200, 200, Chart::TopLeft, 1, 2);
Tabelle->setCell(0, 0, 1, 1, "Diagnosen");
Tabelle->getCell(0, 0)->setFontStyle("Arial Bold");
Tabelle->getCell(0, 0)->setFontSize(10);
Tabelle->getCell(0, 0)->setHeight(16);
Tabelle->getStyle()->setWidth(668);
Tabelle->getStyle()->setBackground(Chart::Transparent, RGB(0, 0, 0), 0);
Tabelle->getCell(0, 0)->setAlignment(Chart::Left);
Tabelle->setCell(0, 1, 1, 1, "Keine");
Tabelle->getCell(0, 1)->setFontStyle("Arial");
Tabelle->getCell(0, 1)->setFontSize(9);
Tabelle->getCell(0, 1)->setHeight(16);
Tabelle->getCell(0, 1)->setAlignment(Chart::Left);
firstPage.setOutputOptions(pageConfig);
doc.addPage(&firstPage);

int startYear = (2021);
int endYear = 2021;
int pageNumber = 0;

for (int yyyy = startYear; yyyy <= endYear; yyyy += 2)
{
MultiChart m(1123, 794);

XYChart* c = drawXYChart(Chart::chartTime(yyyy, 1, 1), Chart::chartTime(yyyy + 1, 1, 1));
m.addChart(0, 120, c);

XYChart* c2 = 0;
if (yyyy < endYear)
{
c2 = drawXYChart(Chart::chartTime(yyyy + 1, 1, 1), Chart::chartTime(yyyy + 2, 1, 1));
m.addChart(0, 120, c2);
}

++pageNumber;

m.setOutputOptions(pageConfig);
doc.addPage(&m);

delete c;
delete c2;
}

// Output the PDF report
doc.outPDF(filename);
TCHAR szFilters[] = _T("PNG (*.png)|*.png|JPG (*.jpg)|*.jpg|GIF (*.gif)|*.gif|")
_T("BMP (*.bmp)|*.bmp|SVG (*.svg)|*.svg|PDF (*.pdf)|*.pdf||");


}

XYChart* CMFCApplication2Dlg::drawXYChart(double startX, double endX)
{
int startIndex = 0;
int endIndex = 164;
int noOfPoints = endIndex - startIndex + 1;

DoubleArray viewPortTimeStamps = DoubleArray(&(myRow1y[0]), 164);
XYChart* c = new XYChart(1100, 390 + 46);

c->setPlotArea(250, 5, 780, 350, RGB(255, 255, 255), RGB(255, 255, 255), 0xD9D9D9, RGB(255, 255, 255), RGB(255, 255, 255))->setGridWidth(1, 2, 0, 0);
c->setPlotArea(250, 5, 780, 350, RGB(255, 255, 255), RGB(255, 255, 255), 0xD9D9D9, RGB(255, 255, 255), RGB(255, 255, 255))->setGridColor(0xD9D9D9, 0xD9D9D9, 0xD9D9D9, RGB(255, 255, 255));
c->yAxis()->setWidth(2);
c->yAxis()->setColors(0xD9D9D9, RGB(0, 0, 0));
c->xAxis()->setDateScale(Startzeit(), Startzeit() + 9899, 900, 300);
c->xAxis()->setLabelFormat("{value|hh:nn}");
c->yAxis()->setLabelStyle("Arial", 8, RGB(0, 0, 0));
c->xAxis()->setLabelStyle("Arial", 8, RGB(0, 0, 0));
c->xAxis()->setLabelGap(3);
c->yAxis()->setTickDensity(40);
c->setAntiAlias(TRUE, 1);
ScatterLayer* systole = c->addScatterLayer(DoubleArray(Systolex, Systolex_size), DoubleArray(Systoley, Systoley_size), "Systole [mmHg]", Chart::InvertedTriangleShape, 11, 0x4472C4, 0x4472C4);
systole->setLineWidth(0);
systole->getDataSet(0)->setSymbolOffset(0, -6);
ScatterLayer* diastole = c->addScatterLayer(DoubleArray(Diastolex, Diastolex_size), DoubleArray(Diastoley, Diastoley_size), "Diastole [mmHg]", Chart::TriangleShape, 11, 0x4472C4, 0x4472C4);
diastole->setLineWidth(0);
diastole->getDataSet(0)->setSymbolOffset(0, 6);
ScatterLayer* mittel = c->addScatterLayer(DoubleArray(Mittelx, Mittelx_size), DoubleArray(Mittely, Mittely_size), "Mitteldruck [mmHg]", Chart::Cross2Shape(0.1), 11, 0x4472C4, 0x4472C4);
mittel->setLineWidth(0);
ScatterLayer* HF = c->addScatterLayer(DoubleArray(HFx, GroesseHF), DoubleArray(HFy, GroesseHF), "Herzfrequenz [/min.]", Chart::CircleShape, 7, 0xFF0000, 0xFF0000);
HF->setLineWidth(1);
c->yAxis()->setLinearScale(0, 130, 10);

Mark* yMark1 = c->yAxis()->addMark(100, RGB(0, 0, 0), "");
yMark1->setLineWidth(1);
yMark1->setZOrder(Chart::GridLinesZ);
// Add a line layer for the lines, using a line width of 2 pixels
LineLayer* layer = c->addLineLayer();
layer->setLineWidth(1);
c->layoutAxes();

for (int w = 0;w < 164;++w)
{
int X1 = systole->getXCoor(Systolex[w]);
int X2 = diastole->getXCoor(Diastolex[w]);
int Y1 = systole->getYCoor(Systoley[w]) - 2;
int Y2 = diastole->getYCoor(Diastoley[w]) + 2;
Line* Linie = c->addLine(X1, Y1, X2, Y2, 0x4472C4, 2);
Linie->setZOrder(Chart::GridLinesZ);
}
HF->moveFront();

// In this demo, we do not have too many data points. In real code, the chart may contain a lot
// of data points when fully zoomed out - much more than the number of horizontal pixels in this
// plot area. So it is a good idea to use fast line mode.
layer->setFastLineMode();

// Now we add the 3 data series to a line layer, using the color red (ff0000), green
// (00cc00) and blue (0000ff)
layer->setXData(viewPortTimeStamps);
return c;
}

void CMFCApplication2Dlg::OnClickedButton1()
{
// The standard CFileDialog
CFileDialog fileDlg(FALSE, _T("pdf"), _T("chartdirector_report"), OFN_HIDEREADONLY |
OFN_OVERWRITEPROMPT, _T("PDF (*.pdf)|*.pdf||"));
if (fileDlg.DoModal() == IDOK)
createPdfReport(TCHARtoUTF8(fileDlg.GetPathName()));
}

  Re: Creating PDF Report
Posted by Peter Kwan on Oct-01-2021 17:45
Attachments:
Hi Medic89,

I do not have your data arrays, so I modified your "drawXYChart" routine to assign random data to your arrays. It works normally. Below is my modified code. I have attached the PDF report generated. It can print normally. Please try it to see if you can print in your printer. (Sometimes it may be printer driver related.)


XYChart* CZoomScrollPdfDlg::drawXYChart(double startX, double endX)
{
    RanSeries r(127);
    DoubleArray m_timeStamps = r.getDateSeries(1827, Chart::chartTime(2015, 1, 1), 300);
    m_dataSeriesA = r.getSeries(1827, 150, -10, 10);
    m_dataSeriesB = r.getSeries(1827, 200, -10, 10);
    m_dataSeriesC = r.getSeries(1827, 250, -8, 8);

    double Startzeit = *m_timeStamps.data;
    const double* myRow1y = m_timeStamps.data + 1;

    const double* Systolex = myRow1y;
    int Systolex_size = 32;

    const double* Systoley = m_dataSeriesA.data;
    int Systoley_size = Systolex_size;

    const double* Diastolex = myRow1y;
    int Diastolex_size = Systolex_size;

    const double* Diastoley = m_dataSeriesB.data;
    int Diastoley_size = Diastolex_size;

    const double* Mittelx = myRow1y;
    int Mittelx_size = Systolex_size;

    const double* Mittely = m_dataSeriesC.data;
    int Mittely_size = Mittelx_size;

    const double* HFx = myRow1y;
    const double* HFy = m_dataSeriesA.data;
    int GroesseHF = Systolex_size;

    int startIndex = 0;
    int endIndex = 164;
    int noOfPoints = endIndex - startIndex + 1;

    DoubleArray viewPortTimeStamps = DoubleArray(&(myRow1y[0]), 164);
    XYChart* c = new XYChart(1100, 390 + 46);

c->setPlotArea(250, 5, 780, 350, RGB(255, 255, 255), RGB(255, 255, 255), 0xD9D9D9, RGB(255, 255, 255), RGB(255, 255, 255))->setGridWidth(1, 2, 0, 0);
c->setPlotArea(250, 5, 780, 350, RGB(255, 255, 255), RGB(255, 255, 255), 0xD9D9D9, RGB(255, 255, 255), RGB(255, 255, 255))->setGridColor(0xD9D9D9, 0xD9D9D9, 0xD9D9D9, RGB(255, 255, 255));
c->yAxis()->setWidth(2);
c->yAxis()->setColors(0xD9D9D9, RGB(0, 0, 0));
c->xAxis()->setDateScale(Startzeit, Startzeit + 9899, 900, 300);
c->xAxis()->setLabelFormat("{value|hh:nn}");
c->yAxis()->setLabelStyle("Arial", 8, RGB(0, 0, 0));
c->xAxis()->setLabelStyle("Arial", 8, RGB(0, 0, 0));
c->xAxis()->setLabelGap(3);
c->yAxis()->setTickDensity(40);
c->setAntiAlias(TRUE, 1);
ScatterLayer* systole = c->addScatterLayer(DoubleArray(Systolex, Systolex_size), DoubleArray(Systoley, Systoley_size), "Systole [mmHg]", Chart::InvertedTriangleShape, 11, 0x4472C4, 0x4472C4);
systole->setLineWidth(0);
systole->getDataSet(0)->setSymbolOffset(0, -6);
ScatterLayer* diastole = c->addScatterLayer(DoubleArray(Diastolex, Diastolex_size), DoubleArray(Diastoley, Diastoley_size), "Diastole [mmHg]", Chart::TriangleShape, 11, 0x4472C4, 0x4472C4);
diastole->setLineWidth(0);
diastole->getDataSet(0)->setSymbolOffset(0, 6);
ScatterLayer* mittel = c->addScatterLayer(DoubleArray(Mittelx, Mittelx_size), DoubleArray(Mittely, Mittely_size), "Mitteldruck [mmHg]", Chart::Cross2Shape(0.1), 11, 0x4472C4, 0x4472C4);
mittel->setLineWidth(0);
ScatterLayer* HF = c->addScatterLayer(DoubleArray(HFx, GroesseHF), DoubleArray(HFy, GroesseHF), "Herzfrequenz [/min.]", Chart::CircleShape, 7, 0xFF0000, 0xFF0000);
HF->setLineWidth(1);
c->yAxis()->setLinearScale(0, 300, 20);

Mark* yMark1 = c->yAxis()->addMark(100, RGB(0, 0, 0), "");
yMark1->setLineWidth(1);
yMark1->setZOrder(Chart::GridLinesZ);
// Add a line layer for the lines, using a line width of 2 pixels
LineLayer* layer = c->addLineLayer();
layer->setLineWidth(1);
c->layoutAxes();

for (int w = 0; w < 30; ++w)
{
    int X1 = systole->getXCoor(Systolex[w]);
    int X2 = diastole->getXCoor(Diastolex[w]);
    int Y1 = systole->getYCoor(Systoley[w]) - 2;
    int Y2 = diastole->getYCoor(Diastoley[w]) + 2;
    Line* Linie = c->addLine(X1, Y1, X2, Y2, 0x4472C4, 2);
    Linie->setZOrder(Chart::GridLinesZ);
}
HF->moveFront();

// In this demo, we do not have too many data points. In real code, the chart may contain a lot
// of data points when fully zoomed out - much more than the number of horizontal pixels in this
// plot area. So it is a good idea to use fast line mode.
layer->setFastLineMode();

// Now we add the 3 data series to a line layer, using the color red (ff0000), green
// (00cc00) and blue (0000ff)
layer->setXData(viewPortTimeStamps);
return c;
}


If the above code works in your computer, but your real code does not work, is it possible to use hard coded data to create some code that I can try?


Regards
Peter Kwan
chartdirector_report.pdf
chartdirector_report.pdf

40.52 Kb

  Re: Creating PDF Report
Posted by Medic89 on Oct-01-2021 21:27
Hi Peter,

your attached PDF report works fine, I can print it without problems. I tried to implement your code, but I don't have m_dataSeries defined. What are those for? In the actual code I have a function, that retrieves the beginning of the diagram and since the diagramm has always the same width, the end point is 9899 seconds greater than the start point (Startzeit() and Startzeit() + 9899).

Another thing that bothers me: The lines of the diagramm do look very thick (with density set to 2), I tried to set it to 1, but then they are too thin, is there a way to get a density in between 1 and 2? Since the value is defined as integer, I cannot enter 1.5.

  Re: Creating PDF Report
Posted by Peter Kwan on Oct-02-2021 03:16
Hi Medic89,

The m_dataSeries are just random numbers. As I do not have you data, I need to some data to plot the chart, so I generate some random numbers right at the top few lines of the code:

RanSeries r(127);
DoubleArray m_timeStamps = r.getDateSeries(1827, Chart::chartTime(2015, 1, 1), 300);
m_dataSeriesA = r.getSeries(1827, 150, -10, 10);
m_dataSeriesB = r.getSeries(1827, 200, -10, 10);
m_dataSeriesC = r.getSeries(1827, 250, -8, 8);

In your own code, you will use your real data, not random numbers. If the chart works with random numbers, but not your real data, please inform me exact what are your real data. It is best if you can hard coded the real data in your code for testing, so that I can run your code with your real data.

For the line width, are you referring to the grid lines?

It is technically impossible to draw a horizontal or vertical line that is 1.5 pixels thick, as it is not allowed by the display hardware. (The hardware does not allow filling half a pixel.) In practice, anti-alias method is used, which means a 1.5 pixel line is still drawn  as a 2 pixel line but with a semi-transparent color. That means drawing a 2 pixel line with a semi-transparent color is equivalent to a 1.5 pixel line. For example, instead of using 0xD9D9D9 as the grid line color, you can use 0x7fD9D9D9 as the grid line color to make it thinner.

Regards
Peter Kwan

  Re: Creating PDF Report
Posted by Medic89 on Oct-02-2021 18:39
Attachments:
Hi Peter,

the code works, even with my data, however, when I open the pdf report in Adobe DC and start to zoom in or out, the rectangular symbols dissapear and they are missing on the printout as well. (see attached report)

Regarding the line with:

Is it possible to increase the resolution of the page? If I increase the resolution by 50% a 1 point line appears to be 1.5 points thick.
chartdirector_report.pdf
chartdirector_report.pdf

48.03 Kb

  Re: Creating PDF Report
Posted by Peter Kwan on Oct-05-2021 00:07
Attachments:
Hi Medic89,

I investigate your PDF in detail. I suspect there are some issues with your data. In the PDF, it seems there are shapes that are far outside the page boundary. How it is handled is up to the PDF viewer. In all the PDF viewers (varous browsers, Apple Preview, etc), they just ignore those points. I suspect the Adobe DC will attempt to draw the point anyway, and this results in various strange problem as the points are too far outside the page.

As mentioned in my previous message, for testing, it is useful to use hard coded data. In this way, you can see the data and make sure they are correct. For your existing code, it is hard to know if all your arrays are correct. For example, there may be uninitialized elements and they may result in random values that are way outside the axis range and so it invisible on the chart, or the memory may be overwritten by other parts of the program. (In C/C++, it is easy for code to write outside the array bounds.) As your chart does not have too many points, it should be feasible to test using hard coded data, like:

double myData[] = { ..... some data values ... };

If the hard coded data always work, but your actual data do not work, at least we know the problem is triggered by the data.

You also mention about a line being 1.5 points thick. Do you mean 1.5 pixels thick?

You can certainly increase the resolution by 50%. But as explained in my last message, it is technically impossible to have anything 1.5 pixels thick due to hardware limitations. Your monitor cannot display anything 1.5 pixels thick.

From experience, if the line is specified as 1.5 pixels thick, the Adobe PDF viewer will probably draw the line segments randomly as 1 or 2 pixels with various shades of colors. I have attached a screen shot for your PDF as rendered by Adobe DC in my computer. You can clearly see that the vertical lines are of different widths. It is the way Adobe choose to draw lines with an "impossible width", so that "on average" the line width is 1.5 pixels.

For Google Chrome, it will probably draw the 1.5 pixel line as 2 pixels. So the line will be thicker than expected, but all vertical lines has the same width.

If your draw the chart directly on screen using the CChartViewer, ChartDirector will behave similar to Chrome, but will round down to 1 pixel instead of round up to 2 pixels.

To change the display resolution, you can use BaseChart.setOutputOption:

https://www.advsofteng.com/doc/cdcpp.htm#BaseChart.setOutputOptions.htm

For display resolution (rendered on screen with CChartViewer), the option is bmpScale. For example:

c->setOutputOptions("bmpScale=1.5");

If it normally not necessary to set the resolution for PDF, because the PDF viewer allows the user to interactively set the resolution (the user can zoom in/out, which is the same as changing the resolution). If you must set the resolution, you can use:

// The industry standard is that dpi=96 corresponds to 100% resolution
c->setOutputOptions("dpi=144");

Regards
Peter Kwan
AcroRd32_20211004234647.png

  Re: Creating PDF Report
Posted by Medic89 on Oct-06-2021 22:29
Hello Peter,

isn't there a way to just "copy" the original Chart (which is a bitmap as far as I understand) on screen and put it on a paper and convert that to a PDF?

Another question:

I have a lot of data, that is supposed to be displayed in tables (they don't belong to the chart), is there a way to copy those data and the chart into word?

  Re: Creating PDF Report
Posted by Peter Kwan on Oct-06-2021 23:14
Hi Medic89,

You can always output the chart as a PDF by using Basechart.makeChart. For example:

c->makeChart("c:/path/to/aaa.pdf");

If the chart has already been displayed to the screen using the MFC CChartViewer, the chart can be obtained from the CChartViewer like:

BaseChart *myChart = myChartViewer->getChart();

Then you can save it using myChart->makeChart("c:/path/to/filename.pdf");

There are several examples included in ChartDirector that demonstrates saving the chart as PDF. One of them is:

https://www.advsofteng.com/doc/cdcpp.htm#xyzoomscroll.htm

ChartDirector cannot generate MS Word document. Instead, MS Word should import the chart and your data. MS Word can import the chart because the chart can be generated in a standard image format (like PNG or BMP), and then MS Word can import images in standard format. MS Word also has tables and can import your data. You may refer to MS Word documentation on how to create a word document and insert images and tables into it programmatically.

https://docs.microsoft.com/en-us/office/vba/api/overview/word

Regards
Peter Kwan

  Re: Creating PDF Report
Posted by Medic89 on Oct-07-2021 16:49
Hi Peter,

I found the following function to save the chart as an image:

void CXYZoomScrollDlg::OnSavePB()
{
    // Supported formats = PNG, JPG, GIF, BMP, SVG and PDF
    TCHAR szFilters[]= _T("PNG (*.png)|*.png|JPG (*.jpg)|*.jpg|GIF (*.gif)|*.gif|")
        _T("BMP (*.bmp)|*.bmp|SVG (*.svg)|*.svg|PDF (*.pdf)|*.pdf||");

    // The standard CFileDialog
    CFileDialog fileDlg(FALSE, _T("png"), _T("chartdirector_demo"), OFN_HIDEREADONLY |
        OFN_OVERWRITEPROMPT, szFilters);
    if(fileDlg.DoModal() != IDOK)
        return;

    // Save the chart
    CString path = fileDlg.GetPathName();
    BaseChart *c = m_ChartViewer.getChart();
    if (0 != c)
        c->makeChart(TCHARtoUTF8(path));
}

Is it possible to so only parts of the chart? In my case, my chart is always 1500 pixels high, but the diagram itself is sometimes smaller, Can I just get an image of the lets say top 500 pixels?

  Re: Creating PDF Report
Posted by Medic89 on Oct-08-2021 19:57
Attachments:
Or is there a way in general to increase the resolution of the output image? When I zoom in, the chart looks very "rough"
chartdirector_demo.png

  Re: Creating PDF Report
Posted by Peter Kwan on Oct-08-2021 23:37
Hi Medic89,

The chart displayed by ChartDirector on the screen should stay sharp when you zoom in. PDF also can stay sharp when you zoom in. For your case, I assume you are referring to the PNG image output with the intention of importing into MS Word.

Of the standard image types, MS Word only supports raster images, which are like digital photographs. If you zoom in a photograph, at some stage, the photograph will look blurred. The blurring can be reduced by using a photograph with more pixels (higher resolution).

The API to increase the number of pixels is BaseChart.setOutputOptions. For example:

// Increase the pixel size to 150% x 150% of the original
c->setOutputOptions("bmpScale=1.5");

Regards
Peter Kwan

  Re: Creating PDF Report
Posted by Medic89 on Oct-09-2021 00:32
Hi Peter,

perfect, now it's sharp when I zoom in. What about eporting just parts of the chart as image? On my example above, there is a large white space underneath the chart, so I'd like to export lets say just the first 1000 pixels of the chart area.

  Re: Creating PDF Report
Posted by Peter Kwan on Oct-09-2021 01:12
Hi Medic89,

May be you can try the following way:

(a) Create another empty chart with the desired size (only 1000 pixels in height).

(b) Copy the original chart to the chart in (a). In this way, you obtain a chart the same as the original chart but only 1000 pixels in height. The original chart is unchanged so it can  be displayed as normal.

(c) Output the chart in (a)

I think it is like:

BaseChart *originalChart = myChartViewer->getChart();

// Any chart is OK for the empty chart. I use a pie chart as
// it is the simplest chart type.
BaseChart *newChart = new PieChart(originalChart->getWidth(), 1000);

// There are several ways to copy one chart to another chart. I will use "DrawArea.merge" here.
// Another alternatives is to use the original chart as the background image of the empty chart,
newChart->getDrawArea()->merge(originalChart->makeChart(), 0. 0. Chart::TopLeft, 0);

// Output the new chart
newChart->setOutputOptions(....);
newChart->makeChart(......);

Regards
Peter Kwan

  Re: Creating PDF Report
Posted by Medic89 on Oct-10-2021 18:25
Hi Peter,

I got another solution, I just resized the multichart to be 50 pixels higher than the actual chart with the setsize() method.

I have another problem/question:

With my app I want to create a complex report with a chart and a few pages of data in various tables. My original plan was to copy the chart in a word template and fill the tables in that word template with data from the app and finally create a pdf. The down side is, during export from word to pdf the chart quality dreceases very much, do you have an idea how to solve that better? Would you create the hole report from my app? The problem is, my report contains some tables with formatted text.

  Re: Creating PDF Report
Posted by Peter Kwan on Oct-11-2021 21:53
Hi Medic89,

You can use ChartDirector to create a page with just text and tables. For text, you can use BaseChart.addText, and for tables, you can use BaseChart.addTable.

See:

https://www.advsofteng.com/doc/cdcpp.htm#BaseChart.addText.htm
https://www.advsofteng.com/doc/cdcpp.htm#BaseChart.addTable.htm

For text, basically can add the text at any location you like. For tables, you can add the table at any location you like too, and then add text to the cells. The format of each piece of text and each cell is configurable. Even within a single line of text, you can specify different colors and fonts for different parts of the text, and you can insert icons too. See:

https://www.advsofteng.com/doc/cdcpp.htm#cdml.htm

Regards
Peter Kwan

  Re: Creating PDF Report
Posted by Medic89 on Oct-14-2021 17:41
Hi Peter,

I tried to set up a table for the data on my report, but when I add Text like this:

PieChart firstPage(794, 1123);
TextBox* TextBox1 = firstPage.addText(50, 50, "Diagnosen:", "Arial Bold", 11);
TextBox* TextBox1k = firstPage.addText(50, 50, buf, "Arial", 10);
TextBox1->setWidth(694);
int H1 = TextBox1k->getHeight();
TextBox1k->setBackground(Chart::Transparent, RGB(0, 0, 0), 0);

But on the printout, the lines around the Boxes do look very bold, is there a way to get them thinner?

  Re: Creating PDF Report
Posted by Peter Kwan on Oct-15-2021 03:06
Hi Medic89.

I cannot try your code because I do not know what is the text in "buf" in your code. Anyway, I try it with some random text. The line width of the box is exactly 1 pixel thick when displaying the PDF at 100% size on my machine. If you think this is not the case in your machine, is it possible to attach the output so I can analyze it. Please include two things:

(a) The PDF file you obtained.

(b) A screen shot that shows the PDF as appears on your screen.

Note that for PDF, you can view it at any resolution you like. For example, you can ask the PDF viewer to display the PDF at 300% size, in this case the line width will be 3 pixels as appeared on the screen.

Regards
Peter Kwan

  Re: Creating PDF Report
Posted by Medic89 on Oct-15-2021 17:31
Attachments:
Hi Peter,

please see the PDF report attached to this post. I also attached two screenshots, One from that pdf report and another one from a report created in word and exported as pdf, both screenshots are made at a zoom of 800%, as you can see, on the word pdf, the line are much thinner than on the chartviewer pdf.
Screenshot 2021-10-15 112823.png
Screenshot 2021-10-15 112801.png
chartdirector_report.pdf
chartdirector_report.pdf

50.93 Kb

  Re: Creating PDF Report
Posted by Peter Kwan on Oct-18-2021 23:28
Hi Medic89,

I have just tried your PDF. At 100% zoom, the line width is exactly 1 pixel. So the PDF correctly reflect the chart.

ChartDirector is basically a graphics program. It aims to create an accurate display on screen. Like other screen oriented graphics programs, such as Photoshop and Windows Paint, the minimum line width is 1 pixel, which matches with the screen.

MS Word aims to print accurately on paper. It uses physical length units, which is appropriate for paper. Traditionally the "point" (pt) is used as unit, where 1 pt = 1/72 inch. Physical units are continuous, so MS Word can use fractional units.

As MS Word (and PDF) prioritize paper over screen, so the screen display often has distortions. For example, lines of the same widths and have rendered at different widths of screen, as illustrated in the following post:

https://www.chartdir.com/forum/download_thread.php?site=chartdir&bn=chartdir_support&thread=1632570844#N1633363677

Also, line width may not zoom proportionally on screen for MS Word / PDF. The line may appear to have the same line width at 100% and 200% zoom. It is even possible for a line at 400% zoom to become thinner than a line at 300% zoom.

In brief, for your case, the 1px is already the minimum line width. I suspect the MS Word PDF also displays the line as 1px at 100% zoom. If you want the line width to be smaller at 800% zoom, the only method is to configure the ChartDirector PDF to use a higher dpi (dot per inch is a scale factor to change the pixel unit to inch unit used in PDF. The industry standard is 96dpi). By default, 1 pixel will be 1/96 inch, or 0.75pt in PDF. If you use a higher dpi, it will become thin in pt unit. However, it also make everything (such as the text) smaller, so it is equivalent to using a smaller zoom factor. To make everything the same size except the line, you have to make everything bigger (eg, use larger text), which keeping the line width unchanged, and apply a larger dpi when creating the PDF.

Regards
Peter Kwan