Public
Edited
Aug 26, 2024
1 star
Insert cell
Insert cell
Insert cell
Supercluster = require("https://unpkg.com/supercluster@8.0.1/dist/supercluster.min.js")
Insert cell
collisions = {
let collisions = await d3.csv(
"https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/3d-heatmap/heatmap-data.csv"
);

collisions = collisions.map((c) => ({
type: "Feature",
properties: { ...c, h3Index: h3.latLngToCell(c.lat, c.lng, 15) },
geometry: { type: "Point", coordinates: [c.lng, c.lat] }
}));
return collisions;
}
Insert cell
randomPoints = {
const numPoints = 1000000; // Number of random points to generate
const randomPoints = [];

for (let i = 0; i < numPoints; i++) {
const lng = -180 + Math.random() * 360; // Longitude between -180 and 180
const lat = -85 + Math.random() * 170; // Latitude between -85 and 85

const feature = {
type: "Feature",
properties: {
h3Index: h3.latLngToCell(lat, lng, 15) // Calculate the H3 index at resolution 15
},
geometry: {
type: "Point",
coordinates: [lng, lat]
}
};

randomPoints.push(feature);
}

return randomPoints;
}
Insert cell
superclusterPerfs = {
// Array to store the durations
let durations = [];

// Step size and initial slice size
const stepSize = 50000;
const maxSize = randomPoints.length; // Maximum size to reach

// Loop over increasing sizes of the random points array
for (let i = stepSize; i <= maxSize; i += stepSize) {
// Slice the random points array to the current size
const currentSlice = randomPoints.slice(0, i);

// Measure the time to cluster the current slice
const start = performance.now();
const index = new Supercluster();
index.load(currentSlice);
const clusters = index.getClusters([-180, -85, 180, 85], 7);
const end = performance.now();

// Calculate and store the duration
const duration = end - start;
durations.push({ size: i, duration: duration });

console.log(
`Size: ${i}, Clusters: ${clusters.length}, Duration: ${duration}ms`
);
}

// Return the array of durations for further analysis or visualization
return durations;
}
Insert cell
Plot.plot({
marginLeft: 55,
x: { tickFormat: (d) => d / 1000 + "k" },
y: { tickFormat: (d) => d + " ms" },
marks: [
Plot.barY(superclusterPerfs, { x: "size", y: "duration", fillOpacity: 0.9 })
]
})
Insert cell
h3Perfs = {
// Array to store the durations
let durations = [];

// Step size and initial slice size
const stepSize = 50000;
const maxSize = randomPoints.length; // Maximum size to reach

// Loop over increasing sizes of the random points array
for (let i = stepSize; i <= maxSize; i += stepSize) {
// Slice the random points array to the current size
const currentSlice = randomPoints.slice(0, i);

const start = performance.now();
const parentResolution = 5;
const groupedFeatures = {};

currentSlice.forEach((feature) => {
const h3Index = feature.properties.h3Index;
const parentIndex = h3.cellToParent(h3Index, parentResolution);
if (!groupedFeatures[parentIndex]) {
groupedFeatures[parentIndex] = [];
}
groupedFeatures[parentIndex].push(feature);
});

const end = performance.now();

const duration = end - start;
durations.push({ size: i, duration: duration });

console.log(
`Size: ${i}, Clusters: ${
Object.keys(groupedFeatures).length
}, Duration: ${duration}ms`
);
}

// Return the array of durations for further analysis or visualization
return durations;
}
Insert cell
Plot.plot({
marginLeft: 55,
y: { tickFormat: (d) => d + " ms" },
x: { tickFormat: (d) => d / 1000 + "k" },
marks: [Plot.barY(h3Perfs, { x: "size", y: "duration", fillOpacity: 0.9 })]
})
Insert cell
Insert cell
h3 = require("h3-js@4.1.0")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more