|| [
{ value: 0.5, source: 'Source 1', details: 'Detail for Source 1' },
{ value: 0.8, source: 'Source 2', details: 'Detail for Source 2' },
{ value: 0.3, source: 'Source 3', details: 'Detail for Source 3' },
{ value: 0.9, source: 'Source 4', details: 'Detail for Source 4' },
{ value: 0.6, source: 'Source 5', details: 'Detail for Source 5' }
];
const bars = [];
const barHeight = 0.5; // Max bar height
barData.forEach((data, index) => {
const phi = Math.acos(-1 + (2 * index) / barData.length); // Latitude
const theta = Math.sqrt(barData.length * Math.PI) * phi; // Longitude
const x = Math.cos(theta) * Math.sin(phi);
const y = Math.sin(theta) * Math.sin(phi);
const z = Math.cos(phi);
const barGeometry = new THREE.CylinderGeometry(0.05, 0.05, data.value * barHeight, 8);
const barMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000 });
const bar = new THREE.Mesh(barGeometry, barMaterial);
bar.position.set(x * 1.1, y * 1.1, z * 1.1); // Position on sphere surface
bar.lookAt(x * 2, y * 2, z * 2); // Orient towards center
bar.userData = data; // Store data for click
scene.add(bar);
bars.push(bar);
// Animate bar growth
bar.scale.y = 0;
new TWEEN.Tween(bar.scale).to({ y: 1 }, 1000).delay(index * 200).start();
});
// Raycaster for clicks
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
canvas.addEventListener('click', (event) => {
const rect = canvas.getBoundingClientRect();
mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(bars);
if (intersects.length > 0) {
const bar = intersects[0].object;
const data = bar.userData;
tooltip.innerHTML = `
${data.source}Value: ${data.value}
${data.details}`;
tooltip.style.display = 'block';
tooltip.style.left = event.clientX + 10 + 'px';
tooltip.style.top = event.clientY + 10 + 'px';
} else {
tooltip.style.display = 'none';
}
});
// Camera position
camera.position.z = 3;
// Animation loop
function animate() {
requestAnimationFrame(animate);
sphere.rotation.y += 0.005;
TWEEN.update();
renderer.render(scene, camera);
}
animate();
});