Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/d3-delaunay@4"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
</head>
<body>
<h2>Beeswarm + Voronoi</h2>
<div id="chart">
</div>
<script>
const height = 300;
const width = 500;
const margin = {top: 20, bottom: 20, left: 20, right: 20};
const svgHeight = height - margin.top - margin.bottom;
const svgWidth = width - margin.left - margin.right
const data = [{date: '2018-01-01'},{date: '2018-06-26'},{date: '2018-06-26'},{date: '2018-06-26'}, {date: '2019-01-01'}];
const parsedData = data.map((d)=>{
return {date: moment(d.date, "YYYY-MM-DD")};
})
const minDate = moment.min(...parsedData.map((d)=> d.date)).toDate();
const maxDate = moment.max(...parsedData.map((d)=> d.date)).toDate();
// columns: index, dateDimension, label
const yScale = d3.scaleTime()
.domain([d3.timeWeek.floor(minDate), d3.timeWeek.ceil(maxDate)])
.range([height - margin.top- margin.bottom, 0]);
var simulation = d3.forceSimulation(parsedData)
.force("x", d3.forceX(function (d) {return svgWidth/2}))
.force("y", d3.forceY((d) => {return yScale(d.date);}).strength(1))
.force("collide", d3.forceCollide(4))
.stop();
const delaunay = new d3.Delaunay.from(parsedData.map((d) => {
return [d.x, d.y];
}));
var points = []
for (i = 0; i < delaunay.points.length/2; i++){
points.push({x: delaunay.points[2*i], y:delaunay.points[2*i + 1]})
}
for (var i = 0; i < 120; ++i) simulation.tick();
var svg = d3
.select('#chart')
.append('svg')
.attr('width', width - margin.top - margin.bottom)
.attr('height', height - margin.top - margin.bottom);
const timelineSvg = svg
.append('svg')
.attr('width', width - margin.left - margin.right)
.attr('height', height - margin.top - margin.bottom)
.attr('transform', `translate(${margin.left}, ${margin.top})`);
timelineSvg
.append('line')
.attr('x1', (width - margin.left - margin.right)/2)
.attr('x2', (width - margin.left - margin.right)/2)
.attr('y1', height - margin.top - margin.bottom)
.attr('y2', 0)
.attr('stroke', 'black');
timelineSvg
.append('g')
.selectAll('circle')
.data(points)
.enter()
.append('circle')
.attr('cx', (d) => d.x)
.attr('cy', (d)=> d.y)
.attr('r', 5);
console.log(points);
</script>
</body>
https://d3js.org/d3.v4.min.js
https://unpkg.com/d3-delaunay@4
https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js