Я хочу показать несколько кривых линий на основе данных JSON, которые я извлекаю из базы данных, которые являются координатами x, y, каждая строка представляет собой отдельный массив из нескольких объекты, содержащие координаты, чтобы сделать полный путь.Нарисуйте кривую между перетаскиваемыми точками с контрольными точками для настройки кривой SVG и d3.js
Все точки должны перетаскиваться, и между каждыми двумя точками должна быть контрольная точка для настройки кривой каждой линии.
До сих пор с помощью Интернета у меня есть набор точек, которые можно перетаскивать, но контрольные точки для кривой являются лишь одной из координат и не создаются динамически, возможно, позиция контрольной точки должна быть разработана и подается в массив до выхода, но я не уверен, что это способ сделать это. (Надежда, что имеет смысл)
См JSFiddle
var point_positions = [];
var json_data_muliple_lines = [[{"id": "82","x": "100","y": "50"}, {"id": "83","x": "25","y": "110"}, {"id": "97","x": "90","y": "150"}, {"id": "98","x": "150","y": "224"}, {"id": "99","x": "250","y": "150"}, {"id": "100","x": "300","y": "200"}, {"id": "100","x": "320","y": "230"}],[{"id": "1","x": "120","y": "60"}, {"id": "2","x": "30","y": "150"}, {"id": "3","x": "120","y": "170"}, {"id": "4","x": "180","y": "260"}, {"id": "5","x": "300","y": "250"}]];
var json_data = [{"line_pi_id": "82","x": "100","y": "50"}, {"line_pi_id": "83","x": "25","y": "110"}, {"line_pi_id": "97","x": "90","y": "150"}, {"line_pi_id": "98","x": "150","y": "224"}, {"line_pi_id": "99","x": "250","y": "150"}, {"line_pi_id": "100","x": "300","y": "200"}, {"line_pi_id": "100","x": "320","y": "230"}];
$.each(json_data, function(i, item) {
line_response = json_data[i];
var line_pi_id = line_response.line_pi_id;
var li_x = parseInt(line_response.x);
var li_y = parseInt(line_response.y);
point_positions.push({
x: li_x,
y: li_y
})
})
var svg = d3.select('#curves').append('svg')
.attr({
width: 1000,
height: 1000
});
var handleRadius = 8;
function curves_init(point_positions) {
var curves = [{
type: 'Q',
points: point_positions
}];
console.log("curves", curves);
var controlLineLayer = svg.append('g').attr('class', 'control-line-layer');
var mainLayer = svg.append('g').attr('class', 'main-layer');
var handleTextLayer = svg.append('g').attr('class', 'handle-text-layer');
var handleLayer = svg.append('g').attr('class', 'handle-layer');
var drag = d3.behavior.drag()
.origin(function(d) {
return d;
})
.on('drag', dragmove);
function dragmove(d) {
d.x = d3.event.x;
d.y = d3.event.y;
d3.select(this).attr({
cx: d.x,
cy: d.y
});
d.pathElem.attr('d', pathData);
if (d.controlLineElem) {
d.controlLineElem.attr('d', controlLinePath);
}
handleTextLayer.selectAll('text.handle-text.path' + d.pathID + '.p' + (d.handleID + 1))
.attr({
x: d.x,
y: d.y
}).text(handleText(d, d.handleID));
}
show_curves(controlLineLayer, mainLayer, handleTextLayer, handleLayer, curves, drag);
}
function pathData(d) {
var p = d.points;
curve = [
'M', p[0].x, ' ', p[0].y,
'Q', p[1].x, ' ', p[1].y,
' ', p[2].x, ' ', p[2].y,
' ', p[3].x, ' ', p[3].y,
' ', p[4].x, ' ', p[4].y,
' ', p[5].x, ' ', p[5].y,
' ', p[6].x, ' ', p[6].y
].join('');
console.log("curve", curve);
return curve;
}
function controlLinePath(d) {
var values = [];
d.points.forEach(function(p) {
values.push(p.x);
values.push(p.y);
});
return 'M' + values.join(' ');
}
function handleText(d, i) {
return 'p' + (i + 1) + ': ' + d.x + '/' + d.y;
}
function show_curves(controlLineLayer, mainLayer, handleTextLayer, handleLayer, curves, drag) {
mainLayer.selectAll('path.curves').data(curves)
.enter().append('path')
.attr({
'class': function(d, i) {
return 'curves path' + i;
},
d: pathData
})
.each(function(d, i) {
var pathElem = d3.select(this),
controlLineElem,
handleTextElem;
if (d.type !== 'L') {
controlLineElem = controlLineLayer.selectAll('path.control-line.path' + i)
.data([d]).enter().append('path')
.attr({
'class': 'control-line path' + i,
d: controlLinePath(d)
});
}
handleTextElem = handleTextLayer.selectAll('text.handle-text.path' + i)
.data(d.points).enter().append('text')
.attr({
'class': function(handleD, handleI) {
return 'handle-text path' + i + ' p' + (handleI + 1);
},
x: function(d) {
return d.x
},
y: function(d) {
return d.y
},
dx: 10,
dy: 0
})
.text(handleText);
handleLayer.selectAll('circle.handle.path' + i)
.data(d.points).enter().append('circle')
.attr({
'class': 'handle path' + i,
cx: function(d) {
return d.x
},
cy: function(d) {
return d.y
},
r: handleRadius
})
.each(function(d, handleI) {
d.pathID = i;
d.handleID = handleI;
d.pathElem = pathElem;
d.controlLineElem = controlLineElem;
})
.call(drag);
});
}
curves_init(point_positions);
Так мне нужна ваша помощь, чтобы выяснить, как создать контрольную точку между каждыми 2 координат, и если мне нужно изменить вывод JSON для построения координаты точки управления и как адаптировать этот код для нескольких путей, поскольку он работает только, если функция pathData() установлена вручную в соответствии с выходом JSON.
Любая помощь приветствуется!