Skip to content

Instantly share code, notes, and snippets.

Last active December 21, 2017 21:09
Show Gist options
  • Save MNoichl/b07c2bc1a5a6367fb0ee3f4aa314346f to your computer and use it in GitHub Desktop.
Save MNoichl/b07c2bc1a5a6367fb0ee3f4aa314346f to your computer and use it in GitHub Desktop.
Philosophers use of modifiers
license: mit

Bar chart of the percentage of modifiers (adverbs and adjectives) in the major works of some selected Philosophers. The texts are taken from Project Gutenbergs<a href=> Philosophy-Page. As most of the texts are translations, it is pretty clear, that the worth of this exercise is limited. But it is still neat that my hypothesis of Nietzsche using the most modifiers seems to show.

forked from parnelandr's block: Reusable Horizontal Bar Chart

Philosophers use of modifiers (adjectives and adverbs)
Source: Maximilian Noichl
Metadata Notes:Philosophers use
Philosopher Percentage in selected oeuvre
Plato 5.3443561151
Aristotle 6.4093806922
Kant 7.4490549355
Russel 6.9229031272
Hume 6.2810492151
Berkely 6.2088989255
Descartes 5.748049564
Nietzsche 7.9100242174
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8">
<script src=""></script>
<link href="|Alegreya+SC|Alegreya+Sans|Alegreya+Sans+SC|Cormorant+Garamond|Cormorant+SC:300,400,500,600,700|EB+Garamond|Fanwood+Text:400,400i|Goudy+Bookletter+1911|IM+Fell+Double+Pica+SC|IM+Fell+French+Canon+SC|IM+Fell+French+Canon:400,400i|IM+Fell+Great+Primer+SC|IM+Fell+Great+Primer:400,400i|Spectral+SC:200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i|Vollkorn+SC:400,600,700,900&amp;subset=latin-ext" rel="stylesheet">
rect {
opacity: 1;
h1 {
font-family: Alegreya SC, serif;
text {
margin-top: 40pt;
text-align: left;
font-family: 'Alegreya SC', serif;
font-size: 12pt;
font-weight: 300;
<script type="text/javascript">
//set up canvas and bar sizes
var canvasWidth = 900,
canvasHeight = 500,
otherMargins = canvasWidth * 0.1,
leftMargin = canvasWidth * 0.25,
maxBarWidth = canvasHeight - - otherMargins - leftMargin
maxChartHeight = canvasHeight - (otherMargins * 2);
//set up linear scale for data to fit on chart area
var xScale = d3.scale.linear()
.range([0, maxBarWidth]);
//set up ordinal scale for x variables
var yScale = d3.scale.ordinal();
//add canvas to HTML
var chart ="body").append("svg")
.attr("height", canvasHeight);
//set up x axis
var xAxis = d3.svg.axis()
//set up y axis
var yAxis = d3.svg.axis()
//add in data
//csv has 4 lines before the data to be graphed
//First line - Title of the chart
//Second line - Source of the data
//Third line - Metadata notes
//Fourth line - blank
//Fifth line - x variable name, y variable name
//Sixth line onwards - x variable value, y variable value
d3.xhr("food.csv").get(function (error, response) {
//retrieve data
var dirtyCSV = response.responseText;
var cleanCSV = dirtyCSV.split('\n').slice(4).join('\n');
var data = d3.csv.parse(cleanCSV)
//retrieve title
var dirtyTitle = dirtyCSV.split('\n').slice(0,1).join('\n');
var title = dirtyTitle.slice(0,-1);
//get variable names
var keys = d3.keys(data[0]);
var namesTitle = keys[0];
var valuesTitle = keys[1];
//accessing the properties of each object with the variable name through its key
var values = function(d) {return +d[valuesTitle];};
var names = function(d) {return d[namesTitle];}
// find highest value
var maxValue = d3.max(data, values);
//set y domain by mapping an array of the variables along x axis
//set x domain with max value and use .nice() to ensure the y axis is labelled above the max y value
xScale.domain([0, maxValue]).nice();
//set bar width with rangeBands ([x axis width], gap between bars, gap before and after bars) as a proportion of bar width
yScale.rangeBands([0, maxChartHeight], 0.1, 0.25);
//set up rectangle elements with attributes based on data
var rects = chart.selectAll("rect")
//set up attributes of svg rectangle elements based on attributes
var rectAttributes = rects
.attr("x", leftMargin)
.attr("y", function (d) {return yScale(d[namesTitle]) + otherMargins; })
.attr("width", function (d) {return xScale(d[valuesTitle])})
.attr("height", yScale.rangeBand())
.attr("fill", "#5E412F")
.on("mouseover", function(d, i) {
//change fill
.attr("fill", "#F07818");
//set up data to show on mouseover
var xPosition = (parseFloat("width")) + leftMargin + 6);
var yPosition = parseFloat("y")) + (parseFloat("height")) / 2);
.attr("id", "tooltip")
.attr("x", xPosition)
.attr("y", yPosition)
.attr("dy", "0.35em")
.attr("text-anchor", "start")
.attr("font-family", "sans-serif")
.attr("font-size", "12px")
.attr("font-weight", "bold")
.attr("fill", "black")
//transition out
.on("mouseout", function(d) {
.attr("fill", "#5E412F");"#tooltip").remove();
//chart title
.attr("x", canvasWidth / 2)
.attr("y", otherMargins / 2)
.attr("dy", "0.35em")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "20px")
.attr("font-weight", "bold")
.attr("fill", "black")
//append x axis
.attr("transform", "translate(" + leftMargin + ", " + (maxChartHeight + otherMargins) + ")")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.style("stroke", "black")
.style("fill", "none")
.style("stroke-width", 1)
.style("shape-rendering", "crispEdges")
.attr("stroke", "none")
.attr("fill", "black");
//append y axis
.attr("transform", "translate(" + leftMargin + ", " + otherMargins + ")")
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "10px")
.style("stroke", "black")
.style("fill", "none")
.style("stroke-width", 1)
.style("shape-rendering", "crispEdges")
.attr("dx", "-1.15em")
.attr("stroke", "none")
.attr("fill", "black")
//.call(yScale.rangeBand()); //calls wrap function below
//x axis title
.attr("x", (maxBarWidth / 2) + leftMargin)
.attr("y", canvasHeight - (otherMargins / 3))
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "14px")
.attr("font-weight", "bold")
.attr("fill", "black")
//y axis title
.attr("transform", "rotate(-90)")
.attr("x", -((maxChartHeight / 2) + otherMargins))
.attr("y", leftMargin / 4)
.attr("text-anchor", "middle")
.attr("font-family", "sans-serif")
.attr("font-size", "14px")
.attr("font-weight", "bold")
.attr("fill", "black")
//chart border - not necessary used for reference for the edge of canvas
var border = chart.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("height", canvasHeight)
.attr("width", canvasWidth)
.style("stroke", "black")
.style("fill", "none")
.style("stroke-width", 0);
//log anything in the console for debugging
//line wrap function adapted from "Wrapping Long Labels" - mike bostock
function wrap(text, width) {
text.each(function() {
var text =,
words = text.text().split(/\s+/).reverse(),
line = [],
lineNumber = 0,
lineHeight = 1.1, //em
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
//while the data is being loaded it turns the strings into a number
function type(d) {
d[yName] = +d[yName];
return d;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment