我正在制作一个桑基图来显示质量流(化学工程的东西)。
具有较少节点的较旧的 .json 文件可以完美地使用相同的代码(如下),但是如果我加载具有更多节点的 .json 文件,它不会显示出来,给我一个“未捕获的类型错误:无法读取属性”节点'未定义的”错误。它进一步说:(匿名函数)@ Sankey_C_11sept15.htm:87 t @ d3.min.js:1 u @ d3.min.js:1 我需要这些文件在没有互联网连接的情况下工作。
旧的 .json 文件有 18 个节点,而新的 .json 文件有 32 个节点,它们之间的连接更多。否则它们是相同的;我相信这不是语法错误。它没有显示的另一个可能原因是我超出了允许的宽度或适合所有连接的东西。我不知道如何改变它(我对此很菜鸟)。
代码:
<!DOCTYPE html>
<meta charset="utf-8">
<title>SANKEY_C 15sept15</title>
<style>
.node rect {
cursor: move;
fill-opacity: .9;
shape-rendering: crispEdges;
}
.node text {
pointer-events: none;
text-shadow: 0 1px 0 #fff;
}
.link {
fill: none;
stroke: #000;
stroke-opacity: .2;
}
.link:hover {
stroke-opacity: .5;
}
</style>
<header>
<a href="http://localhost:8888/">project d3</a>
<span class="date">15 September 2015</span>
</header>
<h1>Wastewater Biorefinery Sankey diagram: Carbon flows</h1>
<p>From formatted JSON, using Malcolm MacLean's book. Not 100% appropriate values yet.<br>
<br>
To Do: Order and distribute streams to load correctly automatically.<br>
To Do: Write macro to export values from .xls sheet into csv and update .htm file with a click of a button - better user interface.
<br>
To change web thingie to local host on UBUNTU, type into terminal:<br>
cd ~/Desktop/project_d3/sankey <br>
then, type <br>
python -m SimpleHTTPServer 8888 &<br>
Error note: this still requires a refresh and choosing the file from the webpage directory. Annoying.<br>
</p>
<body>
<p id="chart">
<script src="d3.min.js"></script>
<script src="sankey.js"></script>
<script> // These are the files you draw the design from - they have to be in the folder. These are not the data (mass flow) files.
var units = "kg C/day";
var margin = {top: 10, right: 10, bottom: 10, left: 10},
width = 1200 - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
var formatNumber = d3.format(",.0f"), // zero decimal places
format = function(d) { return formatNumber(d) + " " + units; },
color = d3.scale.category20();
// append the svg canvas to the page
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Set the sankey diagram properties
var sankey = d3.sankey()
.nodeWidth(36)
.nodePadding(40)
.size([width, height]);
var path = sankey.link();
// load the data (these are your unit processes.)
// TO DO: Write a macro that can create this file with the correct syntax from the excel sheet.)
d3.json("Sankey-formatted_11sept15.json", function(error, graph) { // Sankey_C_flows_6feb15.json is the old file that works
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) { return b.dy - a.dy; });
// add the link titles
link.append("title")
.text(function(d) {
return d.source.name + " → " +
d.target.name + "\n" + format(d.value); });
// add in the nodes
var node = svg.append("g").selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")"; })
.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) { return d.dy; })
.attr("width", sankey.nodeWidth())
.style("fill", function(d) {
return d.color = color(d.name.replace(/ .*/, "")); })
.style("stroke", function(d) {
return d3.rgb(d.color).darker(2); })
.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")
.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);
}
});
</script>
</body>
</html>
“损坏”的 .json 文件:
{
"nodes":[
{"node":0,"name":"A1: Raw, unsettled wastewater in"},
{"node":1,"name":"A2: Agricultural waste in"},
{"node":2,"name":"A3: Forestry waste in"},
{"node":3,"name":"A4: Municipal solid waste in"},
{"node":4,"name":"1. Separator (PST)"},
{"node":5,"name":"A. Splitter 1"},
{"node":6,"name":"2. Bacterial Bioreactor"},
{"node":7,"name":"B. Splitter 2"},
{"node":8,"name":"3. Separator 2"},
{"node":9,"name":"4. Algal bioreactor"},
{"node":10,"name":"C. Splitter 3"},
{"node":11,"name":"5. Separator 3"},
{"node":12,"name":"6. Macrophyte Bioreactor"},
{"node":13,"name":"7. Separator 4"},
{"node":14,"name":"8. Solids Bioreactor"},
{"node":15,"name":"9. Separator 5"},
{"node":16,"name":"G. Compliant effluent"},
{"node":17,"name":"I. Bacterial Product"},
{"node":18,"name":"J. Algal Oil"},
{"node":19,"name":"K. Algal bioproducts"},
{"node":20,"name":"L. Algal biomass"},
{"node":21,"name":"N. Cellulosic fibre"},
{"node":22,"name":"O. Cellulosic biomass"},
{"node":23,"name":"P. Fungal biomass products"},
{"node":24,"name":"Q. Compost"},
{"node":25,"name":"I2. Lost through DSP of bacterial product"},
{"node":26,"name":"J2. Lost through DSP of algal products"},
{"node":27,"name":"N2. Lost through DSP of macrophyte products"},
{"node":28,"name":"P2. Lost through DSP of fungal product"},
{"node":29,"name":"C4. CO2 emission (Bacterial)"},
{"node":30,"name":"E4. CO2 uptake (Algal)"},
{"node":31,"name":"M1. CO2 uptake (Macrophyte)"},
{"node":32,"name":"C4. CO2 emission (Fungal)"},
],
"links":[
{"source":0,"target":4,"value":511.098591549296},
{"source":1,"target":4,"value":28.169014084507},
{"source":2,"target":4,"value":63.3802816901409},
{"source":3,"target":4,"value":112.676056338028},
{"source":4,"target":5,"value":711.747323943662},
{"source":5,"target":6,"value":640.572591549296},
{"source":6,"target":7,"value":509.627428006126},
{"source":7,"target":6,"value":50.9627428006126},
{"source":7,"target":8,"value":458.664685205514},
{"source":8,"target":14,"value":179.678358787707},
{"source":8,"target":9,"value":83.2677858626846},
{"source":5,"target":9,"value":71.1747323943662},
{"source":9,"target":10,"value":188.740576962088},
{"source":10,"target":9,"value":18.8740576962088},
{"source":10,"target":11,"value":169.86651926588},
{"source":11,"target":12,"value":57.4187455906397},
{"source":12,"target":13,"value":62.5864326937972},
{"source":13,"target":14,"value":1.69385299492387},
{"source":4,"target":14,"value":3.57661971830986},
{"source":14,"target":15,"value":345.681595177502},
{"source":8,"target":17,"value":146.174970350742},
{"source":11,"target":18,"value":47.3549068819831},
{"source":11,"target":19,"value":1.19362399882216},
{"source":11,"target":20,"value":47.7163991674996},
{"source":13,"target":21,"value":25.7465655228428},
{"source":13,"target":22,"value":6.4366413807107},
{"source":15,"target":23,"value":65.9937590793412},
{"source":15,"target":24,"value":257.689916405047},
{"source":13,"target":16,"value":28.7093727953198},
{"source":6,"target":29,"value":181.906686103341},
{"source":30,"target":9,"value":15.4234825591918},
{"source":31,"target":12,"value":5.16768710315757},
{"source":14,"target":32,"value":282.830396054319},
{"source":8,"target":25,"value":48.7249901169141},
{"source":11,"target":26,"value":16.1828436269351},
{"source":13,"target":27,"value":0},
{"source":15,"target":28,"value":21.9979196931137},
]}
“好”的 .json 文件:
{
"nodes":[
{"node":0,"name":"WW in"},
{"node":1,"name":"PST"},
{"node":2,"name":"Bacterial Bioreactor"},
{"node":3,"name":"Bact. Separator"},
{"node":4,"name":"Algal bioreactor"},
{"node":5,"name":"Alg. Separator"},
{"node":6,"name":"Macrophyte Bioreactor"},
{"node":7,"name":"Mac. Separator"},
{"node":8,"name":"Solids Bioreactor"},
{"node":9,"name":"Total carbon out"},
{"node":10,"name":"Bacterial Product"},
{"node":11,"name":"Algal Oil"},
{"node":12,"name":"Algal bioproducts"},
{"node":13,"name":"Algal biomass"},
{"node":14,"name":"Compliant effluent"},
{"node":15,"name":"Cellulosic fibre"},
{"node":16,"name":"Cellulosic biomass"},
{"node":17,"name":"Fungal biomass products"},
{"node":18,"name":"Compost"}
],
"links":[
{"source":0,"target":1,"value":14697},
{"source":1,"target":2,"value":13954},
{"source":1,"target":8,"value":743},
{"source":2,"target":3,"value":13954},
{"source":3,"target":10,"value":4186},
{"source":3,"target":4,"value":5623},
{"source":3,"target":8,"value":4144},
{"source":4,"target":5,"value":5623},
{"source":5,"target":6,"value":2811},
{"source":5,"target":11,"value":421},
{"source":5,"target":12,"value":56},
{"source":5,"target":13,"value":2333},
{"source":6,"target":7,"value":2505},
{"source":6,"target":14,"value":281},
{"source":6,"target":8,"value":306},
{"source":7,"target":15,"value":250},
{"source":7,"target":16,"value":2254},
{"source":8,"target":17,"value":1038},
{"source":8,"target":18,"value":4155}
]}