jasondavies / d3-cloud

Create word clouds in JavaScript.
https://www.jasondavies.com/wordcloud/
Other
3.82k stars 1.08k forks source link

Problem with svg support using node.js #144

Closed tomas-lumi closed 6 years ago

tomas-lumi commented 6 years ago

I have problems using the d3-cloud/examples/node.js example and creating an svg canvas. It crashes with a 'Segmentation fault: 11' error. It works with png and the canvas module also works with svg examples so my guess is that the bug is in d3-cloud.

Test code:

var Canvas = require("canvas");
var fs = require('fs');

var cloud = require("../");

var words = ["Hello", "world", "normally", "you", "want", "more", "words", "than", "this"]
    .map(function(d) {
      return {text: d, size: 10 + Math.random() * 90};
    });

var canvas = new Canvas(960, 500, 'svg');

cloud().size([960, 500])
    .canvas(function() { return canvas; })
    .words(words)
    .padding(5)
    .rotate(function() { return ~~(Math.random() * 2) * 90; })
    .font("Arial")
    .fontSize(function(d) { return d.size; })
    .on("end", end)
    .start();

function end(words) { 
    fs.writeFile('out.svg', canvas.toBuffer()); 
} 
jasondavies commented 6 years ago

Two things:

tomas-lumi commented 6 years ago

Thanks for the help, much appreciated. I'm still having problems though, generating the cloud works fine but I get collisions even with small amounts of words. Can you see what I'm doing wrong?

Test code:

var Canvas = require("canvas");
var fs = require('fs');

var cloud = require("../");
var words = ["Hello","world","normally","you","want","more","words","than","this"]
    .map(function(d) {
        return {text: d, size: 10 + Math.random() * 90};
    });

var layout = cloud()
    .timeInterval(10)
    .size([640, 480])
    .canvas(function() { return new Canvas(1, 1); })
    .rotate(0)
    .font("Arial")
    .fontSize(function(d) { return d.size; })
    .on("end", end);

layout.stop().words(words).start();

function end(words, bounds) { 
    var w = bounds[1].x;
    var h = bounds[1].y;

    var canvas = new Canvas(w, h, 'svg');
    var ctx = canvas.getContext('2d');
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    for (var i=0; i < words.length; i++) {
        var word = words[i];
        ctx.font = word.size+'px '+word.font;
        var m = ctx.measureText(word.text);
        ctx.fillText(word.text, (w/2)+word.x, (h/2)+word.y);
    }
    fs.writeFile('out.svg', canvas.toBuffer()); 
}
toe-pyae-sone-oo commented 3 years ago

Why do you add (w/2) and (h/2) in width and height in ctx.fillText(...)?