gpt4 book ai didi

javascript - 防止 D3js Sankey 图表中的循环

转载 作者:行者123 更新时间:2023-12-02 15:40:19 25 4
gpt4 key购买 nike

我正在尝试使用 d3 sankey plugin 创建桑基图具有动态运输数据。它在大多数情况下都工作得很好,除非我得到这样的数据集:

[{"DeparturePort":"CHARLESTON","ArrivalPort":"BREMERHAVEN","volume":5625.74},{"DeparturePort":"CHARLESTON","ArrivalPort":"ITAPOA","volume":2340},{"DeparturePort":"PT EVERGLADES","ArrivalPort":"PT AU PRINCE","volume":41.02},{"DeparturePort":"BREMERHAVEN","ArrivalPort":"CHARLESTON","volume":28}]

我的问题的关键是数据集中的第一个和最后一个条目。似乎在同一个桑基图中具有相反的方向会使 JavaScript 进入无限循环并杀死浏览器。关于如何防止这种情况发生有什么想法吗?

这是我的图表代码,其中 raw 是上面的对象:

var data = raw;
var units = "Volume";

var margin = { top: 100, right: 0, bottom: 30, left: 0 },
width = $("#"+divID).width() - margin.left - margin.right,
height = divID == "enlargeChart" ? 800 - margin.top - margin.bottom : 600 - margin.top - margin.bottom;

var formatNumber = d3.format(",.0f"), // zero decimal places
format = function (d) { return ""; },
color = d3.scale.ordinal()
.range(["#0077c0", "#FF6600"]);

// append the svg canvas to the page
var svg = d3.select("#"+divID).append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("font-size", "12px")
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");

// Set the sankey diagram properties
var sankey = d3.sankey(width)
.nodeWidth(10)
.nodePadding(10)
.size([width, height]);

var path = sankey.link();
// load the data (using the timelyportfolio csv method)
//d3.csv("sankey.csv", function (error, data) {

//set up graph in same style as original example but empty
graph = { "nodes": [], "links": [] };
var checklist = [];
data.forEach(function (d) {
if ($.inArray(d.DeparturePort, checklist) == -1) {
checklist.push(d.DeparturePort)
graph.nodes.push({ "name": d.DeparturePort });
}
if ($.inArray(d.ArrivalPort, checklist) == -1) {
checklist.push(d.ArrivalPort)
graph.nodes.push({ "name": d.ArrivalPort });
}
graph.links.push({
"source": d.DeparturePort,
"target": d.ArrivalPort,
"value": +d.volume
});
});

// return only the distinct / unique nodes
graph.nodes = d3.keys(d3.nest()
.key(function (d) { return d.name; })
.map(graph.nodes));

// loop through each link replacing the text with its index from node
graph.links.forEach(function (d, i) {
graph.links[i].source = graph.nodes.indexOf(graph.links[i].source);
graph.links[i].target = graph.nodes.indexOf(graph.links[i].target);
});

//now loop through each nodes to make nodes an array of objects
// rather than an array of strings
graph.nodes.forEach(function (d, i) {
graph.nodes[i] = { "name": d };
});


sankey
.nodes(graph.nodes)
.links(graph.links)
.layout(32);

// add in the links
var link = svg.append("g").selectAll(".link")
.data(graph.links)
.enter().append("path")
.attr("class", "link")
.attr("d", path)
.style("stroke-width", function (d) { return Math.max(1, d.dy); })
.sort(function (a, b) { setTimeout(function () { return b.dy - a.dy; }, 10);});

// add the link titles
link.append("title")
.text(function (d) {
return d.source.name + " → " +
d.target.name + "\n" + d.value.toFixed(0) + " TEU";
});
$("#" + divID + " .loading").addClass("hide");


// add in the nodes
var node = svg.append("g").selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function (d) {
//setTimeout(function () {
return "translate(" + d.x + "," + d.y + ")";
//}, 10);
})
.call(d3.behavior.drag()
.origin(function (d) { return d; })
.on("dragstart", function () {
this.parentNode.appendChild(this);
})
.on("drag", dragmove));

// add the rectangles for the nodes
node.append("rect")
.attr("height", function (d) { if (d.dy < 0) { d.dy = (d.dy * -1); } return d.dy; })
.attr("width", sankey.nodeWidth())
.style("fill", function (d) {
return d.color = color(d.name);
})
.style("stroke", function (d) {
return d3.rgb(d.color);
})
.append("title")
.text(function (d) {
return d.name + "\n" + format(d.value);
});
// add in the title for the nodes
node.append("text")
.attr("x", -6)
.attr("y", function (d) { return d.dy / 2; })
.attr("dy", ".35em")
.attr("text-anchor", "end")
.style("stroke", function (d) { return "#000000" })
.attr("transform", null)
.text(function (d) { return d.name; })
.filter(function (d) { return d.x < width / 2; })
.attr("x", 6 + sankey.nodeWidth())
.attr("text-anchor", "start");

// the function for moving the nodes
function dragmove(d) {
d3.select(this).attr("transform",
"translate(" + d.x + "," + (
d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))
) + ")");
sankey.relayout();
link.attr("d", path);
}
}, 0)

最佳答案

这是 sankey.js 脚本的问题。

请参阅此提交(在 sankey.js 的一个分支上),它修复了该问题: https://github.com/soxofaan/d3-plugin-captain-sankey/commit/0edba18918aac3e9afadffd4a169c47f88a98f81

while (remainingNodes.length) {

变成:

while (remainingNodes.length && x < nodes.length) {

这应该可以防止无限循环。

关于javascript - 防止 D3js Sankey 图表中的循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32641389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com