- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先对我的问题表示抱歉,因为我认为这是因为我不太了解 D3 库,尤其是 Selections 的工作原理。
这就是我想做的:
这里我不想完全重绘图表;我希望现有的节点和链接保持在原来的位置,而新的节点和链接飞入场景。这就是为什么我将力布局的实例保留在drawGraph函数之外(作为全局变量)。
任务 #1 顺利完成。
问题出在任务 #2 上;我可以让新节点进入场景...,但由于某种原因我无法拖动现有节点。我只能拖动新节点 (Eduardo)。
我在Chrome中调试了它,看到这个“var a”有9个元素(点击后)。因此,我认为 D3 应该为所有这 9 个元素调用函数“force.layout”。所以,如果我理解正确的话,我应该能够拖动所有 9 个圆圈。
但事实并非如此,所以我的代码有问题。谁能指出我哪里错了?
这是代码。之后是 JSON(两个独立的 json,news.json 和 news3.json)。
附加问题:
我不太明白为什么这个 block (关键函数)在第二次调用drawGraph函数时(当json更新为news3.json时)执行了17次(8 + 9)?我的期望是9倍。
var lineSelections = svg.selectAll('line')
.data(dataset.edges, function(d){
console.log(d);
return d.source.index + '.' + d.target.index;
});
提前致谢!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Force layout</title>
<script type="text/javascript" src="../d3/d3.v3.js"></script>
<style type="text/css">
#tooltip {
position: absolute;
width: 200px;
height: auto;
padding: 10px;
background-color: white;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
pointer-events: none;
}
#tooltip.hidden {
display: none;
}
#tooltip p {
margin: 0;
font-family: sans-serif;
font-size: 16px;
line-height: 20px;
}
</style>
</head>
<body>
<div id="tooltip" class="hidden">
<p><span id="type"></span></p>
<p><span id="name"></span></p>
</div>
<p id="refresh">Click on this text to update the chart with new data values (once).</p>
<script type="text/javascript">
//Width and height
var w = 500;
var h = 300;
//http://stackoverflow.com/questions/16455194/how-to-store-a-json-object-loaded-from-a-file
var force = d3.layout.force()
.size([w, h])
.linkDistance([20])
.charge([-50]);
var svg = d3.select('body')
.append('svg')
.attr('width', w)
.attr('height', h);
drawGraph = function(dataset) {
force
.nodes(dataset.nodes)
.links(dataset.edges)
.start();
var lineSelections = svg.selectAll('line')
.data(dataset.edges, function(d){
console.log(d);
return d.source.index + '.' + d.target.index;
});
//Create edges as lines
var edges = lineSelections
.enter()
.append('line')
.style('stroke', function(d) {
if (d.target.type === 'publication') {
return 'red';
} else {
return 'blue';
}
})
.style('stroke-width', function(d) {
return d.weight;
});
var groups = svg.selectAll('g')
.data(dataset.nodes, function(d) {
console.log(d.name);
return d.name;
})
.enter()
.append('g');
var nodes = groups
.append('circle')
.attr('r', function(d) {
if (d.type === 'publication') {
var radius = d.weight / 6;
if (radius < 5) {
radius = 5;
}
return radius;
} else {
return d.weight * 3;
}
})
.style('fill', function(d, i) {
if (d.type === 'publication') {
return 'black';
} else {
return 'green';
}
});
var a = svg.selectAll('g circle');
a.call(force.drag);
//Create labels
var text = groups
.append('text')
.text(function(d) {
if (d.type === 'publication') {
return d.name;
} else {
return '';
}
})
.attr('x', function(d, i) {
d.x;
})
.attr('y', function(d) {
d.x;
})
.attr('font-family', 'sans-serif')
.attr('font-size', '24px')
.attr('fill', 'orange');
groups
.on("mouseover", function(d) {
//Get this bar's x/y values, then augment for the tooltip
//var hmm = d3.select(this).select('circle').attr('cx');
var xPosition = d3.select(this).select('circle').attr('cx');
var yPosition = d3.select(this).select('circle').attr('cy');
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#type")
.text(d.type);
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#name")
.text(d.name);
//Show the tooltip
//d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function() {
//Hide the tooltip
d3.select("#tooltip").classed("hidden", true);
})
//Every time the simulation "ticks", this will be called
force.on('tick', function() {
edges.attr('x1', function(d) { return d.source.x; })
.attr('y1', function(d) { return d.source.y; })
.attr('x2', function(d) { return d.target.x; })
.attr('y2', function(d) { return d.target.y; });
nodes.attr('cx', function(d) { return d.x; })
.attr('cy', function(d) { return d.y; });
//Update all labels
svg.selectAll('text')
.data(dataset.nodes)
.attr('x', function(d, i) {
return d.x;
})
.attr('y', function(d) {
return d.y;
});
});
}
d3.json('news.json', function(dataset) {
drawGraph(dataset);
});
d3.select("p")
.on("click", function() {
});
d3.select("#refresh")
.on("click", function() {
d3.json('news3.json', function(dataset) {
console.log(dataset);
drawGraph(dataset);
});
});
</script>
</body>
</html>
<小时/>
news.json
{
"nodes": [
{ "name": "El Universal", "type": "publication", "weight": 10 },
{ "name": "Milenio", "type": "publication", "weight": 4},
{ "name": "Proceso", "type": "publication", "weight": 4},
{ "name": "Paco", "type": "person", "weight": 12},
{ "name": "Juan", "type": "person", "weight": 5},
{ "name": "Alberto", "type": "person", "weight": 5 },
{ "name": "Xochitl", "type": "person", "weight": 3 },
{ "name": "Reforma", "type": "publication", "weight": 2}
],
"edges": [
{ "source": 3, "target": 0, "weight": 9},
{ "source": 3, "target": 1, "weight": 3},
{ "source": 4, "target": 2, "weight": 4},
{ "source": 4, "target": 0, "weight": 1},
{ "source": 5, "target": 3, "weight": 5},
{ "source": 6, "target": 1, "weight": 1},
{ "source": 6, "target": 7, "weight": 2},
{ "source": 6, "target": 1, "weight": 1},
{ "source": 3, "target": 5, "weight": 4},
{ "source": 4, "target": 5, "weight": 1}
]
}
news3.json
{
"nodes": [
{ "name": "El Universal", "type": "publication", "weight": 10 },
{ "name": "Milenio", "type": "publication", "weight": 4},
{ "name": "Proceso", "type": "publication", "weight": 4},
{ "name": "Paco", "type": "person", "weight": 12},
{ "name": "Juan", "type": "person", "weight": 5},
{ "name": "Alberto", "type": "person", "weight": 5 },
{ "name": "Xochitl", "type": "person", "weight": 3 },
{ "name": "Reforma", "type": "publication", "weight": 2},
{ "name": "Eduardo", "type": "person", "weight": 2}
],
"edges": [
{ "source": 3, "target": 0, "weight": 9},
{ "source": 3, "target": 1, "weight": 3},
{ "source": 4, "target": 2, "weight": 4},
{ "source": 4, "target": 0, "weight": 1},
{ "source": 5, "target": 3, "weight": 5},
{ "source": 6, "target": 1, "weight": 1},
{ "source": 6, "target": 7, "weight": 2},
{ "source": 6, "target": 1, "weight": 1},
{ "source": 3, "target": 5, "weight": 4},
{ "source": 4, "target": 5, "weight": 1},
{ "source": 8, "target": 7, "weight": 2}
]
}
最佳答案
在我修改了分配给 force.on('tick', ...);
上的勾号事件的函数后,我得到了它的工作。 。小修改:而不是使用 groupSelection.selectAll('circle')
和groupSelection.selectAll('text')
,现在我用groupSelection.select('circle')
和groupSelection.select('text')
.
您可以看到一个工作演示here .
这是代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3: Force layout</title>
<script type="text/javascript" src="../d3/d3.v3.js"></script>
<style type="text/css">
#tooltip {
position: absolute;
width: 200px;
height: auto;
padding: 10px;
background-color: white;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
pointer-events: none;
}
#tooltip.hidden {
display: none;
}
#tooltip p {
margin: 0;
font-family: sans-serif;
font-size: 16px;
line-height: 20px;
}
</style>
</head>
<body>
<div id="tooltip" class="hidden">
<p><span id="type"></span></p>
<p><span id="name"></span></p>
</div>
<p id="refresh">Click on this text to update the chart with new data values (once).</p>
<script type="text/javascript">
//Width and height
var w = 300;
var h = 200;
//http://stackoverflow.com/questions/16455194/how-to-store-a-json-object-loaded-from-a-file
var force = d3.layout.force()
.size([w, h])
.linkDistance([20])
.charge([-50]);
var svg = d3.select('body')
.append('svg')
.attr('width', w)
.attr('height', h);
drawGraph = function(dataset) {
force.nodes(dataset.nodes);
force.links(dataset.edges);
force.start();
var lineSelections = svg.selectAll('line')
.data(dataset.edges, function(d){
return '.'.concat(d.source.name, '.', d.target.name);
});
lineSelections
.enter()
.append('line')
.style('stroke', function(d) {
if (d.target.type === 'publication') {
return 'red';
} else {
return 'blue';
}
})
.style('stroke-width', function(d) {
return d.weight;
});
var groupSelection = svg.selectAll('g')
.data(dataset.nodes, function(d) {
return d.name;
})
.call(force.drag);
var groups = groupSelection
.enter()
.append('g')
.call(force.drag);
groups
.append('circle')
.attr('r', function(d) {
if (d.type === 'publication') {
var radius = d.weight / 6;
if (radius < 5) {
radius = 5;
}
return radius;
} else {
return d.weight * 3;
}
})
.style('fill', function(d, i) {
if (d.type === 'publication') {
return 'black';
} else {
return 'green';
}
});
//Create labels
groups
.append('text')
.text(function(d) {
if (d.type === 'publication') {
return d.name;
} else {
return d.name;
}
})
.attr('x', function(d, i) {
d.x;
})
.attr('y', function(d) {
d.x;
})
.attr('font-family', 'sans-serif')
.attr('font-size', '14px')
.attr('fill', 'orange');
//Every time the simulation "ticks", this will be called
force.on('tick', function() {
lineSelections
.attr('x1', function(d) {
return d.source.x;
})
.attr('y1', function(d) {
return d.source.y;
})
.attr('x2', function(d) {
return d.target.x;
})
.attr('y2', function(d) {
return d.target.y;
});
groupSelection
.select('circle')
.attr('cx', function(d) {
return d.x;
})
.attr('cy', function(d) {
return d.y;
});
//Update all labels
groupSelection
.select('text')
.attr('x', function(d, i) {
return d.x;
})
.attr('y', function(d) {
return d.y;
});
});
}
d3.json('news.json', function(dataset) {
drawGraph(dataset);
});
d3.select("p")
.on("click", function() {
});
d3.select("#refresh")
.on("click", function() {
console.log('==================');
d3.json('news3.json', function(dataset) {
drawGraph(dataset);
});
});
</script>
</body>
</html>
关于javascript - D3、JSON、图表、强制布局、数据更新、不完全重绘、拖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22540348/
初学者 android 问题。好的,我已经成功写入文件。例如。 //获取文件名 String filename = getResources().getString(R.string.filename
我已经将相同的图像保存到/data/data/mypackage/img/中,现在我想显示这个全屏,我曾尝试使用 ACTION_VIEW 来显示 android 标准程序,但它不是从/data/dat
我正在使用Xcode 9,Swift 4。 我正在尝试使用以下代码从URL在ImageView中显示图像: func getImageFromUrl(sourceUrl: String) -> UII
我的 Ubuntu 安装 genymotion 有问题。主要是我无法调试我的数据库,因为通过 eclipse 中的 DBMS 和 shell 中的 adb 我无法查看/data/文件夹的内容。没有显示
我正在尝试用 PHP 发布一些 JSON 数据。但是出了点问题。 这是我的 html -- {% for x in sets %}
我观察到两种方法的结果不同。为什么是这样?我知道 lm 上发生了什么,但无法弄清楚 tslm 上发生了什么。 > library(forecast) > set.seed(2) > tts lm(t
我不确定为什么会这样!我有一个由 spring data elasticsearch 和 spring data jpa 使用的类,但是当我尝试运行我的应用程序时出现错误。 Error creatin
在 this vega 图表,如果我下载并转换 flare-dependencies.json使用以下 jq 到 csv命令, jq -r '(map(keys) | add | unique) as
我正在提交一个项目,我必须在其中创建一个带有表的 mysql 数据库。一切都在我这边进行,所以我只想检查如何将我所有的压缩文件发送给使用不同计算机的人。基本上,我如何为另一台计算机创建我的数据库文件,
我有一个应用程序可以将文本文件写入内部存储。我想仔细看看我的电脑。 我运行了 Toast.makeText 来显示路径,它说:/数据/数据/我的包 但是当我转到 Android Studio 的 An
我喜欢使用 Genymotion 模拟器以如此出色的速度加载 Android。它有非常好的速度,但仍然有一些不稳定的性能。 如何从 Eclipse 中的文件资源管理器访问 Genymotion 模拟器
我需要更改 Silverlight 中文本框的格式。数据通过 MVVM 绑定(bind)。 例如,有一个 int 属性,我将 1 添加到 setter 中的值并调用 OnPropertyChanged
我想向 Youtube Data API 提出请求,但我不需要访问任何用户信息。我只想浏览公共(public)视频并根据搜索词显示视频。 我可以在未经授权的情况下这样做吗? 最佳答案 YouTube
我已经设置了一个 Twilio 应用程序,我想向人们发送更新,但我不想回复单个文本。我只是想让他们在有问题时打电话。我一切正常,但我想在发送文本时显示传入文本,以确保我不会错过任何问题。我正在使用 p
我有一个带有表单的网站(目前它是纯 HTML,但我们正在切换到 JQuery)。流程是这样的: 接受用户的输入 --- 5 个整数 通过 REST 调用网络服务 在服务器端运行一些计算...并生成一个
假设我们有一个名为 configuration.js 的文件,当我们查看内部时,我们会看到: 'use strict'; var profile = { "project": "%Projec
这部分是对 Previous Question 的扩展我的: 我现在可以从我的 CI Controller 成功返回 JSON 数据,它返回: {"results":[{"id":"1","Sourc
有什么有效的方法可以删除 ios 中 CBL 的所有文档存储?我对此有疑问,或者,如果有人知道如何从本质上使该应用程序像刚刚安装一样,那也会非常有帮助。我们正在努力确保我们的注销实际上将应用程序设置为
我有一个 Rails 应用程序,它与其他 Rails 应用程序通信以进行数据插入。我使用 jQuery $.post 方法进行数据插入。对于插入,我的其他 Rails 应用程序显示 200 OK。但在
我正在为服务于发布请求的 API 调用运行单元测试。我正在传递请求正文,并且必须将响应作为帐户数据返回。但我只收到断言错误 注意:数据是从 Azure 中获取的 spec.js const accou
我是一名优秀的程序员,十分优秀!