Я пытаюсь нарисовать то, что, на мой взгляд, составляет граф силы в d3, но в одной плоской линии. Я бы хотел примерно 4-5 точек разного размера в зависимости от их величины, равномерно расположенных между ними (не по центру, а расстояние между сторонами кругов должно быть постоянным) и линии, чтобы присоединиться к ним. Таким образом, в формате ASCII, что-то вроде:d3 force layout как линия (координата y остается неизменной)
o---O---o---O
Я пытался избежать сложных вычислений, чтобы выяснить координаты центра и начало и конец каждой строки, так что казалось, что расположение силы может сделать трюк. К сожалению, когда я собрал это вместе, я не могу заставить его работать очень хорошо. Часто точки в конечном итоге отстает от других точек, так что для графа 4 узла, как выше, он приходит, ища что-то подобное:
O---O
Есть ли способ, чтобы получить макет силы работать в 1 измерение вместо 2 ? Или я застрял, выполняя все расчеты расстояния между собой? Код я работаю ниже:
var width = 500;
var height = 200;
var svg = d3.select($el[0])
.append('svg')
.attr('width', width)
.attr('height', height);
var data_nodes = [
{ x: width/2, y: height/2, count: 5 },
{ x: width/2, y: height/2, count: 0 },
{ x: width/2, y: height/2, count: 1 },
{ x: width/2, y: height/2, count: 10 },
];
var data_links = [
{ source: 0, target: 1 },
{ source: 1, target: 2 },
{ source: 2, target: 3 },
];
var force = d3.layout.force()
.nodes(data_nodes)
.links(data_links)
.linkDistance(150)
.linkStrength(0.5)
.gravity(0.7)
.friction(0.3)
.size([width, height])
.charge(-300);
var links = svg.selectAll('line')
.data(data_links)
.enter()
.append('line')
.attr('stroke', '#65759E')
.attr('stroke-width', 4)
.attr('x1', function (d) { return data_nodes[d.source].x; })
.attr('y1', function (d) { return data_nodes[d.source].y; })
.attr('x2', function (d) { return data_nodes[d.target].x; })
.attr('y2', function (d) { return data_nodes[d.target].y; });
var nodes = svg.selectAll('circle')
.data(data_nodes)
.enter()
.append('circle')
.attr('fill', '#65759E')
.attr('r', function (d) { return 10 + Math.sqrt(d.count) * 4; })
.attr('cx', function (d, i) { return d.x + i * 10; })
.attr('cy', function (d, i) { return d.y; });
force.on('tick', function() {
nodes.attr('cx', function (d) { return d.x; });
links.attr('x1', function (d) { return d.source.x; })
.attr('x2', function (d) { return d.target.x; });
});
force.start();
Возможно, было бы намного легче создать этот макет с нуля, чем попытаться сдержать 2D-силовую структуру, чтобы создать приятный 1D-макет. Однако, если вы действительно этого хотите, способ избежать «захвата» в перекрывающиеся круги должен состоять в том, чтобы инициализировать график узлами, упорядоченными в строке в соответствии с порядком их соединений. – AmeliaBR
просто сбросьте координату y в обработчике 'tick' –
@AmeliaBR, который, похоже, сделал трюк. Если вы хотите опубликовать его в качестве ответа, я буду отмечать его как правильное. Я начал сам создавать макет, но вычисления, которые мне пришлось бы сделать, были немного болезненными. – lobati