I have build Leaflet based map visualization with circles on it made in D3. Based on the data selections, the map gets updated with values. Now, I am trying to change the stroke of circles based on another set of data. I mean if in my dataset there are 100 rows. After filtering, I show 60 circles and in these 60 points I have selected 30 points and I want to add the stroke to these 30 points and keep the rest of 60 points on map. Is it possible to do so?
.style("stroke", ....)
Can we call another dataset at this position?
This is my code
function updateSubset(filterLoad = 0) {
function applyLatLngToLayer(d) {
var y = d.geometry.coordinates[1]
var x = d.geometry.coordinates[0]
return map.latLngToLayerPoint(new L.LatLng(y, x))
}
var arr = geoData.features;
var filterObjArray = Object.entries(seldata_category);
console.log(filterObjArray)
var filterQuantArray = Object.entries(seldata_quant);
console.log(filterQuantArray)
var result = arr.filter(o => filterObjArray.every(([k,v]) => v.includes(o.properties[k])) && filterQuantArray.every(([k,[l,h]]) => o.properties[k] >= l && o.properties[k] <= h));
console.log(result);
console.log(seldata_category);
// handling size of the circles
var size_name = sizedropDown[current.size];
var size_extent = sizeExtents[current.size];
//console.log(colorExtents)
var sizeScale = d3.scaleSqrt()
.domain(size_extent)
.range([5,15]);
// handlimg color of the circles
var color_name = colordropDown[current.color];
var color_extent = colorExtents[current.color];
// console.log(color_extent)
var ordinalScale = d3.scaleOrdinal()
.domain(color_extent)
.range(c10(color_extent.length));
console.log(seldata_category)
console.log(seldata_quant)
// creating points using paths
var points = g.selectAll("circle")
.data(result);
var pointsEnter = points.enter().append("circle")
.attr("class", "points");
//console.log(points)
points.merge(pointsEnter).attr("r", function(d) { return sizeScale(d.properties[size_name]);})
.style("fill-opacity", 0.4)
.style("fill", function(d){ return ordinalScale(d.properties[color_name]);})
.on("mouseover",function(d){
var details = [];
for(var prop in d.properties){
details.push("<label>"+prop + " : </label>" + d.properties[prop]);
}
d3.select("#info_box").selectAll("li").data(details).enter().append("li").html(function(d){return d;});
$('#info_box li').addClass('list-group-item');
})
.on("mouseout", function(d){d3.select("#info_box").selectAll("li").remove();});
// map.on("viewreset", update);
//update();
map.on("viewreset", update);
update();
function update() {
var bounds = path.bounds(geoData);
topLeft = [bounds[0][0] + 10 , bounds[0][1] - 10]
bottomRight = [bounds[1][0] + 10 , bounds[1][1] + 10];
svg.attr("width", bottomRight[0] - topLeft[0])
.attr("height", bottomRight[1] - topLeft[1])
.style("left", topLeft[0] + "px")
.style("top", topLeft[1] + "px");
g.attr("transform", "translate(" + -topLeft[0] + "," + -topLeft[1] + ")");
var x = d3.selectAll('circle');
x.attr("transform",
function(d) {
return "translate(" +
applyLatLngToLayer(d).x + "," +
applyLatLngToLayer(d).y + ")";
});
}
points.exit().remove();
}
Related
I have multiple group elements with text element inside them. When I'm zooming with the mouse wheel, then everything is fine, my text is still inside my paths (polygons).
But when I'm zooming in automatically, then my text doesn't relocate.
Here is my function with auto zoom, I'm trying to find a specific path by ID, fill it with yellow, center and zoom to it.
function findByID(ID) {
svgContainer.selectAll("path")
.data(feat.features)
.filter(function (d) {
if (d.properties.myID == ID) {
centered = centered !== d && d;
var paths = svgContainer.selectAll("path")
.classed("active", function (d) {
d === centered;
});
var t0 = projection.translate(),
s0 = projection.scale();
projection.fitSize([width, height], centered);
var interpolateTranslate = d3.interpolate(t0, projection.translate()),
interpolateScale = d3.interpolate(s0, projection.scale());
var interpolator = function (t) {
projection.scale(interpolateScale(t))
.translate(interpolateTranslate(t));
paths.attr("d", path);
};
d3.transition()
.duration(5000)
.tween("projection", function () {
return interpolator;
});
return true;
}
})
.attr("fill", "#e9f356");
}
Here is a screenshot where I used my mouse wheel:
And here is a screenshot after my auto zoom is done. My lines are fade away also, why is it so?
Edit: This is how I add my text:
svgContainer.selectAll(null)
.data(feat.features.filter(function (d) { return d.properties.myId > 0; }))
.enter()
.append("g").attr("id", "txt")
.attr("transform", function (a) {
var centro = path.centroid(a);
return "translate(" + centro[0] + "," + centro[1] + ")";
})
.append("text")
.attr("text-anchor", "middle")
.attr("font-size", function (d) {
var bb = path.bounds(d)
return ((bb[1][0] - bb[0][0]) / 10) + "px";
})
.text("A/10/10/3");
Ok, I did it but when I try to zoom out with the mouse wheel it zooms out completely instantly. How can I make it smooth?
function findByID(ID) {
svgContainer.selectAll("path")
.data(feat.features)
.filter(function (d) {
if (d.properties.myID == ID) {
var bounds = path.bounds(d),
dx = bounds[1][0] - bounds[0][0],
dy = bounds[1][1] - bounds[0][1],
x = (bounds[0][0] + bounds[1][0]) / 2,
y = (bounds[0][1] + bounds[1][1]) / 2,
scale = .9 / Math.max(dx / width, dy / height),
translate = [width / 2 - scale * x, height / 2 - scale * y];
d3.select("#mainGroup").transition()
.duration(5000)
.style("stroke-width", 1.5 / scale + "px")
.attr("transform", "translate(" + translate + ")scale(" + scale + ")");
return true;
}
})
.attr("fill", "#e9f356");
}
Below is how I creat a bar chart using rects in D3. However, how would I modify that to get the bar chart with path property in d3js?
I have a json file which has the data to be read and am trying to create a bar chart with paths rather than rectangles in d3js.
Json :
[
{
"name": "sam",
"age": 24
},
{
"name": "baby",
"age": 23
},
{
"name": "adu",
"age": 21
},
{
"name": "ja",
"age": 23
},
{
"name": "mack",
"age": 34
}
]
Code:
<script>
d3.json("mydata.json", function (data) {
var canvas = d3.select('body').append('svg')
.attr('width', 500)
.attr('height', 500);
canvas.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('width',function (d) { return d.age * 10; })
.attr('height', 48)
.attr('y', function (d, i) { return i * 50; })
.attr('fill', 'blue');
canvas.selectAll('text')
.data(data)
.enter()
.append('text')
.attr('fill','white')
.attr('y', function (d, i) {
return i* 50 + 24;
})
.text(function (d) {
return d.name;
})
});
</script>
I have searched through many sites. I am unable to get though
You can't assign a d attribute to a rectangle, but you can make a bar chart out of paths rather than rectangles. All you need to do is know the coordinates of the corners of the rectangle. You really only need two corners on opposite sides. If you had top left and bottom right coordinates ([x0,y0] and [x1,y1] respectively) you could do something like:
function drawRect(x0,y0,x1,y1) {
var p1 = x0 + " " + y0;
var p2 = x0 + " " + y1;
var p3 = x1 + " " + y1;
var p4 = x1 + " " + y0;
var l = "L"; // cause I'm lazy.
return "M"+p1+l+p2+l+p3+l+p4+"Z";
}
This moves the cursor to p1, then draws connecting lines from p1 to p2 to p3 to p4 and then returns to the start with Z.
With scaled values this could get a bit verbose either passing scaled parameters or scaling the values in the path making function (as I do below).
This might look like (paths fade in so you can see that they match the rects):
var data = [1,2,3,5,8,3];
var width = 500;
var height = 300;
var svg = d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height);
var x = d3.scaleBand()
.domain(d3.range(data.length))
.range([0,width]);
var y = d3.scaleLinear()
.domain([0,d3.max(data)])
.range([height,0]);
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("width", x.bandwidth())
.attr("height", function(d) { return height-y(d); })
.attr("x", function(d,i) { return x(i); })
.attr("y", function(d) { return y(d); })
svg.selectAll("path")
.data(data)
.enter()
.append("path")
.attr("d", makeRect)
.attr("fill","orange")
.style("opacity",0)
.transition()
.style("opacity",1)
.duration(1500);
function makeRect(d,i) {
var x0 = x(i);
var y0 = y(d);
var x1 = x(i) + x.bandwidth();
var y1 = height;
var p1 = x0 + " " + y0;
var p2 = x0 + " " + y1;
var p3 = x1 + " " + y1;
var p4 = x1 + " " + y0;
var l = "L";
return "M"+p1+l+p2+l+p3+l+p4+"Z";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
But, this can't really be a preferred option in most cases. It is more complex than the rectangles for sure. The rectangle should be preferable, unless of course you are trying to do some sort of manipulation on the path that you can't do with a rectangle, or maybe you want rounded edges. Perhaps you are projecting the path on a globe or maybe you want to do some path transition (I've added extra vertices to the rectangle path to smooth the transition, in most cases, ideally the start and end paths of a transition have the same number of vertices):
var data = [1,2,3,5,8,3];
var width = 500;
var height = 200;
var svg = d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height);
var x = d3.scaleBand()
.domain(d3.range(data.length))
.range([0,width]);
var y = d3.scaleLinear()
.domain([0,d3.max(data)])
.range([height,0]);
svg.selectAll("path")
.data(data)
.enter()
.append("path")
.attr('d', d3.symbol().type( d3.symbols[1]).size(function(d){ return d*100; }) )
.attr("transform","translate(0,"+height/2+")")
.transition()
.attr("transform",function(d,i) { return "translate("+(x(i)+x.bandwidth()/2) + "," + height/2 + ")" })
.attr("fill","steelblue")
.duration(1500)
.transition()
.attr("d", makeRect)
.attr("fill","orange")
.attr("transform","translate(0,0)")
.duration(1500);
//*/
function makeRect(d,i) {
var x0 = x(i);
var y0 = y(d);
var x1 = x(i) + x.bandwidth();
var y1 = height;
var p1 = x0 + " " + y0;
var p2 = x0 + " " + y1;
var p3 = x1 + " " + y1;
var p4 = x1 + " " + y0;
var l = "L";
return "M"+p1+l+p1+l+p1+l+p4+l+p4+l+p4+l+p3+l+p3+l+p3+l+p2+l+p2+l+p2+"Z";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
I've got this legend:
As you can see, each legend entry is the same width. Instead, I'd like each legend entry's width to vary based upon the width of the entry's symbol and text. Ultimately, I want the same distance between the ends of the leading entry's text and the start of the following entry's symbol. In other words, I'd like the same distance between 'OA' and the plus sign as between the 'OI' and the diamond and the 'RARC' and the square. I need this to be based on pixels (string lengths won't suffice). I've been trying all sorts of stuff, but haven't been successful.
Here's my code:
var legendData = [["OA", "yellow", "circle"], ["OI", "blue", "cross"], ["RARC", "green", "diamond"], ["CAPE", "red", "square"], ["Other", "black", "triangle-down"]];
this.svg.selectAll('.legend').remove() //remove remnants of previous legend so new legend has clean slate...eliminates overlays during resizing
var legend = this.svg.append('g')
.attr("class", "legend")
.attr("height", 0)
.attr("width", 0)
.attr('transform', 'translate(' + (ScatterChart.Config.margins.left + (width * .008)) + ',' + (height += .40 * ScatterChart.Config.margins.bottom) + ')');
var legendRect = legend
.selectAll('g')
.data(legendData)
;
var labelLength = 0
var labelLengthPrevious = 0
var legendRectE = legendRect.enter()
.append("g")
.attr("transform", function (d, i) {
//labelLength = labelLengthPrevious //Need to figure out pixel lengths
//labelLengthPrevious += (d[0].length) + 50
//return 'translate(' + labelLength + ', ' + 0 + ' )'; // y is constant and x growing
return 'translate(' + (i * (.15 * width)) + ', ' + 0 + ' )'; // y is constant and x growing
})
;
legendRectE
.append('path')
.attr("d", d3.svg.symbol().type((d) => {
return d[2]
}
).size((d3.min([height, width]) * ScatterChart.Config.axisFontMultiplier) * (d3.min([height, width]) * ScatterChart.Config.symbolSizeMultiplier)))
.style("fill", function (d) {
return d[1];
})
.attr('stroke', 'black')
;
//This asserts legendRectE as a node...I think. I do this so I can use the width and height measurements of legendRectE.
var node: SVGElement = <SVGElement>legendRectE.node()
legendRectE
.append("text")
.attr("x", function (d) {
return node.getBoundingClientRect().width
})
.attr("y", function (d) {
return node.getBoundingClientRect().height / 2.25
})
.text(function (d) {
return d[0];
})
.style('font-size', function () { return d3.min([height, width]) * ScatterChart.Config.axisFontMultiplier + "px" })
;
I think the answer would have something to do with this line: return 'translate(' + (i * (.15 * width)) + ', ' + 0 + ' )'; // y is constant and x growing. Right now, it just shifts to the right by multiplying the index by 15% of the chart's width. I figure I need to somehow substitute the width of the legendRectE (or of legendRect or legend) in place of (I * (.15 * width)). I can't figure out how to do that.
You can see that I use the following to get the width of legendRectE later in the code: var node: SVGElement = <SVGElement>legendRectE.node(), followed by node.getBoundingClientRect().width.
node.getBoundingClientRect().width gives me a width value where you see it being used now, but when I use this same approach to determine a value for the translate I mentioned, it chokes; and when I use legendRect or legend instead of legendRectE I only get '0'.
I thought I'd be able to edit the transform function something like this:
var legendRectE = legendRect.enter()
.append("g")
.attr("transform", function (d, i) {
var node: SVGElement = <SVGElement>legendRectE.node()
return 'translate(' + node.getBoundingClientRect().width + ', ' + 0 + ' )'; // y is constant and x growing
})
;
Obviously, I was wrong. Any ideas/advice?
p.s. I'm using d3 v3.5.
The challenge is that it is (as far as I know) difficult to determine the transform when appending elements initially as the widths are unknown. But you could go back and calculate the width of each legend entry after they are all appended and then reposition the legend entries accordingly.
The snippet below positions everything overtop of each other to start, then calculates the svg width of each legend g using getBBox. Then, using d3.sum, calculates the width of each element that was appended before it (and thus should be to the left of it) and sets the translate value to the sum of those widths accordingly.
It can probably be cleaned up a bit probably, it's a little quick. If there is lag before the elements are positioned correctly, appending them transparently and then fading them in after they are positioned might be an elegant (visually, less so programatically) solution (or appending them initially outside of the view box).
d3v4:
var data = ['short text','much longer text','the longest text passage','short text'];
var svg = d3.select('body')
.append('svg')
.attr('width',800)
.attr('height',200);
var groups = svg.selectAll('g')
.data(data)
.enter()
.append('g');
var rect = groups.append('rect')
.attr('fill',function(d,i) { return d3.schemeCategory10[i];})
.attr('height',30)
.attr('width',30);
var text = groups.append('text')
.attr('y', 20)
.attr('x', 35)
.text(function(d) { return d; });
// Now space the groups out after they have been appended:
var padding = 10;
groups.attr('transform', function(d,i) {
return "translate("+(d3.sum(data, function(e,j) {
if (j < i) { return groups.nodes()[j].getBBox().width; } else return 0; }) + padding * i) + ",0)";
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
d3v3:
var data = ['short text','much longer text','the longest text passage','short text'];
var svg = d3.select('body')
.append('svg')
.attr('width',800)
.attr('height',200);
var groups = svg.selectAll('g')
.data(data)
.enter()
.append('g');
var color = ["orange","red","purple","green"];
var rect = groups.append('rect')
.attr('fill',function(d,i) { return color[i];})
.attr('height',30)
.attr('width',30);
var text = groups.append('text')
.attr('y', 20)
.attr('x', 35)
.text(function(d) { return d; });
// Now space the groups out after they have been appended:
var padding = 10;
groups.attr('transform', function(d,i) {
return "translate("+(d3.sum(data, function(e,j) {
if (j < i) { return groups[0][j].getBBox().width; } else return 0; }) + padding * i) + ",0)";
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
I have created a simple pie chart using D3.js and I wish to pop out each element/path of the pie chart on click event of those elements.
Here is the pie chart I am talking about: jsfiddle.net/ankur881120/kt97oq57.
arcs.filter(function(d) { return d.endAngle - d.startAngle > .2; }).append("svg:text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
//.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")"; })
.attr("transform", function(d) { //set the label's origin to the center of the arc
//we have to make sure to set these before calling arc.centroid
d.outerRadius = outerRadius; // Set Outer Coordinate
d.innerRadius = outerRadius/2; // Set Inner Coordinate
return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")";
Now I want to pop out say element in red color on click of red color element.
Looking for all of your suggestions, to solve this issue.
I just answered a very similar question about this yesterday. Your use case is different enough, so against my better judgement, I'll answer it again.
Essentially, add the click handler and transition your arc "group" (arc and text labels) together:
var arcs = vis.selectAll("g.slice")
// Associate the generated pie data (an array of arcs, each having startAngle,
// endAngle and value properties)
.data(pie)
// This will create <g> elements for every "extra" data element that should be associated
// with a selection. The result is creating a <g> for every object in the data array
.enter()
// Create a group to hold each slice (we will have a <path> and a <text>
// element associated with each slice)
.append("svg:g")
.attr("class", "slice") //allow us to style things in the slices (like text)
// ADDED CLICK HANDLER
.on('click',function(d,i){
d3.select(this)
.transition()
.duration(500)
.attr("transform",function(d){
// this this group expanded out?
if (!d.data._expanded){
d.data._expanded = true;
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
var x = Math.cos(a) * 20;
var y = Math.sin(a) * 20;
// move it away from the circle center
return 'translate(' + x + ',' + y + ')';
} else {
d.data._expanded = false;
// move it back
return 'translate(0,0)';
}
});
});
Updated fiddle.
Complete code:
var canvasWidth = 300, //width
canvasHeight = 300, //height
outerRadius = 100, //radius
color = d3.scale.category20(); //builtin range of colors
var dataSet = [
{"legendLabel":"One", "magnitude":20},
{"legendLabel":"Two", "magnitude":40},
{"legendLabel":"Three", "magnitude":50},
{"legendLabel":"Four", "magnitude":16},
{"legendLabel":"Five", "magnitude":50},
{"legendLabel":"Six", "magnitude":8},
{"legendLabel":"Seven", "magnitude":30}];
var vis = d3.select("body")
.append("svg:svg") //create the SVG element inside the <body>
.data([dataSet]) //associate our data with the document
.attr("width", canvasWidth) //set the width of the canvas
.attr("height", canvasHeight) //set the height of the canvas
.append("svg:g") //make a group to hold our pie chart
.attr("transform", "translate(" + 1.5*outerRadius + "," + 1.5*outerRadius + ")") // relocate center of pie to 'outerRadius,outerRadius'
// This will create <path> elements for us using arc data...
var arc = d3.svg.arc()
.outerRadius(outerRadius);
var pie = d3.layout.pie() //this will create arc data for us given a list of values
.value(function(d) { return d.magnitude; }) // Binding each value to the pie
.sort( function(d) { return null; } );
// Select all <g> elements with class slice (there aren't any yet)
var arcs = vis.selectAll("g.slice")
// Associate the generated pie data (an array of arcs, each having startAngle,
// endAngle and value properties)
.data(pie)
// This will create <g> elements for every "extra" data element that should be associated
// with a selection. The result is creating a <g> for every object in the data array
.enter()
// Create a group to hold each slice (we will have a <path> and a <text>
// element associated with each slice)
.append("svg:g")
.attr("class", "slice") //allow us to style things in the slices (like text)
.on('click',function(d,i){
d3.select(this)
.transition()
.duration(500)
.attr("transform",function(d){
if (!d.data._expanded){
d.data._expanded = true;
var a = d.startAngle + (d.endAngle - d.startAngle)/2 - Math.PI/2;
var x = Math.cos(a) * 20;
var y = Math.sin(a) * 20;
return 'translate(' + x + ',' + y + ')';
} else {
d.data._expanded = false;
return 'translate(0,0)';
}
});
});
arcs.append("svg:path")
//set the color for each slice to be chosen from the color function defined above
.attr("fill", function(d, i) { return color(i); } )
//this creates the actual SVG path using the associated data (pie) with the arc drawing function
.attr("d", arc);
// Add a legendLabel to each arc slice...
arcs.append("svg:text")
.attr("transform", function(d) { //set the label's origin to the center of the arc
//we have to make sure to set these before calling arc.centroid
d.outerRadius = outerRadius + 50; // Set Outer Coordinate
d.innerRadius = outerRadius + 45; // Set Inner Coordinate
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle") //center the text on it's origin
.style("fill", "Purple")
.style("font", "bold 12px Arial")
.text(function(d, i) { return dataSet[i].legendLabel; }); //get the label from our original data array
// Add a magnitude value to the larger arcs, translated to the arc centroid and rotated.
arcs.filter(function(d) { return d.endAngle - d.startAngle > .2; }).append("svg:text")
.attr("dy", ".35em")
.attr("text-anchor", "middle")
//.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")"; })
.attr("transform", function(d) { //set the label's origin to the center of the arc
//we have to make sure to set these before calling arc.centroid
d.outerRadius = outerRadius; // Set Outer Coordinate
d.innerRadius = outerRadius/2; // Set Inner Coordinate
return "translate(" + arc.centroid(d) + ")rotate(" + angle(d) + ")";
})
.style("fill", "White")
.style("font", "bold 12px Arial")
.text(function(d) { return d.data.magnitude; });
// Computes the angle of an arc, converting from radians to degrees.
function angle(d) {
var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
return a > 90 ? a - 180 : a;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
I'm trying to make radial bar chart using d3js, but I'm having some trouble with the data model. I have a fiddle here showing what I want to achieve. At the moment the size of the bars are randomly created, but I want to be able to provide my own data (values between 1 and 6) into the chart, but I'm having trouble understanding the data model/structure of d3js, so help would be appreciated!
$(function(){
var $container = $('.chart-container'),
τ = 2 * Math.PI,
width = $container.width(),
height = $container.height(),
outerRadius = Math.min(width,height)/2.5,
innerRadius = 10,
fontSize = (Math.min(width,height)/4);
var dataset = {
weeks: [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
};
var color = d3.scale.ordinal() .range(['rgb(247,251,255)','rgb(222,235,247)','rgb(198,219,239)','rgb(158,202,225)','rgb(107,174,214)','rgb(66,146,198)','rgb(33,113,181)','rgb(8,81,156)','rgb(8,48,107)']);
var pie = d3.layout.pie()
.sort(null);
var arc = d3.svg.arc();
var svg = d3.select('.chart-container').append("svg")
.attr("width", '100%')
.attr("height", '100%')
.attr('viewBox','0 0 '+Math.min(width,height) +' '+Math.min(width,height) )
.attr('preserveAspectRatio','xMinYMin')
.append("g")
.attr("transform", "translate(" + Math.min(width,height) / 2 + "," + Math.min(width,height) / 2 + ")");
var gs = svg.selectAll("g").data(d3.values(dataset)).enter().append("g").attr("class", "arc");
var path = gs.selectAll("path")
.data(function(d) { return pie(d); })
.enter().append("path")
.attr("fill", function(d, i) { return color(i); })
.attr("d", function(d, i, j) { return arc.innerRadius(10).outerRadius(20*getRandomInt (1, 6))(d); });
});
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Change your dataset variable and colours here, just pre-populate your required arrays and inject them into D3. i.e. d3.values(dataset)
var dataset = {
weeks: [5,10]
};
var color = d3.scale.ordinal().range(['#ccc','#c33']);