graf: i hrany uz jsou ciste Svelte
This commit is contained in:
		
							parent
							
								
									a05ee0eedc
								
							
						
					
					
						commit
						427ea184f2
					
				
					 4 changed files with 60 additions and 42 deletions
				
			
		|  | @ -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'> | ||||
|  |  | |||
|  | @ -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
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								frontend/src/GraphEdge.svelte
									
									
									
									
									
										Normal file
									
								
							|  | @ -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" /> | ||||
|    | ||||
|  | @ -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 + 6; | ||||
|   $: cy = task === undefined || task.y === undefined ? 0 : task.y - 6; | ||||
|   $: 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; | ||||
|   } | ||||
| 
 | ||||
|   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> | ||||
|  |  | |||
		Reference in a new issue