Skip to content

Instantly share code, notes, and snippets.

@A6Brgeuka
Last active February 9, 2017 15:14
Show Gist options
  • Save A6Brgeuka/0260a85cd8e2478d4cbf0ac22712dbb6 to your computer and use it in GitHub Desktop.
Save A6Brgeuka/0260a85cd8e2478d4cbf0ac22712dbb6 to your computer and use it in GitHub Desktop.
mastery over time
license: mit
date score error
2016-12-20 -0.3 0.1
2016-12-21 -0.2 0.2
2016-12-22 0.2 0.3
2016-12-23 0.2 0.4
2016-12-24 0.2 0.5
2016-12-25 0.2 0.1
2016-12-26 0.3 0.2
2016-12-27 0.25 0.3
2016-12-28 0.5 0.4
2016-12-29 0.4 0.5
2016-12-30 0.5 0.1
2016-12-31 0.35 0.2
2017-1-1 0.0 0.3
2017-1-2 0.3 0.4
2017-1-3 -0.2 0.5
2017-1-4 -0.1 0.1
2017-1-5 0.0 0.2
2017-1-6 0.1 0.3
2017-1-7 0.2 0.4
2017-1-8 0.3 0.5
2017-1-9 0.3 0.1
2017-1-10 0.3 0.2
2017-1-11 0.2 0.3
2017-1-12 0.1 0.4
2017-1-13 0.0 0.5
2017-1-14 -0.2 0.1
2017-1-15 -0.3 0.2
2017-1-16 -0.4 0.3
2017-1-17 -0.3 0.4
2017-1-18 0.1 0.5
<html>
<head>
<title>vertical boxplot</title>
<meta charset="utf-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" type="text/JavaScript"></script>
</head>
<style>
svg {
border: 1px solid gray;
background: #3de7b3;
}
line {
shape-rendering: crispEdges;
stroke: #000000;
}
line.minor {
stroke: #777777;
stroke-dasharray: 2,2;
}
path.domain {
fill: none;
stroke: black;
}
</style>
<body>
</body>
<script>
d3.csv("data.csv", boxplot)
function boxplot(data) {
const height = 300;
const width = 900;
const daysLength = 30;
const margin = {
'top': 20,
'bottom': 20,
'left': 20,
'right': 30
}
const xAxisLength = width - margin.left - margin.right;
const yAxisLength = height - margin.top - margin.bottom;
d3.select("body")
.append("svg")
.attr("height", height)
.attr("width", width);
const days = data.map(d => d.date).slice(-daysLength);
const startDay = new Date(days[0]);
const endDay = new Date(days[days.length - 1]);
const maxScoreValue = 2;
const minScoreValue = -2;
const score = [minScoreValue, maxScoreValue];
// --- scales ---
const xScale = d3.time.scale()
.domain([
startDay,
endDay,
])
.range([
0,
xAxisLength
]);
const yScale = d3.scale.linear()
.domain(score) // 0% to 100%
.range([
yAxisLength,
0
]);
// --- axis ---
const xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.tickSize(-5)
.ticks(daysLength)
.tickFormat(d3.time.format(""));
// .tickValues(days);
const yAxis = d3.svg.axis()
.scale(yScale)
.orient("right")
.ticks(18)
.tickSize(-10)
// .tickSubdivide(true); // deprecated, I know
// --- render axis ---
const xAxisTransform = `translate(${margin.left},${height/2})`;
d3.select("svg").append("g")
.attr("transform", xAxisTransform)
.attr("id", "xAxisG")
.call(xAxis);
const yAxisTransform = `translate(${width-margin.left},${margin.top})`;
d3.select("svg").append("g")
.attr("transform", yAxisTransform)
.attr("id", "yAxisG")
// .call(yAxis);
// --- set x y for data ---
const dataCoords = data.map(d => {
d.x = xScale(new Date(d.date));
d.y = yScale(d.score);
return d;
});
// console.log(dataCoords, 'dataCoords');
// --- render shapes ---
d3.select("svg").selectAll("g.box")
.data(dataCoords)
.enter()
.append("g")
.attr("class", "box")
.attr("transform", function(d){
return `translate(${(margin.left)},${(margin.top)})`;
})
.each(function(d,i){
const xLineCoord = (xScale(new Date(d.date)));
const lineWidth = 6;
if (i === dataCoords.length - 1) {
d3.select(this)
.append("line")
.attr("class", "max")
.attr("x1", (xLineCoord - lineWidth/2) + 15)
.attr("x2", (xLineCoord + lineWidth/2) + 15)
.attr("y1", yScale(maxScoreValue))
.attr("y2", yScale(maxScoreValue))
.style("stroke", "#ffffff")
.style("stroke-width", "1px");
d3.select(this)
.append("line")
.attr("class", "median")
.attr("x1", (xLineCoord - lineWidth/2) + 15)
.attr("x2", (xLineCoord + lineWidth/2) + 15)
.attr("y1", yScale(0))
.attr("y2", yScale(0))
.style("stroke", "#ffffff")
.style("stroke-width", "1px");
d3.select(this)
.append("line")
.attr("class", "min")
.attr("x1", (xLineCoord - lineWidth/2) + 15)
.attr("x2", (xLineCoord + lineWidth/2) + 15)
.attr("y1", yScale(minScoreValue))
.attr("y2", yScale(minScoreValue))
.style("stroke", "#ffffff")
.style("stroke-width", "1px");
}
d3.select(this)
.append("line")
.attr("class", "max")
.attr("x1", (xLineCoord - lineWidth/2) - 15)
.attr("x2", (xLineCoord + lineWidth/2) - 15)
.attr("y1", yScale(maxScoreValue))
.attr("y2", yScale(maxScoreValue))
.style("stroke", "#ffffff")
.style("stroke-width", "1px");
d3.select(this)
.append("line")
.attr("class", "median")
.attr("x1", (xLineCoord - lineWidth/2) - 15)
.attr("x2", (xLineCoord + lineWidth/2) - 15)
.attr("y1", yScale(0))
.attr("y2", yScale(0))
.style("stroke", "#ffffff")
.style("stroke-width", "1px");
d3.select(this)
.append("line")
.attr("class", "min")
.attr("x1", (xLineCoord - lineWidth/2) - 15)
.attr("x2", (xLineCoord + lineWidth/2) - 15)
.attr("y1", yScale(minScoreValue))
.attr("y2", yScale(minScoreValue))
.style("stroke", "#ffffff")
.style("stroke-width", "1px");
d3.select(this)
.append("line")
.attr("class", "max")
.attr("x1", xLineCoord - lineWidth/2)
.attr("x2", xLineCoord + lineWidth/2)
.attr("y1", yScale(maxScoreValue))
.attr("y2", yScale(maxScoreValue))
.style("stroke", "#ffffff")
.style("stroke-width", "1px");
d3.select(this)
.append("line")
.attr("class", "median")
.attr("x1", xLineCoord - lineWidth/2)
.attr("x2", xLineCoord + lineWidth/2)
.attr("y1", yScale(0))
.attr("y2", yScale(0))
.style("stroke", "#ffffff")
.style("stroke-width", "1px");
d3.select(this)
.append("line")
.attr("class", "min")
.attr("x1", xLineCoord - lineWidth/2)
.attr("x2", xLineCoord + lineWidth/2)
.attr("y1", yScale(minScoreValue))
.attr("y2", yScale(minScoreValue))
.style("stroke", "#ffffff")
.style("stroke-width", "1px");
const widthRect = 6;
const heightRect = yScale(+d.score - +d.error) - yScale(+d.score + +d.error)
d3.select(this)
.append("rect")
.attr("class", "range")
.attr("width", widthRect)
.attr("x", (xScale(new Date(d.date))) - widthRect/2)
.attr("y", yScale(+d.score + +d.error))
.attr('rx', 4)
.attr('ry', 4)
.attr("height", heightRect)
.style("fill", "#76eeca");
const radius = 3;
d3.select(this)
.append("circle")
.attr("cx", (xScale(new Date(d.date))))
.attr("cy", yScale(d.score))
.attr("r", radius)
.style("fill", "white")
.style("stroke-width", "1px");
})
}
</script>
</footer>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment