Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Adaptive Line Chart Scaling

By create large random datasets, we can create charts that adapt and react to any dataset. This bl.ock allows users to generate any desired number of lines and any desired number of points and see the response of the chart change over time.

<!DOCTYPE html>
<meta charset="utf-8">
body {
font: 10px sans-serif;
div {
padding-left: 50px;
padding-top: 15px;
width: 50%;
margin: 0 auto;
font: 14px;
input {
border-top: 0;
border-left: 0;
border-right: 0;
text-align: center;
font: 14px;
width: 60px;
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
.x.axis path {
display: none;
.line {
fill: none;
stroke-width: 1.5px;
Number of Lines:
<input id="linecount" name="lines" value="7" onkeyup="render()"></input>
Points per Line:
<input id="pointcount" name="points" value="3" onkeyup="render()"></input>
<script src=""></script>
var width = 960,
height = 500-37;
var margin = {top: 20, right:20, bottom:20, left:50};
// draw and append the container
var svg ="body").append("svg")
.attr("height", height)
.attr("width", width)
.attr("transform","translate(" + margin.left + "," + margin.right + ")");
var xScale = d3.scale.linear()
.range([0,width - margin.left - margin.right]);
var yScale = d3.scale.linear()
.range([height - - margin.bottom,0]);
var line = d3.svg.line().interpolate("monotone")
.x(function(d){ return xScale(d.x); })
.y(function(d){ return yScale(d.y); });
// create random data
function newData(lineNumber, points){
return d3.range(lineNumber).map(function(){
return d3.range(points).map(function(item,idx){
return {x:idx/(points-1),y:Math.random()*100};
function render(){
// generate new data
var data = newData(+document.getElementById("linecount").value,+document.getElementById("pointcount").value);
// obtain absolute min and max
var yMin = data.reduce(function(pv,cv){
var currentMin = cv.reduce(function(pv,cv){
return Math.min(pv,cv.y);
return Math.min(pv,currentMin);
var yMax = data.reduce(function(pv,cv){
var currentMax = cv.reduce(function(pv,cv){
return Math.max(pv,cv.y);
return Math.max(pv,currentMax);
// set domain for axis
// create axis scale
var yAxis = d3.svg.axis()
// if no axis exists, create one, otherwise update it
if (svg.selectAll(".y.axis")[0].length < 1 ){
.attr("class","y axis")
} else {
// generate line paths
var lines = svg.selectAll(".line").data(data).attr("class","line");
// transition from previous paths to new paths
.style("stroke", function(){
return '#'+Math.floor(Math.random()*16777215).toString(16);
// enter any new data
.style("stroke", function(){
return '#'+Math.floor(Math.random()*16777215).toString(16);
// exit
// initial page render
// continuous page render
setInterval(render, 1500);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment