d3 projection geoMercator returns none - javascript

I'm trying to plot some cordinates on an image using d3 v4 following this Link.When i'm trying to pass my co-ordinates to the projection function it returns NAN for some of the data points. I got some help from here that javascript follows the following latitude and longitude convention but not sure how it exacty works.
This is the format of my data:
{coordinates: [60, 84],coordinates: [204, 92.4],coordinates: [117, 132.72]}
D3 code :
var el = d3.select('.js-map'),
// 150 DPI image
width = 300,
// 150 DPI image
height = 300;
var thisObj = this;
var projection = d3.geoMercator()
.scale(1)
.translate([0, 0])
console.log('projection', projection);
var path = d3.geoPath()
.projection(projection);
var map = el.append('svg')
.attr('width', width)
.attr('height', height);
map.append('image')
.attr('xlink:href', this.floorMaps[0])
.attr('width', width)
.attr('height', height);
this.floorSensorInfo.forEach((data, index) => {
var lonlat = projection(data.coordinates);
console.log('Longitude Latitude', lonlat);
I can see my data output like [2.0420352248333655, NaN]and not sure what happened exactly.
and moreover if someone can explain following the first link which i realy don't understand it would be really helpful
Exported bounds of raster image
rasterBounds = [[-122.7895, 45.4394], [-122.5015, 45.6039]]
Update:
#Andrew suggested to plot normal co-ordinates because latitude and longitude apply only to world maps. So i had pasted my below working code version now which is plotting the points on the image now.
var svg = d3.select("body")
.append("svg")
.attr("width",960)
.attr("height",500)
// image width and height in pixels, we don't want to skew this or scale this (then image units aren't straight pixels)
var imageWidth = 300;
var imageHeight = 168;
var color_hash = { 0 : ["apple", "green"],
1 : ["mango", "orange"],
2 : ["cherry", "red"]
}
function scale(coords) {
return [coords[0] * imageWidth / 100, coords[1] * imageHeight / 100];
}
svg.append("image")
.attr("width",imageWidth)
.attr("height",imageHeight)
.attr("x", 0) // could be non-zero, but we would have to shift each circle that many pixels.
.attr("y", 0)
.attr("xlink:href", this.floorMaps[0])
var data = this.floorSensorInfo
// var dataNest = d3.nest()
// .key(function (d) { return d['sensor_name']; })
// .entries(data)
data.forEach(function (d, i) {
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) { return (d.value)[0]; })
.attr("cy", function(d) { return (d.value)[1]; })
.attr("r", 5)
.style("fill", function(d) {
var color = color_hash[data.indexOf(d)][1]
return color;
})
svg.append('text')
.attr("x", 20+(i)*100) // space legend
.attr("y", imageHeight+20)
// style the legend
.style("stroke", function () { // Add the colours dynamically
return d['color'] = color_hash[data.indexOf(d)][1];
})
//.attr("dy", ".35em")
.text( d.sensor_name);
//.text("jjjjjjj")
})}

var svg = d3.select("body")
.append("svg")
.attr("width",960)
.attr("height",500)
// image width and height in pixels, we don't want to skew this or scale this (then image units aren't straight pixels)
var imageWidth = 300;
var imageHeight = 168;
var color_hash = { 0 : ["apple", "green"],
1 : ["mango", "orange"],
2 : ["cherry", "red"]
}
function scale(coords) {
return [coords[0] * imageWidth / 100, coords[1] * imageHeight / 100];
}
svg.append("image")
.attr("width",imageWidth)
.attr("height",imageHeight)
.attr("x", 0) // could be non-zero, but we would have to shift each circle that many pixels.
.attr("y", 0)
.attr("xlink:href", this.floorMaps[0])
var data = this.floorSensorInfo
// var dataNest = d3.nest()
// .key(function (d) { return d['sensor_name']; })
// .entries(data)
data.forEach(function (d, i) {
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) { return (d.value)[0]; })
.attr("cy", function(d) { return (d.value)[1]; })
.attr("r", 5)
.style("fill", function(d) {
var color = color_hash[data.indexOf(d)][1]
return color;
})
svg.append('text')
.attr("x", 20+(i)*100) // space legend
.attr("y", imageHeight+20)
// style the legend
.style("stroke", function () { // Add the colours dynamically
return d['color'] = color_hash[data.indexOf(d)][1];
})
//.attr("dy", ".35em")
.text( d.sensor_name);
//.text("jjjjjjj")
})}
javascript d3.js

