- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有这个树形布局,需要它在 X 轴上使用时间刻度来将节点固定到日期。此外,我需要将根节点(它在 JSON 数据中有一个 is_root
属性)保留在时间范围之外。 Here是树形布局的 Codepen,我也将代码粘贴到这里:
var json = {
"name": "Meet Treat",
"is_root": true,
"children": [
{
"name": "Meeting 1",
"date": "Sun Jan 01 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 2",
"date": "Tue Jan 10 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 5",
"date": "Fri Feb 10 2012 00:00:00 GMT-0300 (ART)"
}
]
},
{
"name": "Meeting 4",
"date": "Wed Feb 01 2012 00:00:00 GMT-0300 (ART)"
}
]
},
{
"name": "Meeting 3",
"date": "Fri Jan 20 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 7",
"date": "Thu Mar 01 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 8",
"date": "Sat Mar 10 2012 00:00:00 GMT-0300 (ART)"
}
]
}
]
},
{
"name": "Meeting 6",
"date": "Mon Feb 20 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 9",
"date": "Tue Mar 20 2012 00:00:00 GMT-0300 (ART)"
},
{
"name": "Meeting 10",
"date": "Sun Apr 01 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 13",
"date": "Tue May 01 2012 00:00:00 GMT-0300 (ART)"
}
]
}
]
},
{
"name": "Meeting 11",
"date": "Tue Apr 10 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 14",
"date": "Thu May 10 2012 00:00:00 GMT-0300 (ART)"
},
{
"name": "Meeting 16",
"date": "Fri Jun 01 2012 00:00:00 GMT-0300 (ART)"
}
]
},
{
"name": "Meeting 12",
"date": "Fri Apr 20 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 15",
"date": "Sun May 20 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 17",
"date": "Sun Jun 10 2012 00:00:00 GMT-0300 (ART)"
}
]
},
{
"name": "Meeting 18",
"date": "Wed Jun 20 2012 00:00:00 GMT-0300 (ART)"
}
]
},
{
"name": "Meeting 19",
"date": "Sun Jul 01 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 21",
"date": "Fri Jul 20 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 22",
"date": "Wed Aug 01 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 23",
"date": "Fri Aug 10 2012 00:00:00 GMT-0300 (ART)"
},
{
"name": "Meeting 24",
"date": "Mon Aug 20 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 25",
"date": "Sat Sep 01 2012 00:00:00 GMT-0300 (ART)"
}
]
}
]
}
]
},
{
"name": "Meeting 27",
"date": "Thu Sep 20 2012 00:00:00 GMT-0300 (ART)"
}
]
},
{
"name": "Meeting 20",
"date": "Tue Jul 10 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 26",
"date": "Mon Sep 10 2012 00:00:00 GMT-0300 (ART)",
"children": [
{
"name": "Meeting 28",
"date": "Mon Oct 01 2012 00:00:00 GMT-0300 (ART)"
}
]
},
{
"name": "Meeting 29",
"date": "Wed Oct 10 2012 00:00:00 GMT-0300 (ART)"
}
]
}
]
};
var m = [20, 120, 20, 120],
w = 1280 - m[1] - m[3],
h = 1000 - m[0] - m[2],
i = 0,
root;
var tree = d3.layout.tree()
.size([h, w]);
var diagonal = d3.svg.diagonal()
.projection(function(d) { return [d.y, d.x]; });
var vis = d3.select("#graph").append("svg:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
root = json;
root.x0 = h / 2;
root.y0 = 0;
update(root);
function update(source) {
var duration = d3.event && d3.event.altKey ? 5000 : 500;
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse();
// Normalize for fixed-depth.
nodes.forEach(function(d) { d.y = d.depth * 180; });
// Update the nodes…
var node = vis.selectAll("g.node")
.data(nodes, function(d) { return d.id || (d.id = ++i); });
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
;//.on("click", function(d) { toggle(d); update(d); });
nodeEnter.append('image')
.attr('xlink:href', 'http://www.uni-regensburg.de/Fakultaeten/phil_Fak_II/Psychologie/Psy_II/beautycheck/english/durchschnittsgesichter/m(01-32)_gr.jpg')
.attr('width', 40)
.attr('height', 40)
.attr('x', -40)
.attr('y', -20)
.attr('clip-path', 'url(#clip1)');
var clip1 = nodeEnter.append('clipPath')
.attr('id', 'clip1')
.attr('x', 0)
.attr('y', 0);
clip1.append('circle')
.attr('r', 20)
.attr('cx', -20);
nodeEnter.append('image')
.attr('xlink:href', 'http://0.tqn.com/d/hairremoval/1/0/e/-/-/-/eyebrow-classic.jpg')
.attr('width', 40)
.attr('height', 40)
.attr('x', 0 )
.attr('y', -20)
.attr('clip-path', 'url(#clip2)');
var clip2 = nodeEnter.append('clipPath')
.attr('id', 'clip2')
.attr('x', 0)
.attr('y', 0);
clip2.append('circle')
.attr('r', 20)
.attr('cx', 20);
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr("transform", function(d) { return "translate(" + source.y + "," + source.x + ")"; })
.remove();
// Update the links…
var link = vis.selectAll("path.link")
.data(tree.links(nodes), function(d) { return d.target.id; });
// Enter any new links at the parent's previous position.
link.enter().insert("svg:path", "g")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: source.x0, y: source.y0};
return diagonal({source: o, target: o});
})
.transition()
.duration(duration)
.attr("d", diagonal);
// Transition links to their new position.
link.transition()
.duration(duration)
.attr("d", diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr("d", function(d) {
var o = {x: source.x, y: source.y};
return diagonal({source: o, target: o});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function(d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
代码很乱,因为我在玩一个例子。我试过的是添加这样的时间尺度:
var timeScale = d3.time.scale().domain([new Date(2012, 0, 1), new Date(2012, 10, 1)]).range([100, w]);
并替换这一行 (#231):
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; });
用这个:
.attr("transform", function(d) { return "translate(" + timeScale(new Date(d.date)) + "," + d.x + ")"; });
或者这个:
.attr("transform", function(d) { return "translate(" + d.y + "," + timeScale(new Date(d.date)) + ")"; });
但运气不好,他们失去了连贯的立场。另外,我不知道为什么在我所基于的示例中,它应用 CSS 转换 translate
使用 Y 然后 X 值,其中 translate
的 CSS 规范指出值应该首先是 X,然后是 Y。tree.nodes()
中是否缺少某些内容?
最佳答案
我知道怎么做了。首先,我们需要创建一个时间尺度:
var timeScale = d3.time.scale().domain([new Date(2012, 0, 1), new Date(2012, 10, 1)]).range([100, w]);
请注意,我设置了一个固定的日期范围。您可以构建一个逻辑来使用您的数据来获取它。
然后,更新节点的转换...
var nodeUpdate = node.transition()
.duration(duration)
.attr("transform", function(d) {
var y = timeScale(new Date(d.date));
if (d3.map(d).has('is_root')) {
y = d.y;
}
return "translate(" + y + "," + d.x + ")";
});
...以及链接的转换:
link.transition()
.duration(duration)
.attr("d", function (d) {
if (d3.map(d.source).has('is_root') && d.source.is_root) {
return diagonal({ source: { x: d.source.x, y: d.source.y }, target: { x: d.target.x, y: timeScale(new Date(d.target.date)) } });
}
return diagonal({ source: { x: d.source.x, y: timeScale(new Date(d.source.date)) }, target: { x: d.target.x, y: timeScale(new Date(d.target.date)) } });
});
最后,如果你想在图表上显示日期刻度,你可以添加以下代码,否则不需要。
var dates = [];
for (var i = 0; i < 12; i++) {
for (var j = 1; j <= 20; j += 9) {
(j == 19) && (j = 20);
dates.push(new Date(2012, i, j));
}
}
var axisGroup = vis.append('svg:g');
axisGroup.selectAll('.xTicks')
.data(dates)
.enter()
.append('svg:line')
.attr('x1', timeScale)
.attr('y1', -5)
.attr('x2', timeScale)
.attr('y2', h + 5)
.attr('stroke', 'lightgray')
.attr('stroke-width', 1)
.attr('class', 'xTicks');
axisGroup.selectAll('text.xAxisBottom')
.data(dates)
.enter()
.append('svg:text')
.text(function (datum) { return datum.getDate() + '/' + (datum.getMonth() + 1) + '/' + datum.getFullYear(); })
.attr('x', timeScale)
.attr('y', h + 20)
.attr('text-anchor', 'middle')
.attr('class', 'xAxisBottom');
它生成将被勾选的日期并添加相应的行和标签。
至于...
Also, I don't know why in the example I'm basing on, it applies the CSS transition translate using Y and then X values, where the CSS specification for translate states that values should be X first, then Y. Is there something that I'm missing from tree.nodes()?
以这种方式为链接创建对 Angular 线:
var diagonal = d3.svg.diagonal().projection(function(d) { return [d.y, d.x]; });
使用投影方法反转 X 和 Y 轴,并为其提供一个返回轴反转的函数。这就是为什么 Y 变成 X,反之亦然。
关于javascript - d3.js - 具有树状布局,如何更改 X 轴以在 D3 中使用时间刻度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12251005/
SO亲爱的 friend 们: 2014 年 3 月 18 日。我正在处理一种情况,在使用 ng-repeat 时,数组内的元素(我从 Json 字符串中获取)更改了原始顺序。 需要明确的是,数组中的
有很多问题询问如何在 JavaScript 单击处理程序中更改 div 的类,例如,此处:Change Div style onclick .我理解得很好(只需更改 .className),并且它有效
我从access导入了一个数据库到mysql,但其中一个表的列名“股数”带有空格,但我尝试更改、替换甚至删除列名,但失败了。任何人都可以帮助解决这一问题 String UpdateQuary = "U
我正在做一个随机的学校元素。 目前,我有一个包含两个 CSS 的页面。一种用于正常 View ,一种用于残障人士 View 。 此页面还包括两个按钮,它们将更改使用的样式表。 function c
我需要使用 javascript 更改 HTML 元素中的文本,但我不知道该怎么做。 ¿有什么帮助吗? 我把它定义成这样: Text I want to change. 我正在尝试这样做: docum
我在它自己的文件 nav_bar.shtml 中有一个主导航栏,每个其他页面都包含该导航栏。这个菜单栏是一个 jQuery 菜单栏(ApyCom 是销售这些导航栏的公司的名称)。导航栏上的元素如何确定
我正在摆弄我的代码,并开始想知道这个变化是否来自: if(array[index] == 0) 对此: if(!array[index] != 0) 可能会影响任何代码,或者它只是做同样的事情而我不需
我一直在想办法调整控制台窗口的大小。这是我正在使用的函数的代码: #include #include #define WIDTH 70 #define HEIGHT 35 HANDLE wHnd;
我有很多情况会导致相同的消息框警报。 有没有比做几个 if 语句更简单/更好的解决方案? PRODUCTS BOX1 BOX2 BOX3
我有一个包含这些元素的 XELEMENT B Bob Petier 19310227 1 我想像这样转换前缀。 B Bob Pet
我使用 MySQL 5.6 遇到了这种情况: 此查询有效并返回预期结果: select * from some_table where a = 'b' and metadata->>"$.countr
我想知道是否有人知道可以检测 R 中日期列格式的任何中断的包或函数,即检测日期向量格式更改的位置,例如: 11/2/90 12/2/90 . . . 15/Feb/1990 16/Feb/1990 .
我希望能够在小部件显示后更改 GtkButton 的标签 char *ButtonStance == "Connect"; GtkWidget *EntryButton = gtk_button_ne
我正在使用 Altera DE2 FPGA 开发板并尝试使用 SD 卡端口和音频线路输出。我正在使用 VHDL 和 C 进行编程,但由于缺乏经验/知识,我在 C 部分遇到了困难。 目前,我可以从 SD
注意到这个链接后: http://www.newscientist.com/blogs/nstv/2010/12/best-videos-of-2010-progress-bar-illusion.h
我想知道在某些情况下,即使剧本任务已成功执行并且 ok=2,ansible 也会显示“changed=0”。使用 Rest API 和 uri 模块时会发生这种情况。我试图找到解释但没有成功。谁能告诉
这个问题已经有答案了: 已关闭12 年前。 Possible Duplicate: add buttons to push notification alert 是否可以在远程通知显示的警报框中指定有
当您的 TabBarController 中有超过 5 个 View Controller 时,系统会自动为您设置一个“更多” View 。是否可以更改此 View 中导航栏的颜色以匹配我正在使用的颜
如何更改.AndroidStudioBeta文件夹的位置,默认情况下,该文件夹位于Windows中的\ .. \ User \ .AndroidStudioBeta,而不会破坏任何内容? /编辑: 找
我目前正在尝试将更具功能性的编程风格应用于涉及低级(基于 LWJGL)GUI 开发的项目。显然,在这种情况下,需要携带很多状态,这在当前版本中是可变的。我的目标是最终拥有一个完全不可变的状态,以避免状
我是一名优秀的程序员,十分优秀!