D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
emeeks
Full window
Github gist
More bounding box collide
Another attempt at better bounding box collision for d3 force.
<html> <head> <title>d3v4 Simple Word Cloud</title> <meta charset="utf-8" /> <script src="https://d3js.org/d3.v4.min.js"></script> <script src="d3-force.js"></script> </head> <style> svg { height: 500px; width: 500px; border: 1px solid gray; } </style> <body> <div id="viz"> <svg class="main"> </svg> </div> </body> <footer> <script> d3.csv("words.csv",function(error,data) {createWordcloud(data)}); //d3.csv("words.csv",function(error,data) {roundWordCloud(data)}); function roundWordCloud(data) { var simulation = d3.forceSimulation(data) .force("x", d3.forceX().strength(0.002)) .force("y", d3.forceY().strength(0.002)) .force("collide", d3.forceCollide().radius(function(d) { return 5; }) .iterations(2)) .on("tick", updateNetwork); var color = d3.scaleOrdinal(d3.schemeCategory10) var nodeEnter = d3.select("svg.main") .append("g") .attr("transform", "translate(250,250)") .selectAll("g.node") .data(data) .enter() .append("g") .attr("class", "node") nodeEnter.append("circle") .attr("r", 5) .style("pointer-events", "none") .style("fill", function (d,i) {return color(i)}) .style("stroke", function (d,i) {return color(i)}) .style("stroke-width", 1) .style("fill-opacity", 0.2) function updateNetwork(e) { d3.select("svg.main").selectAll("g.node") .attr("transform", function (d) {return "translate(" + d.x + "," + d.y + ")"}); } } function createWordcloud(data) { var combinedData = []; combinedData = data var networkCenter = d3.forceCenter().x(250).y(250); var textScale = d3.scaleLinear().domain([10,70]).range([2,10]) var forceX = d3.forceX(function (d) {return 250}) .strength(0.02) var forceY = d3.forceY(function (d) {return 250}) .strength(0.02) var collide = d3.forceRectCollide(function (d,i) { return i%2 === 0 ? [[-(d.text.length * textScale(d.frequency)),-15],[(d.text.length * textScale(d.frequency)),15]] : [[-15,-(d.text.length * textScale(d.frequency))],[15,(d.text.length * textScale(d.frequency))]] }) .strength(1) .iterations(2) var color = d3.scaleOrdinal(d3.schemeCategory10) var force = d3.forceSimulation(combinedData) .force("center", networkCenter) .force("x", forceX) .force("y", forceY) .force("collide", collide) .on("tick", updateNetwork); var nodeEnter = d3.select("svg.main").selectAll("g.node") .data(combinedData) .enter() .append("g") .attr("class", "node") nodeEnter.append("rect") .attr("height", function (d,i) { return i%2 === 0 ? 30 : d.text.length * textScale(d.frequency) * 2 }) .attr("width", function (d,i) { return i%2 === 0 ? d.text.length * textScale(d.frequency) * 2 : 30 }) .attr("y", function (d,i) { return i%2 === 0 ? -15 : -(d.text.length * textScale(d.frequency)) }) .attr("x", function (d,i) { return i%2 === 0 ? -(d.text.length * textScale(d.frequency)) : -15 }) .style("pointer-events", "none") .style("fill", function (d,i) {return color(i)}) .style("stroke", function (d,i) {return color(i)}) .style("stroke-width", 1) .style("fill-opacity", 0.2) function updateNetwork(e) { d3.select("svg.main").selectAll("g.node") .attr("transform", function (d) {return "translate(" + d.x + "," + d.y + ")"}); } } </script> </footer> </html>
https://d3js.org/d3.v4.min.js