Related

Adjusting circle size text and svg size

I am a new javascript programmer. I'm trying to adjust the circles' size and svg size given the size of the window. Also, the code now creates circles of different sizes, but haven't been able to simultaneously adjust to the text size.
var width = 600;
var height = 600;
// Place your JSON here.
var data = [
{ CategoryName: 'Adaptive Security', SkillProficiencyId: 1 },
{ CategoryName: 'Programmer', SkillProficiencyId: 2 },
{ CategoryName: 'Coffee Drinker', SkillProficiencyId: 3 }
];
/*
This 'cxBase' will be multiplied by element's index, and sum with offset.
So for 3 elements, cx = 0, 200, 400 ...
All these values changeable by this vars.
*/
const cxBase = 200;
const cxOffset = 100;
console.log(data);
// Make SVG container
var svgContainer = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
// This function will iterate your data
data.map(function(props, index) {
var cx = cxBase * (index) + cxOffset; // Here CX is calculated
var elem = svgContainer.selectAll("div").data(data);
var elemEnter = elem.enter()
.append("g")
var circles = elemEnter.append("circle")
.attr("cx", cx)
.attr("cy", 100)
.attr("r", props.SkillProficiencyId * 20)
.style("fill", "blue");
elemEnter
.append("text")
.style("fill", "white")
.attr("dy", function(d){
return 105;
})
.attr("dx",function(d){
return cx - (props.CategoryName.length * 3.5);
})
.text(function (d) {
return props.CategoryName
});
});
Using .attr("viewBox", "0 0 680 490") doesn't work so far. Just makes all the circles bigger but not in proportion to the window
// Make SVG container
var svgContainer = d3.select("body")
.append("svg")
.attr("viewBox", "0 0 680 490")
.attr("presserveAspectRatio", "xMinYMin meet")
//.attr("height", height)
;
I made five improvements:
Circle's width based on SkillProficiencyId.
Increased the svg width from 600 to 900.
Text will appear always on the middle of the circle: text.style("text-anchor", "middle") did the trick.
Text size proportional to circle size;
A smartest way to calc circle dx (w/o using arbritary offsets);
Codepen: https://codepen.io/mayconmesquita/pen/RwWoZbv
JS Code:
var width = 900;
var height = 400;
// Place your JSON here.
var data = [
{ CategoryName: 'Adaptive Security', SkillProficiencyId: 1 },
{ CategoryName: 'Programmer', SkillProficiencyId: 2 },
{ CategoryName: 'Coffee Lover', SkillProficiencyId: 3 },
{ CategoryName: 'Coffee Roaster', SkillProficiencyId: 4 }
];
function getCircleSize(SkillProficiencyId) {
var minSize = 60;
return minSize + (minSize * (SkillProficiencyId * .2));
}
// Make SVG container
var svgContainer = d3
.select("body")
.classed("svg-container", true)
.append("svg")
.attr("width", width)
.attr("height", height);
// This function will iterate your data
data.map(function(props, index) {
/*
The new CX calc:
('circleSize' * 2) will be multiplied by element's index.
So for 3 elements, cx = 70, 140, 210 ...
All these values changeable by this vars.
*/
var circleSize = getCircleSize(props.SkillProficiencyId);
var cx = (circleSize * 2) * (index); // Here CX is calculated
var elem = svgContainer.selectAll("div").data(data);
var elemEnter = elem
.enter()
.append("g")
.attr("transform", "translate(100, 0)"); // prevent svg crops first circle
var circles = elemEnter
.append("circle")
.attr("cx", cx)
.attr("cy", 160)
.attr("r", circleSize)
.style("fill", "blue");
elemEnter
.append("text")
.style("fill", "white")
.attr("dy", 165)
.attr("dx", cx)
.text(props.CategoryName)
.style("font-size", ((circleSize * .2) + index) + "px")
.style("text-anchor", "middle");
});

Circle packing matrix with consistent scale

