Skip to content

Commit

Permalink
Merge pull request #153 from fhstp/clique_analysis
Browse files Browse the repository at this point in the history
Clique analysis
  • Loading branch information
alex-rind authored Dec 14, 2024
2 parents 35550d8 + fdb1f3c commit b29813d
Show file tree
Hide file tree
Showing 7 changed files with 271 additions and 55 deletions.
100 changes: 51 additions & 49 deletions src/components/EgoEditForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,63 +27,63 @@
</div>

<div class="field is-horizontal" v-if="emoji">
<div class="field-label is-normal">
<label class="label">Emoji</label>
</div>
<br />
<div class="field-body">
<div>
<div style="display: flex; align-items: center; margin-top: 10px;">
<div>
{{
selectedEmoji == null || selectedEmoji.length < 1
? t("noemoji")
: selectedEmoji
}}
<div class="field-label is-normal">
<label class="label">Emoji</label>
</div>
<br />
<div class="field-body">
<div>
<div style="display: flex; align-items: center; margin-top: 10px">
<div>
{{
selectedEmoji == null || selectedEmoji.length < 1
? t("noemoji")
: selectedEmoji
}}
</div>
</div>
</div>
</div>
</div>
</div>

<div class="field is-horizontal" v-if="emoji">
<div class="field-label is-normal">
<label class="label">{{ t("selectEmoji") }}</label>
</div>
<div class="field-body">
<div class="dropdown" :class="{ 'is-active': showEmojiPicker }">
<div >
<button
type="button"
class="button is-small"
@click="toggleEmojiPicker"
>
<span>{{ t("selectemoji") }}</span>
</button>
<button
v-if="selectedEmoji != null && selectedEmoji.length > 0"
@click="removeEmoji"
class="button is-small"
style="margin-left: 10px;"
>
<span>{{t("removeemoji")}}</span>
</button>
</div>
<div class="dropdown-menu">
<div class="field is-horizontal" v-if="emoji">
<div class="field-label is-normal">
<label class="label">{{ t("selectEmoji") }}</label>
</div>
<div class="field-body">
<div class="dropdown" :class="{ 'is-active': showEmojiPicker }">
<div>
<button
type="button"
class="button is-small"
@click="toggleEmojiPicker"
>
<span>{{ t("selectemoji") }}</span>
</button>
<button
v-if="selectedEmoji != null && selectedEmoji.length > 0"
@click="removeEmoji"
class="button is-small"
style="margin-left: 10px"
>
<span>{{ t("removeemoji") }}</span>
</button>
</div>
<div class="dropdown-menu">
<div>
<EmojiPicker
v-model="selectedEmoji"
:native="true"
:disableSkinTones="true"
@select="onSelectEmoji"
/>
<div>
<EmojiPicker
v-model="selectedEmoji"
:native="true"
:disableSkinTones="true"
@select="onSelectEmoji"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

