Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Collision Not Detected when Font not yet Loaded #108

Open
speakerjohnash opened this issue Oct 26, 2016 · 3 comments
Open

Collision Not Detected when Font not yet Loaded #108

speakerjohnash opened this issue Oct 26, 2016 · 3 comments
Labels

Comments

@speakerjohnash
Copy link

I ran into this problem and have seen it in two online examples as well:

http://bl.ocks.org/ericcoopey/6382449
https://www.pubnub.com/blog/2014-10-09-quick-word-cloud-from-a-chatroom-with-d3js/

Basically if you have a particular font, like something from Google fonts, if the font hasn't yet loaded to the page, the first draw will have words overlapping. The solution is to ensure that the css has been used via CSS prior to js execution. However it would be nice if there was an in library fix to this as it seems that it's a pretty common problem.

@brightrain
Copy link

👍 this. It helped me resolve an overlapping issue that popped up seemingly out of nowhere. Was using Google fonts and perhaps they changed the way they are retrieved? So I just removed the goog fonts and changed from
.font("Open Sans', sans-serif")
to just
.font("sans-serif")
when initializing and from
.style("font-family", "'Open Sans', sans-serif")
to just
.style("font-family", "sans-serif")
in the draw function.

Whole thing looks like this if it's helpful:

               var layout = d3.layout.cloud()
                        .size([800, 600])
                        .words(data)
                        .padding(3)
                        .rotate(function () { return (~~(Math.random() * 6) - 3) * 30; })
                        .font("sans-serif")
                        .fontSize(function (d) { return d.size / 10; })
                        .on("end", draw);
                    layout.start();
                    
                    function draw(words) {
                        var container = d3.select("#wordCloudContainer").append("div");
                        container.append("svg")
                            .attr("width", layout.size()[0])
                            .attr("height", layout.size()[1])
                            // leaving this transparent for now but could set background color
                            //.style("background-color", "white")
                          .append("g")
                            .attr("transform", "translate(" + layout.size()[0] / 2 + "," + layout.size()[1] / 2 + ")")
                          .selectAll("text")
                            .data(words)
                          .enter().append("text")
                            .style("font-size", function (d) { return d.size + "px"; })
                            .style("font-family", "sans-serif")
                            .style("fill", function (d, i) { return fill(i); })
                            .attr("text-anchor", "middle")
                            .attr("transform", function (d) {
                                return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
                            })
                            .text(function (d) { return d.text; });
                    }

@jasondavies jasondavies added the req label Mar 2, 2017
@michaelByrne
Copy link

michaelByrne commented Aug 31, 2017

Hello,

I wanted to raise this again. I'm trying to get the same effect as on the interactive example page, but I don't see any way to add in the Impact font (or any other named font) without breaking the positioning. Are there any other workarounds?

Thanks,

  • michael

Whoops, looks like I figured it out as below.

d3.layout.cloud()
			.size([this._width, this._height])
			.words(this.words)
			.rotate(() => this._rotations[Math.floor(Math.random() * this._rotations.length)])
			.font("Impact")
			.fontWeight("normal")
			.padding(1)
			.fontSize(function(d) { return d.size; })
			.spiral("archimedean")
			.on('end', () => {
				this._drawWordCloud(this.words);
			})
			.start();
	}
private _drawWordCloud(words) {
	this._svg
		.selectAll('text')
		.data(words)
		.enter()
		.append('text')
		.style('font-size', d => d.size + 'px')
		.style("font-family", "Impact")
		.style('fill', (d, i) => {
			return this._fillScale(i);
		})
		.attr('text-anchor', 'middle')
		.attr('transform', d => 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')')
		.attr('class', 'word-cloud')
		.text(d => {
			return d.text;
		});`

@mootinator
Copy link

I had to deal with issues caused by loading a web-font when the word cloud is the only thing on the page and described my (different) solution here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants