https://d3js.slack.com/archives/C07ET41MG/p1494494798691344
Updated to use d3.timer. As the angles doesn't iterate through every integer up to 360, the test if the radar angle == target angle is now a less then/greater then test of the previous and current angle
Added a map, inspired by Mike Bostock's comment about an unrelated radar screen: https://twitter.com/mbostock/status/864224750259666944
Built with blockbuilder.org
forked from tomshanley's block: Radar v0.1
forked from tomshanley's block: Radar v0.2
forked from tomshanley's block: Radar v0.3
xxxxxxxxxx
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Radar</title>
<!-- CSS -->
<style>
html, body, svg {
background: black;
}
.radar {
stroke: chartreuse;
stroke-linecap: round;
fill: none;
stroke-width: 1px;
}
.stroke {
fill: none;
stroke: chartreuse;
stroke-width: 3px;
}
.fill {
fill: none;
}
.graticule {
fill: none;
stroke: chartreuse;
stroke-width: .5px;
stroke-opacity: 0.5;
}
.land {
fill: chartreuse;
opacity: 0.5
}
.boundary {
fill: none;
stroke: chartreuse;
stroke-width: 1px;
}
</style>
<body>
<div id="radar"></div>
<!--
<button id="btn-update">rotate</button>
-->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/topojson-client@3"></script>
<script>
const heightWidth = 500;
const margin = 10;
const radius = (heightWidth/2) - margin;
const duration = 5;
const radians = 0.0174532925;
var numberOfLines = 50;
var strokeWidth = 5;
var radarAngle = 45; //degrees
const green = "chartreuse";
const targetAngle = 56; //degrees
const targetDistance = 0.5; // % of radius
const targetX = xPosition(targetAngle, (radius * targetDistance));
const targetY = yPosition(targetAngle, (radius * targetDistance));
/*d3.select("#btn-update").on('click', function() {
updateAngle();
rotateRadar();
} );*/
var currentAngle = 0;
var previousAngle = 0;
//adapted from https://bl.ocks.org/mbostock/3757110
var projection = d3.geoAzimuthalEquidistant()
.translate([heightWidth / 2, heightWidth / 2])
.scale(90)
.center([0,0])
.rotate([0,-90])
.clipAngle(150)
var svg = d3.select("#radar")
.append("svg")
.attr("width", heightWidth + margin + margin)
.attr("height", heightWidth + margin + margin);
var path = d3.geoPath()
.projection(projection);
d3.json("https://unpkg.com/world-atlas/world/50m.json", function(error, world) {
if (error) throw error;
svg.insert("path", ".graticule")
.datum(topojson.feature(world, world.objects.land))
.attr("class", "land")
.attr("d", path);
svg.insert("path", ".graticule")
.datum(topojson.mesh(world, world.objects.countries, function(a, b) { return a !== b; }))
.attr("class", "radar")
.attr("d", path);
});
var radar = svg.append("g")
.attr("transform", "translate(" + (margin + radius) + "," + (margin + radius) + ")");
var circle = radar.selectAll("circle")
.data([1,2,3,4])
.enter()
.append("circle")
.attr("class", "radar")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", function(d){ return radius * (d/4) })
.style("fill", "none")
.style("stroke-width", "2px");
radar.append("line")
.attr("class", "radar")
.attr("x1", -radius)
.attr("x2", radius)
radar.append("line")
.attr("class", "radar")
.attr("y1", -radius)
.attr("y2", radius)
var lines = radar.append("g");
var lineData = [];
d3.range(numberOfLines).forEach(function(el) {
let a = (radarAngle * (el/numberOfLines)) - radarAngle;
lineData.push({ angle: a, value: el });
});
lines.selectAll(".lines")
.data(lineData)
.enter()
.append("line")
.attr("class", "radar")
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", function(d) {
return xPosition(d.angle, radius);
})
.attr("y2", function(d) {
return yPosition(d.angle, radius);
})
.style("stroke-width", strokeWidth)
.style("opacity", function(d){ return 1 * (d.value/numberOfLines); })
var target = radar.append("circle")
.attr("class", "target")
.attr("cx", targetX)
.attr("cy", targetY)
.attr("r", 20)
.style("fill", "chartreuse")
.style("opacity", 0)
/*setInterval(function(){
updateAngle();
rotateRadar();
}, duration);*/
d3.timer(function(elapsed){
previousAngle = currentAngle;
currentAngle = (elapsed / 10) % 360;
rotateRadar();
});
function rotateRadar() {
//line.attr("transform", "rotate(" + currentAngle + ")");
lines.attr("transform", "rotate(" + currentAngle + ")");
if (previousAngle < targetAngle && currentAngle >= targetAngle ) {
target.style("opacity", 1);
target.transition()
.duration(1000)
.style("opacity", 0);
};
};
function updateAngle() {
currentAngle = currentAngle == 359 ? 0 : currentAngle + 1;
};
function xPosition(angle, distance) {
var a = 360 - angle;
return distance * Math.sin( a * radians );
};
function yPosition(angle, distance) {
var a = 360 - angle;
return distance * Math.cos( a * radians );
};
</script>
</body>
</html>
https://d3js.org/d3.v4.min.js
https://unpkg.com/topojson-client@3