Created
November 25, 2015 03:39
-
-
Save d3byex/ba05a6b171c6c77f5909 to your computer and use it in GitHub Desktop.
D3byEX 8.7: Focus + Context
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<meta name="description" content="D3byEX 8.7" /> | |
<meta charset="utf-8"> | |
<style> | |
</style> | |
<body> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<script> | |
var width = 960, height = 600; | |
var margins = { top: 10, left: 50, right: 50, bottom: 50, between: 50 }; | |
var bottomGraphHeight = 50; | |
var topGraphHeight = height - (margins.top + margins.bottom + margins.between + bottomGraphHeight); | |
var graphWidths = width - margins.left - margins.right; | |
var svg = d3.select('body') | |
.append('svg') | |
.attr('width', width) | |
.attr('height', height) | |
.style('font', '10px sans-serif'); | |
svg.append('defs') | |
.append('clipPath') | |
.attr('id', 'clip') | |
.append('rect') | |
.attr('width', width) | |
.attr('height', height); | |
var focus = svg | |
.append('g') | |
.attr('transform', 'translate(' + margins.left + ',' + margins.top + ')'); | |
var context = svg.append('g') | |
.attr('class', 'context') | |
.attr('transform', 'translate(' + margins.left + ',' + | |
(margins.top + topGraphHeight + margins.between) + ')'); | |
var xScaleTop = d3.time.scale().range([0, graphWidths]), | |
xScaleBottom = d3.time.scale().range([0, graphWidths]), | |
yScaleTop = d3.scale.linear().range([topGraphHeight, 0]), | |
yScaleBottom = d3.scale.linear().range([bottomGraphHeight, 0]); | |
var xAxisTop = d3.svg.axis().scale(xScaleTop).orient('bottom'), | |
xAxisBottom = d3.svg.axis().scale(xScaleBottom).orient('bottom'); | |
var yAxisTop = d3.svg.axis().scale(yScaleTop).orient('left'); | |
var lineTop = d3.svg.line() | |
.x(function (d) { return xScaleTop(d.date); }) | |
.y(function (d) { return yScaleTop(d.close); }); | |
var lineBottom = d3.svg.line() | |
.x(function (d) { return xScaleBottom(d.date); }) | |
.y(function (d) { return yScaleBottom(d.close); }); | |
var brush = d3.svg.brush() | |
.x(xScaleBottom) | |
.on('brush', function brushed() { | |
xScaleTop.domain(brush.empty() ? xScaleBottom.domain() : brush.extent()); | |
focus.select('.x.axis').call(xAxisTop); | |
}); | |
d3.tsv('https://gist.githubusercontent.com/d3byex/b6b753b6ef178fdb06a2/raw/0c13e82b6b59c3ba195d7f47c33e3fe00cc3f56f/aapl.tsv', function (error, data) { | |
data.forEach(function (d) { | |
d.date = d3.time.format('%d-%b-%y').parse(d.date); | |
d.close = +d.close; | |
}); | |
xScaleTop.domain(d3.extent(data, function (d) { return d.date; })); | |
yScaleTop.domain(d3.extent(data, function (d) { return d.close; })); | |
xScaleBottom.domain(d3.extent(data, function (d) { return d.date; })); | |
yScaleBottom.domain(d3.extent(data, function (d) { return d.close; })); | |
var topXAxisNodes = focus.append('g') | |
.attr('class', 'x axis') | |
.attr('transform', 'translate(' + 0 + ',' + (margins.top + topGraphHeight) + ')') | |
.call(xAxisTop); | |
styleAxisNodes(topXAxisNodes, 0); | |
focus.append('path') | |
.datum(data) | |
.attr('class', 'line') | |
.attr('d', lineTop); | |
var topYAxisNodes = focus.append('g') | |
.call(yAxisTop); | |
styleAxisNodes(topYAxisNodes); | |
context.append('path') | |
.datum(data) | |
.attr('class', 'line') | |
.attr('d', lineBottom); | |
var bottomXAxisNodes = context.append('g') | |
.attr('transform', 'translate(0,' + bottomGraphHeight + ')') | |
.call(xAxisBottom); | |
styleAxisNodes(bottomXAxisNodes, 0); | |
context.append('g') | |
.attr('class', 'x brush') | |
.call(brush) | |
.selectAll('rect') | |
.attr('y', -6) | |
.attr('height', bottomGraphHeight + 7); | |
context.selectAll('.extent') | |
.attr({ | |
stroke: '#000', | |
'fill-opacity': 0.125, | |
'shape-rendering': 'crispEdges' | |
}); | |
styleLines(svg); | |
}); | |
function styleLines(svg) { | |
svg.selectAll('path.line') | |
.attr({ | |
fill: 'none', | |
'stroke-width': 1.5, | |
stroke: 'steelblue', | |
'clip-path': 'url(#clip)' | |
}); | |
} | |
function styleAxisNodes(axisNodes, strokeWidth) { | |
axisNodes.selectAll('.domain') | |
.attr({ | |
fill: 'none', | |
'stroke-width': strokeWidth, | |
stroke: 'black' | |
}); | |
axisNodes.selectAll('.tick line') | |
.attr({ | |
fill: 'none', | |
'stroke-width': 1, | |
stroke: 'black' | |
}); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Adding id to the path makes it more obviuos, but just using the class
.line
can get us there too: