im new to d3. I found the script below (from http://bl.ocks.org/dbuezas) that will generate a random values on the chart when you press the button, my problem is instead of random, i want to put my own values on the chart. Please help.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
svg {
width: 100%;
height: 100%;
}
path.slice{
stroke-width:2px;
}
polyline{
opacity: .3;
stroke: black;
stroke-width: 2px;
fill: none;
}
</style>
<body>
<button class="randomize">randomize</button>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var svg = d3.select("body")
.append("svg")
.append("g")
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
var width = 960,
height = 450,
radius = Math.min(width, height) / 2;
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.svg.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.4);
var outerArc = d3.svg.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var key = function(d){ return d.data.label; };
var color = d3.scale.ordinal()
.domain(["Lorem ipsum", "dolor sit", "amet", "consectetur", "adipisicing", "elit", "sed", "do", "eiusmod", "tempor", "incididunt"])
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
function randomData (){
var labels = color.domain();
return labels.map(function(label){
return { label: label, value: Math.random() }
});
}
change(randomData());
d3.select(".randomize")
.on("click", function(){
change(randomData());
});
function change(data) {
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice.enter()
.insert("path")
.style("fill", function(d) { return color(d.data.label); })
.attr("class", "slice");
slice
.transition().duration(1000)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.label;
});
function midAngle(d){
return d.startAngle + (d.endAngle - d.startAngle)/2;
}
text.transition().duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate("+ pos +")";
};
})
.styleTween("text-anchor", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start":"end";
};
});
text.exit()
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pie(data), key);
polyline.enter()
.append("polyline");
polyline.transition().duration(1000)
.attrTween("points", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyline.exit()
.remove();
};
</script>
</body>
I tried doing this code below, but it doenst work.
function randomData (){
var labels = color.domain();
return labels.map(function(label){
return { label: "testlabel1",value: "41"
},
{ label: "testlabel2", value: "27"
},
{ label: "testlabel3", value: "101"
},
{ label: "testlabel4", value: "79"
}
});
}
You can try this code, it works, but it hasnt the array of data, so it runs only one time and becomes static.
function randomData (){
return [{ label: 'one', value: 10 },
{ label: 'two', value: 20 },
{ label: 'three', value: 30 },
{ label: 'four', value: 35 },
{ label: 'five', value: 5 }
];}
Here randomData () gives back the array like [object Object], I am doing the similar donut, will send you the final variant later.
You can paste JSON ARRAY in function label or make ajax call for remote data
function randomData (){
var labels = color.domain();
return labels.map(function(label){
return { /* YOUR JSON ARRAY */ }
});
}
Related
I am trying to draw the label line the outer most point of the circle like this picture.
var svg = d3.select("body")
.append("svg")
.append("g")
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
var width = 960,
height = 450,
radius = Math.min(width, height) / 2;
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.svg.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.4);
var outerArc = d3.svg.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var key = function(d) {
return d.data.label;
};
var color = d3.scale.ordinal()
.domain(["53% KILLED 2791", "dolor sit", "amet", "consectetur", "adipisicing", "elit", "sed", "do", "eiusmod", "tempor", "incididunt"])
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
function randomData() {
var labels = color.domain();
return labels.map(function(label) {
return {
label: label,
value: Math.random()
}
});
}
change(randomData());
d3.select(".randomize")
.on("click", function() {
change(randomData());
});
function change(data) {
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice.enter()
.insert("path")
.style("fill", function(d) {
return color(d.data.label);
})
.attr("class", "slice");
slice
.transition().duration(1000)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.label;
});
function midAngle(d) {
return d.startAngle + (d.endAngle - d.startAngle) / 2;
}
text.transition().duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate(" + pos + ")";
};
})
.styleTween("text-anchor", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start" : "end";
};
});
text.exit()
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pie(data), key);
polyline.enter()
.append("polyline");
polyline.transition().duration(1000)
.attrTween("points", function(d){
this._current = this._current || d;
console.log('_current = ' + JSON.stringify(this._current));
console.log('d = ' + JSON.stringify(d));
var interpolate = d3.interpolate(this._current, d);
console.log('interpolate = ' + JSON.stringify(interpolate(0)));
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
console.log('t = ' + JSON.stringify(t));
console.log('d2 = ' + JSON.stringify(d2));
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyline.exit()
.remove();
};
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
svg {
width: 100%;
height: 100%;
}
path.slice {
stroke-width: 2px;
}
polyline {
opacity: .3;
stroke: black;
stroke-width: 2px;
fill: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<button class="randomize">randomize</button>
I am new to D3 and not too sure how to calculate the points to achieve this. I tried looking up formulas what calculating circles but wasn't sure which formula is best for this situation.
Any help is greatly appreciated.
Based on your code, you can see that the lines connecting the arc segments to the text is drawn by this code (near the end of your snippet):
return [arc.centroid(d2), outerArc.centroid(d2), pos];
It basically draws:
from the center of the segment, arc.centroid(d2) (which is drawn between the 0.4 to 0.8 of the radius)
makes a stop at the virtual outer arc, outerArc.centroid(d2) (which is drawn at 0.9) of the radius: this is where the line bends
and finally ends at pos where the text label is anchored at
So, if you want it to start outside the main pie chart, simply supply a new arc to the first argument. Let's give that arc a radius of 0.82, for example:
var polylineStartArc = d3.svg.arc()
.innerRadius(radius * 0.82)
.outerRadius(radius * 0.82);
And then you ammend your polyline drawing logic with this:
return [polylineStartArc.centroid(d2), outerArc.centroid(d2), pos];
Of course, you can adjust this value between the range of 0.8 and 0.9:
you want to keep it >0.8 so that it does not intersect with the pie chart
you want to keep it <0.9 so that it does not go further out than the "bend" in the line
See proof-of-concept below:
var svg = d3.select("body")
.append("svg")
.append("g")
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
var width = 960,
height = 450,
radius = Math.min(width, height) / 2;
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.svg.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.4);
var outerArc = d3.svg.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
var polylineStartArc = d3.svg.arc()
.innerRadius(radius * 0.82)
.outerRadius(radius * 0.82);
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var key = function(d) {
return d.data.label;
};
var color = d3.scale.ordinal()
.domain(["53% KILLED 2791", "dolor sit", "amet", "consectetur", "adipisicing", "elit", "sed", "do", "eiusmod", "tempor", "incididunt"])
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
function randomData() {
var labels = color.domain();
return labels.map(function(label) {
return {
label: label,
value: Math.random()
}
});
}
change(randomData());
d3.select(".randomize")
.on("click", function() {
change(randomData());
});
function change(data) {
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice.enter()
.insert("path")
.style("fill", function(d) {
return color(d.data.label);
})
.attr("class", "slice");
slice
.transition().duration(1000)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.label;
});
function midAngle(d) {
return d.startAngle + (d.endAngle - d.startAngle) / 2;
}
text.transition().duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate(" + pos + ")";
};
})
.styleTween("text-anchor", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start" : "end";
};
});
text.exit()
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pie(data), key);
polyline.enter()
.append("polyline");
polyline.transition().duration(1000)
.attrTween("points", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [polylineStartArc.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyline.exit()
.remove();
};
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
svg {
width: 100%;
height: 100%;
}
path.slice {
stroke-width: 2px;
}
polyline {
opacity: .3;
stroke: black;
stroke-width: 2px;
fill: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<button class="randomize">randomize</button>
I am trying to change the following example i started out with to edit the lines such that they
start 5px outside the center of the slice
have a 4px circle around
The design is as follows. The main part im struggling with initially is changing the starting point. I think the circle will be easy if i can figure that out.
Any suggestions how to achieve this?
var svg = d3.select("body")
.append("svg")
.append("g")
var isDount = false;
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
var width = 200,
height = 200,
radius = Math.min(width, height) / 2,
transitionSpeed = 600;
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.arc()
.outerRadius(radius * 0.8)
.innerRadius(isDount ? radius * 0.4 : 0);
var outerArc = d3.arc()
.innerRadius(radius * 0.9)
.outerRadius(isDount ? radius * 0.9 : 0);
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var key = function(d) {
return d.data.label;
};
var color = d3.scaleOrdinal()
.domain(["Lorem ipsum", "dolor sit", "amet", "consectetur"]) //, "adipisicing", "elit", "sed", "do", "eiusmod", "tempor", "incididunt"
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
function randomData() {
var labels = color.domain();
return labels.map(function(label) {
return {
label: label,
value: Math.random()
}
});
}
change(randomData());
d3.select(".randomize")
.on("click", function() {
change(randomData());
});
function change(data) {
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice.enter()
.insert("path")
.style("fill", function(d) {
return color(d.data.label);
})
.attr("class", "slice")
.merge(slice)
.transition().duration(transitionSpeed)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
function midAngle(d) {
return d.startAngle + (d.endAngle - d.startAngle) / 2;
}
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
console.log(d3.format('.3f')(d.data.value))
var showValue = true;
return showValue ? d3.format('.3f')(d.data.value) : d.data.label;
})
.merge(text)
.transition().duration(transitionSpeed)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate(" + pos + ")";
};
})
.styleTween("text-anchor", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start" : "end";
};
});
text.exit()
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pie(data), key);
polyline.enter()
.append("polyline")
.merge(polyline)
.transition().duration(transitionSpeed)
.attrTween("points", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyline.exit()
.remove();
};
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
svg {
width: 100%;
height: 100%;
}
path.slice {
stroke-width: 2px;
}
polyline {
opacity: .3;
stroke: black;
stroke-width: 1px;
fill: none;
}
.labels text {
font-size: 12px;
}
<button class="randomize">c</button>
<script src="http://d3js.org/d3.v4.min.js"></script>
You could make a new arc variable and change the innerradius to a higher value. for example
var arc2 = d3.arc()
.outerRadius(radius * 0.8 -10)
.innerRadius(isDount ? radius * 0.4 : 0);
and reference it in the attrTween & mess around with the values
return [arc2.centroid(d2), outerArc.centroid(d2), pos];
I also added the circles the way you wanted:
var circles = svg.selectAll(".circles")
.data(pie(data));
circles = circles.enter()
.append("circle")
.attr("class","circles")
.attr("r",3)
.attr("fill","#999")
.merge(circles)
circles.transition().duration(transitionSpeed)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * .95 * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate("+ circlesArc.centroid(d2) +")";
};
})
circles.exit().remove();
Here's a fork:
var svg = d3.select("body")
.append("svg")
.append("g")
var isDount = false;
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
var width = 200,
height = 200,
radius = Math.min(width, height) / 2,
transitionSpeed = 600,
outerRadius = height / 2 - 20;
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.arc()
.outerRadius(radius * 0.8 -10)
.innerRadius(isDount ? radius * 0.4 : 0);
var arc2 = d3.arc()
.outerRadius(radius * 0.8 -10)
.innerRadius(radius * 0.9)
var outerArc = d3.arc()
.innerRadius(radius * .99)
.outerRadius(radius * .99);
var circlesArc = d3.arc()
.innerRadius(radius * 0.8)
.outerRadius(radius * 0.8);
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var key = function(d) {
return d.data.label;
};
var color = d3.scaleOrdinal()
.domain(["Lorem ipsum", "dolor sit", "amet", "consectetur"]) //, "adipisicing", "elit", "sed", "do", "eiusmod", "tempor", "incididunt"
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
function randomData() {
var labels = color.domain();
return labels.map(function(label) {
return {
label: label,
value: Math.random()
}
});
}
change(randomData());
d3.select(".randomize")
.on("click", function() {
change(randomData());
});
function change(data) {
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice.enter()
.insert("path")
.style("fill", function(d) {
return color(d.data.label);
})
.attr("class", "slice")
.merge(slice)
.transition().duration(transitionSpeed)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
function midAngle(d) {
return d.startAngle + (d.endAngle - d.startAngle) / 2;
}
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
console.log(d3.format('.3f')(d.data.value))
var showValue = true;
return showValue ? d3.format('.3f')(d.data.value) : d.data.label;
})
.merge(text)
.transition().duration(transitionSpeed)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate(" + pos + ")";
};
})
.styleTween("text-anchor", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start" : "end";
};
});
text.exit()
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pie(data), key);
polyline.enter()
.append("polyline")
.merge(polyline)
.transition().duration(transitionSpeed)
.attrTween("points", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc2.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyline.exit()
.remove();
var circles = svg.selectAll(".circles")
.data(pie(data));
circles = circles.enter()
.append("circle")
.attr("class","circles")
.attr("r",3)
.attr("fill","#999")
.merge(circles)
circles.transition().duration(transitionSpeed)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * .95 * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate("+ circlesArc.centroid(d2) +")";
};
})
circles.exit().remove();
};
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
svg {
width: 100%;
height: 100%;
}
path.slice {
stroke-width: 2px;
}
polyline {
opacity: .3;
stroke: black;
stroke-width: 1px;
fill: none;
}
.labels text {
font-size: 12px;
}
<button class="randomize">c</button>
<script src="https://d3js.org/d3.v4.min.js"></script>
I'm working on graphics and I met some difficulties on charts. I want to draw a pie chart (or donut) and to display labels in two lines or more in order to get the more space for the graph.
Here is my code
var dataGroupPotential = [];
var pieGroup;
var svg;
processData("pieGPChart");
function processData(chartDivId) {
$("#pieGPLegend").text("Title : myTitle");
//Construction du tableau data
dataGroupPotential.push({
label: "long text 1 : 100 000 000",
value: 100000000
});
dataGroupPotential.push({
label: "long text 2 : 200 000 000",
value: 200000000
});
dataGroupPotential.push({
label: "long text 3 : 300 000 000",
value: 300000000
});
var width = $("#" + chartDivId).width();
var dividor = 2.75;
var height = width / dividor;
//Ajout des éléments svg pour tracer le graphique
svg = d3.select("#" + chartDivId).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(" + width / 2 + "," + height / 2 + ")");;
svg.append("g").attr("class", "slices");
svg.append("g").attr("class", "labels");
svg.append("g").attr("class", "lines");
$("#" + chartDivId).height(height);
drawMyPie(svg, dataGroupPotential, width, height);
window.addEventListener('resize', function(event) {
// do stuff here
var chartDivId = "pieGPChart";
var width = $("#" + chartDivId).width();
var dividor = 2.75;
var height = width / dividor;
$("#" + chartDivId).height(height);
drawMyPie(svg, dataGroupPotential, width, height);
});
}
function drawMyPie(svg, data, width, height) {
var radius = Math.min(width, height) / 2;
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.4);
var outerArc = d3.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
//svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var key = function(d) {
return d.data.label;
};
var color = d3.scaleOrdinal(d3.schemeCategory20);
change(data);
function mergeWithFirstEqualZero(first, second) {
var secondSet = d3.set();
second.forEach(function(d) {
secondSet.add(d.label);
});
var onlyFirst = first
.filter(function(d) {
return !secondSet.has(d.label)
})
.map(function(d) {
return {
label: d.label,
value: 0
};
});
return d3.merge([second, onlyFirst])
.sort(function(a, b) {
return d3.ascending(a.label, b.label);
});
}
function change(data) {
var duration = 3000;
var data0 = svg.select(".slices").selectAll("path.slice")
.data().map(function(d) {
return d.data
});
if (data0.length == 0) data0 = data;
var was = mergeWithFirstEqualZero(data, data0);
var is = mergeWithFirstEqualZero(data0, data);
/* ------- SLICE ARCS -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(was), key);
slice.enter()
.insert("path")
.attr("class", "slice")
.style("fill", function(d) {
return color(d.data.label);
})
.each(function(d) {
this._current = d;
});
slice = svg.select(".slices").selectAll("path.slice")
.data(pie(is), key);
slice
.transition().duration(duration)
.attrTween("d", function(d) {
var interpolate = d3.interpolate(this._current, d);
var _this = this;
return function(t) {
_this._current = interpolate(t);
return arc(_this._current);
};
});
slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice
.exit().transition().delay(duration).duration(0)
.remove();
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(was), key);
text.enter()
.append("text")
.attr("dy", ".35em")
.style("opacity", 0)
.text(function(d) {
return d.data.label;
})
.each(function(d) {
this._current = d;
});
//var legend = text.enter();
//text.append("text")
// .attr("dy", "-10")
// .style("opacity", 0)
// .text(function (d) {
// return d.data.label;
// })
//.each(function (d) {
// this._current = d;
//});
//text.append("text")
// .attr("dy", "10")
// .style("opacity", 0)
// .text(function (d) {
// return d.data.label;
// })
//.each(function (d) {
// this._current = d;
//});
function midAngle(d) {
return d.startAngle + (d.endAngle - d.startAngle) / 2;
}
text = svg.select(".labels").selectAll("text")
.data(pie(is), key);
text.transition().duration(duration)
.style("opacity", function(d) {
return d.data.value == 0 ? 0 : 1;
})
.attrTween("transform", function(d) {
var interpolate = d3.interpolate(this._current, d);
var _this = this;
return function(t) {
var d2 = interpolate(t);
_this._current = d2;
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate(" + pos + ")";
};
})
.styleTween("text-anchor", function(d) {
var interpolate = d3.interpolate(this._current, d);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start" : "end";
};
});
text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
text
.exit().transition().delay(duration)
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pie(was), key);
polyline.enter()
.append("polyline")
.style("opacity", 0)
.each(function(d) {
this._current = d;
});
polyline = svg.select(".lines").selectAll("polyline")
.data(pie(is), key);
polyline.transition().duration(duration)
.style("opacity", function(d) {
return d.data.value == 0 ? 0 : .5;
})
.attrTween("points", function(d) {
this._current = this._current;
var interpolate = d3.interpolate(this._current, d);
var _this = this;
return function(t) {
var d2 = interpolate(t);
_this._current = d2;
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyline = svg.select(".lines").selectAll("polyline")
.data(pie(data), key);
polyline
.exit().transition().delay(duration)
.remove();
};
}
svg {
width: 100%;
height: 100%;
}
path.slice {
stroke-width: 2px;
}
polyline {
opacity: .3;
stroke: black;
stroke-width: 2px;
fill: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.js"></script>
<div class="panel panel-default">
<div class="panel-body">
<div style="text-align:center;" class="row">
<h4 id="pieGPLegend"></h4>
<div id="pieGPChart"></div>
</div>
</div>
</div>
For the label, I would like to have something like that
long text 1
100 000 000
I already try some stuff, but didn't work. Here is what I try but I'm still confusing with d3js
var legend = text.enter();
text.append("text")
.attr("dy", "-10")
.style("opacity", 0)
.text(function (d) {
return d.data.label;
})
.each(function (d) {
this._current = d;
});
text.append("text")
.attr("dy", "10")
.style("opacity", 0)
.text(function (d) {
return d.data.label;
})
.each(function (d) {
this._current = d;
});
any help, advice, comment is welcome ! thank you
Damien
If you want to always break your text after the colon, the easiest approach is using a <tspan>:
.append("tspan")
.attr("x", 0)
.attr("dy", "1.3em")
.text(function(d) {
return d.data.label.split(":")[1];
})
Here is your code with that change:
var dataGroupPotential = [];
var pieGroup;
var svg;
processData("pieGPChart");
function processData(chartDivId) {
$("#pieGPLegend").text("Title : myTitle");
//Construction du tableau data
dataGroupPotential.push({
label: "long text 1 : 100 000 000",
value: 100000000
});
dataGroupPotential.push({
label: "long text 2 : 200 000 000",
value: 200000000
});
dataGroupPotential.push({
label: "long text 3 : 300 000 000",
value: 300000000
});
var width = $("#" + chartDivId).width();
var dividor = 2.75;
var height = width / dividor;
//Ajout des éléments svg pour tracer le graphique
svg = d3.select("#" + chartDivId).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(" + width / 2 + "," + height / 2 + ")");;
svg.append("g").attr("class", "slices");
svg.append("g").attr("class", "labels");
svg.append("g").attr("class", "lines");
$("#" + chartDivId).height(height);
drawMyPie(svg, dataGroupPotential, width, height);
window.addEventListener('resize', function(event) {
// do stuff here
var chartDivId = "pieGPChart";
var width = $("#" + chartDivId).width();
var dividor = 2.75;
var height = width / dividor;
$("#" + chartDivId).height(height);
drawMyPie(svg, dataGroupPotential, width, height);
});
}
function drawMyPie(svg, data, width, height) {
var radius = Math.min(width, height) / 2;
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.4);
var outerArc = d3.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
//svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var key = function(d) {
return d.data.label;
};
var color = d3.scaleOrdinal(d3.schemeCategory20);
change(data);
function mergeWithFirstEqualZero(first, second) {
var secondSet = d3.set();
second.forEach(function(d) {
secondSet.add(d.label);
});
var onlyFirst = first
.filter(function(d) {
return !secondSet.has(d.label)
})
.map(function(d) {
return {
label: d.label,
value: 0
};
});
return d3.merge([second, onlyFirst])
.sort(function(a, b) {
return d3.ascending(a.label, b.label);
});
}
function change(data) {
var duration = 3000;
var data0 = svg.select(".slices").selectAll("path.slice")
.data().map(function(d) {
return d.data
});
if (data0.length == 0) data0 = data;
var was = mergeWithFirstEqualZero(data, data0);
var is = mergeWithFirstEqualZero(data0, data);
/* ------- SLICE ARCS -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(was), key);
slice.enter()
.insert("path")
.attr("class", "slice")
.style("fill", function(d) {
return color(d.data.label);
})
.each(function(d) {
this._current = d;
});
slice = svg.select(".slices").selectAll("path.slice")
.data(pie(is), key);
slice
.transition().duration(duration)
.attrTween("d", function(d) {
var interpolate = d3.interpolate(this._current, d);
var _this = this;
return function(t) {
_this._current = interpolate(t);
return arc(_this._current);
};
});
slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice
.exit().transition().delay(duration).duration(0)
.remove();
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(was), key);
text.enter()
.append("text")
.attr("dy", ".35em")
.style("opacity", 0)
.text(function(d) {
return d.data.label.split(":")[0] + ":";
})
.each(function(d) {
this._current = d;
})
.append("tspan")
.attr("x", 0)
.attr("dy", "1.3em")
.text(function(d) {
return d.data.label.split(":")[1];
})
.each(function(d) {
this._current = d;
});
//var legend = text.enter();
//text.append("text")
// .attr("dy", "-10")
// .style("opacity", 0)
// .text(function (d) {
// return d.data.label;
// })
//.each(function (d) {
// this._current = d;
//});
//text.append("text")
// .attr("dy", "10")
// .style("opacity", 0)
// .text(function (d) {
// return d.data.label;
// })
//.each(function (d) {
// this._current = d;
//});
function midAngle(d) {
return d.startAngle + (d.endAngle - d.startAngle) / 2;
}
text = svg.select(".labels").selectAll("text")
.data(pie(is), key);
text.transition().duration(duration)
.style("opacity", function(d) {
return d.data.value == 0 ? 0 : 1;
})
.attrTween("transform", function(d) {
var interpolate = d3.interpolate(this._current, d);
var _this = this;
return function(t) {
var d2 = interpolate(t);
_this._current = d2;
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate(" + pos + ")";
};
})
.styleTween("text-anchor", function(d) {
var interpolate = d3.interpolate(this._current, d);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start" : "end";
};
});
text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
text
.exit().transition().delay(duration)
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pie(was), key);
polyline.enter()
.append("polyline")
.style("opacity", 0)
.each(function(d) {
this._current = d;
});
polyline = svg.select(".lines").selectAll("polyline")
.data(pie(is), key);
polyline.transition().duration(duration)
.style("opacity", function(d) {
return d.data.value == 0 ? 0 : .5;
})
.attrTween("points", function(d) {
this._current = this._current;
var interpolate = d3.interpolate(this._current, d);
var _this = this;
return function(t) {
var d2 = interpolate(t);
_this._current = d2;
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyline = svg.select(".lines").selectAll("polyline")
.data(pie(data), key);
polyline
.exit().transition().delay(duration)
.remove();
};
}
svg {
width: 100%;
height: 100%;
}
path.slice {
stroke-width: 2px;
}
polyline {
opacity: .3;
stroke: black;
stroke-width: 2px;
fill: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.js"></script>
<div class="panel panel-default">
<div class="panel-body">
<div style="text-align:center;" class="row">
<h4 id="pieGPLegend"></h4>
<div id="pieGPChart"></div>
</div>
</div>
</div>
I have been working from this D3 block http://bl.ocks.org/dbuezas/9306799.
I have the code pretty much the way I want it. Except the chart only animates when part of the data set is shared. If the the dataset contains no labels in common, the graph is simply swapped out. How do I make it do a growing arc transition from the beginning so the user always knows when new data is presented? I am taking this snippet out of an angular directive so it might not stand quite on its own, fyi.
var padding = 0;
var height = 350;
var width = 450;
var svg = d3.select("body")
.append("svg")
.attr('viewBox','0 0 '+ width +' '+ height)
.attr('preserveAspectRatio','xMinYMin')
.append("g")
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
var radius = Math.min(width, height) / 2;
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.svg.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.6);
var outerArc = d3.svg.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
svg.attr("transform", "translate(" + width / 2 + "," + element.parent().height() / 2 + ")");
var key = function(d){ return d.data.label; };
var color = d3.scale.category20b();
var dataset = [
{
label: "SUPPLY",
percentage: "22",
value: 10621
},
{
label: "FROZEN",
percentage: "22",
value: 17621
}
];
render(dataset);
function render(data) {
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice.enter()
.insert("path")
.style("fill", function(d) { return color(d.data.label); })
.attr("class", "slice");
slice
.transition().duration(1000)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
/* ------- TOOLTIP -----------*/
var tooltip = d3.select(element.parent()[0])
.append('div')
.attr('class', 'donut-tip bodhi-tooltip');
tooltip.append('div')
.attr('class', 'bodhi-tooltip-text');
slice.on('mouseover', function(d) {
tooltip.select('.bodhi-tooltip-text').html(d.data.label + '</br>' + d.data[scope.tooltipKeyOne] + "%" + '</br>' + "$" + (d.data.total / 100).toFixed(2));
tooltip.style('display', 'table');
});
slice.on('mouseout', function(d) {
tooltip.style('display', 'none');
});
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.label;
});
function midAngle(d){
return d.startAngle + (d.endAngle - d.startAngle)/2;
}
text.transition().duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
return "translate("+ pos +")";
};
})
.styleTween("text-anchor", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start":"end";
};
});
text.exit()
.remove();
};
The heart of the problem is there's no starting point for entering slices to tween from. That said, I'd really simplify the tween code a bit:
slice.enter()
.insert("path")
.style("fill", function(d) {
return color(d.data.label);
})
.attr("class", "slice")
.each(function(d){
this._current = { //<-- give the entering slices a starting point
startAngle: d.startAngle, //<-- have them "grow" from nothing
endAngle: d.startAngle
};
});
slice
.transition().duration(1000)
.attrTween("d", function(d) {
var endAt = { //<-- have the arc end where it's supposed to
startAngle: d.startAngle,
endAngle: d.endAngle
};
var interpolate = d3.interpolate(this._current, endAt);
this._current = endAt; //<-- store this for next cycle
return function(t) {
return arc(interpolate(t));
};
})
Full working code:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3#3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
<script>
var padding = 0;
var height = 350;
var width = 450;
var svg = d3.select("body")
.append("svg")
.attr('viewBox', '0 0 ' + width + ' ' + height)
.attr('preserveAspectRatio', 'xMinYMin')
.append("g")
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
var radius = Math.min(width, height) / 2;
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.svg.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.6);
var outerArc = d3.svg.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var key = function(d) {
return d.data.label;
};
var color = d3.scale.category20b();
update();
setInterval(update, 2000);
function update() {
var someData = [];
for (var i = 0; i < Math.random() * 10; i++){
someData.push({
label: "Slice " + i,
percentage: "22",
value: Math.random()
});
}
render(someData);
}
function render(data) {
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice.enter()
.insert("path")
.style("fill", function(d) {
return color(d.data.label);
})
.attr("class", "slice")
.each(function(d){
this._current = {
startAngle: d.startAngle,
endAngle: d.startAngle
};
});
slice
.transition().duration(1000)
.attrTween("d", function(d) {
var endAt = {
startAngle: d.startAngle,
endAngle: d.endAngle
};
var interpolate = d3.interpolate(this._current, endAt);
this._current = endAt;
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.label;
});
function midAngle(d) {
return d.startAngle + (d.endAngle - d.startAngle) / 2;
}
text.transition().duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
return "translate(" + pos + ")";
};
})
.styleTween("text-anchor", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start" : "end";
};
});
text.exit()
.remove();
};
</script>
</body>
</html>
I'm new to D3 and i'm trying to use a d3 chart for some visualizations, but i can't seem to figure out how to add data to this specific graphic:
http://bl.ocks.org/dbuezas/9306799
I tried to use:
d3.csv("data.csv", type, function(error, data) {
if (error) throw error; });
but i can't seem to find how to use it with the current setup.
I would appreciate if someone could point me in the right direction.
code:
<script>
var svg = d3.select("body")
.append("svg")
.append("g")
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
var width = 960,
height = 450,
radius = Math.min(width, height) / 2;
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var arc = d3.svg.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.4);
var outerArc = d3.svg.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var key = function(d){ return d.data.label; };
var color = d3.scale.ordinal()
.domain(["Lorem ipsum", "dolor sit", "amet", "consectetur", "adipisicing", "elit", "sed", "do", "eiusmod", "tempor", "incididunt"])
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
function randomData (){
var labels = color.domain();
return labels.map(function(label){
return { label: label, value: Math.random() }
});
}
change(randomData());
d3.select(".randomize")
.on("click", function(){
change(randomData());
});
function change(data) {
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pie(data), key);
slice.enter()
.insert("path")
.style("fill", function(d) { return color(d.data.label); })
.attr("class", "slice");
slice
.transition().duration(1000)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
/* ------- TEXT LABELS -------*/
var text = svg.select(".labels").selectAll("text")
.data(pie(data), key);
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.label;
});
function midAngle(d){
return d.startAngle + (d.endAngle - d.startAngle)/2;
}
text.transition().duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate("+ pos +")";
};
})
.styleTween("text-anchor", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start":"end";
};
});
text.exit()
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pie(data), key);
polyline.enter()
.append("polyline");
polyline.transition().duration(1000)
.attrTween("points", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyline.exit()
.remove();
};
</script>
Working code here.
First you need to make a json file with some data example below:
[{
"label": "Lorem ipsum",
"value": 0.719082972034812
}, {
"label": "dolor sit",
"value": 0.03566315700300038
}, {
"label": "amet",
"value": 0.14385902439244092
}, {
"label": "consectetur",
"value": 0.5280405324883759
}, {
"label": "adipisicing",
"value": 0.42760335514321923
}, {
"label": "elit",
"value": 0.7200075597502291
}, {
"label": "sed",
"value": 0.7396465912461281
}, {
"label": "do",
"value": 0.8943409691564739
}, {
"label": "eiusmod",
"value": 0.02541762450709939
}, {
"label": "tempor",
"value": 0.31414360040798783
}, {
"label": "incididunt",
"value": 0.8193990120198578
}]
Refer my plunk data.json
Then in the script load the json like this
d3.json("data.json", function(json) {
change(json);//pass the loaded the json to change function for drawing.
});
I also had the same problem, but in my case, I am coming from a ruby application. Data is loaded off the database and I can't really have a json file to be loaded in JavaScript.
I slightly modified #dbuezas examples only to have a reusable function. I am setting up the svg object and calling change inside.
I'm in a ERB views, and I have my data in ruby instance variables.
<script>
var colors = d3.scale.ordinal()
.domain(<%= #pie_categories.inspect.html_safe %>)
.range(<%= #pie_colors.inspect.html_safe %>);
var chart_data = <%= #pie_chart_data.to_json.html_safe %>;
var width = 450, height = 350;
create_pie_chart_at('#categories_pie_chart',
colors, chart_data, width, height);
</script>