Browse Source

graf: i hrany uz jsou ciste Svelte

mj-deploy
Vašek Šraier 4 years ago
parent
commit
427ea184f2
  1. 2
      frontend/public/grafik.html
  2. 37
      frontend/src/Graph.svelte
  3. 17
      frontend/src/GraphEdge.svelte
  4. 46
      frontend/src/GraphNode.svelte

2
frontend/public/grafik.html

@ -4,7 +4,7 @@
<meta charset='utf-8'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<title>Svelte app</title>
<title>Graulohík</title>
<link rel='icon' type='image/png' href='/favicon.png'>
<link rel='stylesheet' href='/global.css'>

37
frontend/src/Graph.svelte

@ -1,5 +1,6 @@
<script type="ts">
import GraphNode from "./GraphNode.svelte";
import GraphEdge from "./GraphEdge.svelte";
import { onMount } from "svelte";
import * as d3 from "d3";
import { createLinksFromTaskMap } from "./task-loader";
@ -28,22 +29,6 @@
.select("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Initialize the links
var link = svg
.selectAll("line")
.data(edges)
.enter()
.append("line")
.style("stroke", "#aaa");
/*var node = svg
.selectAll("g")
.data(nodes)
.enter()
.append("circle")
.attr("r", 20)
.style("fill", "#69b3a2");*/
// Let's list the force we wanna apply on the network
var simulation = d3
.forceSimulation(nodes) // Force algorithm is applied to data.nodes
@ -56,7 +41,7 @@
}) // This provide the id of a node
.links(edges) // and this the list of links
)
.force("charge", d3.forceManyBody().strength(-400)) // This adds repulsion between nodes. Play with the -400 for the repulsion strength
.force("charge", d3.forceManyBody().strength(-500)) // This adds repulsion between nodes. Play with the -400 for the repulsion strength
.force("x", d3.forceX()) // attracts elements to the zero X coord
.force("y", d3.forceY()) // attracts elements to the zero Y coord
.on("tick", ticked)
@ -64,20 +49,7 @@
// 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;
});
edges = edges;
nodes = nodes;
}
});
@ -93,6 +65,9 @@
<div bind:this={container}>
<svg>
<g>
{#each edges as edge}
<GraphEdge {edge} />
{/each}
{#each nodes as task}
<GraphNode {task} />
{/each}

17
frontend/src/GraphEdge.svelte

@ -0,0 +1,17 @@
<script lang="ts">
import type { SimulationLinkDatum } from "d3";
import { onMount } from "svelte";
import type { TaskDescriptor } from "./task-loader";
export let edge: SimulationLinkDatum<TaskDescriptor>;
$: x1 = edge === undefined || edge.source === undefined || edge.source.x === undefined ? 0 : edge.source.x;
$: y1 = edge === undefined || edge.source === undefined || edge.source.y === undefined ? 0 : edge.source.y;
$: x2 = edge === undefined || edge.target === undefined || edge.target.x === undefined ? 0 : edge.target.x;
$: y2 = edge === undefined || edge.target === undefined || edge.target.y === undefined ? 0 : edge.target.y;
</script>
<line {x1} {x2} {y1} {y2} style="stroke: #aaa" />

46
frontend/src/GraphNode.svelte

@ -1,18 +1,44 @@
<script lang="ts">
import { onMount } from "svelte";
import type { TaskDescriptor } from "./task-loader";
import Hoverable from "./Hoverable.svelte";
export let task: TaskDescriptor;
let hovering: boolean = false;
let text_element: SVGTextElement;
$: cx = task === undefined || task.x === undefined ? 0 : task.x;
$: cy = task === undefined || task.y === undefined ? 0 : task.y;
function enter() {
hovering = true;
}
function leave() {
hovering = false;
}
$: cx = task === undefined || task.x === undefined ? 0 : task.x + 6;
$: cy = task === undefined || task.y === undefined ? 0 : task.y - 6;
let ellipse_rx = 20;
let ellipse_ry = 20;
onMount(() => {
const bbox = text_element.getBBox();
ellipse_rx = bbox.width / 2 + 8;
ellipse_ry = bbox.height / 2 + 8;
});
</script>
<Hoverable let:hovering={focused}>
{#if !focused}
<circle r="20" style="fill: #69b3a2" {cx} {cy} />
<g on:mouseenter={enter} on:mouseleave={leave}>
{#if !hovering}
<ellipse rx={ellipse_rx} ry={ellipse_ry} style="fill: #69b3a2" {cx} {cy} />
{:else}
<circle r="20" style="fill: #ffb3a2" {cx} {cy} />
{/if} -->
<text x={cx} y={cy}>{task.id}</text>
</Hoverable>
<ellipse rx={ellipse_rx} ry={ellipse_ry} style="fill: #ffb3a2" {cx} {cy} />
{/if}
<text
bind:this={text_element}
x={cx}
y={cy + 5}
text-anchor="middle"
alignment-baseline="middle">
{task.id}
</text>
</g>