Support #3173
closedWPieCharts unprintable to PDF with 1 or 0 items.
0%
Description
Not sure if this is a bug, but when I make a WPieChart with 1 or 0 items, it becomes unprintable in PDFs, the page simply reads "Failed to load PDF document". The WPieChart prints fine if it has 2 or more items. How can I print a PDF with 1 or less items?
The code I used is the sample code from the widget gallery PDF output Rendering HTML to PDF example, with some minor modifications.
The sample code is below, with the WPieChart initialization and printing below that.
namespace
{
void HPDF_STDCALL error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no, void *user_data)
{
user_data;
fprintf(stderr, "libharu error: error_no=%04X, detail_no=%d\n", (u32) error_no, (s32) detail_no);
}
}
class ReportResource : public Wt::WResource
{
public:
ReportResource(const std::vector<Wt::Chart::WPieChart*> pie_charts, Wt::WTable* table, Wt::WObject* parent = 0) : Wt::WResource(parent),
_table(NULL)
{
suggestFileName("report.pdf");
_table = table;
s32 charts = pie_charts.size();
for(s32 chart = 0; chart < charts; ++chart)
{
_pie_charts.push_back(pie_charts[chart]);
}
}
ReportResource(Wt::Chart::WPieChart* pie_charts, Wt::WTable* table, Wt::WObject* parent = 0) : Wt::WResource(parent),
_table(NULL)
{
suggestFileName("report.pdf");
_table = table;
_pie_charts.push_back(pie_charts);
}
virtual void handleRequest(const Wt::Http::Request& request, Wt::Http::Response& response)
{
request;
response.setMimeType("application/pdf");
HPDF_Doc pdf = HPDF_New(error_handler, 0);
// Note: UTF-8 encoding (for TrueType fonts) is only available since libharu 2.3.0 !
HPDF_UseUTFEncodings(pdf);
renderReport(pdf);
HPDF_SaveToStream(pdf);
unsigned int size = HPDF_GetStreamSize(pdf);
HPDF_BYTE *buf = new HPDF_BYTE[size];
HPDF_ReadFromStream (pdf, buf, &size);
HPDF_Free(pdf);
response.out().write((char*)buf, size);
delete[] buf;
}
private:
Wt::WTable* _table;
std::vector<Wt::Chart::WPieChart*> _pie_charts;
void renderReport(HPDF_Doc pdf)
{
//Get the html for the table
std::stringstream ss;
_table->htmlText(ss);
renderPdf(ss.str(), pdf);
}
void renderPdf(const Wt::WString& html, HPDF_Doc pdf)
{
//Make the page
HPDF_Page page = HPDF_AddPage(pdf);
HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
//Get the renderer to render the table data
Wt::Render::WPdfRenderer renderer(pdf, page);
renderer.setMargin(1.50);
renderer.setDpi(180);
renderer.useStyleSheet("Ventus/examples/simple/css/normalize.css");
renderer.useStyleSheet("Ventus/examples/simple/css/simple.css");
renderer.useStyleSheet("Ventus/build/ventus.css");
renderer.useStyleSheet("Ventus/examples/simple/css/browseralert.css");
renderer.render(html);
//Make a pdf image to render the chart
Wt::WPdfImage pdfImage(100, 100, this);
Wt::WPainter* p = renderer.getPainter(renderer.startPage(0));
u32 charts = _pie_charts.size();
u32 position = 500;
for(u32 chart = 0; chart < charts; ++chart)
{
_pie_charts[chart]->paint(*p, Wt::WRectF(200, position, 900, 900));
position += 900;
}
std::ofstream f("report.pdf", std::ios::out | std::ios::app | std::ios::binary);
pdfImage.write(f);
}
};
WPieChart initialization and printing. I'm also aiming to print a table on the same page, but you can ignore that code.
Wt::WContainerWidget* container = new Wt::WContainerWidget();
Wt::WPushButton* make_pdf = new Wt::WPushButton("Create pdf sample");
//Create table
Wt::WTable* report_table = new Wt::WTable(container);
report_table->addStyleClass("table table-bordered table-striped no-wrap");
report_table->setHeaderCount(1);
report_table->setMargin(Wt::WLength::Auto, Wt::Left | Wt::Right);
report_table->setMargin(30, Wt::Top | Wt::Bottom);
report_table->setMaximumSize(400, Wt::WLength::Auto);
report_table->elementAt(0, 0)->addWidget(new Wt::WText("Category"));
report_table->elementAt(0, 1)->addWidget(new Wt::WText("Total Cost"));
//Setup the chart's model
Wt::WStandardItemModel* _graph_model = new Wt::WStandardItemModel(container);
// Configure the header.
_graph_model->insertColumns(_graph_model->columnCount(), 2);
_graph_model->setHeaderData(0, Wt::WString("Item"));
_graph_model->setHeaderData(1, Wt::WString("Amount"));
//Create a pie chart
Wt::Chart::WPieChart *pie_chart = new Wt::Chart::WPieChart(container);
pie_chart->setModel(_graph_model); // Set the model.
pie_chart->setLabelsColumn(0); // Set the column that holds the labels.
pie_chart->setDataColumn(1); // Set the column that holds the data.
// Configure location and type of labels.
pie_chart->setDisplayLabels(Wt::Chart::Outside | Wt::Chart::TextLabel | Wt::Chart::TextPercentage); //Set where to display the text
// Enable a 3D and shadow effect.
pie_chart->setPerspectiveEnabled(true, 0.2); // Enable a 3D effect.
pie_chart->setShadowEnabled(true);
//pie_chart->setExplode(0, 0.3); // Explode the first item.
pie_chart->setPalette(new GraphPalette(Wt::Chart::WStandardPalette::GrayScale)); //Set the palette
pie_chart->resize(800, 400); // WPaintedWidget must be given an explicit size.
pie_chart->setMargin(10, Wt::Top | Wt::Bottom); // Add margin vertically.
pie_chart->setMargin(Wt::WLength::Auto, Wt::Left | Wt::Right); // Center horizontally.
// Set data in the model.
_graph_model->insertRows(_graph_model->rowCount(), 1);
_graph_model->setData( _graph_model->rowCount() - 1, 0, Wt::WString("Blueberry"));
_graph_model->setData( _graph_model->rowCount() - 1, 1, 120);
_graph_model->insertRows(_graph_model->rowCount(), 1);
_graph_model->setData( _graph_model->rowCount() - 1, 0, Wt::WString("Cherry"));
_graph_model->setData( _graph_model->rowCount() - 1, 1, 10);
ReportResource* pdf = new ReportResource(pie_chart, report_table, container);
make_pdf->setLink(pdf);
When the button is pressed, it should create the PDF. Removing the code that adds 2 sample items to the WPieChart right below the "// Set data in the model." comment will cause the error to happen. Is it something I am doing wrong with initializing the WPieChart, or some other setting?
Updated by Koen Deforche over 10 years ago
- Status changed from New to InProgress
- Assignee set to Michael Vilsker
- Target version changed from 3.3.2 to 3.3.4
Michael, I suspect this is an error in libharu, which we can easily work around if we avoid creating an arc of exactly 360 degrees?
Updated by Michael Vilsker over 10 years ago
Hey Denis,
I could not reproduce the error message (maybe we use different versions of haru).
There was a problem in drawing circle.
You will be able to find the fix on git soon, I believe that will also fix the other error.
Updated by Michael Vilsker over 10 years ago
- Status changed from InProgress to Resolved
Updated by Koen Deforche about 10 years ago
- Status changed from Resolved to Closed