chart = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);
svg.append("g").call(xAxis);
svg.append("g").call(yAxis);
const dataFixed = a_new_data.map(d => (
{
px:d.x,
fx:x(d.x),
py:d.y,
title:d.title,
values:d.values,
length:d.length
}));
const simulation = d3.forceSimulation(dataFixed)
.force("y", d3.forceY(d=> y(d.py)))
.force("collide", d3.forceCollide(r + 10).iterations(4))
for(let i=2; i<100; i++)
simulation.tick();
simulation.stop();
let g = svg.append("g")
.attr("stroke-width", 1.5)
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.selectAll("g")
.data(dataFixed);
g = g.enter().append('g')
.attr("transform", d => `translate(${d.x},${d.y})`);
const n = 25;
const l = 100;
g.selectAll('circle').data(d=>{
if (d['Occorrenza']==='no ambientazione') {
return Array.from( Array(n), (x,index)=>({ x: d.length/n*(index+1), category: 'empty' }));
}
return Array.from( Array(n), (x,index)=> {
const val_x = d.length/n*(index+1);
const row = d.values.find(v=>val_x >=v['Start'] && val_x <= v['End']);
let category = 'empty';
let movement = 'no';
let direction = 'none'
if (row) {
category = row['INT EST'];
movement = row['Movimento'];
direction = row['Direzione'];
}
const obj = {
x: val_x,
category: category,
movement: movement,
direction: direction
}
console.log(obj)
return obj;
})
})
.enter().append("circle")
.classed('movement',d=>d.movement!=='-'&&d.movement!=='no')
.attr("fill", d=>color(d.category))
.attr("stroke", d=>d.category!=='empty'?'none':'#ccc')
.attr('stroke-alignment','inner')
.attr("r",d=>r)
.attr("cx",(d,i)=>l/n*i);
g.selectAll('circle')
.filter(d=>d=>d.movement!=='-'&&d.movement!=='no')
.style('animation-delay', (d,i)=>(d.direction==='IND'?-1:1)*i*250+'ms');
g.append("text")
.attr("x", 0)
.text(function (d) { return d.title.slice(0,10);})
.on('mouseenter',function(d){d3.select(this).text(d=>d.title)})
.on('mouseleave',function(d){d3.select(this).text(d=>d.title.slice(0,10))});
return svg.node();
}