SVG to PNG Server side - using node.js - node.js

I'm trying to follow this tutorial on converting a d3.js SVG Vis to a PNG server-side (using Node.js) http://eng.wealthfront.com/2011/12/converting-dynamic-svg-to-png-with.html
Link to full code: https://gist.github.com/1509145
However, I keep getting this error whenever I attempt to make a request to load my page
/Users/me/Node/node_modules/jsdom/lib/jsdom.js:171
features = JSON.parse(JSON.stringify(window.document.implementation._fea
^
TypeError: Cannot read property 'implementation' of undefined
at exports.env.exports.jsdom.env.processHTML (/Users/dereklo/Node/node_modules/jsdom/lib/jsdom.js:171:59)
at Object.exports.env.exports.jsdom.env (/Users/dereklo/Node/node_modules/jsdom/lib/jsdom.js:262:5)
at Server.<anonymous> (/Users/dereklo/Node/Pie/pie_serv.js:26:9)
at Server.EventEmitter.emit (events.js:91:17)
at HTTPParser.parser.onIncoming (http.js:1785:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:111:23)
at Socket.socket.ondata (http.
Does anybody know why this might be? I've installed the jsdom module fine, so I don't really know what's causing these issues...thanks in advance.
EDIT
This is the code I'm using to implement the node.js server. My latest issue is below this source...
var http = require('http'),
url = require('url'),
jsdom = require('jsdom'),
child_proc = require('child_process'),
w = 400,
h = 400,
__dirname = "Users/dereklo/Node/pie/"
scripts = ["/Users/dereklo/Node/pie/d3.min.js",
"/Users/dereklo/Node/pie/d3.layout.min.js",
"/Users/dereklo/Node/pie/pie.js"],
//scripts = ["./d3.v2.js",
// "./d3.layout.min.js",
// "./pie.js"]
htmlStub = '<!DOCTYPE html><div id="pie" style="width:'+w+'px;height:'+h+'px;"></div>';
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'image/png'});
var convert = child_proc.spawn("convert", ["svg:", "png:-"]),
values = (url.parse(req.url, true).query['values'] || ".5,.5")
.split(",")
.map(function(v){return parseFloat(v)});
convert.stdout.on('data', function (data) {
res.write(data);
});
convert.on('exit', function(code) {
res.end();
});
jsdom.env({features:{QuerySelector:true}, html:htmlStub, scripts:scripts, done:function(errors, window) {
var svgsrc = window.insertPie("#pie", w, h, values).innerHTML;
console.log("svgsrc",svgsrc);
//jsdom's domToHTML will lowercase element names
svgsrc = svgsrc.replace(/radialgradient/g,'radialGradient');
convert.stdin.write(svgsrc);
convert.stdin.end();
}});
}).listen(8888, "127.0.0.1");
console.log('Pie SVG server running at http://127.0.0.1:8888/');
console.log('ex. http://127.0.0.1:8888/?values=.4,.3,.2,.1');
Latest Issue
events.js:66
throw arguments[1]; // Unhandled 'error' event
^
Error: This socket is closed.
at Socket._write (net.js:519:19)
at Socket.write (net.js:511:15)
at http.createServer.jsdom.env.done (/Users/dereklo/Node/Pie/pie_serv.js:38:19)
at exports.env.exports.jsdom.env.scriptComplete (/Users/dereklo/Node/node_modules/jsdom/lib/jsdom.js:199:39)

