// }
// const circleNew = svgGrid.select(`#ind_${ind.id}`)
// .attr('fill', strokeSelectionColor)
// // .attr('fill', getIndividualColor(ind))
// // .transition()
// // .duration(250)
// // .attr('stroke', strokeSelectionColor);
// selectedInd = ind;
// // Draw the big graph
// const graph = d3.select('#big_graph')
// .transition()
// .duration(250)
// .attr('opacity', 0)
// .transition()
// .duration(150)
// .attr('href', `#graph_svg_ind_${String(ind.id)}`)
// .transition()
// .duration(250)
// .attr('opacity', 1);
// svgGrid.select('#currentFitnessTick')
// .transition()
// .ease(d3.easeCubicOut)
// .attr('visibility', 'visible')
// .attr('transform', `translate(10, ${colorLegendScale(ind.fitness)})`)
// .selectAll('text')
// .text(ind.fitness)
// }
// function drawGraphInner(graph) {
// // return drawGraph(graph).node();
// return ForceGraph(graph, {
// nodeId: d => d.id,
// // nodeGroup: d => d.group,
// nodeStroke: 'green',
// nodeStrokeWidth: 3, // node stroke width, in pixels
// nodeFill: "white", // node stroke color
// nodeTitle: d => d.name,
// linkStrokeWidth: 3,
// nodeRadius: 15, // node radius, in pixels
// width: 300,
// height: 300,
// linkStrength: 0.1,
// invalidation // a promise to stop the simulation when the cell is re-run
// })
// }
// // Create main SVG & inner SVGs
// const svg = d3.create('svg').attr('width', width).attr('height', height);
// const svgGrid = svg.insert('svg').attr('width', '50%').attr('height', '100%');
// const svgGraph = svg.insert('svg').attr('width', '50%').attr('height', '100%').attr('x', '50%');
// // Add borders
// svg.selectAll('svg').insert('rect').attr('height', '100%').attr('width', '100%').attr('fill', 'none').attr('stroke', 'black').attr('stroke-width', 3);
// // Add titles
// svg.selectAll('svg')
// .insert('text')
// .attr("text-anchor", "middle")
// .attr("x", '50%')
// .attr("y", margin)
// .style('font', fontStyle)
// .data(['Individuals', 'Graph'])
// .text((d) => d)
// // Draw big graph
// svgGraph.insert('use').attr('width', '100%').attr('height', '100%').attr('id', 'big_graph');
// const dataLinks = dataReal.links.slice()
// const dataIndividuals = dataReal.nodes.slice()
// .sort((a, b) =>
// d3.ascending(a.lifespan[0], b.lifespan[0])
// || d3.descending(a.lifespan[1], b.lifespan[1]));
// const dataIndividualsPerGeneration = Array.from(
// d3.group(dataIndividuals, ind => ind.lifespan[0]),
// ([, value]) => value);
// for (let ind of dataIndividuals) {
// ind.posY = dataIndividualsPerGeneration[ind.lifespan[0]].findIndex(gen_ind => gen_ind.id == ind.id);
// }
// for (let ind of dataIndividuals) {
// ind.hasVisibleLifespan = false;
// let gen = ind.lifespan[0];
// ind.class = `gen_${gen}`;
// ind.posX = ind.lifespan[1];
// let lifespanLength = (ind.lifespan[1] - ind.lifespan[0]) + 1;
// if (lifespanLength <= 1) continue;
// ind.hasVisibleLifespan = true;
// for (let current_gen of d3.range(gen + 1, gen + lifespanLength)) {
// ind.class = ind.class + ` gen_${current_gen}`
// if (current_gen > dataIndividualsPerGeneration.length - 1) continue;
// let index = dataIndividualsPerGeneration[current_gen].findIndex((ind_2) => ind_2.posY == ind.posY);
// for (let ind_2 of dataIndividualsPerGeneration[current_gen].slice(index)) {
// // tmp.push([ind.id, ind_2.id, ind.posY, ind_2.posY]);
// ind_2.posY = ind_2.posY + 1;
// }
// }
// }
// // return data_visible_lifespans
// // Define scales
// const maxPosX = d3.max(d3.merge(dataIndividuals.map(n => n.lifespan)))
// const maxPosY = d3.max(dataIndividuals.map((ind) => ind.posY))
// const gridLengthX = maxPosX + 1
// const gridLengthY = maxPosY + 1
// const r = d3.min([
// (gridWidth - margin - marginWithAxis - colorLegendWidth) / (3 * gridLengthX + 1),
// (height - margin - marginWithAxis) / (3 * gridLengthY + 1)
// ]);
// // return r;
// const ind_stroke_width = r / 5;
// const generationsScale = d3.scaleLinear()
// // .range([marginWithAxis, gridWidth - (margin)])
// .range([marginWithAxis + 2 * r, marginWithAxis + (r * (3 * gridLengthX - 1))])
// .domain([0, maxPosX]);
// // return generationsScale.range();
// const individualsScale = d3.scaleLinear()
// // .range([marginWithAxis, height - (margin)])
// .range([marginWithAxis + 2 * r, marginWithAxis + (r * (3 * gridLengthY - 1))])
// .domain([0, maxPosY]);
// const fitnessDomain = d3.extent(dataIndividuals.map((ind) => ind.fitness)).reverse()
// const fitnessScale = d3.scaleSequential()
// .domain(fitnessDomain)
// .interpolator(d3.interpolateViridis);
// // Define visible lifespans data
// const dataIndividualsWithLifespan = [dataIndividuals.filter((ind) => ind.hasVisibleLifespan),
// (ind) => ind.id]
// // Append the link to the svg element
// svgGrid.selectAll()
// .data(dataLinks)
// .join('path')
// .attr('d', (link) => {
// const ind_1 = dataIndividuals.find((ind) => ind.id == link.source)
// const ind_2 = dataIndividuals.find((ind) => ind.id == link.target)
// return d3.linkHorizontal()({
// source: [getXGridPosition(ind_2.lifespan[0] - 1), getYGridPosition(ind_1.posY)],
// target: [getXGridPosition(ind_2.lifespan[0]), getYGridPosition(ind_2.posY)],
// })
// })
// .attr('stroke', 'black')
// .attr('fill', 'none');
// const individualGroups = svgGrid.selectAll()
// .data(dataIndividuals, (ind) => ind.id)
// .join('g')
// .attr('id', (ind) => `g_ind_${ind.id}`)
// .attr('style', (ind) => `stroke:${getIndividualColor(ind)}`)
// // Transparent lifespans for actions
// individualGroups.data(...dataIndividualsWithLifespan)
// .insert('line')
// // .attr('stroke', 'black')
// .attr('stroke-width', r * 2)
// .attr('visible', 'none')
// .attr('stroke-opacity', 0)
// .attr('x1', (ind) => getXGridPosition(ind.lifespan[0]) - r)
// .attr('x2', (ind) => getXGridPosition(ind.lifespan[1]) + r)
// .attr('y1', (ind) => getYGridPosition(ind.posY))
// .attr('y2', (ind) => getYGridPosition(ind.posY))
// // Lifespan lines
// individualGroups.data(...dataIndividualsWithLifespan)
// .insert('g')
// .insert('line')
// // .attr('stroke', 'black')
// .attr('stroke-width', ind_stroke_width)
// .attr('stroke-linecap', 'round')
// .attr('x1', (ind) => getXGridPosition(ind.lifespan[0]))
// .attr('x2', (ind) => getXGridPosition(ind.lifespan[1]))
// .attr('y1', (ind) => getYGridPosition(ind.posY))
// .attr('y2', (ind) => getYGridPosition(ind.posY))
// // .select()
// // .data(function (ind) {
// // console.log(ind);
// // const positions = [];
// // for (let x of d3.range(ind.lifespan[0], ind.lifespan[1])) positions.push([x, ind.posY]);
// // return positions;
// // })
// // .clone()
// // .attr('x1', (d) => getXGridPosition(d[0]))
// // .attr('x2', (d) => getXGridPosition(d[0]))
// // .attr('y1', (d) => getYGridPosition(d[1]) + r/4)
// // .attr('y2', (d) => getYGridPosition(d[1]) - + r/4)
// .clone()
// .attr('x1', (ind) => getXGridPosition(ind.lifespan[0]))
// .attr('x2', (ind) => getXGridPosition(ind.lifespan[0]))
// .attr('y1', (ind) => getYGridPosition(ind.posY) + r/4)
// .attr('y2', (ind) => getYGridPosition(ind.posY) - r/4)
// .clone()
// .attr('x1', (ind) => getXGridPosition(ind.lifespan[1]))
// .attr('x2', (ind) => getXGridPosition(ind.lifespan[1]))
// .attr('y1', (ind) => getYGridPosition(ind.posY) + r/4)
// .attr('y2', (ind) => getYGridPosition(ind.posY) - r/4)
// // Circles of individuals
// individualGroups.data(dataIndividuals, (ind) => ind.id)
// .insert('g')
// .attr('id', (ind) => `ind_linear_transform_${ind.id}`)
// .attr('class', (ind) => 'ind_linear_transform ' + ind.class)
// .attr('transform', (ind) => `translate(${getXGridPosition(ind.posX)}, ${getYGridPosition(ind.posY)})`)
// .attr('pos_x', (ind) => ind.posX)
// .insert('g')
// .attr('id', (ind) => `ind_scale_transform_${ind.id}`)
// .attr('class', (ind) => 'ind_scale_transform ' + ind.class)
// .attr('transform', 'scale(1)')
// .insert('circle')
// // .attr('stroke', 'black')
// .attr('stroke-width', ind_stroke_width)
// .attr('r', r)
// .attr('fill', (ind) => `url(#graph_fill_pattern_ind_${ind.id})`)
// .attr('id', (ind) => `ind_${ind.id}`)
// .on('mouseover', function(event, ind) {
// d3.select(this)
// .transition()
// // .attr('stroke', strokeSelectionColor)
// d3.select(`#ind_scale_transform_${ind.id}`)
// .transition()
// .ease(d3.easeCubicOut)
// .attr('transform', 'scale(2)')
// })
// .on('mouseout', function(event, ind) {
// d3.select(this)
// .transition()
// // .attr('stroke', null)
// d3.select(`#ind_scale_transform_${ind.id}`)
// .transition()
// .attr('transform', 'scale(1)')
// })
// .on('click', function(event, ind) {
// // const bg_graph = d3.select('#big_graph_background')
// // .attr('href', `#graph_svg_ind_${ind.id}`);
// selectIndividual(ind);
// })
// ;
// // Graph images
// const individualDefs = individualGroups
// .data(dataIndividuals, (ind) => ind.id)
// .insert('defs')
// .attr('id', (ind) => `defs_ind_${ind.id}`)
// for (let ind of dataIndividuals) {
// console.log(ind)
// let graphSVG = drawGraphInner(ind.graph)
// d3.select(individualGroups.select(`#defs_ind_${ind.id}`).node().appendChild(graphSVG))
// .attr('width', '100%')
// .attr('height', 'auto')
// // .attr('width', r * 2)
// // .attr('height', r * 2)
// .attr('id', `graph_svg_ind_${ind.id}`)
// // .attr('patternContentUnits', 'userSpaceOnUse')
// // individualFillPattern.nodes().se(`#graph_fill_pattern_ind_${ind.id}`).node().appendChild(graphSVG)
// // console.log(i)
// // let graphSVG = drawGraph(dataIndividuals[i].graph)
// // individualFillPattern.node().appendChild(graphSVG)
// }
// const individualFillPattern = individualDefs
// .insert('pattern')
// // .attr('patternContentUnits', 'userSpaceOnUse')
// .attr('id', (ind) => `graph_fill_pattern_ind_${ind.id}`)
// // .attr('viewBox', (ind) => grah_view_box)
// .attr('x', '0%')
// .attr('y', '0%')
// .attr('width', '100%')
// .attr('height', '100%')
// individualFillPattern.insert('rect') // white background instead of transparent
// .attr('width', '100%')
// .attr('height', '100%')
// .attr('fill', 'white');
// individualFillPattern.insert('use')
// .attr('width', r * 2)
// .attr('height', r * 2)
// .attr('href', (ind) => `#graph_svg_ind_${ind.id}`);
// // individualFillPattern.append('svg')
// // .html((ind) => drawGraph(ind.graph).getInnerHTML())
// // // .html(() => svg_graph_placeholders[d3.randomInt(svg_graph_placeholders.length)()].getInnerHTML()) // TODO: malke specific for an individual
// // // .attr('patternContentUnits', 'userSpaceOnUse')
// // .attr('width', r * 2)
// // .attr('height', r * 2)
// // // .attr('width', '100%')
// // // .attr('height', '100%')
// // .attr('id', (ind) => `graph_svg_ind_${ind.id}`)
// // .attr('viewBox', graphViewBox) // TODO: fit to my individual graphs
// // .attr('overflow', 'visible')
// // ;
// individualGroups.data(...dataIndividualsWithLifespan)
// .on("mousemove", function(event, ind) {
// // var element = d3.select(this)
// // .select('circle')
// var xy = d3.pointer(event, svgGrid.node());
// var lifespan_start = getXGridPosition(ind.lifespan[0])
// var lifespan_end = getXGridPosition(ind.lifespan[1])
// var pos_x = d3.max([d3.min([xy[0], lifespan_end]), lifespan_start])
// // d3.select(this)
// // .transition()
// // .ease(d3.easeCubicOut)
// // .attr('style', `stroke:${strokeSelectionColor}`);
// d3.select(this)
// .select('.ind_linear_transform')
// .transition()
// .ease(d3.easeCubicOut)
// .attr('transform', `translate(${pos_x}, ${getYGridPosition(ind.posY)})`);
// d3.select(this)
// .select('circle')
// .transition()
// .ease(d3.easeCubicOut)
// // .attr('stroke', 'orange');
// })
// .on("mouseleave", function(event, ind) {
// // d3.select(this)
// // .transition()
// // .ease(d3.easeCubicOut)
// // .attr('style', `stroke:${getIndividualColor(ind)}`);
// d3.select(this)
// .select('.ind_linear_transform')
// .transition()
// .attr('transform', `translate(${getXGridPosition(ind.posX)}, ${getYGridPosition(ind.posY)})`)
// d3.select(this)
// .select('circle')
// .transition()
// .ease(d3.easeCubicOut)
// // .attr('stroke', null);
// });
// const axisGenerations = svgGrid.append('g')
// .attr("transform", `translate(${0},${height - marginOfAxis})`)
// .style("font", ticksFontStyle)
// .style("stroke-width", 3);
// axisGenerations.call(
// d3.axisTop(generationsScale)
// .ticks(maxPosX)
// .tickSize(0)
// ).select('.domain').remove();
// svgGrid.append("text")
// .attr("text-anchor", "middle")
// .attr("x", gridWidth / 2 + margin - colorLegendWidth)
// .attr("y", height - marginOfAxis / 2)
// .style('font', fontStyle)
// .text('generation');
// axisGenerations.selectAll('.tick')
// .on('mouseover', function(event) {
// d3.select(this).attr('style', `color: ${strokeSelectionColor}`)
// var genNum = d3.select(this).text()
// d3.selectAll(`.gen_${genNum}.ind_scale_transform`)
// .transition()
// .ease(d3.easeCubicOut)
// .attr('transform', 'scale(1.5)')
// d3.selectAll(`.gen_${genNum}.ind_linear_transform`)
// .transition()
// .attr('transform', (ind) => `translate(${getXGridPosition(genNum)}, ${getYGridPosition(ind.posY)})`);
// })
// .on('mouseout', function(event) {
// d3.select(this).attr('style', 'color: black')
// var genNum = d3.select(this).text()
// d3.selectAll(`.gen_${genNum}.ind_scale_transform`)
// .transition()
// .ease(d3.easeCubicOut)
// .attr('transform', 'scale(1)')
// d3.selectAll(`.gen_${genNum}.ind_linear_transform`)
// .transition()
// .attr('transform', (ind) => `translate(${getXGridPosition(ind.posX)}, ${getYGridPosition(ind.posY)})`);
// })
// const colorLegend = legend({
// color: fitnessScale,
// title: 'fitness',
// tickSize: 5,
// width: colorLegendWidth,
// height: height - margin - marginWithAxis,
// });
// d3.select(colorLegend).selectAll('g').attr('font-family', null);
// d3.select(colorLegend).selectAll('text').attr('font-weight', null);
// d3.select(colorLegend).select('text.title').style('font', fontStyle)
// d3.select(colorLegend).selectAll('g.tick').style('font', ticksFontStyle)
// const visibleTick = d3.select(colorLegend)
// .insert('g')
// .attr('id', 'currentFitnessTick')
// .attr('visibility', 'hidden');
// visibleTick.insert('line')
// .attr('stroke', strokeSelectionColor)
// .attr('stroke-width', 3)
// .attr('x1', -10)
// .attr('x2', 5);
// // visibleTick.insert('text')
// // .attr('fill', strokeSelectionColor)
// // .style('font', fontStyle)
// // // .style('backgroundColor', 'white')
// // .attr('x', 13)
// // .attr('dy', '0.32em')
// // .text('test');
// visibleTick.insert('text')
// // .attr('fill', strokeSelectionColor)
// .style('font', ticksFontStyle)
// .style('stroke', 'white')
// .style('stroke-width', '0.3em')
// // .style('backgroundColor', 'white')
// .attr('x', -17)
// .attr("text-anchor", "end")
// .attr('dy', '0.32em')
// .text('test')
// .clone()
// .attr('fill', strokeSelectionColor)
// .style('stroke', null)
// .style('stroke-width', null)
// ;
// svgGrid.insert('svg').html(colorLegend.getInnerHTML())
// .attr('id', 'colorLegend')
// .attr('height', '50%')
// .attr('width', colorLegendWidth)
// .attr('x', gridWidth - colorLegendWidth - margin)
// .attr('y', margin)
// .attr('overflow', 'visible');
// const colorLegendScale = d3.scaleLinear()
// .range([
// Number(d3.select(colorLegend).select('image').attr('y')) + Number(d3.select(colorLegend).select('image').attr('height')),
// d3.select(colorLegend).select('image').attr('y')
// ])
// .domain(fitnessDomain)
// return svg.node();
// }