Skip to content

Instantly share code, notes, and snippets.

@meesern
Created December 17, 2012 11:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meesern/4317695 to your computer and use it in GitHub Desktop.
Save meesern/4317695 to your computer and use it in GitHub Desktop.
Line tension experiment
<!DOCTYPE html>
<html>
<head>
<title>Line Chart</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<style type="text/css">
body {
font: 10px sans-serif;
}
path {
fill: url(#grad1);
stroke-width: 1.5px;
}
circle {
fill: #fff;
stroke: #000;
}
</style>
</head>
<body>
<script type="text/javascript">
var slices = 200;
var cycle_time = 10000;
var step = 0;
var data = [{x:64, y:61},{x:109, y:86},{x:133, y:56},{x:183, y:79},{x:174, y:119},
{x:211, y:133},{x:211, y:182},{x:174, y:201},{x:172, y:248},{x:118, y:259},
{x:105, y:245},{x:80, y:264},{x:36, y:238},{x:47, y:202},{x:19, y:189},
{x:20, y:147},{x:46, y:133},{x:37, y:83}];
//Ref: http://bl.ocks.org/1016220
var w = 960,
h = 500,
p = 40,
x = d3.scale.linear().domain([-50, 300]).range([p, w - p]),
y = d3.scale.linear().domain([-50, 300]).range([h - p, p]),
cx = x(140),
cy = y(140);
//return svg path commands for a line based on d3.svg.line
//interpolate cardinal gives cubic spline and requires x and y to be given
var line = d3.svg.line()
.interpolate("cardinal-closed")
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
var vis = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("svg:g");
//make 1 path
//attr 'd' is the path commands, generate them from local fn 'line'
//colour between brown and steel blue
vis.selectAll("path")
.data([0])
.enter().append("svg:path")
.attr("d", function(d) { return line.tension(d)(data); })
.style("stroke", d3.interpolateRgb("brown", "steelblue"));
//Add the point circles at the data
vis.selectAll("circle")
.data(data)
.enter().append("svg:circle")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", 4.5);
setInterval(function () {
step = step + 1;
var arcsin = (step/slices)*(2*Math.PI);
tension = (Math.sin(arcsin)+1)/2;
//attr 'd' is the path commands, generate them from local fn 'line'
//colour between brown and steel blue
vis.selectAll("path")
.data([tension])
.attr("d", function(d) { return line.tension((d*0.6)+0.2)(data); })
.style("stroke", d3.interpolateRgb("brown", "steelblue"))
.attr("transform",function(d){
var scale = 0.8+0.4*(1-d);
//keep the centre point invariant under the scale
var tx = cx*d*0.4 - cx*0.2;
var ty = cy*d*0.4 - cy*0.2;
return "scale("+scale+") translate("+tx+","+ty+")";});
d3.select('#gradstop2')
.data([tension])
.attr("offset", function(d){return 65+((1-d)*20)+"%"});
}, cycle_time/slices);
</script>
<svg>
- <defs>
- <radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
- <stop offset="0%" style="stop-color:#F98DFA;
- stop-opacity:1" />
- <stop offset="75%" id="gradstop2" style="stop-color:#FDF6F0;stop-opacity:0.8" />
- </radialGradient>
- </defs>
- </svg>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Line Chart</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<style type="text/css">
body {
font: 10px sans-serif;
}
.rule line {
stroke: #eee;
shape-rendering: crispEdges;
}
.rule line.axis {
stroke: #000;
}
path {
fill: none;
stroke-width: 1.5px;
}
circle {
fill: #fff;
stroke: #000;
}
</style>
</head>
<body>
<a href="string.html">String Version</a>
<br/>
<a href="closed.html">Closed Version</a>
<script type="text/javascript">
var data = d3.range(10).map(function(i) {
return {x: i / 9, y: (Math.sin(i * 2) + 1) / 2};
});
//Ref: http://bl.ocks.org/1016220
var w = 960,
h = 500,
p = 40,
x = d3.scale.linear().domain([0, 1]).range([p, w - p]),
y = d3.scale.linear().domain([0, 1]).range([h - p, p]);
//return svg path commands for a line based on d3.svg.line
//interpolate cardinal gives cubic spline and requires x and y to be given
var line = d3.svg.line()
.interpolate("cardinal")
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
var vis = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("svg:g");
//Make 10 rules from the data
//Each is an empty g class 'rule' element
var rules = vis.selectAll("g.rule")
.data(x.ticks(10))
.enter().append("svg:g")
.attr("class", "rule");
// For each (10) rule make a horizontal gridline
rules.append("svg:line")
.attr("x1", x)
.attr("x2", x)
.attr("y1", p)
.attr("y2", h - p - 1);
// For each (10) rule make a vertical gridline
// Call it the axis if it has no data
rules.append("svg:line")
.attr("class", function(d) { return d ? null : "axis"; })
.attr("y1", y)
.attr("y2", y)
.attr("x1", p)
.attr("x2", w - p + 1);
//append the x-scale value
rules.append("svg:text")
.attr("x", x)
.attr("y", h - p + 3)
.attr("dy", ".71em")
.attr("text-anchor", "middle")
.text(x.tickFormat(10));
//append the y-scale value
rules.append("svg:text")
.attr("y", y)
.attr("x", p - 3)
.attr("dy", ".35em")
.attr("text-anchor", "end")
.text(y.tickFormat(10));
//make 6 paths
//attr 'd' is the path commands, generate them from local fn 'line'
//colour between brown and steel blue
vis.selectAll("path")
.data([0, 0.2, 0.4, 0.6, 0.8, 1])
.enter().append("svg:path")
.attr("d", function(d) { return line.tension(d)(data); })
.style("stroke", d3.interpolateRgb("brown", "steelblue"));
//Add the point circles at the data
vis.selectAll("circle")
.data(data)
.enter().append("svg:circle")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", 4.5);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>Line Chart</title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<style type="text/css">
body {
font: 10px sans-serif;
}
.rule line {
stroke: #eee;
shape-rendering: crispEdges;
}
.rule line.axis {
stroke: #000;
}
path {
fill: none;
stroke-width: 1.5px;
}
circle {
fill: #fff;
stroke: #000;
}
</style>
</head>
<body>
<script type="text/javascript">
var slices = 200;
var step = 0;
var data = d3.range(10).map(function(i) {
return {x: i / 9, y: (Math.sin(i * 2) + 1) / 2};
});
//Ref: http://bl.ocks.org/1016220
var w = 960,
h = 500,
p = 40,
x = d3.scale.linear().domain([0, 1]).range([p, w - p]),
y = d3.scale.linear().domain([0, 1]).range([h - p, p]);
//return svg path commands for a line based on d3.svg.line
//interpolate cardinal gives cubic spline and requires x and y to be given
var line = d3.svg.line()
.interpolate("cardinal")
.x(function(d) { return x(d.x); })
.y(function(d) { return y(d.y); });
var vis = d3.select("body").append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("svg:g");
//Make 10 rules from the data
//Each is an empty g class 'rule' element
var rules = vis.selectAll("g.rule")
.data(x.ticks(10))
.enter().append("svg:g")
.attr("class", "rule");
// For each (10) rule make a horizontal gridline
rules.append("svg:line")
.attr("x1", x)
.attr("x2", x)
.attr("y1", p)
.attr("y2", h - p - 1);
// For each (10) rule make a vertical gridline
// Call it the axis if it has no data
rules.append("svg:line")
.attr("class", function(d) { return d ? null : "axis"; })
.attr("y1", y)
.attr("y2", y)
.attr("x1", p)
.attr("x2", w - p + 1);
//append the x-scale value
rules.append("svg:text")
.attr("x", x)
.attr("y", h - p + 3)
.attr("dy", ".71em")
.attr("text-anchor", "middle")
.text(x.tickFormat(10));
//append the y-scale value
rules.append("svg:text")
.attr("y", y)
.attr("x", p - 3)
.attr("dy", ".35em")
.attr("text-anchor", "end")
.text(y.tickFormat(10));
//make 1 path
//attr 'd' is the path commands, generate them from local fn 'line'
//colour between brown and steel blue
vis.selectAll("path")
.data([0])
.enter().append("svg:path")
.attr("d", function(d) { return line.tension(d)(data); })
.style("stroke", d3.interpolateRgb("brown", "steelblue"));
//Add the point circles at the data
vis.selectAll("circle")
.data(data)
.enter().append("svg:circle")
.attr("cx", function(d) { return x(d.x); })
.attr("cy", function(d) { return y(d.y); })
.attr("r", 4.5);
setInterval(function () {
step = step + 1;
var arcsin = (step/slices)*(2*Math.PI);
tension = (Math.sin(arcsin)+1)/2;
//attr 'd' is the path commands, generate them from local fn 'line'
//colour between brown and steel blue
vis.selectAll("path")
.data([tension])
.attr("d", function(d) { return line.tension(d)(data); })
.style("stroke", d3.interpolateRgb("brown", "steelblue"));
}, 3000/slices);
</script>
</body>
</html>
@meesern
Copy link
Author

meesern commented Dec 20, 2012

From Mike Bostock's gist:1016220

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment