chart = {
var margin = {top: 50, right: 30, bottom: 50, left: 30};
var w = width - margin.left - margin.right;
var h = height - margin.top - margin.bottom;
const svg = d3.select(DOM.svg(width, height))
.attr("shape-rendering", "geometric-precision");
var padding = 2,
radius = 3;
var xAxisTicks = graph.nodes.map(function(xTick) {
return xTick.id;
});
var x = d3.scalePoint()
.domain(xAxisTicks)
.range([margin.left, w + margin.right]);
var xAxis = d3.axisBottom(x);
var colorScale = d3.scaleOrdinal(d3.schemeCategory10)
.domain(xAxisTicks);
svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + h + ')')
.call(xAxis);
var nodes = [], index = 0, clusters = {};
graph.links.forEach(link => {
for(var i=0; i < link.opens; i++) {
nodes.push({
index: index,
source: link.source,
target: link.target,
cluster: link.source + '::' + link.target,
x: x(link.target),
//fx: x(link.target),
y: margin.top + (h/2)
});
if(!clusters[link.source + '::' + link.target]) {
clusters[link.source + '::' + link.target] = nodes[nodes.length-1];
}
index++;
}
});
var simulation = d3.forceSimulation(nodes)
.force('x', d3.forceX(function(d) { return x(d.target); }).strength(1))
.force('y', d3.forceY(h / 2))
.force('collide', d3.forceCollide(4))
//.force('cluster', cluster().strength(0.2))
//.on('tick', layoutTick)
.stop();
/*
var simulation = d3.forceSimulation(nodes)
.force('y', d3.forceY(250))
.force('collide', d3.forceCollide().radius(radius + padding))
.force('manyBody', d3.forceManyBody().strength(-10))
.stop();
*/
for (var i = 0; i < 150; ++i) simulation.tick();
var circle = svg.selectAll('circle')
.data(nodes)
.enter().append('circle')
.style('fill', function(d) { return colorScale(d.source); })
.attr('cx', function(d) { return d.x } )
.attr('cy', function(d) { return d.y } )
.attr('r', radius)
.style('opacity', 0.6);
//.on('mouseover', tip.show)
//.on('mouseout', tip.hide)
function layoutTick() {
circle
.attr('cx', function(d) { return d.x } )
.attr('cy', function(d) { return d.y } )
.attr('r', radius)
}
//Move d to be adjacent to the cluster node.
function cluster() {
var nodes,
strength = 0.1;
function force(alpha) {
// scale + curve alpha value
alpha *= strength * alpha;
nodes.forEach(function(d) {
var cluster = clusters[d.cluster];
if (cluster.index === d.index) return;
console.log('---------------'); //fish
console.log('d:', d); //fish
console.log('cluster:', cluster); //fish
let x = d.x - cluster.x,
y = d.y - cluster.y,
l = Math.sqrt(x * x + y * y),
r = d.radius + cluster.radius;
if(l != r) {
l = (l - r) / l * alpha;
d.x -= x *= l;
d.y -= y *= l;
cluster.x += x;
cluster.y += y;
}
});
}
force.initialize = function (_) {
nodes = _;
}
force.strength = _ => {
strength = _ == null ? strength : _;
return force;
};
return force;
}
return svg.node()
}