现在使用d3.js大约一个星期了。仍然掌握着一切。我正在尝试使用d3.js创建极坐标轮廓图像,例如this one created with Python (matplotlib/numpy)。
我搜索了d3图库并看到了一些看起来很近的图片,特别是Circular Heat Chart,并概述了使用radial scales和d3 contours的内容。
这是我到目前为止所拥有的。
<!DOCTYPE html>
<style>
.frame {
fill: none;
stroke: #000;
}
.axis text {
font: 10px sans-serif;
}
.axis line,
.axis circle {
fill: none;
stroke: #777;
stroke-dasharray: 1,4;
}
.axis :last-of-type circle {
stroke: #333;
stroke-dasharray: none;
}
.line {
fill: none;
stroke: red;
stroke-width: 1.5px;
}
</style>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-contour.v1.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script>
// convert degrees to radians
function deg2rad(deg) {
return deg * 0.017453292519943295;
}
// populate array of setup values, every degree from 0 to 359
// and for wind speeds 0 to 25 m/s
var wspd_max = 25, wspd_bins = wspd_max + 1;
var setup = new Array(360 * wspd_bins);
for (var wdir = 0, k = 0; wdir < 360; wdir++) {
for (var wspd = 0; wspd <= wspd_max; wspd++, k++) {
u1 = Math.cos(deg2rad(wdir + 10)) * wspd
u2 = Math.cos(deg2rad(wdir + 25)) * wspd
ur = 1.0 * ((u1 * 28) + (u2 * 70)) / 98
setup[k] = 1.637 * Math.sign(ur) * Math.pow(Math.abs(ur), 1.5)
}
}
// width, height, and radius for the polar plot
var width = 500,
height = 500,
radius = 220;
// scale the radial axis
var r = d3.scaleLinear()
.domain([0, wspd_max])
.range([0, radius]);
// create the svg
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// radial axis ticks
var gr = svg.append("g")
.attr("class", "r axis")
.selectAll("g")
.data(r.ticks(5).slice(1)) // .slice(1) removes the tick for zero
.enter().append("g");
// add the circles for each wind speed
gr.append("circle")
.attr("r", r);
// add the tick labels (5, 10, 15, 20, 25)
gr.append("text")
.attr("y", function(d) { return -r(d) - 4; })
.attr("transform", "rotate(15)")
.style("text-anchor", "middle")
.text(function(d) { return d; });
var ga = svg.append("g")
.attr("class", "a axis")
.selectAll("g")
.data(d3.range(0, 360, 30))
.enter().append("g")
.attr("transform", function(d) { return "rotate(" + -d + ")"; });
// add lines extending outwardly
ga.append("line")
.attr("x2", radius);
// add degree markers (0°, 30°, ... 330°)
ga.append("text")
.attr("x", radius + 6)
.attr("dy", ".35em")
.style("text-anchor", function(d) { return d < 270 && d > 90 ? "end" : null; })
.attr("transform", function(d) { return d < 270 && d > 90 ? "rotate(180 " + (radius + 6) + ",0)" : null; })
.text(function(d) { return d + "°"; });
// range of the contours
var thresholds = d3.range(-100, 100, 5);
var contours = d3.contours().size([wspd_bins, 360]).thresholds(thresholds);
// contour colors
var color = d3.scaleLinear()
.domain(d3.extent(thresholds))
.interpolate(function() { return d3.interpolateYlGnBu; });
// draw the contours
svg.selectAll("path")
.data(contours(setup))
.enter().append("path")
.attr("d", d3.geoPath())
.attr("fill", function(d) { return color(d.value); });
</script>
此代码生成this image,我觉得它在正确的轨道上,但显然不是理想的结果。我觉得我需要在d3.geoPath()
中指定投影,或者我需要将径向刻度r
传递给最后一个代码块,但是我被卡住了。任何帮助将不胜感激!