Why is my D3 visualization not captured by phantomjs? It is the only element on this page not captured and saved as png.
My oncoprintsave.js file:
var page = require('webpage').create();
page.viewportSize = { width: 1920, height: 1080 };
page.open('https://jonkatz2.github.io/2019/03/11/D3-oncoprint', function(status) {
if (status !== 'success') {
console.log('Unable to load the address!');
phantom.exit(1);
} else {
window.setTimeout(function () {
page.render('oncoprint.png');
phantom.exit();
}, 2000);
}
});
and in my Ubuntu console I enter:
phantomjs oncoprintsave.js
This is just a representative example. I am making a shiny app in which I plan to capture some D3 visualizations as png (server-side) and include them in a rmarkdown-PDF report. I've tried r2d3::save_d3_png and got blank images, and I'm trying to troubleshoot it by calling htmlwidgets::saveWidget directly, then sending a system call to phantomjs on the resulting html page.
I suspect an error in my D3 script is causing it to fail, but I'm too new to D3 to identify it, and no errors appear if I add the --debug=true option.
I never solved this, but I switched to chrome and got what I want:
google-chrome --headless --disable-gpu --screenshot --window-size=1920,1080 https://jonkatz2.github.io/2019/03/11/D3-oncoprint
Related
I am attempting to generate a PDF of a page using Puppeteer.. in local development.. I am able to return the PDF with proper page breaks.. however in production (Heroku server) my PDF has page breaks in the middle of my content!
Here is the code:
const browser = await puppeteer.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox']
})
console.log('browser has been opened')
const page = await browser.newPage()
page.setViewport({width: 1000, height: 1056})
await page.waitFor(1000)
await page.emulateMediaType('screen')
await page.waitFor(5000)
console.log('about to create PDF - standby')
const pdf = await page.pdf({
format: 'Letter',
printBackground: true,
path: MY PATH
})
console.log('pdf created')
await browser.close()
console.log('browser closed')
}
Things I have tried..
changing the CSS to include the following..
#media print {
.page {
page-break-after: always;
}
}
speaking to the owner of the heroku / puppeteer buildpack to confirm it is not an issue there
https://github.com/jontewks/puppeteer-heroku-buildpack/issues/59
emailing collaborators from the PPTR github repo
tested various different types of page.emulateMedia() and styling options
here is a screenshot of the weird page break for reference..
https://user-images.githubusercontent.com/31495981/72014061-2aba7000-322d-11ea-8334-1d1df80f41d5.png
puppyteer can't use page-break-<any> css rules with flexbox. Rewrite your css without flexbox and puppyteer will use page-break as should
I have a mobile application that allows uploading images either via camera or choosing it from a photo library. While uploading the user is prompted if he or she wants a high quality image to be uploaded or not. If yes, quality option is set to 100 else set to 50. This seems to work fine for android and ios builds but not for windows build. Even after selecting the high quality option, the image uploaded has low quality.Is there something that I'm missing? A plugin that might need to be added specific to windows to make stuff work?
Please help.
I've included a part of the code snippet:
.factory('$Camera', function ($q, $crypt, $settings) {
return {
getPicture: function () {
var q = $q.defer();
var options = {
quality: $settings.getValue('uploadHighQualityImage') ? 100 : 50,
destinationType: navigator.camera.DestinationType.FILE_URI,
sourceType: navigator.camera.PictureSourceType.CAMERA,
targetWidth: 500,
targetHeight: 500
};
navigator.camera.getPicture(function (result) {
// Put the options
q.resolve(result);
}, function (err) {
q.reject(err);
}, options);
return q.promise;
},
I'm debugging a problem with my Meteor application, when using IE8, IE9.
When using Chrome or Safari i haven't this problem:
In Ie errors:
"Template" is undefined.
"Meteor" is undefined.
If i wrap all templates from my files in 'if':
if (Meteor.isClient) {my Template code};
or if it is server code:
if (Meteor.isServer) {my Template code};
It work in ie9, but not in ie8.
I think Meteor create my templates in it's template, such as:
my code:
if (Meteor.isClient) {
Template.default.rendered = function () {
$(window).resize(function () {
myFunction();
});
}
}
Meteor wrap my template and in ie8 i can see my template and this:
(function () {
Template.__define__("default", (function () {
var self = this;
var template = this;
return [ Spacebars.include(self.lookupTemplate("navbar")), "\n\n ", HTML.DIV({
"class": "content-wrapper"
}, "\n ", HTML.DIV({
"class": "container"
}, "\n\n ", Spacebars.include(self.lookupTemplate("yield")), "\n\n "), "\n "), "\n\n ", Spacebars.include(self.lookupTemplate("footer")) ];
}));
})();
In application use libraries iron-router, nvd3js, bootstrap-3. may be it is their errors, but a think it is Meteors error. I'm use Meteor 0.8.0.
If my meteor application can work with ie8-9 - please, say me! And if you can - say how? I'm will be very thankful!
This usually happens when some other error causes the rest of the Meteor Javascript not to load properly. You should examine the first error that is printed out in the console, which is almost always the culprit.
If you can update your question with the whole error log, I can update my answer with the diagnosis.
We are using Cordova 3.4.0 to develop an app. Everything works fine on Android and iOS and also if we launch our app in a desktop browser. But we are stuck with really strange issue on Windows Phone 8.1.
Here is a simplified code example to test.
index.html in the application root:
<!DOCTYPE html>
<html>
<head>
<title>Mobile sandbox</title>
<meta charset="UTF-8">
<script type="text/javascript" src="libs/jquery/jquery.min.js"></script>
</head>
<body>
<div id="redbox" style="width:100px;height:100px;background-color:red;">
</div>
<div id="greenbox" style="width:100px;height:100px;background-color:green;">
</div>
<script>
$(function () {
alert("Requesting data for redbox...");
$.ajax("test/redText.html")
.done(function (text) {
alert("Filling redbox with contents " + text);
$("#redbox").html(text);
})
.fail(function () {
alert("Error in redbox");
})
.always(function () {
alert("Complete redbox");
});
alert("Requesting data for greenbox...");
$.ajax("test/greenText.html")
.done(function (text) {
alert("Filling greenbox with contents " + text);
$("#greenbox").html(text);
})
.fail(function () {
alert("Error in greenbox");
})
.always(function () {
alert("Complete greenbox");
});
});
</script>
</body>
</html>
test/greenText.html:
<span>GREEN</span>
test/redText.html:
<span>RED</span>
The only dependency to run this test is jQuery which we have put in libs/jquery/ folder.
Now, if we run this code in every desktop browser and in iOS and Android, no matter if from local folder (with browser flags for local AJAX) or from server, we get the right sequence of alerts and AJAX loads correct data in appropriate boxes:
Requesting data for redbox...
Requesting data for greenbox...
Filling redbox with contents <span>RED</span>
Complete redbox
Filling greenbox with contents <span>GREEN</span>
Complete greenbox
We get the same result if we run the index.html on Windows Phone through its Internet Explorer.
But when we deploy the same code to Windows Phone as Cordova app, strange thing happens. The redbox request never receives any data, nor any errors. The greenbox request receives data of redbox, and thus we have empty red box and green box with text "RED" in it.
Here is the sequence of alerts:
Requesting data for redbox...
Requesting data for greenbox...
Filling greenbox with contents <span>RED</span>
Complete greenbox
What's going on there, why one AJAX request does not return and the other receives wrong response? How do we fix it?
EDIT 1:
Our nest step will be to find out if it's Cordova specific issue (I see there is some XHRHelper object in the Corodva WP8 template) or it's Microsoft's phone:WebBrowser fault.
EDIT 2:
It seems, WebBrowser itself does not support AJAX requests to local files (I got "Access denied") and that's why Cordova invented XHRHelper class. But I found a related bugreport which they closed as "Cannot reproduce":
https://issues.apache.org/jira/browse/CB-4873
Is there any Cordova developer here who could suggest a fix for XHRHelper, so it supports multiple sequential AJAX requests?
Again, I cannot reproduce your results. I quickly put together a version which I will post to the JIRA issue: https://issues.apache.org/jira/browse/CB-4873
Requesting data for redbox...
Requesting data for greenbox...
Filling redbox with contents
<span>REd</span>
Complete redbox
Filling greenbox with contents
<span>GREEN</span>
Complete greenbox
I modified your source a little just to make sure there were no issues with alert interfering ...
var eventLog = [];
var oneDone = false;
$(function () {
eventLog.push("Requesting data for redbox...");
$.ajax("redText.html")
.done(function (text) {
eventLog.push("Filling redbox with contents " + text);
$("#redbox").html(text);
})
.fail(function (e) {
eventLog.push("Error in redbox" + JSON.stringify(e));
})
.always(function () {
eventLog.push("Complete redbox");
if (oneDone) {
console.log(eventLog.join("\n"));
alert(eventLog.join("\n"));
}
else {
oneDone = true;
}
});
eventLog.push("Requesting data for greenbox...");
$.ajax("greenText.html")
.done(function (text) {
eventLog.push("Filling greenbox with contents " + text);
$("#greenbox").html(text);
})
.fail(function () {
eventLog.push("Error in greenbox");
})
.always(function () {
eventLog.push("Complete greenbox");
if (oneDone) {
console.log(eventLog.join("\n"));
alert(eventLog.join("\n"));
}
else {
oneDone = true;
}
});
});
I'm attempting to create a node server that serves up a png image generated using the node-wkhtml module (basically just a wrapper for the wkhtmltoimage/wkhtmltopdf command line utility). Here's what I have so far:
var http = require('http');
var Image = require("node-wkhtml").image();
http.createServer(function (request, response) {
new Image({ url: "www.google.com" }).convert (function (err, stdout) {
//var theImage = new Buffer (stdout, 'binary');
response.writeHead(200, {'Content-Type' : 'image/png',
'Content-Length' : stdout.length
});
response.write (stdout, 'binary');
response.end ();
//write out an error, if there is one
if (err)
console.log (err);
});
}).listen(8124);
Basically, the module calls the command:
wkhtmltoimage www.google.com -
which then generates a png image and writes it to the stdout. The amount of data served seems to be correct, but I can't get the browser to display it (nor does it work if I download it as a file). I tried the following command:
wkhtmltoimage www.google.com - > download.png
and sure enough, download.png was created and contained a snapshot of the google homepage, meaning that the wkhtmltoimage utility is working correctly, and the command works. I'm a beginner at node, so I'm not super familiar how to serve up a binary file like this, can anyone see any glaring issues? Here's the node module code that works the magic:
Image.prototype.convert = function(callback) {
exec(util.buildCommand(this), {encoding: 'binary', maxBuffer: 10*1024*1024}, callback);
}
(the buildCommand function just generates the "wkhtmltoimage www.google.com -" command, and I've verified it does this correctly, using node inspector.
UPDATE:
In case anyone finds this later and is interested, I found the solution. The plugin I was using (node-wkhtml) was not properly handling large buffers, due to the choice of using child-process.exec I changed the plugin code to use child-process.spawn instead, and it worked as desired.