拖动圆圈和相应的反应文本标签

  • 本文关键字:文本标签 拖动 d3.js
  • 更新时间 :
  • 英文 :


我需要制作一个具有可拖动点和可拖动文本标签的散点图,这些点和文本标签对它们的新位置做出反应,到目前为止,我已经能够绘制点和它们各自的标签,但不能使它们的位置和文本标签都做出反应。

我尝试将拖动类附加到存储文本的类,但没有成功。我错过了什么?感谢您的帮助。

https://jsfiddle.net/pdf8wn2h/

<script>
var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 50},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;

let points = [[0, 0], [1, 7],[2, 21],[3, 36],[4, 50],[5, 55],[6, 60],[7, 65],[8, 70],[9, 75],[10, 80],[11, 85],[12, 90],[13, 95],[14, 100],[15, 100]];
var x = d3.scaleLinear()
.rangeRound([0, width]);
var y = d3.scaleLinear()
.rangeRound([height, 0]);
var xAxis = d3.axisBottom(x),
yAxis = d3.axisLeft(y);
var line = d3.line()
.x(function(d) { return x(d[0]); })
.y(function(d) { return y(d[1]); });
let drag = d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended);
svg.append('rect')
.attr('class', 'zoom')
.attr('cursor', 'move')
.attr('fill', 'none')
.attr('pointer-events', 'all')
.attr('width', width)
.attr('height', height)
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(d3.extent(points, function(d) { return d[0]; }));
y.domain(d3.extent(points, function(d) { return d[1]; }));
focus.append("path")
.datum(points)
.attr("fill", "none")
.attr("stroke", "green")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1.5)
.attr("d", line);
focus.selectAll('g')
.data(points)
.enter()
.append('circle')
.attr('r', 5.0)
.attr('cx', function(d) { return x(d[0]);  })
.attr('cy', function(d) { return y(d[1]); })
.style('cursor', 'pointer')
.style('fill', 'green');

focus.selectAll('.dodo')
.data(points)
.enter()
.append("text")
.attr("class", "dodo")
.attr("x", function(d) { return x(d[0]); })
.attr("y", function(d) { return y(d[1]); })
.attr("dx", ".71em")
.attr("dy", ".35em")
.text(function(d) { return d[1];});
focus.selectAll('circle')
.call(drag);
focus.append('g')
.attr('class', 'axis axis--x')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
focus.append('g')
.attr('class', 'axis axis--y')
.call(yAxis);


function dragstarted(d) {
d3.select(this).raise().classed('active', true);
}
function dragged(d) {
// d[0] = x.invert(d3.event.x); Restringe o movimento do eixo x
d[1] = y.invert(d3.event.y);
d3.select(this)
.attr('cx', x(d[0]))
.attr('cy', y(d[1]))
focus.select('path').attr('d', line);
}
function dragended(d) {
d3.select(this).classed('active', false);
}

</script>

请参阅以下片段中的解决方案:

var svg = d3.select("svg"),
margin = {top: 20, right: 20, bottom: 30, left: 50},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom;


let points = [[0, 0], [1, 7],[2, 21],[3, 36],[4, 50],[5, 55],[6, 60],[7, 65],[8, 70],[9, 75],[10, 80],[11, 85],[12, 90],[13, 95],[14, 100],[15, 100]];

var x = d3.scaleLinear()
.rangeRound([0, width]);

var y = d3.scaleLinear()
.rangeRound([height, 0]);

var xAxis = d3.axisBottom(x),
yAxis = d3.axisLeft(y);

var line = d3.line()
.x(function(d) { return x(d[0]); })
.y(function(d) { return y(d[1]); });

let drag = d3.drag()
.on('start', dragstarted)
.on('drag', dragged)
.on('end', dragended);

svg.append('rect')
.attr('class', 'zoom')
.attr('cursor', 'move')
.attr('fill', 'none')
.attr('pointer-events', 'all')
.attr('width', width)
.attr('height', height)
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')

var focus = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

x.domain(d3.extent(points, function(d) { return d[0]; }));
y.domain(d3.extent(points, function(d) { return d[1]; }));

focus.append("path")
.datum(points)
.attr("fill", "none")
.attr("stroke", "green")
.attr("stroke-linejoin", "round")
.attr("stroke-linecap", "round")
.attr("stroke-width", 1.5)
.attr("d", line);

const pointG = focus.selectAll('g.point')
.data(points)
.enter()
.append('g')
.classed('point', true)
.attr('transform', d => `translate(${x(d[0])},${y(d[1])})`);

pointG.append('circle')
.attr('r', 5.0)
.style('cursor', 'pointer')
.style('fill', 'green');

pointG.append('text')
.attr("dx", ".71em")
.attr("dy", ".35em")
.text(function(d) { return d[1];});
focus.selectAll('g.point')
.call(drag);

focus.append('g')
.attr('class', 'axis axis--x')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);

focus.append('g')
.attr('class', 'axis axis--y')
.call(yAxis);


function dragstarted(d) {
d3.select(this).raise().classed('active', true);
}

function dragged(d) {
// d[0] = x.invert(d3.event.x); Restringe o movimento do eixo x
d[1] = y.invert(d3.event.y);
d3.select(this)
.attr('transform', `translate(${x(d[0])},${y(d[1])})`)
focus.select('path').attr('d', line);

}

function dragended(d) {
d3.select(this).classed('active', false);
}
<svg width="500" height="500"></svg>
<script src="https://d3js.org/d3.v4.min.js" charset="utf-8"></script>

最新更新