Reputation: 273
I'm quite new to d3/SVG, and I'm trying to make something slightly complex.
Here's an example of the shape I'm trying to draw:
Any ideas about how I could achieve this? I've been fiddling around with pattern fills without much luck. Or, it's easy to create a rectangle of bars, do I do that and then use it as a fill for the circle? Or, is it a matter of creating six different shapes with the relevant arcs.
Any pointers are appreciated.
Upvotes: 2
Views: 668
Reputation: 38221
The easiest way may be to simply append rectangles (as you note this is fairly easy) but add a clip path. This will keep things simple for appending rectangles and allow you to change the clip path if you want to change your radius or shape (without having to update each rectangle):
svg = d3.select('body')
.append('svg')
.attr('width',500)
.attr('height',500);
color = d3.schemeCategory20;
circle = svg.append('circle')
.attr('cx',250)
.attr('cy',250)
.attr('r',150)
.attr('fill','none')
.attr('id','clipper');
clipPath = svg.append('clipPath')
.attr('id',"clip")
.append("use")
.attr("xlink:href","#clipper");
rects = svg.selectAll('rect')
.data(d3.range(20))
.enter()
.append('rect')
.attr('x',function(d,i) { return i * 25 })
.attr('y',0)
.attr('width',25)
.attr('height',500)
.attr('fill',function(d,i) { return color[i]; })
.attr("clip-path","url(#clip)")
animate();
function animate() {
svg.select('circle')
.transition()
.attr('r',100)
.duration(1000)
.transition()
.attr('r',200)
.duration(1000)
.on('end',animate);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
To add your own colors to the rectangles you could specify your own color array:
var width = 300;
var height = 300;
var svg = d3.select('body')
.append('svg')
.attr('width',width)
.attr('height',height);
// Use CSS colors
// var color = ["darkgreen","blue","purple","red","orange","yellow"];
// or Use hex colors:
var color = ["#111","#222","#333","#444","#555","#666"];
var n = 6;
var circle = svg.append('circle')
.attr('cx',width/2)
.attr('cy',height/2)
.attr('r',width/2)
.attr('fill','none')
.attr('id','clipper');
var clipPath = svg.append('clipPath')
.attr('id',"clip")
.append("use")
.attr("xlink:href","#clipper");
var rects = svg.selectAll('rect')
.data(d3.range(n))
.enter()
.append('rect')
.attr('x',function(d,i) { return i * width / n })
.attr('y',0)
.attr('width',width/n)
.attr('height',500)
.attr('fill',function(d,i) { return color[i]; })
.attr("clip-path","url(#clip)")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
The above snippet will append a specified number of rectangles across the circle (n
in the code), and will append colors to them from the array. In the original example, d3.schemeCategory20
is just an array. The i
in the inline function function (d,i)
will return the element increment which is why an array works easily in getting a fill color.
Upvotes: 3