Project

General

Profile

Scatter Chart and WPdfImage error 1025

Added by Stefan Arndt about 2 years ago

Hi there,
I have a problem here and hope someone can shine some light on this.
Below is a small test program based on "Scatter plot of a function" from the widget gallery (https://www.webtoolkit.eu/widgets/graphics-charts/scatter-plot). Nothing fancy there.
But I get an exception when opening the page:

[2022-Sep-15 22:59:41.743] 323566 - [info] "config: reading Wt config file: resources/wt_config.xml (location = '/home/;)/chartTest')"
[2022-Sep-15 22:59:41.743] 323566 - [info] "wthttp: reading wthttpd configuration from: resources/server_config"
[2022-Sep-15 22:59:41.743] 323566 - [info] "WServer/wthttp: initializing built-in wthttpd"
[2022-Sep-15 22:59:41.744] 323566 - [info] "WLogger: Opened log file (access.log)."
[2022-Sep-15 22:59:41.744] 323566 - [info] "wthttp: started server: http://127.0.0.1:11112"
[2022-Sep-15 22:59:43.552] 323566 - [info] "Wt: session created (#sessions = 1)"
[2022-Sep-15 22:59:43.552] 323566 [/ N6qKgxfFWdsi7mWt] [info] "WEnvironment: UserAgent: Mozilla/5.0 (X11; Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0"
terminate called after throwing an instance of 'Wt::WException'
  what():  WPdfImage error: error_no=1025, detail_no=0
Magick: abort due to signal 6 (SIGABRT) "Abort"...

From reading other posts and looking at the source, I now know the issue could be a problem with libharu. I am using these versions (arch linux):

libharu 2.4.2-1
wt 4.8.0-1

In hpdf_error.h I have "#define HPDF_INVALID_DOCUMENT 0x1025" .. which does not help me at all. I am using a pie chart in other places and it works fine.

Any ideas?

#include <Wt/Chart/WCartesianChart.h>
#include <Wt/WApplication.h>
#include <Wt/WServer.h>
#include <Wt/WStandardItemModel.h>
#include <Wt/WText.h>

#include <cmath>
#include <memory>

using namespace Wt;

std::unique_ptr<Wt::WContainerWidget> createChart();

int main(int argc, char** argv)
{
    try
    {
        WServer server(argv[0]);
        server.setServerConfiguration(argc, argv, "resources/server_config");

        server.addEntryPoint(
            Wt::EntryPointType::Application,
            [](WEnvironment const& env) {
                std::unique_ptr<Wt::WApplication> app = std::make_unique<Wt::WApplication>(env);
                app->root()->addNew<Wt::WText>("Chart Test");
                app->root()->addWidget(std::move(createChart()));
                return app;
            },
            "",
            "");

        if(server.start())
        {
            WServer::waitForShutdown();
            server.stop();
        }
    }
    catch(Wt::WServer::Exception const& e)
    {
        std::cerr << "Wt::WServer::Exception in main():" << e.what() << std::endl;
    }
}

std::unique_ptr<Wt::WContainerWidget> createChart()
{
    using namespace Wt;

    auto container = std::make_unique<WContainerWidget>();

    auto model = std::make_shared<WStandardItemModel>(40, 2);
    model->setHeaderData(0, WString("X"));
    model->setHeaderData(1, WString("Y = sin(X)"));

    for(unsigned i = 0; i < 40; ++i)
    {
        double x = (static_cast<double>(i) - 20) / 4;

        model->setData(i, 0, x);
        model->setData(i, 1, std::sin(x));
    }

    /*
     * Create the scatter plot.
     */
    Chart::WCartesianChart* chart = container->addNew<Chart::WCartesianChart>();
    chart->setModel(model);        // Set the model.
    chart->setXSeriesColumn(0);    // Set the column that holds the X data.
    chart->setLegendEnabled(true); // Enable the legend.

    chart->setType(Chart::ChartType::Scatter); // Set type to ScatterPlot.

    // Typically, for mathematical functions, you want the axes to cross
    // at the 0 mark:
    chart->axis(Chart::Axis::X).setLocation(Chart::AxisValue::Zero);
    chart->axis(Chart::Axis::Y).setLocation(Chart::AxisValue::Zero);

    // Provide space for the X and Y axis and title.
    chart->setPlotAreaPadding(120, Side::Right);
    chart->setPlotAreaPadding(40, Side::Top | Side::Bottom);

    // Add the curves
    auto s = std::make_unique<Chart::WDataSeries>(1, Chart::SeriesType::Curve);
    s->setShadow(WShadow(3, 3, WColor(0, 0, 0, 127), 3));
    chart->addSeries(std::move(s));

    chart->resize(800, 300); // WPaintedWidget must be given explicit size.

    chart->setMargin(10, Side::Top | Side::Bottom);            // Add margin vertically
    chart->setMargin(WLength::Auto, Side::Left | Side::Right); // Center horizontally

    return container;
}

Replies (5)

RE: Scatter Chart and WPdfImage error 1025 - Added by Stefan Arndt about 2 years ago

I was able to get some more insights. The problem indeed seems to be related to changes in libharu as I have problems running the widgetgallery example provided by the wt package and also compiling Wt from source by myself:

  • before libharu-2.4
    • can run example
    • can compile wt
  • libharu-2.4.0-1
    • cannot run example
    • can compile wt
  • libharu-2.4.2-1
    • cannot run example
    • cannot compile wt

libharu-2.4 is quiet recent (my file is from August 12th). I can live with downgrading libharu for the moment, but this issue might pop up for everyone later anyway.

Here are the compilation errors for reference:

[  4%] Building CXX object src/CMakeFiles/wt.dir/Wt/WPdfImage.C.o
/home/.../wt/src/Wt/WPdfImage.C: In member function ‘virtual void Wt::WPdfImage::setChanged(Wt::WFlags<Wt::PainterChangeFlag>)’:
/.../wt/src/Wt/WPdfImage.C:233:37: error: ‘HPDF_PROJECTING_SCUARE_END’ was not declared in this scope; did you mean ‘HPDF_PROJECTING_SQUARE_END’?
  233 |         HPDF_Page_SetLineCap(page_, HPDF_PROJECTING_SCUARE_END); // scuary !
      |                                     ^~~~~~~~~~~~~~~~~~~~~~~~~~
      |                                     HPDF_PROJECTING_SQUARE_END
/.../wt/src/Wt/WPdfImage.C:265:34: error: cannot convert ‘const HPDF_UINT16*’ {aka ‘const short unsigned int*’} to ‘const HPDF_REAL*’ {aka ‘const float*’}
  265 |         HPDF_Page_SetDash(page_, dash_ptn, 2, 0);
      |                                  ^~~~~~~~
      |                                  |
      |                                  const HPDF_UINT16* {aka const short unsigned int*}
In file included from /.../wt/src/Wt/WPdfImage.h:17,
                 from /.../wt/src/Wt/WPdfImage.C:13:
/usr/include/hpdf.h:1191:39: note:   initializing argument 2 of ‘HPDF_STATUS HPDF_Page_SetDash(HPDF_Page, const HPDF_REAL*, HPDF_UINT, HPDF_REAL)’
 1191 |                     const HPDF_REAL  *dash_ptn,
      |                     ~~~~~~~~~~~~~~~~~~^~~~~~~~
/.../wt/src/Wt/WPdfImage.C:274:34: error: cannot convert ‘const HPDF_UINT16*’ {aka ‘const short unsigned int*’} to ‘const HPDF_REAL*’ {aka ‘const float*’}
  274 |         HPDF_Page_SetDash(page_, dash_ptn, 2, 0);
      |                                  ^~~~~~~~
      |                                  |
      |                                  const HPDF_UINT16* {aka const short unsigned int*}
/usr/include/hpdf.h:1191:39: note:   initializing argument 2 of ‘HPDF_STATUS HPDF_Page_SetDash(HPDF_Page, const HPDF_REAL*, HPDF_UINT, HPDF_REAL)’
 1191 |                     const HPDF_REAL  *dash_ptn,
      |                     ~~~~~~~~~~~~~~~~~~^~~~~~~~
/.../wt/src/Wt/WPdfImage.C:283:34: error: cannot convert ‘const HPDF_UINT16*’ {aka ‘const short unsigned int*’} to ‘const HPDF_REAL*’ {aka ‘const float*’}
  283 |         HPDF_Page_SetDash(page_, dash_ptn, 4, 0);
      |                                  ^~~~~~~~
      |                                  |
      |                                  const HPDF_UINT16* {aka const short unsigned int*}
/usr/include/hpdf.h:1191:39: note:   initializing argument 2 of ‘HPDF_STATUS HPDF_Page_SetDash(HPDF_Page, const HPDF_REAL*, HPDF_UINT, HPDF_REAL)’
 1191 |                     const HPDF_REAL  *dash_ptn,
      |                     ~~~~~~~~~~~~~~~~~~^~~~~~~~
/.../wt/src/Wt/WPdfImage.C:292:34: error: cannot convert ‘const HPDF_UINT16*’ {aka ‘const short unsigned int*’} to ‘const HPDF_REAL*’ {aka ‘const float*’}
  292 |         HPDF_Page_SetDash(page_, dash_ptn, 6, 0);
      |                                  ^~~~~~~~
      |                                  |
      |                                  const HPDF_UINT16* {aka const short unsigned int*}
/usr/include/hpdf.h:1191:39: note:   initializing argument 2 of ‘HPDF_STATUS HPDF_Page_SetDash(HPDF_Page, const HPDF_REAL*, HPDF_UINT, HPDF_REAL)’
 1191 |                     const HPDF_REAL  *dash_ptn,
      |                     ~~~~~~~~~~~~~~~~~~^~~~~~~~
make[2]: *** [src/CMakeFiles/wt.dir/build.make:5000: src/CMakeFiles/wt.dir/Wt/WPdfImage.C.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:1572: src/CMakeFiles/wt.dir/all] Error 2
make: *** [Makefile:136: all] Error 2

RE: Scatter Chart and WPdfImage error 1025 - Added by Roel Standaert about 2 years ago

Have you tried compiling Wt on the master branch from source? I recently fixed this issue: https://redmine.webtoolkit.eu/issues/10909

I'll include the bugfix in Wt 4.8.1.

RE: Scatter Chart and WPdfImage error 1025 - Added by Roel Standaert about 2 years ago

Looks like Wt doesn't quite properly compile with version 2.4.2, since they no longer include hpdf_version.h in hpdf.h. That include should be added to WPdfImage.C to make it compile again.

RE: Scatter Chart and WPdfImage error 1025 - Added by Roel Standaert about 2 years ago

It appears to also be necessary to include hpdf_version.h in the widget gallery's PdfRenderer.cpp to make sure it runs HPDF_UseUTFEncodings (otherwise TTF font rendering won't work properly).

RE: Scatter Chart and WPdfImage error 1025 - Added by Stefan Arndt about 2 years ago

Yes, I used the up-to-date master branch when compiling Wt (I should have noted that earlier).

I can confirm that including hpdf_version.h fixes the compilation issues with version 2.4.2.1 and the problem with running the widgetgallery example (scatter chart) is also gone. Thanks :)

    (1-5/5)