Skip to content

Instantly share code, notes, and snippets.

@i-tu
Last active Dec 9, 2015
Embed
What would you like to do?
Pie chart
var shortData = [{
'Title': 'Kandidaatiksi',
'Value': 18691
}, {
'Title': 'Maisteriksi',
'Value': 9494
}, {
'Title': 'Lisensiaatiksi',
'Value': 235
}, {
'Title': 'Tohtoriksi',
'Value': 4682
}];
function pie(selector, data, titleText) {
var keys = makeKeys(data);
var values = makeValues(data);
var totalValues = sum(values);
var normalizedValues = normalize(values, totalValues);
var color = d3.scale.ordinal()
.range(
d3.range(data.length).map(
d3.scale.linear()
.domain([0, data.length - 1])
.range(["#011828", "#6db8f3"])
.interpolate(d3.interpolateHcl)
)
);
function makeKeys(data) {
var output = [];
return data.map(function(d) {
for (var key in d) {
return String(key) + " " + String(d[key]);
}
});
}
function render() {
var arcTween = function(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function(t) {
return arc(i(t));
};
}
var pie = d3.select(selector);
// Measurements
var width = pie.node().getBoundingClientRect().width;
var pieDiameter = width/3;
var valueTextHeight = width/42;
var titleTextHeight = width/42;
var textSpacing = 1.4 * (valueTextHeight + titleTextHeight);
var topTitleTextHeight = valueTextHeight;
var topTitleHeight = valueTextHeight * 1.2;
var legend_x = pieDiameter/2;
var legendHeight = ((textSpacing * data.length) + topTitleHeight ) * 1.05;
var height = Math.max(pieDiameter, legendHeight);
var top_y = -height/2.25;
// set the thickness of the inner and outer radii
var oRadius = pieDiameter / 2 * 0.9;
var iRadius = pieDiameter / 2 * 0.3;
var duration = 1000;
pie.selectAll('svg').remove()
var svg = pie
.append("svg")
.attr("width", width)
.attr("height", height);
// construct default pie laoyut
var pie = d3.layout.pie().value(function(d) {
return d;
}).sort(null);
// construct arc generator
var arc = d3.svg.arc()
.outerRadius(oRadius)
.innerRadius(iRadius);
// creates the pie chart container
var g = svg.append('g')
.attr('transform', function() {
return 'translate(' + pieDiameter / 2 + ',' + height / 2 + ')';
});
var empty = makeEmpty(data.length);
var path = g.datum(empty)
.selectAll("path")
.data(pie)
.enter()
.append("path")
.attr("class", "piechart")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc)
.each(function(d) {
this._current = d;
})
var text = g.selectAll("text")
.data(data)
.enter();
text.append("text")
.style('font-family', 'sans-serif')
.style('font-weight', 'bold')
.style('font-size', valueTextHeight + 'px')
.attr("x", legend_x)
.attr("y", function(d, i) {
return top_y + (textSpacing * i) + valueTextHeight + topTitleHeight ;
})
.attr("fill", function(d, i) {
return color(i);
})
.text(function(d) {
return d['Value'];
})
.attr("opacity", 0)
.transition()
.duration(function(d, i) {
return duration - (1 - (i+1)/data.length)*duration;
})
.attr("opacity", 1);
text.append("text")
.style('font-family', 'sans-serif')
.style('font-size', titleTextHeight + 'px')
.style('font-weight', 'light')
.attr("x", legend_x)
.attr("y", function(d, i) {
return top_y + (textSpacing * i) + topTitleHeight;
})
.attr("fill", function(d, i) {
return color(i);
})
.text(function(d) {
return d['Title'];
})
.attr("opacity", 0)
.transition()
.duration(function(d, i) {
return duration - (1 - (i+1)/data.length)*duration;
})
.attr("opacity", 1) ;
g.append("text")
.style('font-family', 'sans-serif')
.style('font-size', topTitleTextHeight + 'px')
.style('font-weight', 'bold')
.style('text-decoration', 'underline')
.attr("x", legend_x)
.attr("y", top_y + topTitleHeight - topTitleTextHeight)
.text(totalValues + ' ' + titleText) ;
// add transition to new path
g.datum(normalizedValues).selectAll("path")
.data(pie)
.transition()
.duration(1000)
.attrTween("d", arcTween);
// add any new paths
g.datum(normalizedValues).selectAll("path")
.data(pie)
.enter().append("path")
.attr("class", "piechart")
.attr("fill", function(d, i) {
return color(i);
})
.attr("d", arc)
.each(function(d) {
this._current = d;
});
// remove data not being used
g.datum(normalizedValues).selectAll("path")
.data(pie).exit().remove();
}
function makeEmpty(size) {
return d3.range(size).map(function(item) {
return 0;
});
};
function sum(values) {
return values.reduce(function(prev, curr) {
return prev + curr;
});
}
function makeValues(input) {
return input.map(function(d) {
return d['Value'];
});
};
function makeKeys(input) {
return input.map(function(d) {
return d['Title'];
});
};
function normalize(values, totalSum) {
return values.map(function(d) {
return (d / totalSum) * 100;
});
}
// 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.
render();
d3.select(window).on('resize.' + selector, function() {
render();
console.log("je")
});
}
/* GATTAGA */
var studentData = [{
'Title': 'Kandidaatiksi',
'Value': 18691
}, {
'Title': 'Maisteriksi',
'Value': 9494
}, {
'Title': 'Lisensiaatiksi',
'Value': 235
}, {
'Title': 'Tohtoriksi',
'Value': 4682
}];
var publicationData = [{
'Title': 'Vertaisarvioituja tieteellisiä artikkeleita',
'Value': 6690
}, {
'Title': 'Tieteellisiä kirjoituksia',
'Value': 1369
}, {
'Title': 'Tieteellistä kirjaa',
'Value': 304
}, {
'Title': 'Ammattiyhteisöille suunnattuja julkaisuja',
'Value': 912
}, {
'Title': 'Suurelle yleisölle suunnattuja julkaisuja',
'Value': 1114
}];
var moneyData = [{
'Title': 'Valtion perusrahoitus',
'Value': 439
}, {
'Title': 'Täydentävä rahoitus',
'Value': 257
}, {
'Title': 'Sijoitustoiminta',
'Value': 13
}, {
'Title': 'Helsingin yliopiston rahastot',
'Value': 4
}, {
'Title': 'Varainhankinta',
'Value': 2
}];
var otherEmployeeData = [{
'Title': 'IT-henkilöstö',
'Value': 343
}, {
'Title': 'Kirjastohenkilöstö',
'Value': 316
}, {
'Title': 'Tekninen henkilöstö',
'Value': 400
}, {
'Title': 'Hallintohenkilöstö',
'Value': 1507
}, {
'Title': 'Opetuksen ja tutkimuksen tukihenkilöstö',
'Value': 723
}, {
'Title': 'Muut',
'Value': 225
}];
pie("#yksi", studentData, 'opiskelijaa');
pie("#kaksi", publicationData, 'julkaisua');
pie("#kolme", otherEmployeeData, 'muuta työntekijää');
pie("#nelja", moneyData, 'MEUR rahoitusta');
<!DOCTYPE HTML>
<meta charset="utf-8">
<html>
<body>
<div style="width:100%;height:100px;border-style:dotted;border-color:#CCC;margin-bottom:25px;">
</div>
<div style="width: 100%;">
<div style="width: 50%;margin: 0px auto;border-style:dotted;border-color:#CCC;min-width=180px;">
<div id="yksi"></div>
</div>
</div>
<div style="width: 100%;">
<div style="width: 50%;margin: 0px auto;border-style:dotted;border-color:#CCC;min-width=180px;">
<div id="kaksi"></div>
</div>
</div>
<div style="width: 100%;">
<div style="width: 50%;margin: 0px auto;border-style:dotted;border-color:#CCC;min-width=180px;">
<div id="kolme"></div>
</div>
</div>
<div style="width: 100%;">
<div style="width: 50%;margin: 0px auto;border-style:dotted;border-color:#CCC;min-width=180px;">
<div id="nelja"></div>
</div>
</div>
<div style="width: 100%;">
<div style="width: 50%;margin: 0px auto;border-style:dotted;border-color:#CCC;min-width=180px;">
<div id="viisi"></div>
</div>
</div>
<div style="width: 100%;">
<div style="width: 50%;margin: 0px auto;border-style:dotted;border-color:#CCC;min-width=180px;">
<div id="kuusi"></div>
</div>
</div>
<div style="width: 100%;">
<div style="width: 50%;margin: 0px auto;border-style:dotted;border-color:#CCC;min-width=180px;">
<div id="seitseman"></div>
</div>
</div>
<div style="width:100%;height:100px;border-style:dotted;border-color:#CCC;margin-top:25px;"></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="app.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment