Untitled
unknown
plain_text
2 years ago
9.0 kB
6
Indexable
<!DOCTYPE html>
<meta charset="utf-8">
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v6.js"></script>
<link rel="stylesheet" href="style.css">
<!-- Create a div for the header -->
<div id="my_header" style="text-align: center;">
<h1>Networks Graph for Top 100 BoardGames from BoardGameGeek.xom</h1>
<p>Legenda:</p>
<ul style="list-style: none; text-align: left;">
<li><span style="color: #ffffb2;">●</span> 0-5 collegamenti</li>
<li><span style="color: #fecc5c;">●</span> 6-10 collegamenti</li>
<li><span style="color: #fd8d3c;">●</span> 11-15 collegamenti</li>
<li><span style="color: #f03b20;">●</span> 16-20 collegamenti</li>
<li><span style="color: #bd0026;">●</span> 21+ collegamenti</li>
</ul>
</div>
<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
<body>
<script>
// set the dimensions and margins of the graph
const margin = { top: 10, right: 30, bottom: 30, left: 40 },
width = window.innerWidth - margin.left - margin.right,
height = window.innerHeight - margin.top - margin.bottom;
// Create a zoomable SVG element
const svg = d3.select("#my_dataviz")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.call(d3.zoom().on("zoom", function (event) {
svg.attr("transform", event.transform);
}))
.append("g")
.attr("transform",
`translate(${margin.left}, ${margin.top})`);
d3.json("output.json").then(function (data) {
const nodeMap = {};
data.nodes.forEach(node => {
const connectedNodes = data.links.filter(link => link.source == node.id || link.target == node.id)
.map(link => link.source == node.id ? link.target : link.source);
const connectedNodeNames = data.nodes.filter(node => connectedNodes.includes(node.id))
.map(node => node.name);
nodeMap[node.id] = connectedNodeNames;
});
// Define arrow marker
svg.append("defs").append("marker")
.attr("id", "arrow")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 25)
.attr("refY", 0)
.attr("markerWidth", 10)
.attr("markerHeight", 13)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5")
.style("fill", "#9999");
// Define arrow marker
svg.append("defs").append("marker")
.attr("id", "arrow-red")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 25)
.attr("refY", 0)
.attr("markerWidth", 10)
.attr("markerHeight", 13)
.attr("orient", "auto")
.append("path")
.attr("d", "M0,-5L10,0L0,5")
.style("fill", "red");
// Initialize the links
const link = svg
.selectAll("line")
.data(data.links)
.join("line")
.style("stroke", "#999")
.attr("marker-end", "url(#arrow)");
// Create a color scale
const colorScale = d3.scaleQuantize()
.domain([0, d3.max(data.nodes, function (d) {
// Get number of links for this node
return data.links.filter(link => link.source == d.id || link.target == d.id).length;
})])
.range(["#ffffb2", "#fecc5c", "#fd8d3c", "#f03b20", "#bd0026"]);
// Definisci il tooltip
var tip = d3.select("#my_dataviz").append("div")
.attr("class", "tooltip")
.style("opacity", 0)
// Define a pattern for each node
const patterns = svg
.selectAll("pattern")
.data(data.nodes)
.join("pattern")
.attr("id", d => `pattern-${d.id}`)
.attr("width", 1)
.attr("height", 1)
.append("image")
.attr("xlink:href", d => d.image)
.attr("width", 100)
.attr("height", 100)
.attr("x", -12.5)
.attr("y", -23);
// Initialize the nodes
const node = svg
.selectAll("circle")
.data(data.nodes)
.join("circle")
.attr("r", 25)
.style("fill", d => `url(#pattern-${d.id})`)
.attr("xlink:href", function (d) {
return d.image;
})
.on("click", function (event, d) {
// Find connected nodes
const connectedNodes = nodeMap[d.id];
// Show tooltip with connected node names
alert('Connected nodes: \n' + connectedNodes.join(" \n "));
console.log(connectedNodes)
})
.on("mousemove", function (event) {
var mouseX = event.clientX;
var mouseY = event.clientY;
tip.style("left", (mouseX + 10) + "px")
.style("top", (mouseY + 100) + "px")
})
.on("mouseover", (event, d) => {
var mouseX = event.clientX;
var mouseY = event.clientY;
const connectedNodes = nodeMap[d.id];
console.log("ao" + connectedNodes)
tip.style("opacity", 1)
.html('<br> Selected Game: ' + "<span style='color:green'>" + d.name + "</span>" +
'<br> Related games: <br>' + connectedNodes.join(" - \n "))
.style("top", (mouseY + 50) + "px");
link.filter(function (l) {
return l.source === d || l.target === d;
}).transition().duration(200).style("stroke", "red")
.attr("marker-end", "url(#arrow-red)");
})
.on("mouseout", (event, d) => {
tip.style("opacity", 0);
link.filter(function (l) {
return l.source === d || l.target === d;
}).transition().duration(2000).style("stroke", "#999")
.attr("marker-end", "url(#arrow)");
});
node.append("svg:image")
.attr("xlink:href", function (d) {
return d.image;
})
.attr("x", -25)
.attr("y", -25)
.attr("width", 50)
.attr("height", 50);
// Add labels to the nodes
const label = svg
.selectAll("text")
.data(data.nodes)
.join("text")
.attr("dx", 10)
.attr("dy", ".35em")
.style("font-size", 11)
.text(function (d) { return d.name });
// Let's list the force we wanna apply on the network
const simulation = d3.forceSimulation(data.nodes) // Force algorithm is applied to data.nodes
.force("link", d3.forceLink() // This force provides links between nodes
.id(function (d) { return d.id; }) // This provide the id of a node
.links(data.links) // and this the list of links
)
.force("charge", d3.forceManyBody().strength(-4000)) // This adds repulsion between nodes. Play with the -400 for the repulsion strength
.force("center", d3.forceCenter(width / 2, height / 2)) // This force attracts nodes to the center of the svg area
.on("end", ticked);
// This function is run at each iteration of the force algorithm, updating the nodes position.
function ticked() {
link
.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; });
node
.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; });
label
.attr("x", function (d) { return d.x; })
.attr("y", function (d) { return d.y; });
}
console.log(data.links)
});
</script>
</body>Editor is loading...