javascript - D3 - 如何在拖动功能中访问新数据
问题描述
我在一条线上有 5 个组元素,我可以将它们拖过那条线。
在拖动结束时,我将当前元素的位置保存在我的数据对象中。之后,如果我拖动另一个元素,数据数组似乎没有更新。每次在拖动功能中,我都会看到数据的初始状态。
进入、更新、退出
const settingsData = settings.map(({ day, ...rest }) => ({ x: scale(day), y: 50, ...rest}));
const group = d3.select('svg').selectAll(".handlersGroup").data(settingsData, ({ id }) => id);
group.exit().remove();
const itemGroup = group.enter().append('g')
.attr('transform', 'translate(0, 0)')
.attr('class', 'handlersGroup');
itemGroup.append('circle')
.attr("r", 14)
.attr("cy", d => d.y)
.attr("cx", d => d.x)
.style("fill", ({ color }) => color);
itemGroup.append('text')
.attr("y", d => d.y - 15)
.attr("x", d => d.x + 10)
.style("fill", 'black')
.style('opacity', 0)
.text(d => `${d.type} - ${Math.round(scale.invert(d.x))}`);
itemGroup.merge(group);
itemGroup
.call(drag)
.on('mouseover', function () {
d3.select(this).select('text').style('opacity', 1);
})
.on('mouseout', function () {
d3.select(this).select('text').style('opacity', 0);
});
拖动功能
const drag = d3.drag()
.on('drag', function(d) {
const currentX = d3.event.x;
const validatedX = currentX < 37 ?
d.x : currentX > width - 30 ?
d.x : currentX;
const startingTextCorrectionPoint = 500;
const moveAdditional = currentX > startingTextCorrectionPoint ? (currentX - startingTextCorrectionPoint) : 0;
d3.select(this).select("text").attr("x", d.x = validatedX - moveAdditional + 10);
d3.select(this).select('text').text((i) => `${d.type} - ${Math.round(scale.invert(validatedX))}`);
d3.select(this).select("circle")
.attr("cx", d.x = validatedX);
})
.on('start', function() {
d3.event.sourceEvent.stopPropagation()
d3.select(this).raise()
})
.on('end', function({ id, x }) {
// Here everytime settings is the initial data array and not the updated one.
const newSettings = settings.map(el => {
if (el.id === id) {
return {...el, day: Math.round(scale.invert(x))};
}
return el;
});
updateSettings(newSettings);
});
我可以用不同的方法更新设置数组而不使用地图,从而避免这个问题,但我想学习解决这个问题比避免它更好。
我相信我正在迭代的设置数据可以通过在初始声明期间存在的关闭来访问.call(drag)
,因此我无法获得新数据。
如何在函数中访问新的设置数据?
解决方案
目前,我通过更改一些代码并“避免”我最初的问题来解决我的问题。
.on('end', () => {
const nodesData = d3.selectAll('.handlersGroup').data();
const newSettings = nodesData.map(({ x, color, type, id }) =>
({ color, type, id, day: Math.round(scale.invert(x)) }));
updateSettings(newSettings);
});
如果有人知道如何直接访问更新的数据,请发布正确的解决方案
推荐阅读
- java - 调用 (Cucumber) Annotation 时的运行方法
- ios - Swift 仅将最后一项存储在 Array 中
- r - 如何将数据框列除以 3,但根据另一列内容跳过除法
- azure - 使用批准和部署从 azure 管道到 azure 应用服务
- java - 访问存储在 Hashmap 中的 json 有效负载值
- python - 滚动平均图例标签
- spring - 如何在登录时修改 Spring Boot 安全重定向以不重定向回登录?
- c# - 我试图将 oracle 10g 数据库与 C# 控制台应用程序连接起来。我收到无效用户名/密码的错误,即使它们是正确的
- android - 警报对话框不适应暗模式和非暗模式
- python - 带有 rpy2 的 Python 中的序数逻辑回归(R 的 Python 接口):共线预测变量的问题