gpt4 book ai didi

javascript - d3.js v4 minimap 或如何在两个元素上共享缩放?

转载 作者:行者123 更新时间:2023-11-29 10:32:21 25 4
gpt4 key购买 nike

我找到了 zooming with minimap 的这个很好的例子, 但它是用旧版本 v3 编写的。我几乎将其转换为 v4,但 d3.event 存在问题。在 v3 中,d3.event 似乎在调用缩放的两个元素之间共享缩放参数。因此,如果我在主 Canvas 上缩放,然后在小 map Canvas 上缩放 - d3.event 将具有主 Canvas 缩放 d3.event 的最后一个缩放值,它将继续缩放,因为它应该是。但是在 v4 中,两个 d3 缩放事件都以某种方式具有单独的缩放或平移值。如文档中所示:

The zoom behavior stores the zoom state on the element to which the zoom behavior was applied, not on the zoom behavior itself. This is because the zoom behavior can be applied to many elements simultaneously, and each element can be zoomed independently.

但这留下了一个问题,我如何才能在两个元素上共享一个缩放事件?

最佳答案

编辑:

也非常感谢 Bill White,他在同一主题中发布了他更新的文章 - D3 MINIMAP V4 UPDATE .这篇文章实际上是我在问题中发布的示例的更新。


可以找到问题的答案here .

@mbostock 在问题线程中亲切地回答了我的问题。我还找到了另一个解决方案。我成功地将他的代码中的一些逻辑和公式直接实现到我的缩放处理程序中。它就像一个魅力。

所以这是从 v3 到 v4 的更新缩放处理程序:

注意:不包括翻译边界检查。

// ....

var scale = 1;
var minScale = .5;
var maxScale = 7.5;
var translation = [0, 0];

// ....

// Used for both main canvas and minimap zoom
var zoom = d3.zoom()
.on('zoom', zoomHandler);

function zoomHandler(newScale) {
var prevScale = scale;
var previousTranslation = getXYFromTranslate(panCanvas.attr('transform'));
var isZoomEvent = d3.event && d3.event.sourceEvent.deltaY;
var isDragEvent = d3.event && (d3.event.sourceEvent.movementX || d3.event.sourceEvent.movementY);

if (isZoomEvent) {
scale = calculateNewScale(prevScale, d3.event.sourceEvent);
scale = checkScaleBounderies(scale);

var mousePosition = d3.mouse(this);

// Based on d3.js zoom algorythm
translation[0] = mousePosition[0] - ((mousePosition[0] - previousTranslation[0]) / prevScale) * scale;
translation[1] = mousePosition[1] - ((mousePosition[1] - previousTranslation[1]) / prevScale) * scale;
} else if (isDragEvent) {
translation[0] = previousTranslation[0] + d3.event.sourceEvent.movementX;
translation[1] = previousTranslation[1] + d3.event.sourceEvent.movementY;
} else if (newScale) {
scale = newScale;
}

// Apply the new dimensions to the main canvas
panCanvas.attr('transform', 'translate(' + translation + ') scale(' + scale + ')');

// Apply the new dimensions to the minimap
minimap.scale(scale).render();
}

// Calculate the new scale value based on d3.js zoom formula
function calculateNewScale(prevScale, event) {
return prevScale * Math.pow(2, -event.deltaY * (event.deltaMode ? 120 : 1) / 500);
}

// Check if scale has reached max or min
function checkScaleBounderies(newScale) {
return Math.max(minScale, Math.min(maxScale, newScale));
}

//....

function getXYFromTranslate(transform) {
// Create a dummy g for calculation purposes only. This will never
// be appended to the DOM and will be discarded once this function
// returns.
var g = document.createElementNS('http://www.w3.org/2000/svg', 'g');

// Set the transform attribute to the provided string value.
g.setAttributeNS(null, 'transform', transform);

// consolidate the SVGTransformList containing all transformations
// to a single SVGTransform of type SVG_TRANSFORM_MATRIX and get
// its SVGMatrix.
var matrix = g.transform.baseVal.consolidate().matrix;

// As per definition values e and f are the ones for the translation.
return [matrix.e, matrix.f];
}

关于javascript - d3.js v4 minimap 或如何在两个元素上共享缩放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42886375/

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