Browse Source

graph: option to hide nodes

mj-deploy
Vašek Šraier 4 years ago
parent
commit
96dccd779d
  1. 28
      frontend/src/Editor.svelte
  2. 14
      frontend/src/Graph.svelte
  3. 28
      frontend/src/GraphEdge.svelte
  4. 29
      frontend/src/GraphNode.svelte
  5. 1
      frontend/src/tasks.ts
  6. 426
      tasks.json

28
frontend/src/Editor.svelte

@ -68,7 +68,7 @@
} }
// autosave ;) // autosave ;)
let saveTimeoutHandle: number | null = null; let saveTimeoutHandle: NodeJS.Timeout | null = null;
function autosave() { function autosave() {
if (saveTimeoutHandle != null) clearTimeout(saveTimeoutHandle); if (saveTimeoutHandle != null) clearTimeout(saveTimeoutHandle);
@ -77,7 +77,10 @@
await saveTasks(tasks); await saveTasks(tasks);
}, 5000); }, 5000);
} }
$: { tasks; autosave(); }; $: {
tasks;
autosave();
}
function saveLocally() { function saveLocally() {
saveToLocalDisk("tasks.json", tasksToString(tasks)); saveToLocalDisk("tasks.json", tasksToString(tasks));
@ -197,6 +200,20 @@
})); }));
tasks.tasks = [...tasks.tasks, ...newDescriptors]; tasks.tasks = [...tasks.tasks, ...newDescriptors];
} }
function hideSelection() {
for (let t of graph.getCurrentSelection()) {
t.hidden = true;
}
tasks = tasks;
}
function showSelection() {
for (let t of graph.getCurrentSelection()) {
t.hidden = false;
}
tasks = tasks;
}
</script> </script>
<style> <style>
@ -297,7 +314,8 @@
bind:this={graph} bind:this={graph}
{nodeDraggingEnabled} {nodeDraggingEnabled}
on:openTask={openTaskDetailEditorButton} on:openTask={openTaskDetailEditorButton}
{showHiddenEdges} /> {showHiddenEdges}
showHidden={true} />
<div class="container"> <div class="container">
<div class="topLeftHint"> <div class="topLeftHint">
@ -358,6 +376,10 @@
title={isLoggedIn() ? 'Nahraje všechny úlohy z jednoho ročníku, které tu ještě nejsou' : 'Je nutné být přihlášený a na stránce v KSP template.'}>Nahrát title={isLoggedIn() ? 'Nahraje všechny úlohy z jednoho ročníku, které tu ještě nejsou' : 'Je nutné být přihlášený a na stránce v KSP template.'}>Nahrát
celý ročník</button> celý ročník</button>
</div> </div>
<div>
<button on:click={hideSelection}>Skrýt výběr</button>
<button on:click={showSelection}>Zobrazit výběr</button>
</div>
</div> </div>
<div class="taskDetails"> <div class="taskDetails">

14
frontend/src/Graph.svelte

