Spaces:
Running
Running
Commit
·
06f25d9
1
Parent(s):
f17e9d8
Import CSV
Browse files
script.js
CHANGED
|
@@ -513,10 +513,13 @@ function initDiagram() {
|
|
| 513 |
.attr("viewBox", [0, 0, width, height])
|
| 514 |
.attr("preserveAspectRatio", "xMinYMin");
|
| 515 |
|
| 516 |
-
// Create Sankey generator with
|
|
|
|
|
|
|
|
|
|
| 517 |
const sankey = d3.sankey()
|
| 518 |
.nodeWidth(parseInt(document.getElementById('node-width').value))
|
| 519 |
-
.nodePadding(
|
| 520 |
.size([width - textPadding, height - textPadding]); // Create a copy of the data
|
| 521 |
const graph = {
|
| 522 |
nodes: sankeyData.nodes.map(d => Object.assign({}, d)),
|
|
@@ -859,6 +862,9 @@ function importFromCSV(file) {
|
|
| 859 |
const nodeMap = {};
|
| 860 |
let nodeIndex = 0;
|
| 861 |
|
|
|
|
|
|
|
|
|
|
| 862 |
// Parse data rows
|
| 863 |
for (let i = 1; i < lines.length; i++) {
|
| 864 |
const values = lines[i].split(',').map(v => v.trim().replace(/"/g, ''));
|
|
@@ -870,15 +876,36 @@ function importFromCSV(file) {
|
|
| 870 |
|
| 871 |
if (isNaN(value)) continue;
|
| 872 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 873 |
// Add nodes if they don't exist
|
| 874 |
if (!(sourceName in nodeMap)) {
|
| 875 |
nodeMap[sourceName] = nodeIndex++;
|
| 876 |
-
sankeyData.nodes.push({
|
|
|
|
|
|
|
|
|
|
|
|
|
| 877 |
}
|
| 878 |
|
| 879 |
if (!(targetName in nodeMap)) {
|
| 880 |
nodeMap[targetName] = nodeIndex++;
|
| 881 |
-
sankeyData.nodes.push({
|
|
|
|
|
|
|
|
|
|
|
|
|
| 882 |
}
|
| 883 |
|
| 884 |
// Add link
|
|
@@ -889,6 +916,16 @@ function importFromCSV(file) {
|
|
| 889 |
});
|
| 890 |
}
|
| 891 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 892 |
updateLists();
|
| 893 |
initDiagram();
|
| 894 |
saveData();
|
|
@@ -896,6 +933,7 @@ function importFromCSV(file) {
|
|
| 896 |
reader.readAsText(file);
|
| 897 |
}
|
| 898 |
|
|
|
|
| 899 |
// Center diagram
|
| 900 |
function centerDiagram() {
|
| 901 |
nodePositions = {};
|
|
|
|
| 513 |
.attr("viewBox", [0, 0, width, height])
|
| 514 |
.attr("preserveAspectRatio", "xMinYMin");
|
| 515 |
|
| 516 |
+
// Create Sankey generator with dynamic padding based on node count
|
| 517 |
+
const nodeCount = sankeyData.nodes.length;
|
| 518 |
+
const dynamicPadding = Math.max(20, Math.min(120, Math.floor((height - textPadding) / (nodeCount * 1.5))));
|
| 519 |
+
|
| 520 |
const sankey = d3.sankey()
|
| 521 |
.nodeWidth(parseInt(document.getElementById('node-width').value))
|
| 522 |
+
.nodePadding(dynamicPadding)
|
| 523 |
.size([width - textPadding, height - textPadding]); // Create a copy of the data
|
| 524 |
const graph = {
|
| 525 |
nodes: sankeyData.nodes.map(d => Object.assign({}, d)),
|
|
|
|
| 862 |
const nodeMap = {};
|
| 863 |
let nodeIndex = 0;
|
| 864 |
|
| 865 |
+
// First pass: collect all unique nodes and their relationships
|
| 866 |
+
const nodeRelations = new Map(); // Track incoming/outgoing links for each node
|
| 867 |
+
|
| 868 |
// Parse data rows
|
| 869 |
for (let i = 1; i < lines.length; i++) {
|
| 870 |
const values = lines[i].split(',').map(v => v.trim().replace(/"/g, ''));
|
|
|
|
| 876 |
|
| 877 |
if (isNaN(value)) continue;
|
| 878 |
|
| 879 |
+
// Track relationships for column assignment
|
| 880 |
+
if (!nodeRelations.has(sourceName)) {
|
| 881 |
+
nodeRelations.set(sourceName, { in: 0, out: 0, totalValue: 0 });
|
| 882 |
+
}
|
| 883 |
+
if (!nodeRelations.has(targetName)) {
|
| 884 |
+
nodeRelations.set(targetName, { in: 0, out: 0, totalValue: 0 });
|
| 885 |
+
}
|
| 886 |
+
|
| 887 |
+
nodeRelations.get(sourceName).out += 1;
|
| 888 |
+
nodeRelations.get(sourceName).totalValue += value;
|
| 889 |
+
nodeRelations.get(targetName).in += 1;
|
| 890 |
+
nodeRelations.get(targetName).totalValue += value;
|
| 891 |
+
|
| 892 |
// Add nodes if they don't exist
|
| 893 |
if (!(sourceName in nodeMap)) {
|
| 894 |
nodeMap[sourceName] = nodeIndex++;
|
| 895 |
+
sankeyData.nodes.push({
|
| 896 |
+
name: sourceName,
|
| 897 |
+
color: "#4f46e5",
|
| 898 |
+
value: 0 // Will be updated later
|
| 899 |
+
});
|
| 900 |
}
|
| 901 |
|
| 902 |
if (!(targetName in nodeMap)) {
|
| 903 |
nodeMap[targetName] = nodeIndex++;
|
| 904 |
+
sankeyData.nodes.push({
|
| 905 |
+
name: targetName,
|
| 906 |
+
color: "#4f46e5",
|
| 907 |
+
value: 0 // Will be updated later
|
| 908 |
+
});
|
| 909 |
}
|
| 910 |
|
| 911 |
// Add link
|
|
|
|
| 916 |
});
|
| 917 |
}
|
| 918 |
|
| 919 |
+
// Update node values based on maximum flow
|
| 920 |
+
sankeyData.nodes.forEach(node => {
|
| 921 |
+
const relation = nodeRelations.get(node.name);
|
| 922 |
+
node.value = Math.max(
|
| 923 |
+
relation.totalValue,
|
| 924 |
+
relation.in ? relation.totalValue / relation.in : 0,
|
| 925 |
+
relation.out ? relation.totalValue / relation.out : 0
|
| 926 |
+
);
|
| 927 |
+
});
|
| 928 |
+
|
| 929 |
updateLists();
|
| 930 |
initDiagram();
|
| 931 |
saveData();
|
|
|
|
| 933 |
reader.readAsText(file);
|
| 934 |
}
|
| 935 |
|
| 936 |
+
|
| 937 |
// Center diagram
|
| 938 |
function centerDiagram() {
|
| 939 |
nodePositions = {};
|