Heatmap X-Zoomable
Using CandyGraph
by flek
HTML
<script src="https://unpkg.com/[email protected]/gl-matrix-min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/index.js"></script>
<script src="https://unpkg.com/[email protected]/dist/dom-2d-camera.min.js"></script>
<canvas id="canvas" />
CSS
#canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(255, 0, 0, 0.1);
}
JavaScript
const t00 = performance.now();
// Data
const nCols = 2000;
const nRows = 250;
const cellSize = 6;
const cellSpacing = 0;
const width = nCols * cellSize + (nCols - 1) * cellSpacing;
const height = nRows * cellSize + (nRows - 1) * cellSpacing;
const data = { rects: [], colors: [] }
for (let i = 0; i < nRows; i++) {
for (let j = 0; j < nCols; j++) {
const c = Math.random();
const x = j * (cellSize + cellSpacing);
const y = i * (cellSize + cellSpacing);
data.rects.push(x, y, cellSize, cellSize);
data.colors.push(c, c, c, 1.0);
}
}
// DOM
const canvas = document.getElementById('canvas');
const stageBBox = canvas.getBoundingClientRect();
const scale = window.devicePixelRatio;
const viewport = {
x: 0,
y: 0,
width: stageBBox.width * scale,
height: stageBBox.height * scale
};
canvas.style.width = `${stageBBox.width}px`;
canvas.style.height = `${stageBBox.height}px`;
canvas.width = viewport.width;
canvas.height = viewport.height;
// Camera
const maxXScale = cellSize / (stageBBox.width / nCols);
const camera = window.createDom2dCamera(
canvas,
{
isPan: [true, false],
isZoom: [true, false],
scaleBounds: [1, maxXScale]
}
);
// CandyGraph
const cg = new window.candygraph.CandyGraph();
cg.canvas.width = Math.max(viewport.width, 1024 * scale);
cg.canvas.height = Math.max(viewport.height, 1024 * scale);
// Make data reusable for better performance
data.rects = window.candygraph.createDataset(cg, data.rects);
data.colors = window.candygraph.createDataset(cg, data.colors);
const xScale = window.candygraph.createLinearScale([0, width], [0, stageBBox.width * scale]);
const yScale = window.candygraph.createLinearScale([0, height], [stageBBox.height * scale, 0]);
const coords = window.candygraph.createCartesianCoordinateSystem(xScale, yScale);
const scratch1 = new Float32Array(4);
const scratch2 = new Float32Array(4);
function getViewInPx(view) {
scratch2[0] = -1;
scratch2[1] = 0;
scratch2[2] = 0;
scratch2[3] =...