gpt4 book ai didi

javascript - 如何使用 d3.drag 处理散点图中的比例

转载 作者:行者123 更新时间:2023-12-02 22:20:58 24 4
gpt4 key购买 nike

我尝试在 D3 中实现具有拖动行为的散点图,但我不明白如何处理具有拖动效果的缩放。

现在我这样做了:

https://bl.ocks.org/AlexisPister/c60d570d6739a28dfd8ba0c9eae76866/518dc76870582d2fb8d43609e320e91cb246c19d

据我了解,有两个坐标系:我想要绘制的对象之一(每个对象由遵循正常规律的 x 和 y 坐标描述),以及显示的 Canvas 之一。 d3.scale 对象允许在两者之间映射。

首先,为了找到从 d3.event 对象的坐标拖动的对象,我循环遍历所有数据数组并查找哪个对象的缩放坐标等于 d3.event 的 x 和 y。

然后,我使用 d3.event 坐标修改此对象坐标,并使用比例对象进行逆变换,以从 Canvas 坐标系映射到对象坐标系。

但是,这不起作用:当拖动一个点时,它会移动,但不会移动到光标所在的位置。我不明白这种行为。

最佳答案

您需要知道鼠标位置并将其应用于当前的 x 和 y。做了一些更改,看看 mousePosition,您需要更多工作才能使其完美,但您会得到想法

    let width = 960,
height = 500,
radius = 3,
transform = d3.zoomIdentity

let canvas = d3.select("body").append("canvas")
.attr("width", width)
.attr("height", height)

let ctx = canvas.node().getContext("2d");

let data = d3.range(200)
.map(() => { return {"x": d3.randomNormal()(),
"y": d3.randomNormal()()}})

let scaleX = d3.scaleLinear()
.domain(d3.extent(data, function(d){return d.x}))
.range([0, width])

let scaleY = d3.scaleLinear()
.domain(d3.extent(data, function(d){return d.y}))
.range([height, 0])

//canvas.call(d3.zoom()
// .on("zoom", zoomed))

canvas.call(d3.drag()
.subject(dragSubject)
.on("drag", dragged))

function zoomed(){
transform = d3.event.transform
render()
}

function dragSubject(){

x = d3.event.x
y = d3.event.y


for(let i = 0; i < data.length; i++){

point = data[i]
dx = x - scaleX(point.x)
dy = y - scaleY(point.y)

if (dx * dx + dy * dy < radius * radius){
return data[i];
}
}
}


// get the position of the mouse, you need to calculate scale to
function mousePosition(event) {
if (event == undefined || (!event.pageX && !event.offsetX))
return {x:0, y:0}
return { x: event.pageX || event.offsetX, y: event.pageY || event.offsetY };
};

function dragged(){

var mouse = mousePosition(window.event)
d3.event.subject.x = scaleX.invert(d3.event.x + (mouse.x))
d3.event.subject.y = scaleY.invert(d3.event.y + mouse.y)


render()
}

function render(){
ctx.save()
ctx.clearRect(0, 0, width, height)

ctx.beginPath()
//ctx.translate(transform.x, transform.y)
//ctx.scale(transform.k, transform.k)

data.forEach(function(d){
ctx.moveTo(scaleX(d.x) + radius, scaleY(d.y))
ctx.arc(scaleX(d.x), scaleY(d.y), radius, 0, Math.PI * 2)
})
ctx.stroke()

/*
ctx.globalAlpha = 0.2
ctx.fillStyle = "blue"
ctx.fillRect(0,0,width,height) */

ctx.restore()
}

render()
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>

<body>

</body>

关于javascript - 如何使用 d3.drag 处理散点图中的比例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59228931/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com