particleSystem = {
const colorScale = d3.scaleLinear()
.domain(d3.extent(data, row => +row.i_mid))
.range(['#ffffbf', '#a50026'])
.interpolate(d3.interpolateHcl);
const size = d3.scaleSqrt()
.domain([0, d3.max(data, row => +row.i_mid)])
.range([2, 50]);
const projection = d3.geoNaturalEarth1()
.fitExtent([[1, 1], [width, height]], {type: "Sphere"})
.precision(0.1);
const geometry = new THREE.BufferGeometry();
const vertices = [];
const colors = [];
const sizes = [];
let color = new THREE.Color(0x000000);
data.forEach(row => {
const posX = projection([row.xcoord, row.ycoord])[0]-width/2;
const posY = 0;
const posZ = projection([row.xcoord, row.ycoord])[1]-height/2;
vertices.push(posX, posY, posZ);
color.setStyle(colorScale(+row.i_mid));
colors.push(color.r, color.g, color.b);
sizes.push(~~size(+row.i_mid));
})
geometry.addAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
geometry.addAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
geometry.addAttribute('size', new THREE.Float32BufferAttribute(sizes, 1).setDynamic(true));
const material = new THREE.ShaderMaterial({
uniforms: {},
vertexShader: vertexShader,
fragmentShader: fragmentShader,
transparent: true,
blending: THREE.NormalBlending,
vertexColors: true
});
const particleSystem = new THREE.Points(geometry, material);
return particleSystem
}