Skip to content

Instantly share code, notes, and snippets.

@tomshanley
Last active January 22, 2020 23:18
Show Gist options
  • Save tomshanley/0cbafe00f59f4dca046082f2196eb412 to your computer and use it in GitHub Desktop.
Save tomshanley/0cbafe00f59f4dca046082f2196eb412 to your computer and use it in GitHub Desktop.
Animate line and points
license: mit
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<style>
path {
stroke-width: 2px;
fill: none;
}
</style>
</head>
<body>
<p>Click the chart to start the animation.</p>
<div id="line"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script type="text/javascript">
console.clear()
var w = 700;
var h = 300;
var m = 40;
var max = 10
var svg = d3.select("#line")
.append("svg")
.attr("width", w + m + m)
.attr("height", h + m + m)
var chart = svg.append("g")
.attr("transform", "translate(" + m + "," + m + ")")
var data = d3.range(max+1)
.map(function(){
return Math.random() * max
})
var x = d3.scaleLinear()
.domain([0, max])
.range([0, w]);
var y = d3.scaleLinear()
.domain([0, max])
.range([h, 0]);
var line = d3.line()
.x(function(d,i) {return x(i);})
.y(function(d) {return y(d);})
.curve(d3.curveCardinal)
var clipPath = chart.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("id", "clip-rect")
.attr("width", 0)
.attr("height", h)
var bkdPath = chart.append("path")
.attr("d", line(data))
.style("stroke", "lightgrey")
var path = chart.append("path")
.attr("d", line(data))
.style("stroke", "orange")
.attr("clip-path", "url(#clip)")
var bkdCircle = chart.selectAll(".bkd-circle")
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i){
return "translate(" + x(i) + "," + y(d) + ")"
})
.attr("class", "bkd-circle")
.append("circle")
.attr("r", 5)
.style("stroke", "lightgrey")
.style("fill", "white")
var dataPoint = chart.selectAll('.data-point')
.data(data)
.enter()
.append("g")
.attr("transform", function(d, i){
return "translate(" + x(i) + "," + y(d) + ")"
})
.attr("class", "data-point")
.attr("id", (d, i) => "data-point-" + i)
.style("opacity", 0)
dataPoint.append("circle")
.attr("r", 5)
dataPoint.append("text")
.text((d, i) => i + ", " + round2dp(d) )
.attr("dy", 18)
let pointArray = []
let sampleRate = 10
let sampleWidth = w / sampleRate
let currentLength = 0
let node = path.node()
let pathLength = node.getTotalLength()
for (var i = 0; i<sampleRate; i++) {
console.log(i * sampleWidth)
for (var j = 0; j<1000; j++){
let point = node.getPointAtLength(currentLength + j)
console.log(point)
if (point.x >= (sampleWidth * i)) {
console.log("here")
pointArray.push(point)
currentLength = point.x
break
}
}
}
chart.selectAll(".markers")
.data(pointArray)
.enter()
.append("circle")
.attr("cx", d => d.x)
.attr("cy", d => d.y)
.attr("r", 5)
.style("fill", "red")
console.log(pointArray)
let head = chart.append("circle")
.datum(pointArray)
.attr("cx", d => d[0].x)
.attr("cy", d => d[0].y)
.attr("r", 5)
.style("fill", "green")
.attr("id", "head")
/*
var show = false
svg.on("click", function(){
head.transition()
.duration(10000)
.ease(d3.easeLinear)
.tween("attr.cx", function() {
return function(t) {
}
})
d3.select('#clip-rect')
.transition()
.duration(10000)
.ease(d3.easeLinear)
.attr("width", function(d){
let n = w
if (show) {
show = false
n = 0
} else {
show = true
}
return n
})
.tween("attr.fill", function() {
return function(t) {
let kx = show ?
Math.floor(t * max) :
Math.ceil((1-t) * max)
let id = "#data-point-" + kx
d3.selectAll(".data-point")
.style("opacity", 0)
d3.select(id)
.style("opacity", 1)
};
});
})
*/
function round2dp(n) {
return Number.parseFloat(n).toFixed(2);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment