WIP: new map
This commit is contained in:
parent
bbf4061292
commit
214f9680c0
|
@ -0,0 +1,215 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block container_class %}container-fluid{% endblock %}
|
||||||
|
{% block head %}
|
||||||
|
{% load static from staticfiles %}
|
||||||
|
<!-- <script src="{% static "js/d3.js" %}" charset="utf-8"></script> -->
|
||||||
|
<script src="https://d3js.org/d3.v5.min.js"></script>
|
||||||
|
<style>
|
||||||
|
.node {
|
||||||
|
stroke: #fff;
|
||||||
|
stroke-width: 1.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
stroke: #999;
|
||||||
|
stroke-opacity: .6;
|
||||||
|
}
|
||||||
|
|
||||||
|
#plotwin {
|
||||||
|
height: 75vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
{% block body %}
|
||||||
|
<div class="page-header">
|
||||||
|
<h3>{% if crawl.pk %}Crawl run {{crawl.pk}}{% else %}Live Crawl {% endif %} from {{crawl.startTime|date:"d.m.Y H:i"}}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="plotwin" class="container-fluid"></div>
|
||||||
|
<!-- <div id="infowin"><div class="alert alert-info" role="alert">Click on a node for more information</div></div> -->
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
|
||||||
|
const margin = {
|
||||||
|
top: 40,
|
||||||
|
bottom: 10,
|
||||||
|
left: 20,
|
||||||
|
right: 20,
|
||||||
|
};
|
||||||
|
let plotwin = document.getElementById("plotwin")
|
||||||
|
const width = plotwin.offsetWidth - margin.left - margin.right;
|
||||||
|
const height = plotwin.offsetHeight - margin.top - margin.bottom;
|
||||||
|
|
||||||
|
let drag = d3.drag()
|
||||||
|
.on("drag", dragged);
|
||||||
|
|
||||||
|
function dragged() {
|
||||||
|
let current = d3.select(this);
|
||||||
|
current
|
||||||
|
.attr('cx', d3.event.x)
|
||||||
|
.attr('cy', d3.event.y);
|
||||||
|
console.log(`${d3.event.x}, ${d3.event.y}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragmove(d) {
|
||||||
|
let x = d3.event.x;
|
||||||
|
let y = d3.event.y;
|
||||||
|
d3.select(this).attr("transform", "translate(" + x + "," + y + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
const parent_svg = d3
|
||||||
|
.select("#plotwin")
|
||||||
|
.append("svg")
|
||||||
|
.attr("width", width + margin.left + margin.right)
|
||||||
|
.attr("height", height + margin.top + margin.bottom)
|
||||||
|
//.attr("viewBox", [width / 2, height / 2, width, height])
|
||||||
|
.attr("viewBox", [0, 0, width, height])
|
||||||
|
const svg = parent_svg.append("g")
|
||||||
|
// .append("g")
|
||||||
|
// .attr("transform", `translate(${margin.left}, ${margin.top})`);
|
||||||
|
|
||||||
|
parent_svg.call(
|
||||||
|
d3.zoom()
|
||||||
|
.scaleExtent([.1, 4])
|
||||||
|
.on("zoom", function() { svg.attr("transform", d3.event.transform); })
|
||||||
|
);
|
||||||
|
|
||||||
|
//const simulation = d3
|
||||||
|
// .forceSimulation()
|
||||||
|
// .force(
|
||||||
|
// "link",
|
||||||
|
// d3.forceLink().id((d) => d.id)
|
||||||
|
// )
|
||||||
|
// .force("charge", d3.forceManyBody().distanceMin(50).strength(-300))
|
||||||
|
// .force("center", d3.forceCenter(width / 2, height / 2));
|
||||||
|
|
||||||
|
const color = d3.scaleOrdinal(d3.schemeCategory10);
|
||||||
|
|
||||||
|
drag = simulation => {
|
||||||
|
|
||||||
|
function dragstarted(d) {
|
||||||
|
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
|
||||||
|
d.fx = d.x;
|
||||||
|
d.fy = d.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragged(d) {
|
||||||
|
d.fx = d3.event.x;
|
||||||
|
d.fy = d3.event.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragended(d) {
|
||||||
|
if (!d3.event.active) simulation.alphaTarget(0);
|
||||||
|
d.fx = null;
|
||||||
|
d.fy = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return d3.drag()
|
||||||
|
.on("start", dragstarted)
|
||||||
|
.on("drag", dragged)
|
||||||
|
.on("end", dragended);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
d3.json("/api/v2/crawlrun/live/?with_graph").then((data) => {
|
||||||
|
// Links data join
|
||||||
|
data = data.graph
|
||||||
|
|
||||||
|
const simulation = d3.forceSimulation(data.nodes)
|
||||||
|
//.force("link", d3.forceLink(data.links).id(d => d.id).distance(150).strength(1))
|
||||||
|
//.force("link", d3.forceLink().id(function(d) { return d.id; }))
|
||||||
|
.force("link", d3.forceLink().id(d => d.id)
|
||||||
|
.distance(l => {
|
||||||
|
neighs = Math.min(l.source.neighbors, l.target.neighbors);
|
||||||
|
switch(neighs) {
|
||||||
|
case 0: return 40;
|
||||||
|
case 1: return 40;
|
||||||
|
case 2: return 120;
|
||||||
|
case 3:
|
||||||
|
case 4: return 200;
|
||||||
|
default: return 300;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.strength(l => {
|
||||||
|
neighs = Math.min(l.source.neighbors, l.target.neighbors);
|
||||||
|
return 1 / (neighs);
|
||||||
|
|
||||||
|
}))
|
||||||
|
.force("charge", d3.forceManyBody()
|
||||||
|
.strength(-200)
|
||||||
|
.theta(1.1))
|
||||||
|
//.force("collision", d3.forceCollide(50).strength(0.2).iterations(100))
|
||||||
|
//.force("collision", d3.forceCollide(40).strength(0.2))
|
||||||
|
.force("collision", d3.forceCollide(40).strength(0.2))
|
||||||
|
//.force("x", d3.forceX())
|
||||||
|
//.force("y", d3.forceY())
|
||||||
|
.force("center", d3.forceCenter(width / 2, height / 2));
|
||||||
|
//.force("center", d3.forceRadial(100, width / 2, height / 2));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const link = svg
|
||||||
|
.selectAll(".link")
|
||||||
|
.data(data.links)
|
||||||
|
.join((enter) =>
|
||||||
|
enter.append("line")
|
||||||
|
.attr("class", "link"));
|
||||||
|
|
||||||
|
// Nodes data join
|
||||||
|
|
||||||
|
|
||||||
|
let node = svg.selectAll('.node')
|
||||||
|
.data(data.nodes)
|
||||||
|
.enter()
|
||||||
|
.append("g")
|
||||||
|
.attr("id", d => "node-" + d.id)
|
||||||
|
.call(drag(simulation));
|
||||||
|
|
||||||
|
node.append("ellipse")
|
||||||
|
//.attr("rx", d => d.stub ? 35 : 40)
|
||||||
|
//.attr("ry", d => d.stub ? 14 : 20)
|
||||||
|
.attr("rx", d => d.stub ? 34 : (40 + (d.neighbors > 5 ? 5 : 0)))
|
||||||
|
.attr("ry", d => d.stub ? 12 : (20 + (d.neighbors > 5 ? 2 : 0)))
|
||||||
|
.attr("fill", function(d) {
|
||||||
|
if(d.directly_crawled)
|
||||||
|
return "#94FF70";
|
||||||
|
else if(!d.online)
|
||||||
|
return "#FFCCCC";
|
||||||
|
// return "#F0FFEB";
|
||||||
|
else if(d.stub)
|
||||||
|
return "#3291A8"
|
||||||
|
else
|
||||||
|
return "#D1FFC2";
|
||||||
|
})
|
||||||
|
.attr("stroke", "black")
|
||||||
|
.attr("stroke-width", "1px");
|
||||||
|
|
||||||
|
node.append('text')
|
||||||
|
.attr("fill", "black")
|
||||||
|
.attr("font-family", "sans-serif")
|
||||||
|
.attr("font-size", "13px")
|
||||||
|
.attr("font-weight", "bold")
|
||||||
|
.attr("dy", "4")
|
||||||
|
.attr("text-anchor", "middle")
|
||||||
|
.text(d => d.id)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
simulation.nodes(data.nodes).force("link").links(data.links);
|
||||||
|
|
||||||
|
simulation.on("tick", (e) => {
|
||||||
|
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);
|
||||||
|
|
||||||
|
node.attr("transform", d => "translate(" + d.x + "," + d.y + ")");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
Loading…
Reference in New Issue