javascript - 当我在 D3.js 中通过 MySQL 提供多个根时,如何停止错误?
问题描述
我一直在尝试使用 D3.js 生成一个家谱,以将 MySQL 数据直接显示到网页,目前我的代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css" integrity="sha512-1ycn6IcaQQ40/MKBW2W4Rhis/DbILU74C1vSrLJxCq57o941Ym01SwNsOMqvEBFlcgUa6xLiPY/NS5R+E6ztJQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
* {
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
path {
fill: none;
stroke: silver;
stroke-width: 2px;
}
rect {
width: 80px;
height: 40px;
fill: #ffffff;
stroke: silver;
stroke-width: 2px;
}
text {
dominant-baseline: middle;
text-anchor: middle;
}
.global-container {
width: 100vw;
height: 100vh;
}
.svg-container {
width: 100%;
height: 100%;
}
.tree-controls {
position: absolute;
float: right;
top: 0px;
right: 0px;
}
.tree-controls button{
float: right;
padding: 5px;
border: unset;
background-color: #7de37f;
color: #ffffff;
margin: 2.5px;
cursor: pointer;
}
.tree-controls button:hover{
background-color: #61b062;
}
.tree-controls button i{
padding-right: 5px;
}
.hide {
display: none;
}
</style>
</head>
<body onload="center()">
<div class="tree-controls">
<button onclick="zoomIn()"><i class="fas fa-search-plus"></i>| Zoom In</button></br>
<button onclick="zoomOut()"><i class="fas fa-search-minus"></i>| Zoom Out</button></br>
<button onclick="resetZoom()"><i class="fas fa-expand"></i>| Reset Zoom</button></br>
<button onclick="center()"><i class="fas fa-crosshairs"></i>| Center</button>
</div>
<div class="global-container">
</div>
<?php
include_once 'config/logconfig.php';
$conn = new mysqli($hostname, $username, $password, $database);
$queryall = mysqli_query($conn, "SELECT `id`,`pid`,`ppid`,`firstname` FROM product_data");
$rows = array();
while($r = mysqli_fetch_assoc($queryall)) {
$rows[] = $r;
}
$mysqloutput = json_encode($rows);
echo $mysqloutput;
?>
<script>
var data = <?php echo $mysqloutput?>;
console.log(data);
var svg = d3
.select("div.global-container")
.append("svg")
.attr("class", "svg-container")
.append("g")
.attr("class", "table-boundaries");
var dataStructure = d3
.stratify()
.id(function(d){return d.id;})
.parentId(function(d){return d.pid;})
(data);
var treeStructure = d3
.tree()
.size([1000,350]);
var information = treeStructure(dataStructure);
var connections = svg
.append("g")
.selectAll("path")
.data(information.links());
connections
.enter()
.append("path")
.attr("d", function(d){
return "M" + (d.source.x-20) + "," + d.source.y + " v 50 H" + d.target.x + " V" + d.target.y;
})
.attr("class", "connections");
var rectangles = svg
.append("g")
.selectAll("rect")
.data(information.descendants());
rectangles
.enter()
.append("rect")
.attr("x", function(d){return d.x-60;})
.attr("y", function(d){return d.y-20;})
.attr("class", "rectangles");
var spouseRectangles = svg
.append("g")
.selectAll("rect")
.data(information.descendants());
spouseRectangles
.enter()
.append("rect")
.attr("x", function(d){return d.x+60;})
.attr("y", function(d){return d.y-20;})
.classed("hide", function(d){
if(d.data.ppid == null)
return true;
else
return false;
});
var names = svg
.append("g")
.selectAll("text")
.data(information.descendants());
names
.enter()
.append("text")
.text(function(d){return d.data.firstname;})
.attr("x", function(d){return d.x-20;})
.attr("y", function(d){return d.y;})
.attr("class", "names");
let zoom = d3
.zoom()
.scaleExtent([0.25, 10])
.on("zoom", handleZoom);
function initZoom() {d3
.select("svg")
.call(zoom);
}
function handleZoom(e) {d3
.select("svg g")
.attr("transform", e.transform);
}
function zoomIn() {d3
.select("svg")
.transition()
.call(zoom.scaleBy, 2);
}
function zoomOut() {d3
.select("svg")
.transition()
.call(zoom.scaleBy, 0.5);
}
function resetZoom() {d3
.select("svg")
.transition()
.call(zoom.scaleTo, 1);
}
function center() {d3
.select("svg")
.transition()
.call(zoom.translateTo, 0.5 * 330, 0.5 * 340);
}
initZoom();
update();
</script>
</body>
</html>
我正在为 D3.js 提供以下 JSON:
[{"id":"1","pid":null,"ppid":null,"firstname":"Liam"},{"id":"2","pid":"1","ppid":null,"firstname":"Monster"},{"id":"3","pid":"1","ppid":null,"firstname":"Cherry"},{"id":"5","pid":"3","ppid":null,"firstname":"Chandler"},{"id":"6","pid":"3","ppid":null,"firstname":"Fan"},{"id":"7","pid":"1","ppid":null,"firstname":"Derek"},{"id":"8","pid":"1","ppid":null,"firstname":"Sarah"},{"id":"9","pid":"2","ppid":null,"firstname":"Freyah"},{"id":"14","pid":null,"ppid":"2","firstname":"Miss"}]
我不断收到这个错误:
未捕获的错误:e (d3.v7.min.js:2) at (index):105 的多个根
我尝试更改配偶矩形采用的数据类型,但无法弄清楚为什么会出现此错误。
解决方案
你有两个没有 no 的对象parentId
,第一个和最后一个(都有pid: null
)。也就是说,错误消息是正确的:您只能有一个根节点(没有父节点的节点)。
假设最后一个对象有错字并且pid
和ppid
属性被交换,你有一个只有一个根的适当层次结构:
const data = [{
"id": "1",
"pid": null,
"ppid": null,
"firstname": "Liam"
}, {
"id": "2",
"pid": "1",
"ppid": null,
"firstname": "Monster"
}, {
"id": "3",
"pid": "1",
"ppid": null,
"firstname": "Cherry"
}, {
"id": "5",
"pid": "3",
"ppid": null,
"firstname": "Chandler"
}, {
"id": "6",
"pid": "3",
"ppid": null,
"firstname": "Fan"
}, {
"id": "7",
"pid": "1",
"ppid": null,
"firstname": "Derek"
}, {
"id": "8",
"pid": "1",
"ppid": null,
"firstname": "Sarah"
}, {
"id": "9",
"pid": "2",
"ppid": null,
"firstname": "Freyah"
}, {
"id": "14",
"pid": "2",
"ppid": null,
"firstname": "Miss"
}];
const dataStructure = d3
.stratify()
.id(function(d) {
return d.id;
})
.parentId(function(d) {
return d.pid;
})
(data);
console.log(dataStructure)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
但是,如果这不是一个错字,并且您确实有一个具有两个根节点的数据结构,那么您就没有惯用的 D3 解决方案,因为 D3 层次结构明确禁止多个根节点。在这种情况下,您必须编写自己的 JavaScript 或调整 D3 源代码。
推荐阅读
- excel - 将新数据导入现有表访问 vba
- csv - 读取多个文件的替代行并将它们聚合到单个 CSV
- python-3.x - 如何更改熊猫中列名的位置?
- cmd - 在 NetBeans 中安装、配置和测试 WebLogic Server 12c Developer Zip Distribution
- ruby-on-rails - 创建一个 JSON 对象发送回客户端
- javascript - 仅传递不带引号的对象的 ID 名称
- c# - 使用 For 循环中的 WebElement 索引遍历 HTML 表中的“tr”行
- javascript - Knockoutjs vm 没有绑定到正确的元素
- kendo-grid - Angular2 Kendo在过滤器更改后获取或读取网格结果
- macos - 在 MacOS 上使用 Julia 0.7.0 的 TensorFlow.jl 出现分段错误