viewof renderer = {
const width = 800;
const height = 600;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, width / height, 0.1, 1000);
camera.position.set(0, -100, 100);
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height);
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(10, 10, 10);
scene.add(light);
const binSize = 1;
const xValues = binnedData.map(d => d.x);
const yValues = binnedData.map(d => d.y);
const maxCount = Math.max(...binnedData.map(d => d.count));
const xScale = d3.scaleLinear()
.domain(d3.extent(xValues))
.range([-10, 10]);
const yScale = d3.scaleLinear()
.domain(d3.extent(yValues))
.range([-10, 10]);
const zScale = d3.scaleLinear()
.domain([0, maxCount])
.range([0, 10]);
binnedData.forEach(({ x, y, count }) => {
if (count === 0) return;
const scaledX = xScale(x);
const scaledY = yScale(y);
const scaledZ = zScale(count);
const geometry = new THREE.BoxGeometry(1, 1, scaledZ);
const material = new THREE.MeshLambertMaterial({ color: 0x44aa88 });
const cube = new THREE.Mesh(geometry, material);
cube.position.set(scaledX, scaledY, scaledZ / 2);
scene.add(cube);
});
function animate() {
requestAnimationFrame(animate);
scene.rotation.z += 0.005;
scene.rotation.x += 0.005;
renderer.render(scene, camera);
}
animate();
return renderer.domElement;
}