131 lines
5.0 KiB
HTML
131 lines
5.0 KiB
HTML
{% extends "base.html" %}
|
|
{% block app_content %}
|
|
<h1>Job Status <span class="badge badge-{{job.status[0]}}">{{ job.status[1] }}</span></h1>
|
|
<div class="row">
|
|
<div class="col-lg-0">
|
|
{% if job.state.error %}
|
|
<ul>
|
|
{% for err in job.state.error.args %}
|
|
<li>{{err}}</li>
|
|
{% endfor %}
|
|
</ul>
|
|
{% endif %}
|
|
|
|
{% if job.state.progress %}
|
|
<p class="lead">Routing from <b>{{ job.state.progress.from }}</b> to <b>{{ job.state.progress.to }}</b> using
|
|
{{ job.state.progress.mode }}</p>
|
|
<p>Current system: <b>{{ job.state.progress.system }}</b></p>
|
|
<p>Search queue size: <b>{{"{:,}".format(job.state.progress.queue_size) }}</b></p>
|
|
<p>Number of systems checked: <b>{{"{:,}".format(job.state.progress.n_seen) }}
|
|
({{job.state.progress.prc_seen|round(2)}} %)</b></p>
|
|
<p>Estimated time remaining: <b>{{job.t_rem}}</b></p>
|
|
<p>Search Depth: <b>{{job.state.progress.depth}}</b></p>
|
|
<div class="progress" style="width: 100%;">
|
|
<div class="progress-bar progress-bar-striped progress-bar-animated"
|
|
style="width: {{job.state.progress.prc_done}}%;" role="progressbar"
|
|
aria-valuenow="{{job.state.progress.prc_done|round(2)}}" aria-valuemin="0" aria-valuemax="100">
|
|
{{job.state.progress.prc_done|round(2)}} %
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if job.state.result %}
|
|
<h2>Result</h2>
|
|
|
|
<h3>Map</h3>
|
|
<div id="graph">
|
|
</div>
|
|
<script src="https://d3js.org/d3.v5.min.js"></script>
|
|
<script type="text/javascript">
|
|
function dist(a, b) {
|
|
var sum = 0;
|
|
for (var i = 0; i < a.length; ++i) {
|
|
sum += Math.pow(a[i] - b[i], 2)
|
|
}
|
|
return Math.pow(sum, 0.5);
|
|
}
|
|
var width = 512;
|
|
var height = 512;
|
|
var route = {{job.route | tojson}};
|
|
var vis = d3.select("#graph")
|
|
.append("svg").attr("viewBox", [0, 0, width, height]);
|
|
|
|
vis.attr("width", width)
|
|
.attr("height", height);
|
|
var g = vis.append("g");
|
|
|
|
vis.call(d3.zoom()
|
|
.extent([
|
|
[0, 0],
|
|
[width, height]
|
|
])
|
|
.on("zoom", () => {
|
|
g.attr("transform", d3.event.transform);
|
|
}));
|
|
|
|
var lines = [];
|
|
for (var i = 0; i < route.length - 1; ++i) {
|
|
lines.push({
|
|
x1: route[i].pos[1],
|
|
x2: route[i + 1].pos[1],
|
|
y1: -route[i].pos[2],
|
|
y2: -route[i + 1].pos[2],
|
|
dist: dist(route[i].pos, route[i + 1].pos),
|
|
color: route[i].color || '#eee'
|
|
})
|
|
}
|
|
|
|
g.selectAll(".line")
|
|
.data(lines)
|
|
.enter()
|
|
.append("line")
|
|
.attr("x1", (l) => l.x1)
|
|
.attr("y1", (l) => l.y1)
|
|
.attr("x2", (l) => l.x2)
|
|
.attr("y2", (l) => l.y2)
|
|
.style("stroke", (l) => l.color)
|
|
.style("stroke-width", 5)
|
|
.append("title")
|
|
.text((l) => Math.round(l.dist * 100) / 100 + " Ly");
|
|
|
|
g.selectAll("circle .nodes")
|
|
.data(route)
|
|
.enter()
|
|
.append("svg:circle")
|
|
.attr("class", "nodes")
|
|
.attr("cx", (d) => d.pos[1])
|
|
.attr("cy", (d) => -d.pos[2])
|
|
.attr("r", 10)
|
|
.attr("fill", (d) => d.color)
|
|
.append("title")
|
|
.text((d) => d.body + " (" + d.star_type + ")")
|
|
</script>
|
|
<h3>Jumps</h3>
|
|
<table class="table table-striped table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">Num</th>
|
|
<th scope="col">Body</th>
|
|
<th scope="col">Type</th>
|
|
<th scope="col">Distance from arrival</th>
|
|
<th scope="col">Jump distance</th>
|
|
</tr>
|
|
</thead>
|
|
{% for sys in job.route %}
|
|
<tr>
|
|
<th scope="row">{{sys.num}}</td>
|
|
<td>{{sys.body}}</td>
|
|
<td style="color: {{sys.color}}">{{sys.star_type}}</td>
|
|
<td>{{"{:,}".format(sys.distance)}} Ls</td>
|
|
<td>{{"{:,}".format(sys.jump_dist|round(2))}} Ly</td>
|
|
</tr>
|
|
{% endfor %}
|
|
<tr>
|
|
<th scope="row" colspan=4>Total Distance</th>
|
|
<td>{{"{:,}".format(job.route|sum(attribute='jump_dist')|round(2))}} Ly</td>
|
|
</tr>
|
|
</table>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endblock %} |