|
<!DOCTYPE html> |
|
<html lang='en'> |
|
<head> |
|
<meta charset='utf-8'> |
|
<title> |
|
Line Markers in D3 |
|
</title> |
|
<script src='http://d3js.org/d3.v3.min.js' charset='utf-8'></script> |
|
<style type='text/css'> |
|
svg { |
|
display: block; |
|
margin: 0 auto; |
|
} |
|
.axis path, .axis line { |
|
fill: none; |
|
stroke: #594E4D; |
|
shape-rendering: crispEdges; |
|
} |
|
.axis text { |
|
fill: #594E4D; |
|
font-family: sans-serif; |
|
font-size: 14px; |
|
font-weight: bold; |
|
} |
|
#lineGraph { |
|
stroke: rgba(0,0,0,0); |
|
stroke-width: 2; |
|
fill: none; |
|
marker-start: url(#circle); |
|
marker-mid: url(#circle); |
|
marker-end: url(#circle); |
|
} |
|
.circleMarker { |
|
stroke: none; |
|
opacity: 0.5; |
|
fill: #BF6989; |
|
} |
|
.transient { |
|
fill: #D9C7C7; |
|
stroke: #97A676; |
|
stroke-width: 5px; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
<script type='text/javascript'> |
|
var margin = {top: 20, right: 15, bottom: 20, left: 40}; |
|
var width = 555 - margin.left - margin.right; |
|
var height = 440 - margin.top - margin.bottom; |
|
var random = d3.random.normal(5, 2); |
|
var data = []; |
|
for (var i = 0; i < Math.floor(Math.random() * 101); i++) { |
|
data.push(random()); |
|
} |
|
|
|
function circles() { |
|
var svg = d3.select('body') |
|
.append('svg') |
|
.attr({ |
|
'width': width + margin.left + margin.right, |
|
'height': height + margin.top + margin.bottom |
|
}) |
|
.append('g') |
|
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); |
|
svg.append('clipPath') |
|
.attr('id', 'activeGraphArea') |
|
.append('rect') |
|
.attr({ |
|
width: width, |
|
height: height, |
|
x: 0, |
|
y: 0 |
|
}); |
|
svg.append('rect') |
|
.attr({ |
|
width: width, |
|
height: height, |
|
x: 0, |
|
y: 0, |
|
fill: '#F8F8F8' |
|
}); |
|
var xScale = d3.scale.linear().domain([0, data.length]).range([0, width]); |
|
var xAxis = d3.svg.axis().scale(xScale).orient('bottom'); |
|
svg.append('g') |
|
.attr({ |
|
'class': 'x axis', |
|
'transform': 'translate(0,' + height + ')' |
|
}) |
|
.call(xAxis); |
|
var yScale = d3.scale.linear().domain([0, d3.max(data)]).range([height, 0]); |
|
var yAxis = d3.svg.axis().scale(yScale).orient('left'); |
|
svg.append('g') |
|
.attr({ |
|
'class': 'y axis' |
|
}) |
|
.call(yAxis); |
|
|
|
svg.selectAll('circle') |
|
.data(data) |
|
.enter() |
|
.append('circle') |
|
.attr({ |
|
cx: function(d, i) { return xScale(i); }, |
|
cy: function(d) { return yScale(d); }, |
|
r: 5, |
|
'class': 'circleMarker', |
|
'clip-path': 'url(#activeGraphArea)' |
|
}); |
|
|
|
return function() { |
|
xScale.domain([0, data.length]); |
|
yScale.domain([0, d3.max(data)]); |
|
xAxis.scale(xScale); |
|
yAxis.scale(yScale); |
|
svg.select('.x.axis').transition().call(xAxis); |
|
svg.select('.y.axis').transition().call(yAxis); |
|
var latest = data[data.length -1]; |
|
var circles = svg.selectAll('circle.circleMarker') |
|
.data(data); |
|
|
|
circles.transition() |
|
.attr({ |
|
cx: function(d, i) { return xScale(i); }, |
|
cy: function(d) { return yScale(d); }, |
|
r: 5, |
|
'class': 'circleMarker', |
|
'clip-path': 'url(#activeGraphArea)' |
|
}); |
|
|
|
circles.enter() |
|
.append('circle') |
|
.attr({ |
|
cx: function(d, i) { return xScale(i); }, |
|
cy: function(d) { return yScale(d); }, |
|
r: 5, |
|
'class': 'circleMarker', |
|
'clip-path': 'url(#activeGraphArea)' |
|
}); |
|
svg.append('circle') |
|
.attr({ |
|
cx: xScale(data.length - 1), |
|
cy: yScale(latest), |
|
r: 15, |
|
'class': 'transient' |
|
}) |
|
.transition() |
|
.duration(1000) |
|
.attr('r', 0) |
|
.remove(); |
|
}; |
|
} |
|
|
|
var addData = function() { |
|
data.push(random()); |
|
update(); |
|
}; |
|
|
|
setInterval(addData, 25); |
|
|
|
update = circles(); |
|
</script> |
|
</body> |
|
</html> |