I have had mixed results when combining for loops with d3 visuals; in this case it seems to be the most straight-forward solution to have a matrix of circle packs. However, one problem is that if I create the visual this way, the output can be slightly misleading. In the snippet below you will notice that the biggest circle in the third circle pack (152) looks just as big as the biggest circle in the first circle pack (200). So in its current form, the circle packs just reflect the proportions, and the changes in absolute size are not portrayed.
var margins = {top:20, bottom:300, left:30, right:100};
var height = 600;
var width = 1080;
var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;
var svg = d3.select('body')
.append('svg')
.attr('width', totalWidth)
.attr('height', totalHeight);
var graphGroup = svg.append('g')
.attr('transform', "translate("+margins.left+","+margins.top+")");
var data = [
[
{'id':'1Q19'},
{'id':'pooled','parentId':'1Q19','size':29.5},
{'id':'spv','parentId':'1Q19', 'size':11},
{'id':'single','parentId':'1Q19', 'size':200}
],
[
{'id':'2Q19'},
{'id':'pooled','parentId':'2Q19','size':31},
{'id':'spv','parentId':'2Q19', 'size':15},
{'id':'single','parentId':'2Q19', 'size':171}
],
[
{'id':'3Q19'},
{'id':'pooled','parentId':'3Q19','size':28},
{'id':'spv','parentId':'3Q19', 'size':12},
{'id':'single','parentId':'3Q19', 'size':152}
],
[
{'id':'4Q19'},
{'id':'pooled','parentId':'4Q19','size':25},
{'id':'spv','parentId':'4Q19', 'size':214},
{'id':'single','parentId':'4Q19', 'size':101}
],
];
var colorMap = {
'1Q19':"#e7eef8",
'2Q19':"#e7eef8",
'3Q19':"#e7eef8",
'4Q19':"#e7eef8",
'pooled':"#f6d18b",
'spv':"#366092",
'single':"#95b3d7"
};
var strokeMap = {
"pooled":"#000",
"single":"#000",
"spv":"#fff"
};
for (var j=0; j <(data.length); j++) {
var vData = d3.stratify()(data[j]);
var vLayout = d3.pack().size([250, 250]);
var vRoot = d3.hierarchy(vData).sum(function (d) { return d.data.size; });
var vNodes = vRoot.descendants();
vLayout(vRoot);
var thisClass = "circ"+String(j);
var vSlices = graphGroup.selectAll('.'+thisClass).data(vNodes).attr('class',thisClass).enter().append('g');
//console.log(vNodes)
vSlices.append('circle')
.attr('cx', function(d, i) {
return d.x+(j*300)
})
.attr('cy', function (d) { return d.y; })
.attr('r', function (d) { return d.r; })
.style('fill', function(d) { return colorMap[d.data.id]});
vSlices.append('text')
.attr('x', function(d,i) {return d.x+(j*300)})
.attr('y', function(d) {return d.y+5})
.attr('text-anchor','middle')
.style('fill', function(d) {return strokeMap[d.data.id]})
.text(function(d) {return d.data.data.size ? d.data.data.size : null});
}
<script src="https://d3js.org/d3.v5.min.js"></script>
Question
How can I establish a baseline/uniform scale for each of my circle packs in the circle pack matrix? I want the background/overall parent circle to be the same size, but the child circles to factor in absolute values in the packing process.
Note: I'm content with there being more empty space in the circle pack; perhaps in some instances the diameters may not fully span the parent circle. As long as the circles are tangent, the overall aesthetic theme should carry through.
The fact that you're using a loop to create elements in a D3 code is quite problematic, that's true... however, that's not the problem here. Let's see what you said:
I want the background/overall parent circle to be the same size, but the child circles to factor in absolute values in the packing process [...] I'm content with there being more empty space in the circle pack.
Well, unfortunately, that's not how a circle packing works. What you have right now is the correct data visualisation: the leaves would have different sizes, even if they have the same value, depending on the values of the other leaves. A circle packing is a dynamic process/algorithm.
That being said, my suggestion is: leave it as it is (but fix that cumbersome loop).
However, even if I disagree (from a dataviz point) with your request, here is a solution. Set a square root scale:
var radiusScale = d3.scaleSqrt()
.domain([0,250])
.range([0,125]);
And pass the size values to pack.radius:
var vLayout = d3.pack().size([250, 250])
.radius(function(d){
return radiusScale(d.data.data.size)
});
And here is the result:
var margins = {top:20, bottom:300, left:30, right:100};
var height = 600;
var width = 1200;
var totalWidth = width+margins.left+margins.right;
var totalHeight = height+margins.top+margins.bottom;
var svg = d3.select('body')
.append('svg')
.attr('width', totalWidth)
.attr('height', totalHeight);
var graphGroup = svg.append('g')
.attr('transform', "translate("+margins.left+","+margins.top+")");
const radiusScale = d3.scaleSqrt()
.domain([0,250])
.range([0,125]);
var data = [
[
{'id':'1Q19'},
{'id':'pooled','parentId':'1Q19','size':29.5},
{'id':'spv','parentId':'1Q19', 'size':11},
{'id':'single','parentId':'1Q19', 'size':200}
],
[
{'id':'2Q19'},
{'id':'pooled','parentId':'2Q19','size':31},
{'id':'spv','parentId':'2Q19', 'size':15},
{'id':'single','parentId':'2Q19', 'size':171}
],
[
{'id':'3Q19'},
{'id':'pooled','parentId':'3Q19','size':28},
{'id':'spv','parentId':'3Q19', 'size':12},
{'id':'single','parentId':'3Q19', 'size':152}
],
[
{'id':'4Q19'},
{'id':'pooled','parentId':'4Q19','size':25},
{'id':'spv','parentId':'4Q19', 'size':214},
{'id':'single','parentId':'4Q19', 'size':101}
],
];
var colorMap = {
'1Q19':"#e7eef8",
'2Q19':"#e7eef8",
'3Q19':"#e7eef8",
'4Q19':"#e7eef8",
'pooled':"#f6d18b",
'spv':"#366092",
'single':"#95b3d7"
};
var strokeMap = {
"pooled":"#000",
"single":"#000",
"spv":"#fff"
};
for (var j=0; j <(data.length); j++) {
var vData = d3.stratify()(data[j]);
var vLayout = d3.pack().size([250, 250])
.radius(function(d){
return radiusScale(d.data.data.size)
});
var vRoot = d3.hierarchy(vData).sum(function (d) { return d.data.size; });
var vNodes = vRoot.descendants();
vLayout(vRoot);
var thisClass = "circ"+String(j);
var vSlices = graphGroup.selectAll('.'+thisClass).data(vNodes).attr('class',thisClass).enter().append('g');
//console.log(vNodes)
vSlices.append('circle')
.attr('cx', function(d, i) {
return d.x+(j*(j === 3 ? 320 : 310))
})
.attr('cy', function (d) { return d.y; })
.attr('r', function (d) { return d.r; })
.style('fill', function(d) { return colorMap[d.data.id]});
vSlices.append('text')
.attr('x', function(d,i) {return d.x+(j*(j === 3 ? 320 : 310))})
.attr('y', function(d) {return d.y+5})
.attr('text-anchor','middle')
.style('fill', function(d) {return strokeMap[d.data.id]})
.text(function(d) {return d.data.data.size ? d.data.data.size : null});
}
<script src="https://d3js.org/d3.v5.min.js"></script>
Pay attention to the fact that, in the last pack, the overall circle is not the same size (it's bigger). Being the same size is simple impossible, given the packing logic.

Drag Orthographic with circles d3.js

I'm trying to create a globe (Orthographic projection) with a drag, which also has circles on it.
I've been able to create the globe with a drag, and add circles. The problem is that when I drag the circles don't move with the globe.
Here is my bl.ock where you can find my code: http://bl.ocks.org/JulienAssouline/3caf0d6e01aa8220a8d4027cb9158d7e
I've looked at other bl.ock examples such as this one:https://bl.ocks.org/larsvers/f8efeabf480244d59001310f70815b4e
and this one:
https://bl.ocks.org/curran/115407b42ef85b0758595d05c825b346
but I haven't been able to get it to work for me. Their methods seem to be quite different than mine, and I don't completely understand their code.
Would anyone know what method, or what I need to add to my code?
Thanks.
Here is my javascript code:
(function(){
var h = 600;
var w = 900;
var i = 0;
var map = void 0;
var world = void 0;
var US = void 0;
var margin = {
top: 10,
bottom: 40,
left: 0,
right: 30
};
var circleScale = d3.scaleSqrt()
.domain([0, 4445])
.range([0.5, 10])
var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;
var dragging = function(d){
var c = projection.rotate();
projection.rotate([c[0] + d3.event.dx/6, c[1] - d3.event.dy/6])
map.selectAll('path').attr('d', path);
}
var drag = d3.drag()
.on("drag", dragging)
var projection = d3.geoOrthographic().clipAngle(90);
var path = d3.geoPath().projection(projection);
var svg = d3.select("body")
.append("svg")
.attr("id", "chart")
.attr("width", w)
.attr("height", h)
d3.json("world.json", function(json){
d3.csv("arms_transfer_2012_2016_top - arms_transfer_2012_2016_top.csv", function(error, data){
var countries = topojson.feature(json, json.objects.countries).features
var US = countries[168]
map = svg.append('g').attr('class', 'boundary');
world = map.selectAll('path').data(countries);
US = map.selectAll('.US').data([US]);
Circles = map.selectAll(".circles").data(data)
console.log(countries[168])
world.enter()
.append("path")
.attr("class", "boundary")
.attr("d", path)
US.enter()
.append("path")
.attr("class", "US")
.attr("d", path)
.style("fill", "lightyellow")
.style("stroke", "orange")
Circles.enter()
.append("circle")
.attr("class", "importer")
.attr("r", function(d){
return circleScale(d.Millions)
})
.attr("cx", function(d){
var coords = projection([d.Longitude_imp, d.Latitude_imp])
return coords[0];
})
.attr("cy", function(d){
var coords = projection([d.Longitude_imp, d.Latitude_imp])
return coords[1];
})
.style("fill", "#cd0d0e")
svg.append("rect")
.attr("class", "overlay")
.attr("width", w)
.attr("height", h)
.call(drag)
})
})
})();
You have to update the position of the circles in your dragging function:
var dragging = function(d) {
var c = projection.rotate();
projection.rotate([c[0] + d3.event.dx / 6, c[1] - d3.event.dy / 6])
map.selectAll('path').attr('d', path);
map.selectAll(".circles").attr("cx", function(d) {
var coords = projection([d.Longitude_imp, d.Latitude_imp])
return coords[0];
})
.attr("cy", function(d) {
var coords = projection([d.Longitude_imp, d.Latitude_imp])
return coords[1];
})
}
Also, select them using the correct class.
Regarding performance, if you don't want to calculate coords twice, you can use an each:
var dragging = function(d) {
var c = projection.rotate();
projection.rotate([c[0] + d3.event.dx / 6, c[1] - d3.event.dy / 6])
map.selectAll('path').attr('d', path);
map.selectAll(".circles").each(function(d) {
var coords = projection([d.Longitude_imp, d.Latitude_imp])
d3.select(this).attr("cx", function(d) {
return coords[0];
})
.attr("cy", function(d) {
return coords[1];
})
})
}
Here is your bl.ocks with that change: http://bl.ocks.org/anonymous/dc2d4fc810550586d40d4b1ce9088422/40c6e199a5be4e152c0bd94a13ea94eba41f004b
PS: You have a problem with the circles at the far side of the globe... however, this is another issue, already addressed here at S.O. For instance, this answer of mine: https://stackoverflow.com/a/46441983/5768908

concentric emanating circles d3

I have an array of equally spaced values which I am using to draw concentric circles. I want to use an emanating effect, in essence, remove the outermost circle once its value exceeds the maximum value and add a new one at the center to compensate. I am unsure about manipulation on data set to remove and add new circle.
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("body").append("svg");
var w = window.innerWidth;
var h = window.innerHeight;
var separation = Math.min(50, w/12);
var n=Math.floor((w/2)/separation);
var ellipse=new Array(n);
for(var i=1;i<=n;i++){
ellipse[i-1]=(i*separation);
}
svg.attr("width", w).attr("height", h);
var g = svg.append("g");
var e=g.selectAll("ellipse")
.data(ellipse)
.enter()
.append("ellipse")
.attr("cx", w/2)
.attr("cy", h/2)
.attr("rx",0)
.attr("ry",0)
.transition()
.duration(5000)
.attr("rx", function(d,i){return ellipse[i];})
.attr("ry", function(d,i){return ellipse[i]/5;});
loop();
function loop(){
e.transition()
.attr("rx", function(d,i){
return ellipse[i]+separation;
})
.attr("ry", function(d,i){
return (ellipse[i]+separation)/5;
})
.on("end",loop());
}
</script>
You could approach it with a remove().exit() and enter().append() selection for each ring - but essentially you always have the same number of rings on the screen. Why not just recycle the same elements? When the size hits a threshold, reset it to zero, or some other starting value?
Something along the lines of:
var scale = d3.scaleLinear()
.range(["orange","steelblue","purple"])
.domain([0,60]);
var data = [0,10,20,30,40,50,60];
var width = 200;
var height = 200;
var svg = d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height);
var circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("r",function(d) { return d; })
.attr("transform","translate(80,80)")
.attr("fill","none")
.style("stroke-width","4")
.style("stroke",function(d) { return scale(d) });
function transition() {
// Update data, max d is 60:
data = data.map(function(d) { return d == 60 ? 0 : d + 10});
var i = 0;
// Grow circles
circles
.data(data)
.filter(function(d) { return d > 0 })
.transition()
.ease(d3.easeLinear)
.attr("r", function(d) { return d; })
.style("stroke", function(d) { return scale(d) })
.style("opacity",function(d) { return d == 60 ? 0 : 1 })
.duration(1000)
.on("end",function(){if(++i==circles.size()-1) { transition(); } });
// Reset circles where r == 0
circles
.filter(function(d) { return d == 0 })
.attr("r", 0)
.style("opacity",1)
.style("stroke",function(d) { return scale(d); });
}
transition();
<script src="https://d3js.org/d3.v4.min.js"></script>
Note that .on("end",... triggers on each element's transition end - this is why I count to see if all elements are done transitioning before running the transition function again.

arc.centroid returning (NaN, NaN) in D3

Fair warning: I'm a D3 rookie here. I'm building a donut chart using D3 and all is well so far, except that the labels on the slices aren't aligning with the slices. Using the code below, the labels for each slice are rendered in the middle of the chart, stacked on top of each other so they're unreadable. I've dropped the arc.centroid in my transform attribute, but it's returning "NaN,NaN" instead of actual coordinates, and I can't understand where it's reading from that it's not finding a number. My innerRadius and outerRadius are defined in the arc variable. Any help?
(pardon the lack of a jsfiddle but I'm pulling data from a .csv here)
var width = 300,
height = 300,
radius = Math.min(width, height) / 2;
var color = ["#f68b1f", "#39b54a", "#2772b2"];
var pie = d3.layout.pie()
.value(function(d) { return d.taskforce1; })
.sort(null);
var arc = d3.svg.arc()
.innerRadius(radius - 85)
.outerRadius(radius);
var svg = d3.select("#pieplate").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
d3.csv("data.csv", type, function(error, data) {
var path = svg.datum(data).selectAll("path")
.data(pie)
.enter().append("path")
.attr("fill", function(d, i) { return color[i]; })
.attr("d", arc)
.each(function(d) { this._current = d; }); // store the initial angles
var text = svg.selectAll("text")
.data(data)
.enter()
.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.attr("text-anchor", "middle")
.text( function (d) { return d.taskforce1; })
.attr("font-family", "sans-serif")
.attr("font-size", "20px")
.attr("fill", "black");
d3.selectAll("a")
.on("click", switcher);
function switcher() {
var value = this.id;
var j = value + 1;
pie.value(function(d) { return d[value]; }); // change the value function
path = path.data(pie); // compute the new angles
path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs
textLabels = text.text( function (d) { return d[value]; });
}
});
function type(d) {
d.taskforce1 = +d.taskforce1;
d.taskforce2 = +d.taskforce2;
d.taskforce3 = +d.taskforce3;
return d;
}
// Store the displayed angles in _current.
// Then, interpolate from _current to the new angles.
// During the transition, _current is updated in-place by d3.interpolate.
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
return arc(i(t));
};
}
Finally got it. The arc.centroid function expects data with precomputed startAngle and endAngle which is the result of pie(data). So the following helped me:
var text = svg.selectAll("text")
.data(pie(data))
followed by the rest of the calls. Note that you might have to change the way to access the text data that you want to display. You can always check it with
// while adding the text elements
.text(function(d){ console.log(d); return d.data.textAttribute })

Categories