block by nbremer 4b81aff1ff5907ac3db1780a1c6a5e01

Radial SVG gradient - Random bubble art

Full Screen

I used this example to get the opening image for the .net magazine tutorial that I wrote about using SVG gradients in d3.js based data visualizations. All the data is generated randomly so you will see a new visual of circles and lines on each refresh.

It was just something to look nice, uses the idea of the tutorial itself and catch the eye of the reader :)

Open in a new window to see it full size

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	
	<!-- D3.js -->
	<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
	
	<style>
		body {
		  	text-align: center;
			background: black;
		}
	</style>
	
</head>	
<body>
	
	<div id="chart"></div>

	<script>

		///////////////////////////////////////////////////
		//////////////// Set the Scales ///////////////////
		///////////////////////////////////////////////////

		//Set the dimensions of the chart
		var margin = {top: 0, right: 0, bottom: 0, left: 0},
		    width = window.innerWidth - margin.left - margin.right - 20,
		    height = window.innerHeight - margin.top - margin.bottom - 20;
		
		var maxWindowSize = Math.min(width, height);
		
		width = maxWindowSize;
		height = maxWindowSize;
		
		//Set the minimum inner radius and max outer radius of the chart
		var innerRadius = maxWindowSize*0.18,
			outerRadius = maxWindowSize*0.4;

		///////////////////////////////////////////////////
		////////////// Initialize the SVG /////////////////
		///////////////////////////////////////////////////
	      
		//Add the svg canvas for the line chart
		var svg = d3.select("#chart")
		    .append("svg")
		        .attr("width", width + margin.left + margin.right)
		        .attr("height", height + margin.top + margin.bottom)
		    .append("g")
		        .attr("transform", "translate(" + (margin.left + width/2) + "," + (margin.top + height/2) + ")");
	
		///////////////////////////////////////////////////
		///////////// Create the gradient ////////////////
		///////////////////////////////////////////////////
	
		var numColors = 10;
		var colorScale = d3.scale.linear()
		   .domain([0,(numColors-1)/2,numColors-1])
		   .range(["#2c7bb6", "#ffff8c", "#d7191c"])
		   .interpolate(d3.interpolateHcl);

		svg.append("defs").append("radialGradient")
			.attr("id", "gradientRainbow")
			.attr("gradientUnits", "userSpaceOnUse") 
			.attr("cx", "0%")
			.attr("cy", "0%")
			.attr("r", "45%")
			.selectAll("stop") 
			.data(d3.range(numColors))                  
			.enter().append("stop") 
			.attr("offset", function(d,i) { return (i/(numColors-1)*50 + 40) + "%"; })   
			.attr("stop-color", function(d) { return colorScale(d); });
			
		///////////////////////////////////////////////////
		///////////////// Create the data /////////////////
		///////////////////////////////////////////////////

	
		function getRandomNumber(start, end) {
		    return (Math.random() * (end-start) * 100)/100 + start;
		}//function getRandomNumber

		////jsfiddle.net/guffa/tvt5k/
		function rnd2() {
		    return ((Math.random() + Math.random() + Math.random() + Math.random()) - 2) / 2;
		}
		
		//Adjust circle sizes to browser size
		var circleRanges = [20*maxWindowSize/1000, 6*maxWindowSize/1000];
	
		//Create random dataset
		var dataset = [];
		for(var i = 0; i < 2000; i++) {
			var outward = Math.abs(rnd2()) * (outerRadius * 0.8) + innerRadius; //getRandomNumber(innerRadius, outerRadius),
			var radius = Math.abs(rnd2() * circleRanges[0] + circleRanges[1]); //getRandomNumber(1, 18);
	
			if( outward - radius < innerRadius ) {
				outward = innerRadius + radius;
			}
			dataset.push({
				outward: outward, 
				theta: getRandomNumber(1, 360) * Math.PI / 180,
				radius: radius,
			})	
		}//for i

		///////////////////////////////////////////////////
		/////////// Plot the lines and circles ////////////
		///////////////////////////////////////////////////
		
		//Append the lines radiating outward
		var lineWrapper = svg.append("g").attr("class", "lineWrapper");

		lineWrapper.selectAll(".lines")
				.data(d3.range(1,80))
			 	.enter().append("line")
			 	.attr("class", "lines")
				.attr("transform", function(d,i) { return "rotate(" + ( getRandomNumber(1, 360) ) + ")"; })
			 	.attr("x1", 0)
				.attr("y1", function(d) { return getRandomNumber(innerRadius, outerRadius*1.3);  })
			 	.attr("x2", 0)
				.attr("y2", function(d) { return getRandomNumber(innerRadius, outerRadius*1.3);  })
				.style("stroke", "url(#gradientRainbow)")
				.style("stroke-width", function(d) { return getRandomNumber(0.5, 3);  })
				.style("opacity", function(d) { return getRandomNumber(0.2, 0.7);  });
		
		//Append the circles
		var circleWrapper = svg.append("g").attr("class", "circleWrapper");

		circleWrapper.selectAll(".dots")
			 	.data(dataset)
			 	.enter().append("circle")
			 	.attr("class", "dots")
			 	.attr("cx", function(d) { return d.outward * Math.cos(d.theta); })
				.attr("cy", function(d) { return d.outward * Math.sin(d.theta);  })
				.attr("r", function(d) { return d.radius; })
			 	.style("fill", "url(#gradientRainbow)")
				.style("opacity", function(d) { return getRandomNumber(0.2, 0.7);  });
		
	</script>

</body>
</html>