Published
Edited
Apr 30, 2021
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
color = {
const scale = d3.scaleSequential(["blue", "red"]).domain([1,2])
return d => scale(fitnessEvolution[showGeneration - 1][d.index]);
}
Insert cell
Insert cell
Insert cell
fitnessEvolution = {
const initial = initialFitness
const gen = [initial];
for (let i = 0; i < r-1; ++i) {
let pop = gen[gen.length - 1]

// Clone previous fitness
const nextFitness = pop.map(d => d)
// Pick a random birth node proportional to fitness
const nodeBirth = pickRandom(network.nodes, d => nextFitness[d.index])
// Pick a neighbouring node to replace
const neighbours = getNeighbours(nodeBirth)
const nodeDeath = pickRandom(neighbours, d => 1 / nextFitness[d.index])
nextFitness.birth = nodeBirth.index
nextFitness.death = nodeDeath.index
nextFitness.neighbours = neighbours
nextFitness.neighboursFitness = neighbours.map(d => nextFitness[d])
// Replace death node with birth node (replace the fitness)
nextFitness[nodeDeath.index] = nextFitness[nodeBirth.index]
gen.push(nextFitness)
}
return gen
}
Insert cell
initialFitness = network.nodes.map(node => {
if (node.index < initialNumberOfMutants) {
return relativeFitness
}
return 1
})
Insert cell
network = {
const network = graphLattice

const links = network.links//.map(d => Object.create(d));
const nodes = network.nodes//.map(d => Object.create(d));
const simulation = d3.forceSimulation(nodes)
.force("link", d3.forceLink(links).id(d => d.index).strength(1).distance(20).iterations(10))
.force("charge", d3.forceManyBody().strength(-50))
.force("center", d3.forceCenter(width / 2, height / 2));

const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("width", width)
.attr("height", height);

const link = svg.append("g")
.attr("stroke", "#999")
.attr("stroke-opacity", 0.6)
.selectAll("line")
.data(links)
.join("line")
.attr("stroke-width", d => Math.sqrt(d.value));

const node = svg.append("g")
.attr("stroke", "#fff")
.attr("stroke-width", 1.5)
.selectAll("circle")
.data(nodes)
.join("circle")
.attr("class", "node")
.attr("r", 5)
.attr("fill", "black")
.call(drag(simulation));

node.append("title")
.text(d => d.id);

simulation.on("tick", () => {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);

node
.attr("cx", d => d.x)
.attr("cy", d => d.y);
});

invalidation.then(() => simulation.stop());

return { nodes, links, svg, simulation }
}
Insert cell
graphLattice = {
const n = latticeSize;
const nodes = Array.from({length: n * n}, (_, i) => ({index: i, links: [], outLinks: [], inLinks: []}));
const links = [];
for (let y = 0; y < n; ++y) {
for (let x = 0; x < n; ++x) {
if (y > 0) {
const link = {source: (y - 1) * n + x, target: y * n + x}
links.push(link);
nodes[link.source].outLinks.push({...link})
nodes[link.target].inLinks.push({...link})
}
if (x > 0) {
const link = {source: y * n + (x - 1), target: y * n + x}
links.push(link);
nodes[link.source].outLinks.push({...link})
nodes[link.target].inLinks.push({...link})
}
}
}
return {nodes, links};
}
Insert cell
function getNeighbours(node) {
return [...node.outLinks.map(link => link.target), ...node.inLinks.map(link => link.source)]
.map(index => network.nodes[index])
}
Insert cell
getNeighbours(network.nodes[1])
Insert cell
network.nodes[0].outLinks
Insert cell
Insert cell
pickRandom([
['a', 1],
['b', 2],
['c', 3],
['d', 4]
], item => item[1])
Insert cell
function pickRandom(items, getWeight = () => 1) {
// Will contain the sum of all weights
let sum = 0;
// Will contain an array of each weight accumilating the sum of previous weights
const accumulatedWeights = [];

items.forEach((item, i) => {
const weight = getWeight(item, i)
sum += weight
accumulatedWeights.push(sum);
})

const rand = random() * sum;
const item = items[accumulatedWeights.filter(element => element <= rand).length];

return item;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more