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

Message ListMessage List     Post MessagePost Message

  MakeChart2 does not work
Posted by Michele on Apr-05-2022 19:45
Hello,
I am on OSX 12.1, and I am using ChartDirector 7.0. In a C++ code, I create a XYChart, fill it with some data, and successfully export to file as follows

XYChart* c;
[...]
c->addScatterLayer(DoubleArray(x.data(), x.size()), y.data(), y.size()), "", Chart::CircleSymbol, 1, 000000);
    c->makeChart("my_chart.png");

I then load the chart stored in my_chart.png later in the code. I would like to do without writing the chart to a file: I would like to store the image in memory. I tried to used the MakeChart2 function to achieve this, but if I do

c->makeChart2(0);

I get the compilation error

./x.cpp:7013:8: error: no member named 'makeChart2' in 'XYChart'; did you mean 'makeChart'?
    c->makeChart2(0);
       ^~~~~~~~~~
       makeChart
/Applications/ChartDirector/include/chartdir.h:1238:11: note: 'makeChart' declared here
        MemBlock makeChart(int format)
                 ^
1 error generated.


Do you know how to do this?
Thank you!

  Re: MakeChart2 does not work
Posted by Peter Kwan on Apr-05-2022 22:55
Hi Michele,

Please use makeChart instead. For example:

MemBlock m = c->makeChart(Chart::PNG);

Sorry for the confusion documentation. The C++ language supports overloading, which means different methods can have the same name. Unluckily, for our documentation generator, all heading and index must use a unique name. So in the heading, we use BaseChart.makeChart2, but in the "Usage" in the page, it mentions the API is used as "MemBlock makeChart(int format);". So the actual usage in C++ does not have the "2".

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

With the code "MemBlock m = c->makeChart(Chart::PNG);", the m.data will contain a pointer to the memory that contains the image bytes. The m.len will contain the number of bytes.

Best Regards
Peter Kwan

  Re: MakeChart2 does not work
Posted by Michele on Apr-06-2022 22:23
Dear Peter,
Thank you for your reply. Following your suggestion, I would like to use the Memblock m in wxWidgets, to produce a wxBitmap object (https://docs.wxwidgets.org/3.0/classwx_bitmap.html#a6ee4099d6c4c9532aff6e5c1de516f21).

I was thinking about something like

wxBitmap* my_bitmap;
my_bitmap= new wxBitmap(m, width, height, 1) .

However, I am not sure that this will work: can I pass m directly as first argument to wxBitmap? Also, how do I obtain width and length of the bitmap from m?

Thank you
Best,
Michele

  Re: MakeChart2 does not work
Posted by Peter Kwan on Apr-07-2022 02:24
Hi Michele,

Are you aware there is already a port of ChartDirector to wxWidgets? The port is done by a third party "Ulrich Telle".

https://utelle.github.io/wxchartdir/

I am not familiar with wxWidgets, but I checked his source code, and I found it is done in the following way:

MemBlock m = c->makeChart(Chart::BMP);
wxMemoryInputStream in(m.data, m.len);
wxBitmap bmp(wxImage(in, wxBITMAP_TYPE_BMP));

The "new wxBitmap(m, width, height, 1)" you try probably would not work. From wxWidgets documentation, this method expects the bytes to be a monochrome (that, black and white) bit map, with 1 bit per pixel. ChartDirector outputs in standard formats (PNG. JPG, BMP, SVG, PDF), but not in "1 bit per pixel". In standard formats, the memory block already include the width and height information in the image headers, so you just need to pass the memory to wxBitmap and it should be able to create the image.

In the above code, the BMP format is used, because it is fast and efficient. The BMP format is not compressed, and so it is fast to generate. The JPG/PNG employs image compression to reduce file size but have high CPU overhead. The smaller file size is useful if for storage on disk or for transfer through the network, but for display the image needs to be decompressed anyway so using BMP is better.

Hope this can help.

Regards
Peter Kwan

  Re: MakeChart2 does not work
Posted by Michele on Apr-08-2022 01:03
Thank you for your reply, Peter.

I have tried your code

MemBlock m = c->makeChart(Chart::BMP);
wxMemoryInputStream in(m.data, m.len);
wxBitmap bmp(wxImage(in, wxBITMAP_TYPE_BMP));

but it gives an error during runtime. It is not necessary to install
wxChartDir to run it.

Also, following your suggestion, I have tried to stick with the old
code where I write the image to a file, and switched from png to bmp
format, and bmp turns out to be slower than png.

  Re: MakeChart2 does not work
Posted by Peter Kwan on Apr-08-2022 01:55
Hi Michele,

If you save the file to the hard disk, BMP can be slower. It is because hard disk is very slow compared to memory, so its larger size can consume a lot of time to save to disk.

I never tried the code in my last post. (In fact, I never used wxWidget myself.) I just copied the code from wxChartDir.

You mentioned the code has error during "runtime". I assume this means the code can compile successfully, but when it runs, there is some kind of error. Did not error occur in those 3 lines, or did the error occur somewhere else (such as when you actually use the bmp variable)? Note that the code in my last message allocates the wxBitmap on the stack, so it cannot be used outside the scope that contains the code. If you need to store the pointer and use it in another scope, it needs to be allocated in the heap, like:

wxBitmap *bmp = new wxBitmap(wxImage(in, wxBITMAP_TYPE_BMP));

Regards
Peter Kwan

  Re: MakeChart2 does not work
Posted by Ulrich Telle on Apr-10-2022 05:39
Michele wrote:
I have tried your code

MemBlock m = c->makeChart(Chart::BMP);
wxMemoryInputStream in(m.data, m.len);
wxBitmap bmp(wxImage(in, wxBITMAP_TYPE_BMP));

but it gives an error during runtime.

Well, in principle, this code should run without errors. However, I think a small, but important detail is missing: you should set the output option "alpha=1". The following code should work without problems:

c->setOutputOptions("alpha=1");
MemBlock m = c->makeChart(Chart::BMP);
wxMemoryInputStream in(m.data, m.len);
wxBitmap bmp(wxImage(in, wxBITMAP_TYPE_BMP));

If you still get errors, please show the exact error message you get.

Regards,
Ulrich