I'm creating a test program with PhantomJs to create and render a Leaflet map with MarkerClusters, which is run through Phantomjs. However, the jQuery components seem to be coming back with no data.
To test this, I have a html file on the side that is doing the same functions, and can be loaded in a browser directly. It appears to work fine in the test html file, but not through Phantomjs.
Below is the code I am using.
Command Line call:
phanjs/bin/phantomjs test2.js seriesdatageo.js 600 600 geographic
Javascript file (test2.js)
var system = require('system');
var page = require('webpage').create();
var fs = require('fs');
page.injectJs("jquery-1.9.1.min.js") || ( console.log("Unable to load jQuery") && phantom.exit());
page.injectJs("leaflet-src.js") || ( console.log("Unable to load leafet-src.js") && phantom.exit());
page.injectJs("leaflet.markercluster-src.js") || (console.log("Unable to load leaflet.markercluster-src.js") && phantom.exit());
page.injectJs("html2canvas.js") || (console.log("Unable to load html2canvas.js") && phantom.exit());
page.injectJs("d3.min.js") || (console.log("Unable to load d3.min.js") && phantom.exit());
page.injectJs("html2canvas.svg.min.js") || (console.log("Unable to load html2canvas.svg.min.js") && phantom.exit());
page.onConsoleMessage = function (msg) {
console.log(msg);
};
phantom.injectJs(system.args[1]) || (console.log("Unable to load json file") && phantom.exit());
var width = 350, height = 300;
if (system.args.length >= 4) {
width = parseInt(system.args[2], 10);
height = parseInt(system.args[3], 10);
}
console.log("Loaded result file");
var evalArg = {
result: result,
width: width,
height: height
};
var svg = page.evaluate(function(opt) {
if(opt.result.componentType =="chart") {
//...
}else if(opt.result.componentType =="geographic"){
var content = "";
var header = "";
var body = "";
header += "<link rel='stylesheet' href='leaflet.css'/> ";
header += "<link rel='stylesheet' href='screen.css'/> ";
header += "<link rel='stylesheet' href='MarkerCluster.css'/> ";
header += "<link rel='stylesheet' href='MarkerCluster.Default.css'/> ";
body += '<div id="map' + (opt.result.count==0? "": "-" + opt.result.count) + '"></div>';
$('head').append(header);
$('body').append(body);
var map = buildMap();
createOverlay(map);
if(checkLoaded()){
waitForIt();
}
function checkLoaded() {
return document.readyState === "complete";
}
function waitForIt() {
console.log("BEFORE EXPORT");
exportMap();
console.log("AFTER EXPORT");
//console.log(exportMap())
}
function createOverlay(container) {
var svg = d3.select(container.getPanes().overlayPane).append("svg").attr("class", "leaflet-zoom-hide"),
g = svg.append("g");
var transform = d3.geo.transform({
point: projectPoint
}),
path = d3.geo.path().projection(transform);
var mapWidth = parseFloat($("#map").css("width").replace("px", ""));
var mapHeight = parseFloat($("#map").css("height").replace("px", ""));
svg.attr("width", mapWidth)
.attr("height", mapHeight);
// Use Leaflet to implement a D3 geometric transformation.
function projectPoint(x, y) {
var point = container.latLngToLayerPoint(new L.LatLng(y, x));
this.stream.point(point.x, point.y);
}
}
function exportMap() {
console.log(1);
var myDivicons = $(".leaflet-marker-icon"); //undefined
console.log($(".leaflet-marker-icon")[0]);
var dx = [];
var dy = [];
console.log(myDivicons.length); //returns 0 when it should equal 6
for (var i = 0; i < myDivicons.length; i++) {
var curTransform = myDivicons[i].style.transform;
console.log(myDivicons[i]);
var splitTransform = curTransform.split(",");
dx.push(parseFloat(splitTransform[0].split("(")[1].replace("px", "")));
dy.push(parseFloat(splitTransform[1].replace("px", "")));
myDivicons[i].style.transform = "";
myDivicons[i].style.left = dx[i] + "px";
myDivicons[i].style.top = dy[i] + "px";
}
console.log(2);
//get transform value
image= html2canvas($("#map")[0], {
allowTaint: false,
logging: true,
useCORS: true,
background: "#E8F0F6",
onrendered: function (canvas) {
var a = document.createElement('a');
//a.download = name;
var dataUrl = canvas.toDataURL('image/png');
if (a.download !== undefined) {
a.setAttribute("id", 'download');
a.setAttribute("href", dataUrl);
a.setAttribute("download", "sample");
} else if (navigator.msSaveBlob) {
a.addEventListener("click", function (event) {
var blob = dataURItoBlob(dataUrl);
navigator.msSaveBlob(blob, "sample"+'.png');
}, false);
a.setAttribute("onmouseover", "");
a.setAttribute("style", "cursor: pointer; cursor: hand;");
}
document.body.appendChild(a);
//a.click();
},
});
console.log(3);
//console.log($('#download').attr('href'));
console.log($('#download').innerHTML);
return image;
}
function buildMap() {
var tiles = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
}),
latlng = L.latLng(51.505, 10.09);
var map = L.map('map', {
center: latlng,
zoom: 2,
layers: [tiles],
zoomControl: false
});
var markers = L.markerClusterGroup({
spiderfyOnMaxZoom: false,
showCoverageOnHover: false,
zoomToBoundsOnClick: false
});
markers.addLayer(L.marker(L.latLng(-17.216203333, -46.870545)));
markers.addLayer(L.marker(L.latLng(-6.18091, 106.9788)));
markers.addLayer(L.marker(L.latLng(22.6333, 120.267)));
markers.addLayer(L.marker(L.latLng(-6.238933794, 106.868886901)));
markers.addLayer(L.marker(L.latLng(45.518437626, 9.10791372)));
markers.addLayer(L.marker(L.latLng(-7.014492779, -42.125545053)));
markers.addLayer(L.marker(L.latLng(-34.075959932, 18.819547112)));
markers.addLayer(L.marker(L.latLng(-8.14272, 112.56221)));
markers.addLayer(L.marker(L.latLng(45.802121064, 15.960097081)));
markers.addLayer(L.marker(L.latLng(-7.55217, 110.8214)));
markers.addLayer(L.marker(L.latLng(25.251247578, 55.342014803)));
markers.addLayer(L.marker(L.latLng(14.584461153, 121.057085752)));
markers.addLayer(L.marker(L.latLng(16.0796434, 101.8043193)));
markers.addLayer(L.marker(L.latLng(16.0796434, 101.8043193)));
markers.addLayer(L.marker(L.latLng(14.583363333, 120.999746667)));
markers.addLayer(L.marker(L.latLng(16.0796434, 101.8043193)));
markers.addLayer(L.marker(L.latLng(16.0796434, 101.8043193)));
markers.addLayer(L.marker(L.latLng(16.0796434, 101.8043193)));
map.addLayer(markers);
/* Initialize the SVG layer */
map._initPathRoot();
return map;
}
return "TEST";
}
}, evalArg);
console.log("Saved SVG to file");
console.log(svg);
phantom.exit();
Found the issue, the map was not displayed on the screen and the images location was not set.
Code changes which were required were:
add to css file.
#map {
height:800px;
}
//Put this above adding the markers
L.Icon.Default.imagePath = '/images';
map._initPathRoot();