- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
已经显示了许多cases用于通过SVG Geometric Zooming进行力导向图几何缩放。
在几何缩放中,我只需要在缩放功能中添加一个transform属性。但是,在语义缩放中,如果仅在node中添加一个transform属性,则链接将不会连接到node。因此,我想知道在d3中是否存在针对力导向图的几何缩放的解决方案。
这是我的example,其几何缩放遵循先前的情况。我有两个问题:
当我缩小然后拖动整个图时,该图会奇怪地消失。
使用相同的重绘功能
function zoom() {
vis.attr("transform", transform);
}
function transform(d){
return "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")";
}
function zoom() {
node.call(transform);
// update link position
update();
}
function transform(d){
// change node x, y position, not sure what function to put here.
}
最佳答案
我试图找到一个很好的教程来链接,但是找不到真正涵盖所有问题的内容,因此我将自己逐步编写它。
首先,您需要清楚地了解您要完成的工作。这对于两种缩放类型是不同的。我真的不喜欢Mike Bostock引入的术语(这与术语的非d3使用并不完全一致),但我们也可能坚持与其他d3示例保持一致。
在“几何缩放”中,您将缩放整个图像。圆和线越来越大,也越来越远。 SVG具有通过“ transform”属性完成此操作的简便方法。在SVG元素上设置transform="scale(2)"
时,将其绘制为好像一切都大了两倍。对于一个圆,它的半径被绘制成两倍大,并且它的cx
和cy
位置被绘制成距(0,0)点的距离的两倍。整个坐标系发生变化,因此现在一个单位等于屏幕上的两个像素,而不是一个。
同样,transform="translate(-50,100)"
更改整个坐标系,以使坐标系的(0,0)点向左移动50个单位,并从左上角向下移动100个单位(这是默认的原点)。
如果同时翻译和缩放SVG元素,则顺序很重要。如果翻译未按比例缩放,则翻译将以原始单位进行。如果平移是按比例缩放,则平移将按比例缩放单位。d3.zoom.behavior()
方法创建一个侦听鼠标滚轮和拖动事件以及与缩放相关的触摸屏事件的函数。它将这些用户事件转换为自定义的“缩放”事件。
缩放事件有一个比例因子(一个数字)和一个转换因子(两个数字的数组),行为对象根据用户的移动来计算它们。您如何处理这些数字取决于您自己;他们不会直接改变任何东西。 (除了将缩放比例附加到缩放行为功能时,如后面所述。)
对于几何缩放,通常要做的是在包含要缩放内容的<g>
元素上设置比例并转换transform属性。本示例在由均匀放置的网格线组成的简单SVG上实现了几何缩放方法:
http://jsfiddle.net/LYuta/2/
缩放代码很简单:
function zoom() {
console.log("zoom", d3.event.translate, d3.event.scale);
vis.attr("transform",
"translate(" + d3.event.translate + ")"
+ " scale(" + d3.event.scale + ")"
);
}
<g>
元素,该元素本身包含我们要缩放的所有内容。平移和缩放因子直接来自d3行为创建的缩放事件。
stroke-width:1.5;
,但是对于屏幕上等于1.5的内容的定义和更改后的
<g>
元素中的其他任何内容都已更改。
.scaleExtent([min,max])
方法修改了缩放行为对象。这将限制行为将在缩放事件中使用的比例值,无论用户旋转了多少旋钮。
<g>
元素上,而不是
<svg>
本身。这是因为SVG元素作为一个整体被视为HTML元素,并且具有不同的转换语法和属性。
<g>
元素,该元素包含主
<g>
和背景矩形。此处有背景矩形,即使鼠标或触摸不在一行上,也可以观察到鼠标和触摸事件。
<g>
元素本身没有任何高度或宽度,因此无法直接响应用户事件,它仅接收其子级的事件。我将矩形保留为黑色,以便您可以知道它的位置,但是只要将其样式设置为
fill:none;
,就可以将其样式设置为
pointer-events:all;
。矩形不能位于要转换的
<g>
内,因为当您缩小时,响应缩放事件的区域也会缩小,并且可能会超出SVG边缘的视线。
<g>
元素,如
this version of the fiddle所示。但是,您通常不希望整个SVG区域上的事件触发缩放,因此最好知道如何以及为什么使用背景矩形选项。
zoomedPositionX = d3.event.translate[0] + d3.event.scale * dataPositionX
zoomedPositionY = d3.event.translate[1] + d3.event.scale * dataPositionY
vLines.attr("x1", function(d){return d;})
.attr("y1", 0)
.attr("x2", function(d){return d;})
.attr("y2", h);
vLines.attr("x1", function(d){
return d3.event.translate[0] + d*d3.event.scale;
})
.attr("y1", d3.event.translate[1])
.attr("x2", function(d){
return d3.event.translate[0] + d*d3.event.scale;
})
.attr("y2", d3.event.translate[1] + h*d3.event.scale);
function zoom() {
console.log("zoom", d3.event.translate, d3.event.scale);
scaleFactor = d3.event.scale;
translation = d3.event.translate;
tick(); //update positions
}
function tick() {
linkLines.attr("x1", function (d) {
return translation[0] + scaleFactor*d.source.x;
})
.attr("y1", function (d) {
return translation[1] + scaleFactor*d.source.y;
})
.attr("x2", function (d) {
return translation[0] + scaleFactor*d.target.x;
})
.attr("y2", function (d) {
return translation[1] + scaleFactor*d.target.y;
});
nodeCircles.attr("cx", function (d) {
return translation[0] + scaleFactor*d.x;
})
.attr("cy", function (d) {
return translation[1] + scaleFactor*d.y;
});
}
d3.mouse()
下移屏幕位置和数据位置之间的转换。使用
d3.mouse(SVGElement)
计算该SVGElement所使用的坐标系中鼠标的位置。因此,如果我们传入表示转换后的可视化效果的元素,它将返回可直接用于设置对象位置的坐标。
function dragged(d){
if (d.fixed) return; //root is fixed
//get mouse coordinates relative to the visualization
//coordinate system:
var mouse = d3.mouse(vis.node());
d.x = mouse[0];
d.y = mouse[1];
tick();//re-position this node and any links
}
d3.mouse()
返回的SVG坐标不再直接对应于数据坐标。您必须考虑比例和翻译。您可以通过重新排列上面给出的公式来做到这一点:
zoomedPositionX = d3.event.translate[0] + d3.event.scale * dataPositionX
zoomedPositionY = d3.event.translate[1] + d3.event.scale * dataPositionY
dataPositionX = (zoomedPositionX - d3.event.translate[0]) / d3.event.scale
dataPositionY = (zoomedPositionY - d3.event.translate[1]) / d3.event.scale
function dragged(d){
if (d.fixed) return; //root is fixed
//get mouse coordinates relative to the visualization
//coordinate system:
var mouse = d3.mouse(vis.node());
d.x = (mouse[0] - translation[0])/scaleFactor;
d.y = (mouse[1] - translation[1])/scaleFactor;
tick();//re-position this node and any links
}
.x()
和
.y()
方法将缩放对象附加到缩放行为对象。
/*** Configure zoom behaviour ***/
var zoomer = d3.behavior.zoom()
.scaleExtent([0.1,10])
//allow 10 times zoom in or out
.on("zoom", zoom)
//define the event handler function
.x(xScale)
.y(yScale);
//attach the scales so their domains
//will be updated automatically
function zoom() {
console.log("zoom", d3.event.translate, d3.event.scale);
//the zoom behaviour has already changed
//the domain of the x and y scales
//so we just have to redraw using them
drawLines();
}
function drawLines() {
//put positioning in a separate function
//that can be called at initialization as well
vLines.attr("x1", function(d){
return xScale(d);
})
.attr("y1", yScale(0) )
.attr("x2", function(d){
return xScale(d);
})
/* etc. */
/* Set the display size based on the SVG size and re-draw */
function setSize() {
var svgStyles = window.getComputedStyle(svg.node());
var svgW = parseInt(svgStyles["width"]);
var svgH = parseInt(svgStyles["height"]);
//Set the output range of the scales
xScale.range([0, svgW]);
yScale.range([0, svgH]);
//re-attach the scales to the zoom behaviour
zoomer.x(xScale)
.y(yScale);
//resize the background
rect.attr("width", svgW)
.attr("height", svgH);
//console.log(xScale.range(), yScale.range());
drawLines();
}
//adapt size to window changes:
window.addEventListener("resize", setSize, false)
setSize(); //initialize width and height
scale.invert()
。如果为
w = scale(x)
,则为
x = scale.invert(w)
。
function dragged(d){
if (d.fixed) return; //root is fixed
//get mouse coordinates relative to the visualization
//coordinate system:
var mouse = d3.mouse(vis.node());
d.x = xScale.invert(mouse[0]);
d.y = yScale.invert(mouse[1]);
tick();//re-position this node and any links
}
关于svg - d3中力向图的语义缩放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21344340/
我遇到了指针大小随链接宽度变化的问题。我希望能够根据节点之间的连接数动态更改链接宽度。这个功能似乎工作正常,但现在我的指针也改变了大小并移开了。我希望指针保持相同的大小而不是移动。这是 fiddle
我正在尝试根据用户在调查中选择的内容来更改 D3 中具有特定 ID 的节点的颜色。我有这行代码: $("#" + type).find("path, circle").attr("fill", "#3
我创建了一个力导向图,如 this它适用于结构类似于 Miserables.js 的 JSON 文件。该可视化显示了相互引用的出版物之间的网络。 以下代码定义源节点和目标节点的颜色: var colo
我在尝试在力导向图上使用过滤器时遇到困难。我可以过滤掉节点,但不能使关联的链接消失。我对 JavaScript 的了解非常有限,但我想逻辑应该是:如果节点被隐藏,则隐藏关联的链接。我走在正确的道路上吗
我正在尝试提高 D3 力定向图的性能。目前它使用 SVG 元素,但一旦节点数量达到 500 个并且链接 ~ 2000 个,它就几乎无法使用。我正在寻找一些渲染图表的替代方法。 Canvas 似乎是一个
我刚刚开始使用 d3 library .我花了几天时间探索 api 并查看示例,并根据 force-directed graph 开始了我自己的项目。示例。 如果不使用简单的形状(正方形、圆形),我如
我是一名优秀的程序员,十分优秀!