Public
Edited
Apr 26, 2023
Insert cell
Insert cell
Insert cell
Type JavaScript, then Shift-Enter. Ctrl-space for more options. Arrow ↑/↓ to switch modes.

Insert cell
Insert cell
usersData = [artists_angie, artists_stash, artists_evelyn, artists_amelia, artists_rosemary, artists_reid, artists_vivi, artists_fiona];

Insert cell
Insert cell
allArtists = {
let allArtists = {};
usersData.forEach(oneUser => oneUser.forEach(artist => {
if (artist.fans >= 500000 && !allArtists[artist.id]) {allArtists[artist.id] = {
name: artist.name,
fans: artist.fans,
id: artist.id,
genres: artist.genres.split(",")
};
}
}))

return allArtists;
};

Insert cell
viewof genres = Inputs.range([1, 100], {label: "number of genres", step: 1, value: 11})
Insert cell
topGenres = {
let genreCounts = {};
let keys = Object.keys(allArtists);
for (let i = 0; i < keys.length; i++) {
let genres = allArtists[keys[i]].genres;
for (let j = 0; j < genres.length; j++) {
let genre = genres[j].trim();
if (!genreCounts[genre]) {
genreCounts[genre] = 1;
} else {
genreCounts[genre]++;
}
}
}
let topGenres = Object.keys(genreCounts).sort((a, b) => {
return genreCounts[b] - genreCounts[a];
}).slice(0, genres);

return topGenres;
}
Insert cell
allArtistsWithTopGenre = {
let allArtistsWithTopGenre = {};

Object.keys(allArtists).forEach( key => {
const artist = allArtists[key];
allArtistsWithTopGenre[key] = {...artist};
for (let genreCandidate of topGenres){
if (allArtistsWithTopGenre[key].genres.includes(genreCandidate)) {
allArtistsWithTopGenre[key].genre = genreCandidate;
break;
} else {
allArtistsWithTopGenre[key].genre = "other";
}
}
})
return allArtistsWithTopGenre;
}
Insert cell
Insert cell
artistPairs = {
let artistpairs = [];
let keys = Object.keys(allArtists);
for (let i = 0; i < keys.length; i++) {
for (let j = i+1; j < keys.length - 1; j++) {
artistpairs.push({
source: keys[i],
target: keys[j],
value: 0
})
}
}
return artistpairs;
}
Insert cell
Insert cell
filteredPairs = {
usersData.forEach(user => {
let userArtists = user.map(m => m.id);
artistPairs.forEach(pair => {
if (userArtists.includes(pair.source) && userArtists.includes(pair.target)) pair.value++;
})
})
return artistPairs.filter(f => f.value);
}
Insert cell
Insert cell
graphData = {
let object = {};
object.nodes = Object.values(allArtistsWithTopGenre);
object.links = filteredPairs;
return object;
}
Insert cell
Insert cell
Insert cell
chart = ForceGraph(graphData, {
nodeId: d => d.id,
colors: d3.schemeCategory10,
nodeGroup: d => d.genre,
nodeTitle: d => d.name + " (" + d.genre +")",
nodeRadius: d => 5,
linkStrokeWidth: l => Math.sqrt(l.value),
width: 1200,
height: 1200,
invalidation
})

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