Created
June 14, 2013 18:39
-
-
Save kyleslattery/5784217 to your computer and use it in GitHub Desktop.
Resizable, zoomable D3 line chart
This file contains 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
var padding = 0; | |
var data, xScale, yScale, line, area; | |
var prevChartWidth = 0, prevChartHeight = 0; | |
var data = [ | |
[],[] | |
] | |
for (var y = 0; y<data.length; y++) { | |
var prev = 5; | |
if (y==1) prev=2; | |
for (var i=0; i < 100; i+=1) { | |
prev = prev + Math.floor(Math.random()*3)-1; | |
if (prev < 0) prev = 0; | |
data[y].push([i, prev]); | |
} | |
} | |
var svg = d3.select("#chart") | |
.append("svg") | |
// Set up data | |
var yExtents = d3.extent(d3.merge(data), function(d) { return d[1]; }); | |
var xExtents = d3.extent(d3.merge(data), function(d) { return d[0] }); | |
xScale = d3.scale.linear().domain(xExtents) | |
yScale = d3.scale.linear().domain([0,yExtents[1]]) | |
line = d3.svg.line() | |
.x(function(d) { return xScale(d[0]); }) | |
.y(function(d) { return yScale(d[1]); }) | |
.interpolate('basis'); | |
area = d3.svg.area() | |
.x(function(d) { return xScale(d[0]) }) | |
.y(function(d) { return yScale(d[1]) }) | |
.interpolate("basis") | |
$(function() {updateChart(true)}); | |
function updateChart(init) { | |
var $chart = $('#chart'); | |
var chartWidth = $('#chart').width(); | |
var chartHeight = $('#chart').height(); | |
// if (prevChartHeight == chartHeight && prevChartWidth == chartWidth) return; | |
prevChartHeight = chartHeight; | |
prevChartWidth = chartWidth; | |
svg.attr('height', chartHeight).attr('width', chartWidth); | |
xScale.range([0, chartWidth]); | |
yScale.range([chartHeight,0]); | |
area.y0(chartHeight); | |
var pathContainers = svg.selectAll('g.line') | |
.data(data) | |
.enter() | |
.append('g').attr('class', 'line'); | |
var areas = pathContainers.selectAll('path.area') | |
.data(function(d) {return[d]}, function(d) {return d[0]}) | |
.enter().append('path') | |
.attr('class', 'area') | |
.attr('d', area) | |
var lines = pathContainers.selectAll('path.line') | |
.data(function(d,index) { | |
return [d]; | |
}, function(d) { return d[0]}) | |
.enter().append('path') | |
.attr('class', 'line') | |
.attr('d', line) | |
var selectedLines = svg.selectAll('path.line') | |
var selectedAreas = svg.selectAll('path.area') | |
selectedLines.transition().duration(300).attr("d", line) | |
selectedAreas.transition().duration(300).attr("d", area) | |
} | |
function updatedData() { | |
var yExtents = d3.extent(d3.merge(data), function(d) { return d[1]; }); | |
var xExtents = d3.extent(d3.merge(data), function(d) { return d[0]; }); | |
oldXScale = xScale.copy(); | |
oldYScale = yScale.copy(); | |
var selectedLines = svg.selectAll('path.line') | |
var selectedAreas = svg.selectAll('path.area') | |
svg.selectAll('g.line').data(data) | |
selectedLines.attr("d", line) | |
selectedAreas.attr("d", area) | |
xScale.domain(xExtents); | |
console.log(yExtents); | |
yScale.domain([0, yExtents[1]]) | |
selectedLines.transition().duration(300).attr("d", line) | |
selectedAreas.transition().duration(300).attr("d", area) | |
// updateChart(false) | |
} | |
function zoomIn() { | |
var dataLength = data[0].length; | |
var dataLengthBy3 = Math.floor(dataLength/3) | |
for (var i = 0; i<data.length; i++) { | |
data[i] = data[i].slice(dataLengthBy3, dataLengthBy3*2) | |
} | |
updatedData() | |
} | |
function zoomOut() { | |
for (var i = 0; i<data.length; i++) { | |
var dataEnd = data[i][data[i].length-1] | |
var dataStart = data[i][0] | |
var prevEnd = dataEnd[1]; | |
var prevStart = dataStart[1]; | |
for (var j=1; j<25; j++) { | |
prevEnd = prevEnd + Math.floor(Math.random()*3)-1; | |
prevStart = prevStart + Math.floor(Math.random()*3)-1; | |
if (prevEnd < 0) prevEnd = 0; | |
if (prevStart < 0) prevStart = 0; | |
data[i].push([dataEnd[0]+j, prevEnd]) | |
data[i].unshift([dataStart[0]-j, prevStart]) | |
} | |
} | |
updatedData(); | |
} | |
var resizeTimer; | |
window.onresize = function(event) { | |
clearTimeout(resizeTimer); | |
resizeTimer = setTimeout(function() | |
{ | |
updateChart(false); | |
}, 20); | |
} | |
$(function() { | |
$("#zoom_out").click(function() { | |
zoomOut(); | |
}) | |
$("#zoom_in").click(function() { | |
zoomIn(); | |
}) | |
}) |
This file contains 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> | |
<head> | |
<link rel="stylesheet" type="text/css" href="style.css"> | |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
</head> | |
<body> | |
<div id="chart"></div> | |
<p style="text-align: center"><button id="zoom_out">Zoom Out</button> <button id="zoom_in">Zoom In</button></p> | |
<script src="graph.js"></script> | |
</body> | |
</html> |
This file contains 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
body { | |
padding: 0; | |
margin: 0; | |
} | |
#chart { | |
width: 100%; | |
height: 400px; | |
margin: auto; | |
background-color: #ddd; | |
} | |
g.line path.line { | |
fill: none; | |
stroke: #666; | |
stroke-width: 2px; | |
} | |
.area { | |
fill: rgba(0,0, 135, 0.5); | |
stroke-width: 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment