tomgp
7/1/2014 - 4:39 PM

SVG Arrow heads

SVG Arrow heads

  1. How to use an external SVG in a D3 visualisation
  2. How to do custom line endings in SVG eg. arrows or turtles
<html>
<head>
	<title>SVG Arrows with D3</title>
	<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
	<link rel="stylesheet" type="text/css" href="http://www.toffeemilkshake.co.uk/tgp-ui-styles/ui-style.css">
	<style type="text/css">
	.arrow{
		stroke-width:5;
		stroke:#000;
		stroke-dasharray:5, 5;
	}

	circle{
		stroke-width:5;
		stroke:#000;
		fill:#FFF;
	}

	#turtle-icon, #arrow{
		stroke-width:1;
		stroke-dasharray:0;	
	}

	</style>
</head>
<body>
	<h1>Arrow heads and turtles in D3</h1>
	<div class="viz"></div>

	<hr>
	<p><a href="http://www.toffeemilkshake.co.uk">Tom Pearson 2014</a></p>
	<p>Turtle Icon by Martin Smith from <a href="http://thenounproject.com/">The Noun Project</a></p>
	
</body>
<script type="text/javascript">

	d3.xml('turtle.svg', "image/svg+xml", function(xml){
		var importedNode = document.importNode(xml.documentElement, true).getElementsByTagName("g")[0],

		height = 500, width = 800,
		margin = 50,
		type = ['turtle','arrow'];
		svg = d3.select(".viz").append("svg")
		    .attr("width", 800)
		    .attr("height", 600),

		defs = svg.append("defs")

		defs.append("marker")
				.attr({
					"id":"arrow",
					"viewBox":"0 -5 10 10",
					"refX":5,
					"refY":0,
					"markerWidth":4,
					"markerHeight":4,
					"orient":"auto"
				})
				.append("path")
					.attr("d", "M0,-5L10,0L0,5")
					.attr("class","arrowHead");

		defs.append("marker")
				.attr({
					"id":"turtle",
					"viewBox":"0 0 100 100",
					"refX":50,
					"refY":50,
					"markerWidth":10,
					"markerHeight":10,
					"orient":"auto"
				})
				.node().appendChild(importedNode);
		


		d3.range(15).forEach(function(){ //I don't normally do loops like this, just a whim
			svg.append('line')
				.attr({
					"class":"arrow",
					"marker-end":"url(#" + type[Math.round(Math.random())] + ")",
					"x1":width/2,
					"y1":height/2,
					"x2":margin + Math.random()*(width-margin*2),
					"y2":margin + Math.random()*(height-margin*2)
				});
		})

		svg.append('circle')
			.attr({
				cx:width/2,cy:height/2,r:20
			})
	})

	
</script>
</html>