This may prove to be a useful answer to your question if you take out that "using node.js" stipulation. If it doesn't help you, maybe later visitors will find it interesting.
I've been working for some time to solve this same problem (server-side d3 rasterizing), and I've found PhantomJS to be the best solution.
server.js:
var page = require('webpage').create(),
renderElement = require('./renderElement.js'),
Routes = require('./Routes.js'),
app = new Routes();
page.viewportSize = {width: 1000, height: 1000};
page.open('./d3shell.html');
app.post('/', function(req, res) {
page.evaluate(new Function(req.post.d3));
var pic = renderElement(page, '#Viewport');
res.send(pic);
});
app.listen(8000);
console.log('Listening on port 8000.');
Routes.js: https://gist.github.com/3061477
renderElement.js: https://gist.github.com/3176500
d3shell.html should look something like:
<!DOCTYPE HTML>
<html>
<head>
<title>Shell</title>
</head>
<body>
<div id="Viewport" style="display: inline-block"></div>
<script src="http://cdnjs.cloudflare.com/ajax/libs/d3/2.8.1/d3.v2.min.js" type="text/javascript"></script>
</body>
</html>
You can then start the server with phantomjs server.js and POST d3=[d3 code that renders to #Viewport], and the server will respond with a base64-encoded png.
(Requires PhantomJS 1.7 or higher.)

Related

Programming the BeagleBone to turn on LED, Got NodeJS errors

The assignment is about embedded system. We are learning how to use BeagleBone Black and how we can use it to make small-size devices e.g., devices that can measure temperature and pulse.
A part of our first assignment is to follow this guide: https://randomnerdtutorials.com/programming-the-beaglebone-black-with-bonescript/
We need to make a server in Node JS and a index in html. The site provides button to control a LED light that is connected to a breadboard via BeagleBone Black.
I have connected the LED, pins and wires to the BeagleBone Black. Installed Ubuntu 18.14, NodeJS, npm socket.io and Bonescript(Script dedicated to BeagleBone).
I am not using Cloud 9 IDE to run the server.js and index.html.
But I use terminal in Ubuntu.
To start the server i use this command: node server.js
I tried for several days to make the server and index.html to run,
but I get this error or nothing happends:
/home/ubuntu/bonescript/server.js:42
var io = require('socket.io').listen(server);
^
[TypeError: require(...).listen is not a function
at Object.<anonymous> (/home/ubuntu/bonescript/server.js:42:31)
at Module._compile (internal/modules/cjs/loader.js:1137:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)
at Module.load (internal/modules/cjs/loader.js:985:32)
at Function.Module._load (internal/modules/cjs/loader.js:878:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
Can anyone help me pinpoint the problem? I am really stuck on this stage. Thanks.
index.html code:
<!DOCTYPE html>
<html>
<head>
<title>Home Automation Web Server with BeagleBone</title>
<script src = "/socket.io/socket.io.js" ></script>
<script>
// Establishing connection with server
var socket = io.connect();
// Changes the led state
function changeState(state){
if (state==1){
// Emit message changing the state to 1
socket.emit('changeState', '{"state":1}');
// Change led status on web page to ON
document.getElementById("outputStatus").innerHTML = "Status: ON";
}
else if (state==0){
// Emit message changing the state to 0
socket.emit('changeState', '{"state":0}');
// Change led status on web page to OFF
document.getElementById("outputStatus").innerHTML = "Status: OFF";
}
}
</script>
</head>
<h2>LED</h2>
<p id="outputStatus">Status</p>
<button type="button" onclick="changeState(1);">ON</button>
<button type="button" onclick="changeState(0);">OFF</button>
</div>
</body>
</html>
server.js code:
//Loading modules
var http = require('http');
var fs = require('fs');
var path = require('path');
var b = require('bonescript');
// Create a variable called led, which refers to P9_14
var led = "P9_14";
// Initialize the led as an OUTPUT
b.pinMode(led, b.OUTPUT);
// Initialize the server on port 8888
var server = http.createServer(function (req, res) {
// requesting files
var file = '.'+((req.url=='/')?'/index.html':req.url);
var fileExtension = path.extname(file);
var contentType = 'text/html';
// Uncoment if you want to add css to your web page
/*
if(fileExtension == '.css'){
contentType = 'text/css';
}*/
fs.exists(file, function(exists){
if(exists){
fs.readFile(file, function(error, content){
if(!error){
// Page found, write content
res.writeHead(200,{'content-type':contentType});
res.end(content);
}
})
}
else{
// Page not found
res.writeHead(404);
res.end('Page not found');
}
})
}).listen(8888);
// Loading socket io module
var io = require('socket.io').listen(server);
// When communication is established
io.on('connection', function (socket) {
socket.on('changeState', handleChangeState);
});
// Change led state when a button is pressed
function handleChangeState(data) {
var newData = JSON.parse(data);
console.log("LED = " + newData.state);
// turns the LED ON or OFF
b.digitalWrite(led, newData.state);
}
// Displaying a console message for user feedback
server.listen(console.log("Server Running ..."));
I have same problem but solve it already the code on this website is based on older node version, you have to change the code on line
var io = require('socket.io').listen(server);
to
var io = require('socket.io')(server);
and edit variable or remove this line since newer node cant use .listen function twice (the code already use it on server var to open port 8888)
server.listen(console.log("Server Running ..."));
socket.io is an internal library, not an external one. Therefore, when you ran npm install socket.io, you downloaded something that is not the socket.io that you want.
Delete your node_modules, and remove socket.io from package.json, and reinstall bonescript via npm install. Then it should work.

Three.js with Node.js on a server - how to load a TEXTURE?

I have a trouble with Three.js for loading a texture and applying to a mesh cube.
In local, I know there are some issues like running the html file on a apache server with wamp (localhost).
But when I use Node.js and socket.io, how to fix it ?
First, to load three.js, I have to put the web adress of the script src instead of a local "three.js" :
http://threejs.org/build/three.min.js
It works but how about the texture ?
Neither a local or an internet adress for the texture is working...
//var mapUrl = "mercury.jpg";
var mapUrl = "http://threejs.org/examples/textures/cube/skybox/px.jpg";
var map = THREE.ImageUtils.loadTexture(mapUrl); // its not working with both
And if I put my code on a web server running with Node.js like Cloud9, how to fix it ? (same problem as in local with Node.js).
Thank you for your attention.
Here is my complete code.
Server
var http = require('http');
var fs = require('fs');
// Creation du serveur
var app = http.createServer(function (req, res) {
// On lit notre fichier app.html
fs.readFile('gl.html', 'utf-8', function(error, content) {
res.writeHead(200, {'Content-Type' : 'text/html'});
res.end(content);
});
});
var io = require("socket.io");
io = io.listen(app);
io.sockets.on('connection', function (socket) {
socket.on('send', function () {
socket.broadcast.emit('rec');
}); // send
}); // connection
app.listen(8080);
Client (gl.html)
<!DOCTYPE html>
<html>
<head>
<title>Welcome to WebGL</title>
</head>
<body onLoad="onLoad();" style="">
<h1>Webgl</h1>
<div id="container" style="width:95%; height:80%; position:absolute;"></div>
<script type="text/javascript" src="http://threejs.org/build/three.min.js"></script>
<!--<script type="text/javascript" src="Three.js"></script> not working-->
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
var renderer = null,
scene = null,
camera = null,
cube = null,
animating = false;
function onLoad()
{
// Grab our container div
var container = document.getElementById("container");
// Create the Three.js renderer, add it to our div
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize(container.offsetWidth, container.offsetHeight);
container.appendChild( renderer.domElement );
// Create a new Three.js scene
scene = new THREE.Scene();
// Put in a camera
camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 4000 );
camera.position.set( 0, 0, 3 );
// Create a directional light to show off the object
var light = new THREE.DirectionalLight( 0xffffff, 1.5);
light.position.set(0, 0, 1);
scene.add( light );
// Create a shaded, texture-mapped cube and add it to the scene
// First, create the texture map
// var mapUrl = "mercury.jpg";
var mapUrl = "http://threejs.org/examples/textures/cube/skybox/px.jpg";
var map = THREE.ImageUtils.loadTexture(mapUrl); // not working with both !!!
// Now, create a Phong material to show shading; pass in the map
var material = new THREE.MeshPhongMaterial({ map: map });
// Create the cube geometry
var geometry = new THREE.CubeGeometry(1, 1, 1);
// And put the geometry and material together into a mesh
cube = new THREE.Mesh(geometry, material);
// Turn it toward the scene, or we won't see the cube shape!
// cube.rotation.x = Math.PI / 5;
cube.rotation.x = 0.5;
//cube.rotation.y = Math.PI / 5;
// Add the cube to our scene
scene.add( cube );
// Add a mouse up handler to toggle the animation
addMouseHandler();
// Run our render loop
run();
}
function run()
{
// Render the scene
renderer.render( scene, camera );
// Spin the cube for next frame
if (animating)
{
cube.rotation.y -= 0.01;
//cube.rotation.x += 0.05;
}
// Ask for another frame
//requestAnimationFrame(run);
setTimeout(run, 1000/60);
}
function addMouseHandler()
{
var dom = renderer.domElement;
dom.addEventListener( 'mouseup', onMouseUp, false);
}
function onMouseUp (event)
{
event.preventDefault();
animating = !animating;
socket.emit('send');
}
socket.on('rec', function () {
animating = !animating;
});
</script>
</body>
</html>
In fact i just had to use express, place all the files in the folder public and name client index.html.
Now it works ! How can close my question ?
Here is the simple code of the server :
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.listen(8080);
You are running into trouble with CORS. CORS state that textures need to be comming from the same base url or needs special handling on server side. This is easily fixable with a proxy. If you are already using a server thaen it shouldn't be too hard to configure it to handle proxy requests.

Node.js Beginner - Can't get past nodetuts tutorial number 2 - stdout and child process

I was trying to go through the tutorial nodetuts.com - tutorial 2 and unfortunatly could not get the example working, I'm very new to node.js and going through any tutorials I can get hold of. I understand that node.js is still beta and I figured that the code that makes this work is now obsolete. (This is the code):
var http = require('http');
var spawn = require('child_process').spawn;
http.createServer(function(request, response){
response.writeHead(200, {
'Content-Type' : 'text/plain'
});
var tail_child = spawn('tail', ['-f', 'test.txt']);
tail_child.stdout.on('data', function(data){
console.log(data.toString());
response.write(data);
});
}).listen(4000);
Anyway, determined to continue on I have been looking through the documentation on the node website and found this: http://nodejs.org/api/all.html#all_child_pid This is not exactly what I want (I want to complete that tutorial linked to up top) but I wanted to get something todo with child process working and incorperated that code into this:
var http = require('http');
var server = http.createServer(function(res, req){
res.writeHead(200);
res.end('testing');
var spawn = require('child_process').spawn,
grep = spawn('grep', ['ssh']);
console.log('Spawned child pid: ' + grep.pid);
grep.stdin.end();
}).listen(4000);
Unfortunately when I refresh the page http://localhost:4000/ I get nothing and command prompt spits out: (I know it says writeHead is a problem, but it works fine in other examples - (like nodetuts - tutorial 1))
res.writeHead(200);
^
TypeError: Object #<IncomingMessage> has no method 'writeHead'
at Server.<anonymous> (Z:\Joseph Goss Folder\Google Drive\Code\javascript_first\nodejs_first\stdoutTest.js:20:6)
at Server.EventEmitter.emit (events.js:91:17)
at HTTPParser.parser.onIncoming (http.js:1785:12)
at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:111:23)
at Socket.socket.ondata (http.js:1682:22)
at TCP.onread (net.js:404:27)
I wonder why I can't get this working, I'm obviously missing something but I don't know what, and I can't even get past tutorial number 2. :(
I'm running windows 7
I have also looked at this code Why does response.write appear to block my browser in Node.js? and his code doesn't work at all either.
You interchanged req and res in the function passed to createServer
var http = require('http');
var server = http.createServer(function(req, res){
res.writeHead(200);
res.end('testing');
var spawn = require('child_process').spawn,
grep = spawn('grep', ['ssh']);
console.log('Spawned child pid: ' + grep.pid);
grep.stdin.end();
}).listen(4000);

now.js : "Object has no method" error message when trying to start server.js

I installed node.js and now.js successfully.
For now.js, this is how I did:
npm install now -g
npm install now (had to add this one. Without it, I get a "Cannot find now..." error message)
When I start the node server and provide a server.js file like this:
var httpServer = require('http');
httpServer.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.write('Node is ok');
res.end();
}).listen(8080);
console.log('Server runs on http://xxxxx:8080/');
Everything is fine.
Now, I'm trying to add to this file a basic use of now.js:
var nowjs = require("now");
var everyone = nowjs.initialize(httpServer);
everyone.now.logStuff = function(msg){
console.log(msg);
}
I create an index.html file in the same folder (for testing purposes)
<script type="text/javascript" src="nowjs/now.js"></script>
<script type="text/javascript">
now.ready(function(){
now.logStuff("Now is ok");
});
</script>
This time, this is what I get on the terminal when starting the server:
Server runs on http://xxxxx:8080/
[TypeError: Object #<Object> has no method 'listeners']
TypeError: Object #<Object> has no method 'listeners'
at Object.wrapServer (/home/xxxx/node_modules/now/lib/fileServer.js:23:29)
at [object Object].initialize (/home/xxxx/node_modules/now/lib/now.js:181:14)
at Object.<anonymous> (/home/xxxx/server.js:10:22)
at Module._compile (module.js:444:26)
at Object..js (module.js:462:10)
at Module.load (module.js:351:32)
at Function._load (module.js:309:12)
at module.js:482:10
at EventEmitter._tickCallback (node.js:245:11)
Please keep in mind that I'm an absolute beginner.
Thank you for your help
'npm install -g' installs modules at a global level, often with the intent of providing system-wide binaries for terminal usage. Think Ruby Gems. If you want to include a module as part of your project you need to remove the -g.
Also, your httpServer variable is not your server but rather the http module. createServer() returns a server object which you want to capture with a variable to use in your nowjs.initialize() method as follows:
var http = require('http')
, now = require('now')
// Returns an Http Server which can now be referenced as 'app' from now on
var app = http.createServer(
//... blah blah blah
)
// listen() doesn't return a server object so don't pass this method call
// as the parameter to the initialize method below
app.listen(8080, function () {
console.log('Server listening on port %d', app.address().port)
})
// Initialize NowJS with the Http Server object as intended
var everyone = nowjs.initialize(app)

Making an HTTP request using node.js throws EAFNOSUPPORT

I'm trying to make a simple HTTP GET request using node.js, but I'm running into trouble using node.js v0.3.4-pre (i.e. compiled from HEAD as of this morning). Here's my code:
var cli = require('cli');
var http = require('http');
var url = require('url');
cli.parse();
cli.main(function(args, opts) {
this.debug(args[0]);
var siteUrl = url.parse(args[0]);
var site = http.createClient(siteUrl.port, siteUrl.host);
console.log(siteUrl);
var request = site.request("GET", siteUrl.pathname, {'host' : siteUrl.host})
request.end();
request.on('response', function(response) {
response.setEncoding('utf8');
console.log('STATUS: ' + response.statusCode);
response.on('data', function(chunk) {
console.log("DATA: " + chunk);
});
});
});
Here's the error that I get:
node.js:68
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: EAFNOSUPPORT, Address family not supported by protocol family
at doConnect (net.js:499:19)
at Client.connect (net.js:652:30)
at Client._ensureConnection (http.js:1033:10)
at Client.request (http.js:1048:8)
at Object.<anonymous> (/Users/paul/Desktop/readify.js:16:21)
at /usr/local/lib/node/.npm/cli/0.2.3-2/package/cli.js:995:18
at Object.main (/usr/local/lib/node/.npm/cli/0.2.3-2/package/cli.js:1000:9)
at Object.<anonymous> (/Users/paul/Desktop/readify.js:10:5)
at Module._compile (node.js:359:32)
at Object..js (node.js:367:14)
Found the bug, siteUrl.port will be undefined unless the URL explicitly names a port. So, the solution is:
var site = http.createClient(siteUrl.port || 80, siteUrl.host);
var site = http.createClient(siteUrl.port, siteUrl.host);
should rather be
var site = http.createClient(siteUrl.port || 80, siteUrl.hostname);
The same error message appeared on my very old XPSP2-box for ANY connect()-attempts. E.g npm wasn't able to do anything, and simple http requests failed.
While trying to find a solution, this post appeared all over the place, but its not the same issue.
In my case it had to do with WSAIoctl(...) always returning WSAEOPNOTSUPP when querying for WSAID_CONNECTEX, which seemed strange. This led me to a post recommending doing a "netsh winsock reset" from the cmd, which fixed the problem!

Resources