Skip to content
Merged
2 changes: 1 addition & 1 deletion deployment/run_server
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pkill -9 Xvfb
pkill -9 node
pkill -9 electron

xvfb-run --auto-servernum --server-args '-screen 0 640x480x24' /var/www/image-exporter/bin/orca.js serve $REQUEST_LIMIT --safe-mode --verbose $PLOTLYJS_ARG $ORCA_IGNORECERTERRORS_ARG $@ &
xvfb-run --auto-servernum --server-args '-screen 0 1024x768x24' /var/www/image-exporter/bin/orca.js serve $REQUEST_LIMIT --safe-mode --verbose $PLOTLYJS_ARG $ORCA_IGNORECERTERRORS_ARG $@ &
echo \$! > \$PIDFILE

EOF
Expand Down
33 changes: 25 additions & 8 deletions src/component/plotly-dash-preview/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,25 @@ function parse (body, req, opts, sendToRenderer) {
result.timeOut = body.timeout
result.tries = Number(result.timeOut * 1000 / cst.minInterval)

if (cst.sizeMapping[result.pdfOptions.pageSize]) {
result.browserSize = cst.sizeMapping[result.pdfOptions.pageSize]
} else if (body.pageSize && isPositiveNumeric(body.pageSize.width) &&
isPositiveNumeric(body.pageSize.height)) {
var pageSize
if (result.pdfOptions.pageSize) {
pageSize = result.pdfOptions.pageSize
} else if (body.pageSize) {
pageSize = body.pageSize
}

if (cst.sizeMapping[pageSize]) {
result.browserSize = cst.sizeMapping[pageSize]
result.pdfOptions.pageSize = pageSize
} else if (pageSize && isPositiveNumeric(pageSize.width) &&
isPositiveNumeric(pageSize.height)) {
result.browserSize = {
width: body.pageSize.width * cst.pixelsInMicron,
height: body.pageSize.height * cst.pixelsInMicron
width: pageSize.width * cst.pixelsInMicron,
height: pageSize.height * cst.pixelsInMicron
}
result.pdfOptions.pageSize = {
width: Math.ceil(body.pageSize.width),
height: Math.ceil(body.pageSize.height)
width: Math.ceil(pageSize.width),
height: Math.ceil(pageSize.height)
}
} else {
return errorOut(
Expand All @@ -57,6 +65,15 @@ function parse (body, req, opts, sendToRenderer) {
)
}

// Change browser size orientation if landscape
if (result.pdfOptions.landscape) {
result.browserSize = { width: result.browserSize.height, height: result.browserSize.width }
}

// BrowserWindow only accepts integer values:
result.browserSize['width'] = Math.ceil(result.browserSize['width'])
result.browserSize['height'] = Math.ceil(result.browserSize['height'])

sendToRenderer(null, result)
}

Expand Down
2 changes: 2 additions & 0 deletions src/component/plotly-dash-preview/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ function render (info, opts, sendToMain) {
const result = {}

let createBrowserWindowOpts = info.browserSize ? info.browserSize : {}
createBrowserWindowOpts['enableLargerThanScreen'] = true
createBrowserWindowOpts['useContentSize'] = true
createBrowserWindowOpts['show'] = opts.debug

let win = remote.createBrowserWindow(createBrowserWindowOpts)
Expand Down
122 changes: 86 additions & 36 deletions test/unit/plotly-dash-preview_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const tap = require('tap')
const sinon = require('sinon')

const _module = require('../../src/component/plotly-dash-preview')
const constants = require('../../src/component/plotly-dash-preview/constants')
const remote = require('../../src/util/remote')
const { createMockWindow } = require('../common')

Expand Down Expand Up @@ -30,49 +31,98 @@ tap.test('parse:', t => {
t.end()
})
})
t.test('should error when pageSize is not given', t => {
fn({
t.test('pageSize options:', t => {
const mock = () => ({
url: 'https://dash-app.com',
selector: 'dummy'
}, {}, {}, (errorCode, result) => {
t.equal(errorCode, 400)
t.same(result.msg, 'pageSize must either be A3, A4, A5, Legal, Letter, ' +
'Tabloid or an Object containing height and width in microns.')
t.end()
})
})
t.test('should parse properly when pageSize is given', t => {
fn({
url: 'https://dash-app.com',
selector: 'dummy',
pageSize: { height: 1000, width: 1000 }
}, {}, {}, (errorCode, result) => {
t.equal(errorCode, null)

// height/width are converted from microns to pixels:
t.same(result.browserSize, {
height: 3.779527559055118,
width: 3.779527559055118

t.test('should error when not given', t => {
fn(mock(), {}, {}, (errorCode, result) => {
t.equal(errorCode, 400)
t.same(result.msg, 'pageSize must either be A3, A4, A5, Legal, Letter, ' +
'Tabloid or an Object containing height and width in microns.')
t.end()
})
})

function assertEqualSize (browserSize, pageSize, landscape) {
// Browser size is always integer pixels
var bW = browserSize.width
var bH = browserSize.height
t.ok(Number.isInteger(bW), 'browserSize.width is not an integer')
t.ok(Number.isInteger(bH), 'browserSize.height is not an integer')
var pW, pH
if (constants.sizeMapping[pageSize]) {
var equivalentPixelSize = constants.sizeMapping[pageSize]
pW = equivalentPixelSize.width
pH = equivalentPixelSize.height
} else {
pW = pageSize.width * constants.pixelsInMicron
pH = pageSize.height * constants.pixelsInMicron
}
// Round
pW = Math.ceil(pW)
pH = Math.ceil(pH)
t.equal(bW, landscape ? pH : pW, 'browser and page should have the same width')
t.equal(bH, landscape ? pW : pH, 'browser and page should have the same height')
}

// Browser size and page size should be the same assuming a DPI of 96
// to make sure plotly.js figures are appropriately sized right away for print
[
// [pageSize defined at top-level?, pageSize, landscape?]
[true, { height: 1000, width: 1000 }],
[true, 'Letter'],
[false, { height: 1000, width: 1000 }],
[false, 'Letter'],
[true, { height: 1000, width: 1000 }, true],
[true, 'Letter', true],
[false, { height: 1000, width: 1000 }, true],
[false, 'Letter', true]
].forEach(arg => {
var toplevel = arg[0]
var pageSize = arg[1]
var landscape = arg[2]
t.test(`should size window and page properly when ${toplevel ? '' : 'pdf_options.'}pageSize is given`, t => {
var body = mock()
if (toplevel) {
body.pageSize = pageSize
body.pdf_options = {}
} else {
body.pdf_options = { pageSize: pageSize }
}
if (landscape) body.pdf_options.landscape = landscape
fn(body, {}, {}, (errorCode, result) => {
t.equal(errorCode, null)
t.same(result.pdfOptions.pageSize, pageSize)
assertEqualSize(result.browserSize, result.pdfOptions.pageSize, landscape)
t.end()
})
})
t.same(result.pdfOptions.pageSize, {
height: 1000,
width: 1000
})

t.test('pdf_options.pageSize overrides top-level pageSize', t => {
var body = mock()
body.pageSize = { height: 1000, width: 1000 }
body.pdf_options = { pageSize: { height: 2000, width: 2000 } }
fn(body, {}, {}, (errorCode, result) => {
t.equal(errorCode, null)
t.same(result.browserSize, { height: 8, width: 8 })
t.end()
})
t.end()
})
})
t.test('should parse properly when pdf_options are given', t => {
fn({
url: 'https://dash-app.com',
selector: 'dummy',
pdf_options: { pageSize: 'Letter', marginsType: 1 }
}, {}, {}, (errorCode, result) => {
t.equal(errorCode, null)
// height/width are converted to pixels from page-type:
t.same(result.browserSize, { height: 1056, width: 816 })
t.same(result.pdfOptions, { pageSize: 'Letter', marginsType: 1 })
t.end()

t.test('should passthrough pdf_options', t => {
var body = mock()
body.pdf_options = { pageSize: 'Letter', marginsType: 1, crazyOptions: true }
fn(body, {}, {}, (errorCode, result) => {
t.equal(errorCode, null)
t.same(result.pdfOptions, { pageSize: 'Letter', marginsType: 1, crazyOptions: true })
t.end()
})
})
t.end()
})

t.end()
Expand Down