我创建了一个CodePen来说明我的问题:
请参阅CodePen Simple Minimap dashed Viewport .
我是一个小团队的一员,我的工作是(除其他外)做小 Map . 笔中的代码是关于小 Map 的代码的简化版本 . 我是d3js的新手,所以我很高兴听到任何可以改进的东西 .
我遇到了关于虚线矩形的错误,它应该显示我们可以看到的大 Map 的哪个部分 . 平移工作,缩放可能会完成 - (在我看来)只剩下技术问题,当你缩放时,虚线矩形也会平移 . 缩放平移量取决于鼠标位置 - 如果鼠标位于左上角,则平移最小 . 鼠标移动到底部或右侧(或两者)越远,此错误就越明显 .
我正在使用d3.event获取有关平移和缩放量的信息,并注意到即使你根本没有平移,如果你只是缩放,d3.event.translate [0/1]包含值!= 0 . 我的方法有误吗?作为团队的新成员,我无法改变大部分代码,但我可以改变有关小 Map 的一切 .
我需要从中捕获平移和缩放事件
var rect = svg.append("rect")
...
.style("pointer-events", "all");
谁能告诉我我做错了什么?我已经坚持了几天这个问题,任何帮助都会受到很多赞赏 . 提前致谢!
HTML:
<div class="canvas" id="canvas"></div>
CSS:
body
{
background-color: #fcfcfc;
}
.canvas
{
position: absolute;
border-radius: 7px;
background-color: #ddd;
left: 7%;
top: 10%;
}
.minimap {
position: absolute;
border-radius: 8px;
border: 2px solid #c2d1f0;
bottom: 2%;
right: 2%;
}
JS:
var width = 800;
var height = 500;
var canvas = d3.select("#canvas")
.attr("width", width)
.attr("height", height);
var zoom = d3.behavior.zoom()
.scaleExtent([0.1, 10])
.on("zoom", zoomed);
var svg = canvas.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.call(zoom);
// invisible rectangle to handle mouse interaction
var rect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all");
var group = svg.append("g");
function zoomed() {
group.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
// update the minimap whenever pan or zoom have happened
updateMinimap();
}
// an array of circles just to have something to look at and as orientation
var circles = [
{x: 150, y: 100},
{x: 50, y: 50},
{x: 80, y: 350},
{x: 200, y: 150},
{x: 350, y: 200},
{x: 140, y: 300},
{x: 230, y: 280}
];
// draw those circles
group.selectAll("circle")
.data(circles)
.enter()
.append("circle")
.attr("r", 5)
.attr("fill", "red")
.attr("cx", function(d) {return d.x;})
.attr("cy", function(d) {return d.y;})
var minimapScale = 1 / 3; // size of big map times this = size of minimap
var minimapWidth = width * minimapScale;
var minimapHeight = height * minimapScale;
var minimap = canvas.append("svg")
.attr("class", "minimap")
.attr("width", minimapWidth)
.attr("height", minimapHeight);
// run it once so we can see it even if no action was done
updateMinimap();
function updateMinimap() {
// clear outdated objects from minimap
minimap.selectAll("*").remove();
// set default values
var scale = 1;
var dx = 0;
var dy = 0;
if (d3.event) { // overwrite those values when necessary
scale = d3.event.scale;
dx = -d3.event.translate[0] * minimapScale;
dy = -d3.event.translate[1] * minimapScale;
}
// debug output
//console.log("scale: " + scale + ", dx: " + dx + ", dy: " + dy);
// repaint objects on minimap
group.selectAll("*").each(function (circle) {
var cx = circle.x * minimapScale;
var cy = circle.y * minimapScale;
minimap.append("circle")
.attr("r", 2)
.attr("fill", "blue")
.attr("cx", cx)
.attr("cy", cy);
});
// draw the dashed rectangle, indicating where we are on the big map
drawDashedRectangle(scale, dx, dy);
}
function drawDashedRectangle(scale, dx, dy) {
minimap.append("rect")
.attr("x", dx)
.attr("y", dy)
.attr("width", minimapWidth / scale)
.attr("height", minimapHeight / scale)
.style("stroke-dasharray", (10, 5))
.style("stroke-width", 2)
.style("stroke", "gray")
.style("fill", "none");
}
虽然我们不需要在小 Map 上进行平移/缩放交互,但我们希望有something like that . 我们只需要在大 Map 上,小 Map 应该只反映这些变化 .