Skip to content

Instantly share code, notes, and snippets.

@kevinschaul
Last active December 19, 2015 10:29
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save kevinschaul/5940459 to your computer and use it in GitHub Desktop.
Naively show undefined regions in d3 charts (1)
<!DOCTYPE html>
<style>
text {
font-family: Arial, sans-serif;
font-size: 11px;
stroke: none;
fill: #999;
}
.axis {
stroke: none;
fill: none;
}
.tick {
stroke: #999;
shape-rendering: crispEdges;
}
.line {
fill: none;
stroke: #333;
stroke-width: 3px;
}
.area {
fill: #FFB871;
stroke: none;
}
.line-undefined {
stroke-dasharray: 3px 3px;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script>
var width = 300;
var height = 300;
var margin = {
top: 10,
right: 10,
bottom: 20,
left: 40
};
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var chart = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var yearFormat = d3.format("");
var findCriticalPairs = function(data) {
// Store property `critical` on points before and after a series of points.
var inUndefinedSeries = false;
var criticalValues = [];
var criticalPairs = [];
_.each(data, function(e, i) {
if (!e.wineries) {
// If this is the first item in an undefined series, add the previous
// item to the critical values array.
if (!inUndefinedSeries) {
inUndefinedSeries = true;
data[i - 1].critical = true;
criticalValues.push(data[i - 1]);
}
} else if (inUndefinedSeries) {
// When we reach the end of an undefined series, add the current item
// to the critical values array.
inUndefinedSeries = false;
data[i].critical = true;
criticalValues.push(data[i]);
}
// Coerce numbers
e.year = +e.year;
e.wineries = +e.wineries;
});
// These pairs will be used to generate sections of undefined values
for (var i = 0; i < criticalValues.length; i++) {
if (criticalValues[i].critical && i % 2 === 0) {
criticalPairs.push([criticalValues[i], criticalValues[i + 1]]);
}
}
return criticalPairs;
};
d3.csv("wineries.csv", function(err, rows) {
var x = d3.scale.linear()
.domain([1938, 2013])
.range([0, width]);
var y = d3.scale.linear()
.domain([0, 300])
.range([height, 0]);
var xAxis = d3.svg.axis()
.orient("bottom")
.ticks(5)
.tickFormat(d3.round)
.scale(x);
var yAxis = d3.svg.axis()
.orient("left")
.scale(y);
var line = d3.svg.line()
.defined(function(d) { return d.wineries; })
.x(function(d) { return x(+d.year); })
.y(function(d) { return y(+d.wineries); });
var area = d3.svg.area()
.defined(function(d) { return d.wineries; })
.x(function(d) { return x(+d.year); })
.y0(function(d) { return y(+d.wineries); })
.y1(height);
var lineUndefined = d3.svg.line()
.defined(function(d) { return d.critical; })
.x(function(d) { return x(+d.year); })
.y(function(d) { return y(+d.wineries); });
var areaUndefined = d3.svg.area()
.defined(function(d) { return d.critical; })
.x(function(d) { return x(+d.year); })
.y0(function(d) { return y(+d.wineries); })
.y1(height);
chart.append("g")
.attr("class", "axis xAxis")
.attr("transform", "translate(0, " + height + ")")
.call(xAxis);
chart.append("g")
.attr("class", "axis yAxis")
.call(yAxis);
chart.append("path")
.attr("class", "area")
.attr("d", area(rows));
chart.append("path")
.attr("class", "line")
.attr("d", line(rows));
var criticalPairs = findCriticalPairs(rows);
_.each(criticalPairs, function(e) {
chart.append("path")
.attr("class", "area area-undefined")
.attr("d", areaUndefined(e));
chart.append("path")
.attr("class", "line line-undefined")
.attr("d", lineUndefined(e));
});
});
</script>
</body>
</html>
year wineries
1938 9
1943 9
1948 9
1953 8
1958 8
1963
1968
1973
1978 8
1983 23
1988 39
1993
1998
2003 98
2008 184
2013 275
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment