Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
#container{
position:relative;
}
svg{
position:absolute;
}
</style>
</head>
<p>Rotation: <span id="currotation">50</span></p>
<input id="slider" type="range" min="1" max="100" value="50">
<div id="container">
</div>
<body>
<script>
d3.selectAll("#slider")
.on("change",function(){
var selected = d3.select(this).property("value")
d3.select("#currotation").text(selected)
rotation = selected;
rotated_width = width/(Math.cos(rotation/360 * Math.PI*2)+Math.sin(rotation/360 * Math.PI*2))
updateSVG()
})
var rotation = 45;
var margin = {top: 100, right: 30, bottom: 20, left: 30};
var width = 500;
var height = 500;
//calculates the width of an enclosed square for any rotation.
var rotated_width = width/(Math.cos(rotation/360 * Math.PI*2)+Math.sin(rotation/360 * Math.PI*2))
var circleArray = [0,.2,.4,.6,.8,1]
var xScale = d3.scalePoint()
.range([0,rotated_width])
.domain(circleArray)
var xScale_norotation = d3.scalePoint()
.range([0,width])
.domain(circleArray)
var svg = d3.select("#container").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("border","1px solid teal")
.style("overflow","visible")
var margin_g = svg.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")")
margin_g.append("rect")
.attr("width",width)
.attr("height",height)
.style("fill","rgba(0,0,0,.2)")
var container_g = margin_g.append("g")
.attr("transform","translate(0," + (-height/2) + ")")
var rotate_g = container_g.append("g");
rotate_g.append("rect")
.attr("width",rotated_width)
.attr("height",rotated_width)
.attr("fill","red")
.style("opacity",.2)
rotate_g.append("text")
.text("(x = 0, y = 0)")
.attr("y", -5)
.attr("x", 0)
.attr("font-size", 16)
.attr("font-family", "Helvetica")
rotate_g.append("g").call(d3.axisBottom(xScale))
var circles = container_g.selectAll("circle").data(circleArray)
circles.enter().append("circle")
.attr("cx",function(d){return xScale_norotation(d)})
.attr("cy",height/2)
.attr("r",5)
.attr("fill","black")
updateSVG()
function updateSVG(){
//figure out the distance between (0,height) and (width,0) in original x coordinates.
rotate_g.attr("transform","translate(" + width/2 + "," + 0 + ")" + " rotate(" + rotation +")")
rotate_g.select("rect")
.attr("width",rotated_width)
.attr("height",rotated_width)
//fix translation for new width.
var elem_width = rotate_g.select("rect").node().getBoundingClientRect().left;
rotate_g.attr("transform","translate(" + (width/2 - elem_width + margin.left) + "," + 0 + ")" + " rotate(" + rotation +")")
d3.selectAll("circle")
.attr("cx",function(d){return xScale_norotation(d)})
.attr("cy",height/2)
.attr("r",5)
.attr("fill","black")
}
</script>
</body>
https://d3js.org/d3.v4.min.js