This example is explained at the post https://geoexamples.com/other/2019/02/08/cog-tutorial.html
The represented data is a temperature interpolation over Catalonia, and the GeoTIFF is very big. But since it has overlays, only a small amount of data is actually retrieved, making the performance high and the used bandwidth small.
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<script src="geotiff.bundle.min.js"></script>
<script src="d3-marching-squares.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
</head>
<body>
<script>
(async function() {
const tiff = await GeoTIFF.fromUrl("sample.tiff");
let image = await tiff.getImage(3);
let rasterData = await image.readRasters({samples: [0]});
rasterData = rasterData[0];
let data = new Array(image.getHeight());
for (let j = 0; j<image.getHeight(); j++){
data[j] = new Array(image.getWidth());
for (let i = 0; i<image.getWidth(); i++){
data[j][i] = rasterData[i + j*image.getWidth()];
}
}
let intervals = [-2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20];
let bands = rastertools.isobands(data, [0, 1, 0, 0, 0, 1], intervals);
let colorScale = d3.scaleSequential(d3.interpolateBuPu);
let canvas = d3.select("body").append("canvas")
.attr("width", 680)
.attr("height", 500);
let context = canvas.node().getContext("2d");
let path = d3.geoPath()
.context(context);
bands.features.forEach(function(d, i) {
context.beginPath();
context.globalAlpha = 0.7;
context.fillStyle = colorScale((2 + intervals[i])/22);
path(d);
context.fill();
});
})();
</script>
</body>