<div class="field is-horizontal">
<div class="field-label is-normal">
Expand Down Expand Up @@ -115,7 +115,7 @@
<input
class="input"
min="0"
:value="$store.state.nwk.ego.age"
:value="egoAge"
@blur="commitEdit($event, 'age')"
type="number"
/>
Expand All @@ -128,7 +128,7 @@
<div class="control">
<textarea
class="textarea is-small"
:value="$store.state.nwk.ego.note"
:value="egoNote"
@blur="commitEdit($event, 'note')"
:placeholder="t('notesaboutego')"
></textarea>
Expand Down Expand Up @@ -203,7 +203,7 @@ export default defineComponent({
});
// generic event handlers from form to vuex
const commitEdit = (evt: InputEvent, field: keyof Ego) => {
const commitEdit = (evt: UIEvent, field: keyof Ego) => {
const value = (evt.target as InputType).value.trim();
if (value !== store.state.nwk.ego[field]) {
const payload = { [field]: value };
Expand All @@ -216,7 +216,7 @@ export default defineComponent({
store.commit("editEgo", payload);
};
function onSelectEmoji(emoji: any) {
function onSelectEmoji<EmojiType extends { i: string }>(emoji: EmojiType) {
selectedEmoji.value = emoji.i;
showEmojiPicker.value = false;
commitEditEmoji(emoji.i);
Expand Down Expand Up @@ -260,6 +260,8 @@ export default defineComponent({
egoName,
invalidName,
egoGender,
egoAge: computed(() => store.state.nwk.ego.age),
egoNote: computed(() => store.state.nwk.ego.note),
commitEdit,
genderOptions,
editEgoFinished,
Expand Down
23 changes: 18 additions & 5 deletions src/components/StatisticsPanel.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<template>
<nav class="panel">
<p class="panel-heading" style="display: flex" @click.stop="isOpen = !isOpen">
<p
class="panel-heading"
style="display: flex"
@click.stop="isOpen = !isOpen"
>
<span class="icon is-medium">
<font-awesome-icon icon="chart-bar" size="lg" />
</span>
Expand All @@ -18,14 +22,18 @@
:class="{ 'is-active': tab === cat }"
@click="go(cat)"
>
{{ translateCategoryKey(categoryLabel(cat)) }}</a
>
{{ translateCategoryKey(categoryLabel(cat)) }}
</a>
</p>
<StatisticsTable v-if="isOpen && tab === ''"></StatisticsTable>
<StatisticsTableCategories
v-else-if="isOpen"
v-else-if="isOpen && tab !== 'clique'"
:categories="tab"
></StatisticsTableCategories>
<StatisticsTableClique
v-else-if="isOpen && tab === 'clique'"
></StatisticsTableClique>

<div class="panel-block" v-else />
</nav>
</template>
Expand All @@ -35,6 +43,7 @@ import { computed, defineComponent, ref } from "vue";
import { useStore } from "@/store";
import StatisticsTable from "@/components/StatisticsTable.vue";
import StatisticsTableCategories from "@/components/StatisticsTableCategories.vue";
import StatisticsTableClique from "@/components/StatisticsTableClique.vue";
import {
allAlterCategorizationKeys,
getAlterCategorization,
Expand All @@ -60,7 +69,11 @@ export default defineComponent({
}
},
},
components: { StatisticsTable, StatisticsTableCategories },
components: {
StatisticsTableClique,
StatisticsTable,
StatisticsTableCategories,
},
setup() {
const store = useStore();
Expand Down
118 changes: 118 additions & 0 deletions src/components/StatisticsTableClique.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<template>
<div class="panel-block" style="display: block">
<table class="table is-fullwidth">
<tbody>
<tr>
<th title="Clique">{{ t("amountClique") }}</th>
<td>{{ cliquesList.length }}</td>
</tr>
<tr
v-for="(clique, cliqueIndex) in cliquesList"
:key="'clique-number-' + cliqueIndex"
>
<th @click="clickClique(clique.alters)" class="clickAble">
<template
v-for="(a, idx) in clique.alters"
:key="`a_${cliqueIndex}_${idx}`"
>
<template v-if="idx > 0">, </template>
<span :class="{ selalter: isSelected(a.id) }">{{ a.name }}</span>
</template>
</th>
<td>
{{ clique.description }}
</td>
</tr>
</tbody>
</table>
</div>
</template>

<script lang="ts">
import { computed, defineComponent } from "vue";
import { useStore } from "@/store";
import { findCliques } from "@/data/NetworkClustering";
import { sectorIndex } from "@/data/AlterCategories";
import de from "@/de";
import en from "@/en";
import { Alter } from "@/data/Alter";
import { Sectors, SectorsEng } from "@/data/Sectors";
interface CliqueItem {
alters: Alter[];
description: string;
}
export default defineComponent({
mixins: [de, en],
methods: {
t(prop: string) {
return this[document.documentElement.lang][prop];
},
},
setup() {
const store = useStore();
const sectorLabels =
document.documentElement.lang === "de" ? Sectors : SectorsEng;
const cliques = computed((): Alter[][] => {
return findCliques(store.state.nwk);
});
const cliquesList = computed((): CliqueItem[] => {
return cliques.value.map((clique) => {
const sectorIndices = clique
.map((a) => sectorIndex(a))
.filter((d) => d !== null);
const uniqSectorIndices = [...new Set(sectorIndices)];
console.log(uniqSectorIndices);
const sectLabels = uniqSectorIndices
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
.map((d) => sectorLabels[d!])
.join(", ");
return {
// cliqueNumber: `Clique ${idx + 1}`,
alters: clique,
description: clique.length + " (" + sectLabels + ")",
};
});
});
const clickClique = (alteri: Alter[]) => {
if (alteri.length > 0) {
store.commit(
"session/selectAlters",
alteri.map((a) => a.id)
);
}
};
return {
cliquesList,
clickClique,
isSelected: store.getters["session/isSelected"],
};
},
});
</script>

<style scoped lang="scss">
span.selalter {
color: rgb(30, 92, 146);
font-weight: bold;
}
thead th:not([align]) {
text-align: right;
}
td:not([align]) {
text-align: right;
}
th {
font-weight: normal;
}
</style>
21 changes: 20 additions & 1 deletion src/data/AlterCategories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,18 @@ const PROFI: AlterCategorization = {
categories: ["prof. Hilfe", "Netzwerk ohne prof. Hilfe", "gesamtes Netzwerk"],
};

const CLIQUE: AlterCategorization = {
label: "Clique",
inCategory: (catIndex: number, a: Alter): boolean =>
sectorIndex(a) === catIndex,
categories: [
"Familie",
"Freund*innen / Bekannte",
"Kolleg*innen",
"prof. Helfer*innen",
],
};

/* obsolete categorizations (since Jun 2024)
const HORIZON_CUM: AlterCategorization = {
label: "Horizont (kumulativ)",
Expand Down Expand Up @@ -173,7 +185,13 @@ const ALL: AlterCategorization = {
};

export function getAlterCategorization(key = ""): AlterCategorization {
return key === "sector" ? SECTOR : key === "profi" ? PROFI : ALL;
return key === "sector"
? SECTOR
: key === "profi"
? PROFI
: key === "clique"
? CLIQUE
: ALL;
// : key === "horizon"
// ? HORIZON
// : key === "horizon_cum"
Expand All @@ -188,6 +206,7 @@ export const allAlterCategorizationKeys = [
"",
"sector",
"profi",
"clique",
// "horizon",
// "horizon_cum",
// "gender",
Expand Down
Loading

0 comments on commit b29813d

Please sign in to comment.