Last active
September 13, 2019 09:21
-
-
Save LuisSevillano/7646cfbf60cb32b864c9 to your computer and use it in GitHub Desktop.
mouse-over event on line path
This file contains hidden or 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> | |
<title></title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script> | |
<style type="text/css"> | |
body { | |
font: 10px sans-serif; | |
} | |
.randomize { | |
float: left; | |
display: block; | |
width: 90px; | |
font-size: 14px; | |
padding: 0.7em 1em; | |
margin: 1em 0.5em; | |
border: 0.01em solid rgb(197,197,197); | |
background-color: rgb(240,240,240); | |
border-radius: 0.1em; | |
color: rgb(30,30,30); | |
text-align: center; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #777; | |
shape-rendering: crispEdges; | |
} | |
.axis text { | |
fill:#777; | |
} | |
.line { | |
fill: none; | |
stroke: rgb(255,74,27); | |
stroke-width: 1.5px; | |
} | |
</style> | |
</head> | |
<body onload="randomize();"> | |
<div id="chart"></div> | |
<div class="randomize">Randomize</div> | |
<script type="text/javascript"> | |
var margin = {top: 20, right: 50, bottom: 20, left: 20}; | |
width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
var svg = d3.select('#chart').append('svg') | |
.attr('width', width + margin.left + margin.right) | |
.attr('height', height + margin.top + margin.bottom) | |
.append('g') | |
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); | |
var path, trans = 25, circle; | |
function generateData(a,b) { | |
return d3.range(Math.floor(Math.random()*60)+20).map(function(item,index){ | |
return { x:index, y:Math.random()*10*index,z:Math.floor(Math.random()*5)+2 }; | |
}); | |
} | |
var data = generateData(); | |
svg.append("rect") | |
.data(data) | |
.attr('width', width) | |
.attr('height', height) | |
.attr("fill-opacity", "0") | |
.attr("fill", "white") | |
.on("mousemove", point) | |
.on("mouseover", over) | |
.on("mouseleave", leave) | |
.attr("transform", "translate(" + trans + ",0)"); | |
var path = svg.append("path"); | |
var x = d3.scale.linear() | |
.range([0, width]) | |
.domain(d3.extent(data, function(d) { return d.x; })); | |
var y = d3.scale.linear() | |
.range([height, 0]) | |
.domain([0, d3.max(data, function(d) { return d.y+10; })]); | |
var line = d3.svg.line() | |
.interpolate("step-before") | |
.x(function(d) { return x(d.x); }) | |
.y(function(d) { return y(d.y); }); | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.orient("bottom") | |
.ticks(20); | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.orient("left") | |
.ticks(15); | |
var drag = d3.behavior.drag() | |
.origin(function(d) { return d; }) | |
.on("dragstart", dragstarted) | |
.on("drag", function(){ dragged(this); }) | |
.on("dragend", dragended); | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(" + trans + "," + height + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "y axis") | |
.attr("transform", "translate(" + trans + ",0)") | |
.call(yAxis); | |
svg.on("click", function(){ | |
svg.append("circle") | |
.attr("cx", d3.mouse(this)[0]) | |
.attr("cy", d3.event.pageY-10) | |
.attr("fill", "none") | |
.attr("stroke", "#777") | |
.attr("r", "0") | |
.transition() | |
.duration(500) | |
.ease("circle") | |
.attr("r", "50") | |
.attr("stroke", "white") | |
.remove(); | |
}); | |
function point(){ | |
var pathEl = path.node(); | |
var pathLength = pathEl.getTotalLength(); | |
var BBox = pathEl.getBBox(); | |
var scale = pathLength/BBox.width; | |
var offsetLeft = document.getElementById("line").offsetLeft; | |
var _x = d3.mouse(this)[0]; | |
var beginning = _x , end = pathLength, target; | |
while (true) { | |
target = Math.floor((beginning + end) / 2); | |
pos = pathEl.getPointAtLength(target); | |
if ((target === end || target === beginning) && pos.x !== _x) { | |
break; | |
} | |
if (pos.x > _x){ | |
end = target; | |
}else if(pos.x < _x){ | |
beginning = target; | |
}else{ | |
break; //position found | |
} | |
} | |
circle | |
.attr("opacity", 1) | |
.attr("cx", _x+ trans) | |
.attr("cy", pos.y); | |
} | |
function over(){ | |
circle.transition().duration(200).style("opacity", "1"); | |
} | |
function leave(){ | |
circle.transition().duration(200).style("opacity", "0"); | |
} | |
function dragstarted(d){ | |
d3.select(this).style("cursor", "pointer"); | |
d3.event.sourceEvent.stopPropagation(); | |
d3.select(this).attr("fill", "brown"); | |
} | |
function dragged(d){ | |
//d3.select(this).attr("cx", +d3.select(this).attr("cx") + d3.event.dx).attr("cy", +d3.select(this).attr("cy") + d3.event.dy) | |
//d3.select(this).attr("cy", +d3.select(this).attr("cy") + d3.event.dy); | |
var x = d3.select(d).attr("cx"); | |
var y = d3.select(d).attr("cy"); | |
var cradius = d3.select(d).attr("r"); | |
var cx = Math.min(width,+x + d3.event.dx); | |
var cy = Math.min(height,+y + d3.event.dy); | |
var draggedCircles = [{ "x": cx, "y": cy, "radius": cradius }]; | |
d3.select(d) | |
.data(draggedCircles) | |
.attr("cy", function (d) { return d.y; }); | |
} | |
function dragended(d){ | |
d3.select(this) | |
.style("cursor", ""); | |
d3.select(this).attr("fill", "steelblue"); | |
} | |
function randomize(){ | |
var data = generateData(); | |
x.domain(d3.extent(data, function(d) { return d.x; })); | |
y.domain([0, d3.max(data, function(d) { return d.y; })]); | |
svg.selectAll(".circle") | |
.transition() | |
.duration(3500) | |
.attr("r", "0") | |
.style("opacity", "0"); | |
path | |
.datum(data) | |
.attr("class", "line") | |
.attr("id", "line") | |
.attr("stroke-dasharray", totalLength + " " + totalLength) | |
.attr("stroke-dashoffset", totalLength); | |
path | |
.attr("stroke", "rgb(255,74,27)") | |
.attr("stroke-width", "2") | |
.attr("fill", "none") | |
.attr("transform", "translate(" + trans + ",0)") | |
.attr("d", function(d){ | |
return line(d); | |
}); | |
var totalLength = path.node().getTotalLength(); | |
path | |
.attr("stroke-dasharray", totalLength + " " + totalLength) | |
.attr("stroke-dashoffset", totalLength) | |
.transition() | |
.duration(1500) | |
.delay(300) | |
.ease("linear") | |
.attr("stroke-dashoffset", 0) | |
.attr("pointer-events", "none"); | |
svg.select("g.x") | |
.transition() | |
.duration(400) | |
.call(xAxis); | |
svg.select("g.y") | |
.transition() | |
.duration(400) | |
.call(yAxis); | |
var bubbles = svg.selectAll(".circle").data(data); | |
bubbles | |
.enter() | |
.append("circle") | |
.attr("r", "0") | |
.attr("cy" , height) | |
.attr("class", "circle") | |
.attr("fill", "white") | |
.attr("stroke-width", "2") | |
.attr("stroke", "rgb(205,23,25)") | |
.attr("transform", "translate(" + trans + ",0)") | |
.call(drag); | |
bubbles | |
.exit() | |
.transition() | |
.duration(100) | |
.attr("r", "0") | |
.remove(); | |
bubbles | |
.transition() | |
.duration(100) | |
.delay(function(d, i) { | |
return (i / data.length * 1000)-500; | |
}) | |
.attr("r", "0") | |
.style("opacity", "0") | |
.attr("cx" , function(d){ | |
return x(d.x); | |
}) | |
.attr("cy" , function(d){ | |
return y(d.y); | |
}) | |
.transition() | |
.duration(500) | |
.delay(function(d, i) { | |
return (i / data.length * 1000)+500; | |
}) | |
.style("opacity", "1") | |
.attr("r", function(d){ | |
return d.z; | |
}) | |
circle = svg.append("circle") | |
.attr("r", 7) | |
.attr("fill", "rgb(205,23,25)") | |
.style("opacity", "0") | |
.attr("pointer-events", "none") | |
.attr("stroke-width", "2.5") | |
.attr("stroke", "white"); | |
} | |
d3.select(".randomize").on("click", randomize); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment