Skip to content

Commit

Permalink
Make children collapsible
Browse files Browse the repository at this point in the history
  • Loading branch information
katharinawuensche committed Jul 22, 2024
1 parent fd8964b commit 60f8396
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 31 deletions.
114 changes: 85 additions & 29 deletions components/family-tree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@ import {
type AnchorSpec,
BlankEndpoint,
type BrowserJsPlumbInstance,
type Connection,
FlowchartConnector,
newInstance,
type OverlaySpec,
ready,
} from "@jsplumb/browser-ui";
import { ChevronDown } from "lucide-vue-next";
import type { TempTriple } from "@/types/resulttypes";
Expand All @@ -28,6 +31,9 @@ const childContainer = ref<HTMLElement>();
const partnerContainer = ref<HTMLElement>();
const meContainer = ref<HTMLElement>();
const showAllChilldren = ref(false);
const uncollapseChildrenContainer = ref<HTMLElement>();
function filterUniqueObjects(list: Array<{ id: number; name: string }>) {
return list.filter((entry, idx) => list.findIndex((e) => e.id === entry.id) === idx);
}
Expand All @@ -51,13 +57,63 @@ const partners = computed(() => {
props.relations.filter((r) => r.name === "hat Ehe mit").map((r) => r.to),
);
});
const instance = ref<BrowserJsPlumbInstance>();
// Add resize handler to monitor container width and adapt chart
function resizeHandler() {
console.log("Resize");
instance.value?.repaintEverything();
}
const childConnections = ref<Array<Connection | undefined>>();
function drawChildConnections() {
const container =
showAllChilldren.value || children.value.length <= 3
? childContainer.value
: uncollapseChildrenContainer.value;
const childContainerChildren = [...(container?.children ?? [])];
const getOverlays = (idx: number) => {
let overlays: Array<OverlaySpec> = [
{
type: "PlainArrow",
options: { location: 1, direction: 1, length: 8, width: 10 },
},
];
if (idx === 0 && showAllChilldren.value)
overlays.push({
type: "Custom",
options: {
location: 8,
create() {
const d = document.createElement("button");
d.innerHTML = `<img src="/assets/icons/reduce.svg" class="size-4 mr-5" title="${t("FamilyTree.collapse-children")}"/><span class="sr-only">${t("FamilyTree.collapse-children")}</span>`;
d.onclick = toggleShowAllChildren;
return d;
},
},
});
return overlays;
};
instance.value?.batch(() => {
childConnections.value
?.filter((con): con is Connection => con !== undefined)
.forEach((con) => instance.value?.deleteConnection(con));
childConnections.value = childContainerChildren.map((child, idx) => {
return instance.value?.connect({
source: meContainer.value,
target: child,
connector: {
type: FlowchartConnector.type,
options: { midpoint: 0.9999, stub: [12, 20], alwaysRespectStubs: true },
},
anchors: [AnchorLocations.Bottom, AnchorLocations.Top],
endpoint: BlankEndpoint.type,
overlays: getOverlays(idx),
});
});
});
}
onMounted(() => {
ready(() => {
instance.value = newInstance({
Expand Down Expand Up @@ -124,39 +180,20 @@ onMounted(() => {
});
});
});
drawChildConnections();
// Add child connectors only to uppermost children
const childContainerChildren = [...(childContainer.value?.children ?? [])];
const minHeight = Math.min(
...childContainerChildren.map((el) => el.getBoundingClientRect().top),
);
childContainerChildren
.filter((child) => child.getBoundingClientRect().top === minHeight)
.forEach((child) => {
instance.value?.connect({
source: meContainer.value,
target: child,
connector: {
type: FlowchartConnector.type,
options: { midpoint: 0.9, stub: 12, alwaysRespectStubs: true },
},
anchors: [AnchorLocations.Bottom, AnchorLocations.Top],
endpoint: BlankEndpoint.type,
overlays: [
{
type: "PlainArrow",
options: { location: 1, direction: 1, length: 8, width: 10 },
},
],
});
});
window.addEventListener("resize", resizeHandler);
});
});
onBeforeUnmount(() => {
window.removeEventListener("resize", resizeHandler);
});
function toggleShowAllChildren() {
showAllChilldren.value = !showAllChilldren.value;
void nextTick(drawChildConnections);
}
</script>

<template>
Expand Down Expand Up @@ -198,15 +235,34 @@ onBeforeUnmount(() => {
</NuxtLink>
</div>
</div>
<div ref="childContainer" class="mb-2 mt-4 flex flex-wrap justify-evenly gap-2">
<div
v-if="children.length <= 3 || showAllChilldren"
ref="childContainer"
class="mb-2 mt-7 flex flex-wrap justify-evenly gap-x-2 gap-y-6"
>
<NuxtLink
v-for="person in children"
:key="person.id"
:to="localePath(`/detail/person/${person.id}`)"
class="max-w-32 p-2 text-center align-middle"
class="z-10 max-w-32 flex-auto px-2 pt-0 text-center align-middle"
>
{{ person.name }}
<span class="bg-white/50 dark:bg-neutral-800/50">
{{ person.name }}
</span>
</NuxtLink>
</div>
<div
v-else
ref="uncollapseChildrenContainer"
class="mb-2 mt-7 flex flex-wrap justify-evenly gap-2"
>
<button
class="border-2 border-dotted p-2 text-center align-middle"
@click="toggleShowAllChildren"
>
{{ t("FamilyTree.show-all-children", { count: children.length }) }}
<ChevronDown class="inline size-4" />
</button>
</div>
</div>
</template>
4 changes: 3 additions & 1 deletion messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@
"children": "Kinder",
"parents": "Eltern",
"show-all-children": "Zeige alle {count} Kinder",
"show-all-siblings": "Zeige alle {count} Geschwister"
"show-all-siblings": "Zeige alle {count} Geschwister",
"collapse-children": "Kinder einklappen",
"collapse-siblings": "Geschwister einklappen"
},
"ui": {
"showing-results": "Zeige {first} - {last} von {all} Ergebnissen",
Expand Down
4 changes: 3 additions & 1 deletion messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@
"children": "Children",
"parents": "Parents",
"show-all-children": "Show all {count} children",
"show-all-siblings": "Show all {count} siblings"
"show-all-siblings": "Show all {count} siblings",
"collapse-children": "Collapse children",
"collapse-siblings": "Collapse siblings"
},
"ui": {
"showing-results": "Showing {first} - {last} out of {all} results",
Expand Down
1 change: 1 addition & 0 deletions public/assets/icons/reduce.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 60f8396

Please sign in to comment.