- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试将箭头添加到我的布局中,但它不起作用。问题是箭头没有出现在正确的位置,而是出现在我为每个节点绘制的矩形内。解决这个问题的更好方法是什么?我试过更改链接的坐标但没有成功,还尝试更改对 Angular 线对象,但没有成功。
我附加了一个 MWE,以便您可以看到当前状态。
var data = {
"name": "Eve",
"children": [
{
"name": "Cain"
},
{
"name": "Seth",
"children": [
{
"name": "Enos"
},
{
"name": "Noam"
}
]
},
{
"name": "Abel"
},
{
"name": "Awan",
"children": [
{
"name": "Enoch"
}
]
},
{
"name": "Azura"
}
]
};
let width = $(document).width();
let height = $(document).height();
const DX = 80;
const DY = 80;
const MIN_ZOOM = 0.15;
const MAX_ZOOM = Infinity;
const RECT_WIDTH = 40;
const RECT_HEIGHT = 15;
const TRANSITION_DURATION = 700;
let tree = d3.tree().nodeSize([DX, DY]);
let diagonal = d3.linkVertical()
.x(d => d.x + RECT_WIDTH / 2)
.y(d => d.y + RECT_HEIGHT / 2);
function createRoot() {
let root = d3.hierarchy(data);
root.x0 = DX / 2;
root.y0 = 0;
root.descendants().forEach((d, i) => {
d.id = i;
// Auxiliar variable to hide and show nodes when user clicks
d._children = d.children;
// Only the root is displayed at first sight
if (d.depth >= 0) d.children = null;
});
return root;
}
function update(source) {
const nodes = root.descendants().reverse();
const links = root.links();
// Compute the new tree layout
tree(root);
const transition = svg.transition()
.duration(TRANSITION_DURATION)
.tween("resize", window.ResizeObserver ? null : () => () => svg.dispatch("toggle"));
/*=============================NODE SECTION============================== */
// Obtain all the nodes
const node = gNode.selectAll("g")
.data(nodes, d => d.id);
// Enter any new nodes at the parent's previous position.
const nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", d => `translate(${source.x0},${source.y0})`)
.on("click", function (event, d) {
if (d.children) // Node expanded -> Collapse
collapse(d);
else // Node collapsed -> Expand
d.children = d._children
//If we want to restablish the last state is sufficient to do
//d.children = d.children ? null : d._children;
update(d);
centerNode(d);
})
.attr("pointer-events", d => d._children ? "all" : "none");
nodeEnter.append("rect")
// Two different classes, one for the leafs and another for the others
.attr("class", d => d._children ? "expandable" : "leaf")
.attr("height", RECT_HEIGHT)
.attr("width", RECT_WIDTH)
nodeEnter.append("text")
// The position of the text is centered
.attr("x", RECT_WIDTH / 2)
.attr("y", RECT_HEIGHT / 2)
.text(d => d.data.name)
.clone(true).lower();
// Transition nodes to their new position (update)
node.merge(nodeEnter).transition(transition)
.attr("transform", d => `translate(${d.x},${d.y})`)
// Show the nodes
.attr("fill-opacity", 1)
.attr("stroke-opacity", 1);
/* Transition exiting nodes to the parent's new position */
node.exit().transition(transition).remove()
.attr("transform", d => `translate(${source.x},${source.y})`)
// Hide the nodes
.attr("fill-opacity", 0)
.attr("stroke-opacity", 0);
/*=============================LINK SECTION============================== */
const link = gLink.selectAll("path")
.data(links, d => d.target.id);
// Enter any new links at the parent's previous position
const linkEnter = link.enter().append("path")
.attr("class", "link")
.attr("x", RECT_WIDTH / 2)
.attr("y", RECT_HEIGHT / 2)
.attr("marker-end", "url(#end)") // add the arrow to the link end
.attr("d", d => {
const o = {x: source.x0, y: source.y0};
return diagonal({source: o, target: o});
})
// Transition links to their new position
link.merge(linkEnter).transition(transition)
// In this case the link will be the same but moved by the transition
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position
link.exit().transition(transition).remove()
.attr("d", d => {
const o = {x: source.x, y: source.y};
return diagonal({source: o, target: o});
});
// Stash the old positions for transition
root.eachBefore(d => {
d.x0 = d.x;
d.y0 = d.y;
});
}
function centerNode(source) {
let scale = d3.zoomTransform(d3.select("svg").node()).k;
let x = -source.x0 * scale + width / 2 - RECT_WIDTH / 2 * scale;
let y = -source.y0 * scale + height / 2 - RECT_HEIGHT / 2 * scale;
// Define the transition
const transition = svg.transition()
.duration(TRANSITION_DURATION)
.tween("resize", window.ResizeObserver ? null : () => () => svg.dispatch("toggle"));
// Move all the nodes based on the previous parameters
svg.transition(transition)
.call(zoomBehaviours.transform, d3.zoomIdentity.translate(x,y).scale(scale));
}
function collapse(node) {
if (node.children) { // Expanded
node.children = null;
node._children.forEach(collapse)
}
}
// Root creation
const root = createRoot();
// SVG variable that will contain all the configuration for the images.
// We need to append it to the body
const svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
const g = svg.append("g");
// Two groups: One of links and another of nodes
const gLink = g.append("g");
const gNode = g.append("g");
const zoomBehaviours = d3.zoom()
.scaleExtent([MIN_ZOOM, MAX_ZOOM])
.on('zoom', (event) => g.attr('transform', event.transform));
// Add the zoom so that svg knows that it is available
svg.call(zoomBehaviours);
svg.append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 0)
.attr("refY", 0)
.attr("markerWidth", 5)
.attr("markerHeight", 5)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");
update(root);
centerNode(root);
.node {
cursor: pointer;
}
.node .expandable {
stroke: black;
stroke-width: 1.2;
fill: lightskyblue;
}
.node .leaf {
fill: lightskyblue;
}
.node text {
fill: black;
font: 10px sans-serif;
text-anchor: middle;
text-align: center;
dominant-baseline: central;
}
.link {
fill: none;
stroke: black;
stroke-width: 1.5;
stroke-opacity: 0.5;
}
body {
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
</body>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="https://d3js.org/d3.v6.min.js"></script>
<script src="./src/main.js"></script>
</html>
最佳答案
您始终可以按照自己的方式更改source
和target
。例如:
.attr("d", d => {
return diagonal({
source: d.source,
target: {
x: d.target.x,
y: d.target.y - RECT_HEIGHT
}
})
});
这样一来,您就可以独立于另一个进行更改,这仅使用路径生成器会比较困难。
这里是你的代码有那个变化:
var data = {
"name": "Eve",
"children": [{
"name": "Cain"
},
{
"name": "Seth",
"children": [{
"name": "Enos"
},
{
"name": "Noam"
}
]
},
{
"name": "Abel"
},
{
"name": "Awan",
"children": [{
"name": "Enoch"
}]
},
{
"name": "Azura"
}
]
};
let width = $(document).width();
let height = $(document).height();
const DX = 80;
const DY = 80;
const MIN_ZOOM = 0.15;
const MAX_ZOOM = Infinity;
const RECT_WIDTH = 40;
const RECT_HEIGHT = 15;
const TRANSITION_DURATION = 700;
let tree = d3.tree().nodeSize([DX, DY]);
let diagonal = d3.linkVertical()
.x(d => d.x + RECT_WIDTH / 2)
.y(d => d.y + RECT_HEIGHT / 2);
function createRoot() {
let root = d3.hierarchy(data);
root.x0 = DX / 2;
root.y0 = 0;
root.descendants().forEach((d, i) => {
d.id = i;
// Auxiliar variable to hide and show nodes when user clicks
d._children = d.children;
// Only the root is displayed at first sight
if (d.depth >= 0) d.children = null;
});
return root;
}
function update(source) {
const nodes = root.descendants().reverse();
const links = root.links();
// Compute the new tree layout
tree(root);
const transition = svg.transition()
.duration(TRANSITION_DURATION)
.tween("resize", window.ResizeObserver ? null : () => () => svg.dispatch("toggle"));
/*=============================NODE SECTION============================== */
// Obtain all the nodes
const node = gNode.selectAll("g")
.data(nodes, d => d.id);
// Enter any new nodes at the parent's previous position.
const nodeEnter = node.enter().append("g")
.attr("class", "node")
.attr("transform", d => `translate(${source.x0},${source.y0})`)
.on("click", function(event, d) {
if (d.children) // Node expanded -> Collapse
collapse(d);
else // Node collapsed -> Expand
d.children = d._children
//If we want to restablish the last state is sufficient to do
//d.children = d.children ? null : d._children;
update(d);
centerNode(d);
})
.attr("pointer-events", d => d._children ? "all" : "none");
nodeEnter.append("rect")
// Two different classes, one for the leafs and another for the others
.attr("class", d => d._children ? "expandable" : "leaf")
.attr("height", RECT_HEIGHT)
.attr("width", RECT_WIDTH)
nodeEnter.append("text")
// The position of the text is centered
.attr("x", RECT_WIDTH / 2)
.attr("y", RECT_HEIGHT / 2)
.text(d => d.data.name)
.clone(true).lower();
// Transition nodes to their new position (update)
node.merge(nodeEnter).transition(transition)
.attr("transform", d => `translate(${d.x},${d.y})`)
// Show the nodes
.attr("fill-opacity", 1)
.attr("stroke-opacity", 1);
/* Transition exiting nodes to the parent's new position */
node.exit().transition(transition).remove()
.attr("transform", d => `translate(${source.x},${source.y})`)
// Hide the nodes
.attr("fill-opacity", 0)
.attr("stroke-opacity", 0);
/*=============================LINK SECTION============================== */
const link = gLink.selectAll("path")
.data(links, d => d.target.id);
// Enter any new links at the parent's previous position
const linkEnter = link.enter().append("path")
.attr("class", "link")
.attr("x", RECT_WIDTH / 2)
.attr("y", RECT_HEIGHT / 2)
.attr("marker-end", "url(#end)") // add the arrow to the link end
.attr("d", d => {
const o = {
x: source.x0,
y: source.y0
};
return diagonal({
source: o,
target: o
});
})
// Transition links to their new position
link.merge(linkEnter).transition(transition)
// In this case the link will be the same but moved by the transition
.attr("d", d => {
return diagonal({
source: d.source,
target: {
x: d.target.x,
y: d.target.y - RECT_HEIGHT
}
})
});
// Transition exiting nodes to the parent's new position
link.exit().transition(transition).remove()
.attr("d", d => {
const o = {
x: source.x,
y: source.y
};
return diagonal({
source: o,
target: o
});
});
// Stash the old positions for transition
root.eachBefore(d => {
d.x0 = d.x;
d.y0 = d.y;
});
}
function centerNode(source) {
let scale = d3.zoomTransform(d3.select("svg").node()).k;
let x = -source.x0 * scale + width / 2 - RECT_WIDTH / 2 * scale;
let y = -source.y0 * scale + height / 2 - RECT_HEIGHT / 2 * scale;
// Define the transition
const transition = svg.transition()
.duration(TRANSITION_DURATION)
.tween("resize", window.ResizeObserver ? null : () => () => svg.dispatch("toggle"));
// Move all the nodes based on the previous parameters
svg.transition(transition)
.call(zoomBehaviours.transform, d3.zoomIdentity.translate(x, y).scale(scale));
}
function collapse(node) {
if (node.children) { // Expanded
node.children = null;
node._children.forEach(collapse)
}
}
// Root creation
const root = createRoot();
// SVG variable that will contain all the configuration for the images.
// We need to append it to the body
const svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
const g = svg.append("g");
// Two groups: One of links and another of nodes
const gLink = g.append("g");
const gNode = g.append("g");
const zoomBehaviours = d3.zoom()
.scaleExtent([MIN_ZOOM, MAX_ZOOM])
.on('zoom', (event) => g.attr('transform', event.transform));
// Add the zoom so that svg knows that it is available
svg.call(zoomBehaviours);
svg.append("svg:defs").selectAll("marker")
.data(["end"]) // Different link/path types can be defined here
.enter().append("marker") // This section adds in the arrows
.attr("id", String)
.attr("viewBox", "0 -5 10 10")
.attr("refX", 0)
.attr("refY", 0)
.attr("markerWidth", 5)
.attr("markerHeight", 5)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5");
update(root);
centerNode(root);
.node {
cursor: pointer;
}
.node .expandable {
stroke: black;
stroke-width: 1.2;
fill: lightskyblue;
}
.node .leaf {
fill: lightskyblue;
}
.node text {
fill: black;
font: 10px sans-serif;
text-anchor: middle;
text-align: center;
alignment-baseline: central;
}
.link {
fill: none;
stroke: black;
stroke-width: 1.5;
stroke-opacity: 0.5;
}
body {
overflow: hidden;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
</body>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="https://d3js.org/d3.v6.min.js"></script>
<script src="./src/main.js"></script>
</html>
关于javascript - 隐藏在矩形内的链接中的箭头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66638863/
我有一个 PSD 布局要开发,还有一些东西,比如“卡片”,我很好奇我是否可以在没有图像的情况下只使用 CSS3 边框来做到这一点。 http://i.imgur.com/NSZYPsh.png (这些
我想添加一个轻量级的导航栏来切换登录和注册。结果应如下所示: 箭头应指示当前所选页面。 最佳答案 引用这个question ,问题中的 UI 与您的相似,并且可以根据您的需要调整答案中使用的概念。 关
我想创建一个元组,它包含一个箭头和一个描述箭头的字符串。如果我使用函数(而不是箭头)这样做,则以下工作如预期: funTimes10 = (*10) describe10 = "times 10" t
var std_obj = { activeEffect : 'fade', name : 'Jane', displayMe() { const doSomeEffects =
我有一个使用TActionToolBar和TActionManager的工具栏。一个按钮具有子按钮,这些子按钮可通过单击按钮右侧的向下小箭头来使用。 “向下箭头”按钮的宽度非常薄,需要精确的鼠标控制。
我正在使用 Javascript 进行流网络可视化。顶点表示为圆圈,边表示为箭头。 这是我的 Edge 类: function Edge(u, v) { this.u = u; // start
这个问题已经有答案了: Show border triangle in navbar using CSS (3 个回答) 已关闭 7 年前。 我有一个列表菜单,其边框宽度为 1px ...100%。
有什么方法可以从 javafx 2.2 表列中的排序表列中删除排序指示符/箭头吗? 最佳答案 这可以通过 css 来完成 .table-view .arrow { -fx-background
在我的应用程序中,我使用了 googlemap。在那,我在一个特定的位置放置了一个物体(自行车或汽车)。然后我搬到了其他地方。现在,根据我当前的位置,我需要显示一个箭头(校园),即我放置汽车或自行车的
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and t
我一直在 goole 中搜索如何仅使用 css 创建箭头和框。我在这里找到了一个近乎完美的例子:- http://dabblet.com/gist/4639593 如何更改此代码,使箭头指向左而不是右
嗨,我正在为这个问题挠头。我想创建一个如图所示的 CSS 渐变箭头,并能够将红色部分的填充定义为百分比。红色 block 只是纯色。 从这里JFiddle示例 我在创建绿色箭头方面取得了一些进展,但三
我刚刚开始在 Android 中创建一些自定义 View ,但在圆外绘制位图(箭头)时遇到问题。 这是我的代码: Canvas osCanvas = new Canvas(windowFrame);
我正在尝试绘制一个具有渐变的左侧箭头。这是我正在使用的代码,但我不明白为什么它不起作用。 .left-arrow{ position: relative; &:after{ rig
是否可以使用 GD 在 PHP 中创建此图像?我知道我需要使用 GD 和 imagecreate、imagecolorallocate、imagedestroy 等...但我不知道如何做曲线 我需要用
我在我的区域 map 中有一个我正在使用的工具台 http://qtip2.com/ 我调用工具提示时的代码与这个问题中的相同Tooltip on map area tag jQuery(docume
我正在尝试在 Haskell 中学习 Arrows,所以我正在使用基于箭头的 HXT 库为 XML 编写一个简单的应用程序。 HXT wiki 和教程中的示例放弃了函数类型签名。但是,我非常喜欢类型,
我一直在使用 Haskell(特别是 Yampa)中的 Arrowized FRP 库,但我不太清楚如何进行“连续”切换。我的意思是信号通过信号函数(下面的 sf),它本身就是一个信号(如图像的上半部
我想要一个引用,清楚地说明 PHP 的箭头/方法调用运算符 (->) 在运算符绑定(bind)顺序方面的位置。 不幸的是,authoritative PHP manual page关于运算符优先级没有
如何隐藏 QScrollBar 箭头? 我需要隐藏在水平滚动条中。 我试图用 setStyleSheet 隐藏: setStyleSheet(" QScrollBar:left-arrow:horiz
我是一名优秀的程序员,十分优秀!