knowledge-graph-s1 / index.html
Arg1990's picture
Add 2 files
a866253 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Knowledge Graph</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.node {
transition: all 0.3s ease;
cursor: pointer;
}
.node:hover {
transform: scale(1.05);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.link {
stroke: #94a3b8;
stroke-width: 2px;
}
.graph-container {
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
border-radius: 1rem;
}
.tooltip {
position: absolute;
padding: 0.5rem 1rem;
background: white;
border-radius: 0.5rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
pointer-events: none;
opacity: 0;
transition: opacity 0.2s;
z-index: 10;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
.pulse {
animation: pulse 2s infinite;
}
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<div class="container mx-auto px-4 py-12">
<div class="text-center mb-12">
<h1 class="text-4xl font-bold text-gray-800 mb-4">Interactive Knowledge Graph</h1>
<p class="text-xl text-gray-600 max-w-3xl mx-auto">
Visualize complex relationships between concepts in an interactive network diagram.
</p>
<div class="mt-6 flex justify-center space-x-4">
<button id="physicsBtn" class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition">
<i class="fas fa-atom mr-2"></i>Toggle Physics
</button>
<button id="addNodeBtn" class="px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition">
<i class="fas fa-plus mr-2"></i>Add Node
</button>
<button id="resetBtn" class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition">
<i class="fas fa-redo mr-2"></i>Reset Graph
</button>
</div>
</div>
<div class="graph-container relative p-6 shadow-xl">
<div id="graph" class="w-full h-[600px]"></div>
<div id="tooltip" class="tooltip"></div>
</div>
<div class="mt-12 grid grid-cols-1 md:grid-cols-3 gap-8">
<div class="bg-white p-6 rounded-xl shadow-md">
<div class="flex items-center mb-4">
<div class="w-10 h-10 rounded-full bg-blue-100 flex items-center justify-center mr-4">
<i class="fas fa-info-circle text-blue-600"></i>
</div>
<h3 class="text-xl font-semibold text-gray-800">What is a Knowledge Graph?</h3>
</div>
<p class="text-gray-600">
A knowledge graph is a network of interconnected entities and their relationships.
It represents information in a way that's closer to how humans think about concepts.
</p>
</div>
<div class="bg-white p-6 rounded-xl shadow-md">
<div class="flex items-center mb-4">
<div class="w-10 h-10 rounded-full bg-purple-100 flex items-center justify-center mr-4">
<i class="fas fa-project-diagram text-purple-600"></i>
</div>
<h3 class="text-xl font-semibold text-gray-800">Graph Features</h3>
</div>
<ul class="text-gray-600 space-y-2">
<li class="flex items-start">
<i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
<span>Interactive nodes and connections</span>
</li>
<li class="flex items-start">
<i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
<span>Physics-based simulation</span>
</li>
<li class="flex items-start">
<i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
<span>Dynamic tooltips</span>
</li>
</ul>
</div>
<div class="bg-white p-6 rounded-xl shadow-md">
<div class="flex items-center mb-4">
<div class="w-10 h-10 rounded-full bg-green-100 flex items-center justify-center mr-4">
<i class="fas fa-lightbulb text-green-600"></i>
</div>
<h3 class="text-xl font-semibold text-gray-800">Try It Out</h3>
</div>
<p class="text-gray-600 mb-4">
Click on nodes to see details. Drag nodes to rearrange the graph. Use the buttons above to control the visualization.
</p>
<div class="flex space-x-2">
<span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm">Interactive</span>
<span class="px-3 py-1 bg-purple-100 text-purple-800 rounded-full text-sm">Dynamic</span>
<span class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm">Responsive</span>
</div>
</div>
</div>
</div>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Sample knowledge graph data
const graphData = {
nodes: [
{ id: 1, name: "Artificial Intelligence", type: "concept", description: "The simulation of human intelligence processes by machines.", color: "#3B82F6" },
{ id: 2, name: "Machine Learning", type: "subfield", description: "A subset of AI that enables systems to learn from data.", color: "#10B981" },
{ id: 3, name: "Neural Networks", type: "technique", description: "Computational models inspired by biological neural networks.", color: "#8B5CF6" },
{ id: 4, name: "Deep Learning", type: "method", description: "ML technique using multi-layered neural networks.", color: "#EC4899" },
{ id: 5, name: "Natural Language Processing", type: "application", description: "AI field focused on interactions between computers and human language.", color: "#F59E0B" },
{ id: 6, name: "Computer Vision", type: "application", description: "Field of AI that enables computers to interpret visual data.", color: "#6366F1" },
{ id: 7, name: "Reinforcement Learning", type: "method", description: "ML method where agents learn by taking actions in an environment.", color: "#EF4444" }
],
links: [
{ source: 1, target: 2, relation: "includes" },
{ source: 2, target: 3, relation: "uses" },
{ source: 3, target: 4, relation: "basis of" },
{ source: 2, target: 5, relation: "applies to" },
{ source: 2, target: 6, relation: "applies to" },
{ source: 2, target: 7, relation: "includes" },
{ source: 4, target: 5, relation: "enhances" },
{ source: 4, target: 6, relation: "enhances" }
]
};
// Set up the SVG container
const width = document.getElementById('graph').clientWidth;
const height = document.getElementById('graph').clientHeight;
const svg = d3.select("#graph")
.append("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [0, 0, width, height])
.attr("style", "max-width: 100%; height: auto;");
// Set up the simulation
const simulation = d3.forceSimulation(graphData.nodes)
.force("link", d3.forceLink(graphData.links).id(d => d.id).distance(150))
.force("charge", d3.forceManyBody().strength(-500))
.force("center", d3.forceCenter(width / 2, height / 2))
.force("collision", d3.forceCollide().radius(60));
// Create the links
const link = svg.append("g")
.selectAll("line")
.data(graphData.links)
.join("line")
.attr("class", "link")
.attr("stroke-width", 2);
// Add link labels
const linkText = svg.append("g")
.selectAll("text")
.data(graphData.links)
.join("text")
.attr("font-size", 12)
.attr("fill", "#64748b")
.text(d => d.relation);
// Create the nodes
const node = svg.append("g")
.selectAll("g")
.data(graphData.nodes)
.join("g")
.attr("class", "node")
.call(drag(simulation));
// Add circles to the nodes
node.append("circle")
.attr("r", 25)
.attr("fill", d => d.color)
.attr("stroke", "#fff")
.attr("stroke-width", 2);
// Add icons to the nodes based on type
node.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white")
.attr("font-size", "12px")
.html(d => {
switch(d.type) {
case "concept": return "🧠";
case "subfield": return "πŸ”";
case "technique": return "βš™οΈ";
case "method": return "πŸ“Š";
case "application": return "πŸ’»";
default: return "πŸ”˜";
}
});
// Add node labels
const labels = node.append("text")
.attr("dy", 50)
.attr("text-anchor", "middle")
.attr("fill", "#1e293b")
.attr("font-weight", "600")
.text(d => d.name)
.clone(true).lower()
.attr("stroke", "white")
.attr("stroke-width", 3);
// Tooltip setup
const tooltip = d3.select("#tooltip");
node.on("mouseover", function(event, d) {
d3.select(this).select("circle").attr("r", 30);
tooltip.transition()
.duration(200)
.style("opacity", 1);
tooltip.html(`
<h3 class="font-bold text-lg mb-1" style="color: ${d.color}">${d.name}</h3>
<p class="text-sm text-gray-600 mb-1">Type: ${d.type}</p>
<p class="text-sm text-gray-700">${d.description}</p>
`)
.style("left", (event.pageX + 10) + "px")
.style("top", (event.pageY + 10) + "px");
})
.on("mouseout", function() {
d3.select(this).select("circle").attr("r", 25);
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
// Update positions on each tick
simulation.on("tick", () => {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y);
linkText
.attr("x", d => (d.source.x + d.target.x) / 2)
.attr("y", d => (d.source.y + d.target.y) / 2);
node
.attr("transform", d => `translate(${d.x},${d.y})`);
});
// Drag behavior
function drag(simulation) {
function dragstarted(event, d) {
if (!event.active) simulation.alphaTarget(0.3).restart();
d.fx = d.x;
d.fy = d.y;
}
function dragged(event, d) {
d.fx = event.x;
d.fy = event.y;
}
function dragended(event, d) {
if (!event.active) simulation.alphaTarget(0);
d.fx = null;
d.fy = null;
}
return d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended);
}
// Button interactions
let physicsEnabled = true;
document.getElementById('physicsBtn').addEventListener('click', function() {
physicsEnabled = !physicsEnabled;
if (physicsEnabled) {
simulation.alphaTarget(0.3).restart();
this.innerHTML = '<i class="fas fa-atom mr-2"></i>Toggle Physics';
this.classList.remove('bg-gray-600');
this.classList.add('bg-blue-600');
} else {
simulation.alphaTarget(0);
this.innerHTML = '<i class="fas fa-pause mr-2"></i>Toggle Physics';
this.classList.remove('bg-blue-600');
this.classList.add('bg-gray-600');
}
});
document.getElementById('resetBtn').addEventListener('click', function() {
// Reset node positions
graphData.nodes.forEach(node => {
node.fx = null;
node.fy = null;
node.x = Math.random() * width;
node.y = Math.random() * height;
});
if (physicsEnabled) {
simulation.alpha(1).restart();
}
// Add pulse animation to all nodes temporarily
node.select("circle").classList.add("pulse");
setTimeout(() => {
node.select("circle").classList.remove("pulse");
}, 2000);
});
document.getElementById('addNodeBtn').addEventListener('click', function() {
const newNodeId = graphData.nodes.length + 1;
const colors = ["#3B82F6", "#10B981", "#8B5CF6", "#EC4899", "#F59E0B", "#6366F1", "#EF4444"];
const types = ["concept", "subfield", "technique", "method", "application"];
const newNode = {
id: newNodeId,
name: `New Node ${newNodeId}`,
type: types[Math.floor(Math.random() * types.length)],
description: "This is a newly added node to the knowledge graph.",
color: colors[Math.floor(Math.random() * colors.length)]
};
// Add the new node
graphData.nodes.push(newNode);
// Add a random link to an existing node
if (graphData.nodes.length > 1) {
const randomExistingNode = graphData.nodes[Math.floor(Math.random() * (graphData.nodes.length - 1))];
const relations = ["related to", "connected with", "part of", "similar to", "derived from"];
graphData.links.push({
source: newNodeId,
target: randomExistingNode.id,
relation: relations[Math.floor(Math.random() * relations.length)]
});
}
// Update the simulation with new data
updateGraph();
// Highlight the new node
const newNodeElement = node.filter(d => d.id === newNodeId);
newNodeElement.select("circle").classList.add("pulse");
setTimeout(() => {
newNodeElement.select("circle").classList.remove("pulse");
}, 3000);
});
function updateGraph() {
// Update the simulation
simulation.nodes(graphData.nodes);
simulation.force("link").links(graphData.links);
if (physicsEnabled) {
simulation.alpha(1).restart();
}
// Update the links
link.data(graphData.links).join("line").attr("class", "link");
linkText.data(graphData.links).join("text").text(d => d.relation);
// Update the nodes
const newNode = node.data(graphData.nodes).join("g")
.attr("class", "node")
.call(drag(simulation));
newNode.select("circle").attr("fill", d => d.color);
newNode.select("text").text(d => d.name);
// Add icons to new nodes
newNode.filter((d, i) => i >= graphData.nodes.length - 1)
.append("text")
.attr("text-anchor", "middle")
.attr("dy", ".35em")
.attr("fill", "white")
.attr("font-size", "12px")
.html(d => {
switch(d.type) {
case "concept": return "🧠";
case "subfield": return "πŸ”";
case "technique": return "βš™οΈ";
case "method": return "πŸ“Š";
case "application": return "πŸ’»";
default: return "πŸ”˜";
}
});
// Add tooltip to new nodes
newNode.on("mouseover", function(event, d) {
d3.select(this).select("circle").attr("r", 30);
tooltip.transition()
.duration(200)
.style("opacity", 1);
tooltip.html(`
<h3 class="font-bold text-lg mb-1" style="color: ${d.color}">${d.name}</h3>
<p class="text-sm text-gray-600 mb-1">Type: ${d.type}</p>
<p class="text-sm text-gray-700">${d.description}</p>
`)
.style("left", (event.pageX + 10) + "px")
.style("top", (event.pageY + 10) + "px");
})
.on("mouseout", function() {
d3.select(this).select("circle").attr("r", 25);
tooltip.transition()
.duration(500)
.style("opacity", 0);
});
}
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Arg1990/knowledge-graph-s1" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>