Our state of the art Gantt chart


Post by jim@jimclark.net.au »

Exported PNG, A4 Landscape and the produced an image size of 7680 x 4488 Pixels (34.47 MPixels) (1.71)
but when viewing the image I can see a large amount of empty space padding the right and bottom parts of this image.
After trimming off this blank space the image was reduced to 3170 x 2869 Pixels (9.09 MPixels) (1.10)
so about 4510 pixels of blank space padded on to left of gantt image
and 1619 pixel of blank spaced padded to the bottom of gantt image.
This extra blank padding makes it unsuitable for printing, etc.
Please advise if anything can be done to remove this blank padding on PNG exports.
Thanks

Post by Maxim Gorkovsky »

Thank you for feedback, we will look into it. Which OS are you running the server on? Which node version is used?

Post by jim@jimclark.net.au »

OS: Windows 10
Node: 10.17.0
Am running the server and the client (gantt page) on the same Dev machine so is Node 10.17.0 for both.

Post by Maxim Gorkovsky »

Incorrect PNG size is a problem on the server. To get high quality image we use setViewport function with predefined FullHD dimensions. We will update server to set viewport according to the content size in the next version. Or you can try to update server yourself, all you need to do is to take format from the config, get width/height in inches from puppeteer doc, multiply it by 96 and provide to setViewport call in examples/export/server/src/server.js

Post by jim@jimclark.net.au »

Like to but not quite follow your instructions.
Can you edit this code for me an I will give it a shot.
async function processPageIntoPngBuffer(browser, html, config)  {

    return new Promise(async(resolve, reject) => {

        try {

            const page = await browser.newPage();
    
            await page.setViewport({
                width             : 1920,
                height            : 1080,
                // https://github.com/puppeteer/puppeteer/issues/1329
                deviceScaleFactor : 4
            });
            await page.setContent(html, { waitUntil : 'networkidle0' });
            await page.emulateMedia('print');
            const buffer = await page.screenshot(config);
            await page.close();
            resolve(buffer);

        }
        catch (ex) {
            reject(ex.message);
        }
    });
}

Post by Maxim Gorkovsky »

// https://pptr.dev/#?product=Puppeteer&version=v2.0.0&show=api-pagepdfoptions
const paperFormat = {
    letter  : { width : 8.5, height : 11 },
    legal   : { width : 8.5, height : 14 },
    tabloid : { width : 11, height : 17 },
    ledger  : { width : 17, height : 11 },
    a0      : { width : 33.1, height : 46.8 },
    a1      : { width : 23.4, height : 33.1 },
    a2      : { width : 16.54, height : 23.4 },
    a3      : { width : 11.7, height : 16.54 },
    a4      : { width : 8.27, height : 11.7 },
    a5      : { width : 5.83, height : 8.27 },
    a6      : { width : 4.13, height : 5.83 }
};

const inchToPx = function(value) {
    // 1in = 96px for screens
    // https://developer.mozilla.org/en-US/docs/Web/CSS/length#Absolute_length_units
    return Math.round(value * 96);
};

async function processPageIntoPngBuffer(browser, html, config)  {

    return new Promise(async(resolve, reject) => {

        try {
            const viewportConfig = Object.assign({
                fullPage          : true,
                // https://github.com/puppeteer/puppeteer/issues/1329
                deviceScaleFactor : 4
            }, config);
    
            const page = await browser.newPage();
            await page.setContent(html, { waitUntil : 'networkidle0' });
            
            const
                    format = paperFormat[viewportConfig.format.toLowerCase()],
                    width  = viewportConfig.orientation === 'portrait' ? format.width : format.height,
                    height = viewportConfig.orientation === 'portrait' ? format.height : format.width;
                
                viewportConfig.width = inchToPx(width);
                viewportConfig.height = inchToPx(height);
    
            await page.setViewport(viewportConfig);
            await page.emulateMedia('print');
            const buffer = await page.screenshot(config);
            await page.close();
            resolve(buffer);

        }
        catch (ex) {
            reject(ex.message);
        }
    });
}
You also need to change this method call:
file = await processPageIntoPngBuffer(browser, html[i].html, config).catch(async(err) => {
                            await browser.close();
                            reject(err);
                        });
                        
There is also new option on the client to not center the content horizontally, which allows to get PNG without any whitespaces at all. It would be difficult to provide patch for that, I recommend to wait for release which is almost there.

Post by Maxim Gorkovsky »

Have you managed to make it work? Is export feature running fine on your side? We would love to hear feedback

Post by jim@jimclark.net.au »

Hi Maxim, just plugged in your changes for the PNG size and all works correctly . Still adds whitespace to match the selected size .(ie. white space to add width or height to create the given aspect ratio) but that is fine. Unavoidable without stretching the image.
An option to generate a PNG image with no preset size (ie. just the size of the image regardless of aspect ratio) would be useful. We want to add these images into reports and will resize as needed in the report so would the raw un padded image would be easier for us to work with. We will be adding these gantt images into a A3 landscape page on a report. The image itself oes not need to be an A3 landscape. We will make it fit as needed. If it is too short, for example, then we will probably put some text under it. Maybe the new option ( "not center the content horizontally") you mentioned already covers this. Thanks. Looks good.

Post by Maxim Gorkovsky »

An option to generate a PNG image with no preset size (ie. just the size of the image regardless of aspect ratio) would be useful.
Maybe the new option ( "not center the content horizontally") you mentioned already covers this.
Yes, it does. This option was added thanks to your feedback! :)

Do you consider using multipage exporter with PNG? Or single page only? That option exists, but output is rather confusing.
Do I understand correctly that you mostly plan to use PNG export?

Post by jim@jimclark.net.au »

Single Page is all we need. Tried the multipage option but found the output confusing (as you say).
Yes our intention is to mostly use the PNG export that we will then be inserting into reports which are printed as PDFs.

Gantt Chart -> PNG Image -> Report -> PDF (or hard copy).

Post Reply