@ -7,6 +7,7 @@
import { createEdges } from "./tasks"; import { createEdges } from "./tasks";
import { taskStatuses } from "./task-status-cache"; import { taskStatuses } from "./task-status-cache";
import { grabAssignment } from "./ksp-task-grabber"; import { grabAssignment } from "./ksp-task-grabber";
import TaskDetailEditor from "./TaskDetailEditor.svelte";
export let tasks: TasksFile; export let tasks: TasksFile;
export let nodeDraggingEnabled: boolean = false; export let nodeDraggingEnabled: boolean = false;
@ -14,6 +15,7 @@ import { grabAssignment } from "./ksp-task-grabber";
export let showHiddenEdges: boolean = false; export let showHiddenEdges: boolean = false;
export let selection: Set<TaskDescriptor> = new Set(); export let selection: Set<TaskDescriptor> = new Set();
export let showCenterMarker: boolean = false; export let showCenterMarker: boolean = false;
export let showHidden: boolean = false;
let hoveredTask: null | TaskDescriptor = null; let hoveredTask: null | TaskDescriptor = null;
@ -185,6 +187,10 @@ import { grabAssignment } from "./ksp-task-grabber";
window.addEventListener("mouseup", dragStop, { once: true }); window.addEventListener("mouseup", dragStop, { once: true });
} }
export function getCurrentSelection(): Set<TaskDescriptor> {
return selection;
}
onMount(() => { onMount(() => {
setupZoom(); setupZoom();
}); });
@ -308,10 +314,13 @@ import { grabAssignment } from "./ksp-task-grabber";
stroke-dasharray="15,15" /> stroke-dasharray="15,15" />
{/if} {/if}
{#each edges as edge} {#each edges as edge}
<GraphEdge {edge} showLabelEdge={showHiddenEdges} /> {#if showHidden || !(edge?.dependee?.hidden || edge?.dependency?.hidden)}
<GraphEdge {edge} showLabelEdge={showHiddenEdges} />
{/if}
{/each} {/each}
{#each nodes as task} {#each nodes as task}
<GraphNode {#if showHidden || !(task.hidden ?? false) }
<GraphNode
{task} {task}
on:mousedown={dragStart} on:mousedown={dragStart}
selected={selectionToolEnabled && selection.has(task)} selected={selectionToolEnabled && selection.has(task)}
@ -320,6 +329,7 @@ import { grabAssignment } from "./ksp-task-grabber";
on:hoveringChange={nodeHover(task)} on:hoveringChange={nodeHover(task)}
status={$taskStatuses.get(task.id)} status={$taskStatuses.get(task.id)}
on:dblclick={nodeDoubleClick(task)} /> on:dblclick={nodeDoubleClick(task)} />
{/if}
{/each} {/each}
{#if hoveredTask != null && hoveredTask.type == "open-data" } {#if hoveredTask != null && hoveredTask.type == "open-data" }
<g class="tooltip"> <g class="tooltip">

28
frontend/src/GraphEdge.svelte

@ -1,15 +1,29 @@
<script lang="ts"> <script lang="ts">
import type { TaskEdge } from "./graph"; import type { TaskEdge } from "./graph";
export let edge: TaskEdge; export let edge: TaskEdge;
export let showLabelEdge: boolean = false; export let showLabelEdge: boolean = false;
$: [x1, y1] = edge?.dependency?.position ?? [0,0]; $: [x1, y1] = edge?.dependency?.position ?? [0, 0];
$: [x2, y2] = edge?.dependee?.position ?? [0, 0]; $: [x2, y2] = edge?.dependee?.position ?? [0, 0];
$: dx = x1 - x2 $: dx = x1 - x2;
$: dy = y1 - y2 $: dy = y1 - y2;
$: hidden =
(edge?.dependee?.hidden ?? false) ||
(edge?.dependency?.hidden ?? false);
</script> </script>
{#if showLabelEdge || (edge?.dependee?.type ?? null) != "label"} <style>
<path d="m {x2} {y2+0} c 0 0 {dx} {dy-40} {dx} {dy-20}" style="fill:none; stroke: #aaa; stroke-width: 3px" /> .hidden {
stroke-opacity: 0.5;
fill-opacity: 0.5;
}
</style>
{#if showLabelEdge || (edge?.dependee?.type ?? null) != 'label'}
<path
d="m {x2} {y2 + 0} c 0 0 {dx} {dy - 40} {dx} {dy - 20}"
style="fill:none; stroke: #aaa; stroke-width: 3px"
class={hidden ? 'hidden' : ''} />
{/if} {/if}

29
frontend/src/GraphNode.svelte

@ -41,8 +41,7 @@
// every time after that // every time after that
$: { $: {
task.title; task.title;
if (text_element) if (text_element) ensureTextFits();
ensureTextFits();
} }
function dblclick(e: MouseEvent) { function dblclick(e: MouseEvent) {
@ -56,6 +55,12 @@
g:not(.label) { g:not(.label) {
cursor: pointer; cursor: pointer;
} }
.hidden {
fill-opacity: 0.5;
stroke-opacity: 0.5;
}
.label { .label {
font-size: 1.5em; font-size: 1.5em;
fill: gainsboro; fill: gainsboro;
@ -81,7 +86,8 @@
fill: green; /* TODO */ fill: green; /* TODO */
} }
.selected > ellipse, .selected > rect { .selected > ellipse,
.selected > rect {
stroke-width: 4px; stroke-width: 4px;
stroke: red; stroke: red;
} }
@ -94,9 +100,12 @@
on:mouseleave={leave} on:mouseleave={leave}
on:click={click} on:click={click}
on:dblclick={dblclick} on:dblclick={dblclick}
class="{status == null ? '' : status.solved ? 'solved' : status.submitted ? 'submitted' : ''} {task.type} {selected ? 'selected' : 'notSelected'}"> class="{status == null ? '' : status.solved ? 'solved' : status.submitted ? 'submitted' : ''}
{task.type}
{selected ? 'selected' : 'notSelected'}
{task.hidden ?? false ? 'hidden' : ''}">
{#if task.type == 'label'} {#if task.type == 'label'}
{#if selected } {#if selected}
<ellipse rx={ellipse_rx} ry={20} {cx} {cy} /> <ellipse rx={ellipse_rx} ry={20} {cx} {cy} />
{/if} {/if}
<text <text
@ -109,8 +118,14 @@
{task.title == null ? task.id : task.title} {task.title == null ? task.id : task.title}
</text> </text>
{:else} {:else}
{#if task.type == "text"} {#if task.type == 'text'}
<rect class="taskNode" x={cx-ellipse_rx} y={cy-20} height={40} width={2*ellipse_rx} rx={3} /> <rect
class="taskNode"
x={cx - ellipse_rx}
y={cy - 20}
height={40}
width={2 * ellipse_rx}
rx={3} />
{:else} {:else}
<ellipse class="taskNode" rx={ellipse_rx} ry={20} {cx} {cy} /> <ellipse class="taskNode" rx={ellipse_rx} ry={20} {cx} {cy} />
{/if} {/if}

1
frontend/src/tasks.ts

@ -6,6 +6,7 @@ export type TaskDescriptor = {
requires: string[] requires: string[]
comment?: string comment?: string
position?: [number, number] position?: [number, number]
hidden?: boolean
} & ( } & (
{ {
type: "open-data", type: "open-data",

426
tasks.json

File diff suppressed because it is too large