-
-
Save johnburnmurdoch/e9ea3d4eb4a949ea9d14ae70283ab8da to your computer and use it in GitHub Desktop.
d3 axis magnifier: linear scale
This file contains 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
<!DOCTYPE html> | |
<html lang="en-GB"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width,user-scalable=no"> | |
<title>d3 axis magnifier: linear scale</title> | |
<script src="https://unpkg.com/d3/build/d3.min.js"></script> | |
<style media="screen"> | |
#main{ | |
max-width: 600px; | |
margin: 0 auto; | |
} | |
text{ | |
font-size: 12px; | |
fill: #43423e; | |
font-family: sans-serif; | |
pointer-events: none; | |
} | |
.hoverDetector{ | |
fill: transparent; | |
cursor: pointer; | |
} | |
path.domain{ | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.tick line{ | |
shape-rendering: crispEdges; | |
} | |
.point{ | |
fill-opacity:0.5; | |
pointer-events: none; | |
} | |
.label{ | |
opacity: 0; | |
pointer-events: none; | |
} | |
.label.show{ | |
opacity: 1; | |
} | |
.focusRect{ | |
fill: none; | |
stroke: #cec6b9; | |
} | |
</style> | |
</head> | |
<body> | |
<div id=main></div> | |
<script type="text/javascript"> | |
var data = d3.range(0,101,1); | |
data.forEach(function(d,i){ | |
data[i] = Math.random()*100; | |
}); | |
var main = d3.select("#main"); | |
var bounds = main.node().getBoundingClientRect(), | |
width = bounds.width, | |
height = width*0.67, | |
margin = {left:35, top:20, right:0, bottom:20}; | |
var graphic = main.append("svg") | |
.attr("id","graphic") | |
.attr("width",width + "px") | |
.attr("height",height + "px") | |
.style("width",width + "px") | |
.style("height",height + "px"); | |
var yScale = d3.scaleLinear() | |
.range([height-margin.bottom, margin.top]) | |
.domain([0, 100]); | |
var yScaleOriginal = yScale.copy(); | |
var yAx = d3.axisLeft(yScale); | |
var originalTicks = d3.range(0, 101, 10); | |
function zoomScale(focus){ | |
if(focus == "clear"){ | |
yScale = yScaleOriginal.copy(); | |
yAx = d3.axisLeft(yScale); | |
yAxis | |
.transition() | |
.duration(100) | |
.call(yAx); | |
points | |
.transition() | |
.duration(100) | |
.attr("cy", function(d){return yScale(d)}); | |
labels | |
.classed("show", false) | |
.transition() | |
.duration(100) | |
.attr("y", function(d){return yScale(d)+5}); | |
focusRect | |
.transition() | |
.duration(100) | |
.attr("height", 0); | |
}else{ | |
var topAnchor = d3.max([margin.top, focus-50]), | |
bottomAnchor = d3.min([height-margin.bottom, focus+50]), | |
topPoint = Math.ceil(d3.min([100, yScaleOriginal.invert(focus)+1])), | |
bottomPoint = Math.max(0,topPoint-2); | |
var newTicks = d3.range(0, (bottomPoint-5), 10).concat(d3.range(bottomPoint, (topPoint+0.5), 0.5)).concat(d3.range((Math.ceil(topPoint/10)*10), 101, 10)); | |
yScale | |
.range([height-margin.bottom, bottomAnchor, topAnchor, margin.top]) | |
.domain([0, bottomPoint, topPoint, 100]); | |
yAx | |
.tickValues(newTicks) | |
.tickFormat(function(d){ | |
return d % 1 == 0 ? d3.format("d")(d):d3.format(".1f")(d); | |
}); | |
yAxis | |
.transition() | |
.duration(100) | |
.call(yAx); | |
points | |
.transition() | |
.duration(100) | |
.attr("cy", function(d){return yScale(d)}); | |
labels | |
.classed("show", function(d){return d >= bottomPoint && d <= topPoint}) | |
.transition() | |
.duration(100) | |
.attr("y", function(d){return yScale(d)+5}); | |
focusRect | |
.attr("y", topAnchor) | |
.attr("height", (bottomAnchor-topAnchor)); | |
} | |
} | |
var yAxis = graphic.append("g") | |
.attr("class", "y axis") | |
.attr("transform", "translate(" + margin.left + "," + 0 + ")") | |
.call(yAx); | |
var yAxisHoverDetector = graphic.append("rect") | |
.attr("class", "hoverDetector") | |
.attr("x", 0) | |
.attr("width", margin.left+30) | |
.attr("y", margin.top-5) | |
.attr("height", (height-margin.bottom)-margin.top+10) | |
.on("mousemove", function(){ | |
zoomScale(d3.mouse(yAxis.node())[1]); | |
}) | |
.on("mouseleave", function(){ | |
zoomScale("clear"); | |
}); | |
var focusRect = graphic.append("rect") | |
.attr("class", "focusRect") | |
.attr("x", 0) | |
.attr("width", margin.left+50) | |
.attr("y", 0) | |
.attr("height", 0); | |
var points = graphic.selectAll("circle.point") | |
.data(data) | |
.enter() | |
.append("circle") | |
.attr("class", "point") | |
.attr("cx", 50) | |
.attr("cy", function(d){return yScale(d)}) | |
.attr("r", 7) | |
.style("fill", function(d){return d3.hsl(Math.random()*50, Math.random()+0.5, 0.5)}); | |
var labels = graphic.selectAll("text.label") | |
.data(data) | |
.enter() | |
.append("text") | |
.attr("class", "label") | |
.attr("x", 60) | |
.attr("y", function(d){return yScale(d)+5}) | |
.html(function(d){return d3.format('.1f')(d)}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment