D3.js学习笔记:绘制等值线图
目录
D3.js的5.X版本新增d3-contour
组件,支持绘制等值线图。本文介绍使用d3-contour
绘制气象要素等值线图的方法。
数据
使用等经纬度网格的气象要素场,使用《GRIB2要素场转换为图片》介绍的方法,通过图片加载数据。
使用fetch
加载图片和描述文件,使用jimp
获取图片像素值。
Promise.all([
Jimp.read("public/data/t.png"),
fetch("public/data/t.json"),
]).then(values => {
let data_image = values[0];
let metadata_response = values[1];
metadata_response.json().then(metadata => {
let values = data_image.bitmap.data.filter((value: number, index: number) => {
return (index % 4) == 0
});
let real_values = _.map(values, value => {
return (metadata.max_value-metadata.min_value) * value / 255 + metadata.min_value;
});
// continue to draw contours
});
});
上述代码使用描述文件中的信息将图像灰度值数组values
恢复为数据实际值数组real_values
。
绘制等值线填充图
在svg上绘制等值线,创建svg节点,指定宽度和高度。
let width = 1600.;
let height = 800.;
let svg = d3.select("#page")
.append("svg")
.style("width", width)
.style("height", height);
使用d3.ticks
构建等值线的间隔,并为每个间隔分配一个颜色。这里我将最大值最小值区间等分为20分,使用d3.interpolateMagma
色表。
let thresholds = d3.ticks(metadata.min_value, metadata.max_value, 20);
let color = d3.scaleSequential(d3.interpolateMagma)
.domain(d3.extent(thresholds));
使用d3.contours
构建等值线,设置数据矩阵的行宽和列宽,设置等值线间隔,使用实际的数据值生成等值线对象。返回的结果是GeoJSON的数组,每个元素代表一个间隔的等值线。
let contours = d3.contours()
.size([metadata.nx, metadata.ny])
.thresholds(thresholds)
(real_values);
使用d3.geoPath
绘制等值线。这里我将每层的颜色赋值给path
的fill
属性,用于绘制填充图。
let contour_g = svg.append('g');
contour_g.selectAll(".contour")
.data(contours)
.enter().append("path")
.attr("class", "contour")
.attr("d", d3.geoPath())
.attr("fill", function(d) { return color(d.value); });
显示效果如下图所示
绘制等值线
将层次的颜色赋值给path
的stroke
属性,就可以绘制等值线。
contour_g.selectAll(".contour")
.data(contours)
.enter().append("path")
.attr("class", "contour")
.attr("d", d3.geoPath())
.attr("stroke", function(d) { return color(d.value); })
.attr("fill", "none");
效果如下图所示