@@ -282,22 +273,16 @@ export default defineComponent({
);
},
exportCSV: () => {
+ const today = new Date();
downloadText(
store.state.nwk.ego.name +
" " +
- visibleNWKVersion.value?.title +
- " " +
- visibleNWKVersion.value?.date?.substring(8, 10) +
- "." +
- visibleNWKVersion.value?.date?.substring(5, 7) +
- "." +
- visibleNWKVersion.value?.date?.substring(0, 4) +
+ today.toLocaleDateString("en-CA") +
".csv",
- statisticsCSV(store.state.nwk, store.getters["displayName"])
+ statisticsCSV(store.state.record.versions)
);
},
- showStatistics: () => store.commit("session/enable", "statistics"),
pseudonyms: computed(() => store.state.pseudonym.active),
togglePseudonyms: () => store.commit("pseudonym/toggle"),
horizons: computed(() => store.state.view.horizons),
diff --git a/src/components/StatisticsPanel.vue b/src/components/StatisticsPanel.vue
index 9d38574..b51f142 100644
--- a/src/components/StatisticsPanel.vue
+++ b/src/components/StatisticsPanel.vue
@@ -1,16 +1,17 @@
@@ -62,6 +64,9 @@ export default defineComponent({
setup() {
const store = useStore();
+ // whether panel is collapsed is managed locally
+ const isOpen = ref(false);
+
const tab = ref("");
const go = (newTab: string) => {
@@ -77,11 +82,9 @@ export default defineComponent({
categoryLabel: computed(
() => (cat: string) => getAlterCategorization(cat).label
),
+ isOpen,
tab,
go,
- hideStatistics: () => {
- store.commit("session/disable", "statistics");
- },
};
},
});
diff --git a/src/components/StatisticsTable.vue b/src/components/StatisticsTable.vue
index ff88019..9b697ac 100644
--- a/src/components/StatisticsTable.vue
+++ b/src/components/StatisticsTable.vue
@@ -18,47 +18,56 @@
{{ networkSize }} |
-
- {{ t("relationshipweight") }}
+ |
+ {{ t("sizebygender") }}
+ {{ t("female") }}
+ {{ t("male") }}
+ {{ t("diverse") }}
+ {{ t("notspecified") }}
|
- {{ naehenSum }} |
+
+
+ {{ gSize }}
+ |
-
- {{ t("totaldensity") }}
+ |
+ {{ t("sizebyhorizon") }}
+ {{ t(ho) }}
|
- {{
- density.toLocaleString(undefined, {
- minimumFractionDigits: 3,
- maximumFractionDigits: 3,
- })
- }}
+
+ {{ hSz }}
|
-
- {{ t("stars") }}
+ |
+ {{ t("closeness") }}
|
-
- {{ stars }}
+ | {{ naehen }} |
+
+
+
+ {{ t("totaldensity") }}
+ |
+
+ {{ density.toFixed(3) }}
|
-
- {{ t("bridges") }}
+ |
+ {{ t("degree") }}
|
- {{ bridgesCount }} |
+
+ {{ degree }}
+ |
-
- {{ t("bridgepersons") }}
+ |
+ {{ t("stars") }}
|
-
- {{ bridgePersons }}
+ |
+ {{ stars }}
|
@@ -100,6 +109,7 @@ import {
import { getAlterCategorization } from "@/data/AlterCategories";
import de from "@/de";
import en from "@/en";
+import { HORIZON_KEYS } from "@/data/Horizon";
export default defineComponent({
mixins: [de, en],
@@ -140,7 +150,7 @@ export default defineComponent({
});
function makeComputedAlterGroup(
- group: "stars" | "isolated" | "bridgePersons" | "alterZeroEdge"
+ group: "stars" | "isolated" | "alterZeroEdge"
) {
return computed(() => {
const alteri = networkAnalysis.value[group];
@@ -157,9 +167,7 @@ export default defineComponent({
});
}
- const clickCell = (
- group: "stars" | "isolated" | "bridgePersons" | "alterZeroEdge"
- ) => {
+ const clickCell = (group: "stars" | "isolated" | "alterZeroEdge") => {
const alteri = networkAnalysis.value[group];
if (alteri.length > 0) {
store.commit(
@@ -170,14 +178,42 @@ export default defineComponent({
};
return {
- networkSize: computed(() => networkAnalysis.value.alterConnected),
- naehenSum: computed(() => networkAnalysis.value.naehenSum),
+ networkSize: computed(
+ () =>
+ networkAnalysis.value.alterConnected +
+ " (" +
+ networkAnalysis.value.alterConnectable +
+ ")"
+ ),
+ sizeByGender: computed(() =>
+ networkAnalysis.value.genderConnected.map(
+ (g, i) => g + " (" + networkAnalysis.value.genderConnectable[i] + ")"
+ )
+ ),
+ HORIZON_KEYS,
+ sizeByHorizon: computed(() =>
+ networkAnalysis.value.horizonConnected.map(
+ (g, i) => g + " (" + networkAnalysis.value.horizonConnectable[i] + ")"
+ )
+ ),
+ naehen: computed(
+ () =>
+ networkAnalysis.value.naehenAvg.toFixed(1) +
+ " (" +
+ networkAnalysis.value.naehenDev.toFixed(1) +
+ ")"
+ ),
density,
+ degree: computed(
+ () =>
+ networkAnalysis.value.degreeAvg.toFixed(1) +
+ " (" +
+ networkAnalysis.value.degreeDev.toFixed(1) +
+ ")"
+ ),
stars,
isolated: makeComputedAlterGroup("isolated"),
alterZeroEdge: makeComputedAlterGroup("alterZeroEdge"),
- bridgePersons: makeComputedAlterGroup("bridgePersons"),
- bridgesCount: computed(() => networkAnalysis.value.bridges.length),
clickCell,
};
},
@@ -188,4 +224,10 @@ export default defineComponent({
td:not([align]) {
text-align: right;
}
+
+th.sizeby > em {
+ display: block;
+ font-style: normal;
+ margin-left: 3em;
+}
diff --git a/src/components/StatisticsTableCategories.vue b/src/components/StatisticsTableCategories.vue
index 3d44056..0667bd3 100644
--- a/src/components/StatisticsTableCategories.vue
+++ b/src/components/StatisticsTableCategories.vue
@@ -17,23 +17,46 @@
-->
-
+ |
{{ networkSize[i] }}
|
-
- {{ t("relationshipweight") }}
+ |
+ {{ t("sizebygender") }}
+ {{ t("female") }}
+ {{ t("male") }}
+ {{ t("diverse") }}
+ {{ t("notspecified") }}
|
-
- {{ naehenSum[i] }}
+ |
+
+ {{ gSize }}
+ |
+
+
+
+ {{ t("sizebyhorizon") }}
+ {{ t(ho) }}
+ |
+
+
+ {{ hSz }}
+ |
+
+
+
+ {{ t("closeness") }}
+ |
+
+ {{ naehen[i] }}
|
{{ t("categorydensity") }}
|
- {{ density[i] }} |
+ {{ density[i] }} |
+
+
+ {{ t("degree") }}
+ |
+
+ {{ degree[i] }}
+ |
+
{{ t("categorystar") }}
@@ -54,27 +85,6 @@
{{ stars[i] }}
|
-
-
- {{ t("bridges") }}
- |
-
- {{ bridgesCount[i] }}
- |
-
-
-
- {{ t("bridgepersons") }}
- |
-
- {{ bridgePersons[i] }}
- |
-
{{ t("isolatedpersons") }}
@@ -122,6 +132,7 @@ import {
} from "@/data/AlterCategories";
import de from "@/de";
import en from "@/en";
+import { HORIZON_KEYS } from "@/data/Horizon";
export default defineComponent({
mixins: [de, en],
@@ -129,7 +140,7 @@ export default defineComponent({
t(prop: string) {
return this[document.documentElement.lang][prop];
},
- translateCategoryKey(categoryKey: any) {
+ translateCategoryKey(categoryKey: string) {
const lang = document.documentElement.lang;
const translation = CATEGORY_TRANSLATIONS[categoryKey];
@@ -212,7 +223,7 @@ export default defineComponent({
});
function makeComputedAlterGroup(
- group: "stars" | "isolated" | "bridgePersons" | "alterZeroEdge"
+ group: "stars" | "isolated" | "alterZeroEdge"
) {
return computed(() => {
return categoryLabels.value.map((cat) => {
@@ -234,7 +245,7 @@ export default defineComponent({
}
const clickCell = (
- group: "stars" | "isolated" | "bridgePersons" | "alterZeroEdge",
+ group: "stars" | "isolated" | "alterZeroEdge",
cat: string
) => {
const alteri = getOrInit(networkAnalysis.value, cat)[group];
@@ -248,28 +259,47 @@ export default defineComponent({
return {
categoryLabels,
- networkSize: computed((): string[] => {
- return categoryLabels.value.map((cat) =>
- getOrInit(networkAnalysis.value, cat).alterConnected.toFixed(0)
- );
+ networkSize: computed((): string[] =>
+ categoryLabels.value.map((cat) => {
+ const analy = getOrInit(networkAnalysis.value, cat);
+ return analy.alterConnected + " (" + analy.alterConnectable + ")";
+ })
+ ),
+ sizeByGender: computed(() => {
+ return categoryLabels.value.map((cat) => {
+ const analy = getOrInit(networkAnalysis.value, cat);
+ return analy.genderConnected.map(
+ (g, i) => g + " (" + analy.genderConnectable[i] + ")"
+ );
+ });
}),
- naehenSum: computed((): string[] => {
- return categoryLabels.value.map((cat) =>
- getOrInit(networkAnalysis.value, cat).naehenSum.toFixed(0)
- );
+ HORIZON_KEYS,
+ sizeByHorizon: computed(() => {
+ return categoryLabels.value.map((cat) => {
+ const analy = getOrInit(networkAnalysis.value, cat);
+ return analy.horizonConnected.map(
+ (g, i) => g + " (" + analy.horizonConnectable[i] + ")"
+ );
+ });
}),
+ naehen: computed((): string[] =>
+ categoryLabels.value.map((cat) => {
+ const an = getOrInit(networkAnalysis.value, cat);
+ return an.naehenAvg.toFixed(1) + " (" + an.naehenDev.toFixed(1) + ")";
+ })
+ ),
density,
// extDensity,
+ degree: computed((): string[] =>
+ categoryLabels.value.map((cat) => {
+ const an = getOrInit(networkAnalysis.value, cat);
+ return an.degreeAvg.toFixed(1) + " (" + an.degreeDev.toFixed(1) + ")";
+ })
+ ),
stars,
isolated: makeComputedAlterGroup("isolated"),
alterZeroEdge: makeComputedAlterGroup("alterZeroEdge"),
- bridgePersons: makeComputedAlterGroup("bridgePersons"),
- bridgesCount: computed((): string[] => {
- return categoryLabels.value.map((cat) =>
- getOrInit(networkAnalysis.value, cat).bridges.length.toFixed(0)
- );
- }),
clickCell,
};
},
@@ -288,4 +318,10 @@ td:not([align]) {
th {
font-weight: normal;
}
+
+th.sizeby > em {
+ display: block;
+ font-style: normal;
+ margin-left: 2em;
+}
diff --git a/src/data/Alter.ts b/src/data/Alter.ts
index d741d10..6497223 100644
--- a/src/data/Alter.ts
+++ b/src/data/Alter.ts
@@ -60,17 +60,6 @@ export function hasOptionalChanges(alter: Alter) {
);
}
-/**
- * get the "closeness" of an alter in 9 concentric rings around the ego.
- * 9 = very close, ..., 0 = on or beyond the outer horizon.
- * Based on Java class Position by Nikolaus Kelis (v. 1.4.2)
- * @param alter
- * @returns integer between 9 (close) and 0 (distant)
- */
-export function naehenScore(alter: Alter): number {
- return Math.max(9 - Math.floor((alter.distance * 9) / 100), 0);
-}
-
/**
* check if the alter can be connected to the ego or another alter.
* By definition it is not possible to have a connection to a deceased or non-human alter.
diff --git a/src/data/AlterCategories.ts b/src/data/AlterCategories.ts
index e9096ae..46bc83b 100644
--- a/src/data/AlterCategories.ts
+++ b/src/data/AlterCategories.ts
@@ -1,6 +1,4 @@
import { Alter } from "./Alter";
-import { Gender } from "./Gender";
-import { Sectors } from "./Sectors";
type inCategoryType = (catIndex: number, a: Alter) => boolean;
@@ -15,18 +13,18 @@ export const CATEGORY_TRANSLATIONS: Record> = {
de: "Sektor",
en: "Sector",
},
- "Kreis 3": {
- de: "Kreis 3",
- en: "Circle 3",
- },
- "Kreis 3 + 2": {
- de: "Kreis 3 + 2",
- en: "Circle 3 + 2",
- },
- "Kreis 3 + 2 + 1": {
- de: "Kreis 3 + 2 + 1",
- en: "Circle 3 + 2 + 1",
- },
+ // "Kreis 3": {
+ // de: "Kreis 3",
+ // en: "Circle 3",
+ // },
+ // "Kreis 3 + 2": {
+ // de: "Kreis 3 + 2",
+ // en: "Circle 3 + 2",
+ // },
+ // "Kreis 3 + 2 + 1": {
+ // de: "Kreis 3 + 2 + 1",
+ // en: "Circle 3 + 2 + 1",
+ // },
"prof. Hilfe": {
de: "Prof. Hilfe",
en: "Professional Help",
@@ -39,22 +37,22 @@ export const CATEGORY_TRANSLATIONS: Record> = {
de: "gesamtes Netzwerk",
en: "Entire Network",
},
- Geschlecht: {
- de: "Geschlecht",
- en: "Gender",
- },
+ // Geschlecht: {
+ // de: "Geschlecht",
+ // en: "Gender",
+ // },
Überblick: {
de: "Überblick",
en: "Overview",
},
- "Horizont (kumulativ)": {
- de: "Horizont (kumulativ)",
- en: "Cumulative Horizon",
- },
- Horizont: {
- de: "Horizont",
- en: "Horizon",
- },
+ // "Horizont (kumulativ)": {
+ // de: "Horizont (kumulativ)",
+ // en: "Cumulative Horizon",
+ // },
+ // Horizont: {
+ // de: "Horizont",
+ // en: "Horizon",
+ // },
Familie: {
de: "Familie",
en: "Family",
@@ -71,22 +69,22 @@ export const CATEGORY_TRANSLATIONS: Record> = {
de: "prof. Helfer*innen",
en: "Professional Helpers",
},
- weiblich: {
- de: "weiblich",
- en: "Female",
- },
- männlich: {
- de: "männlich",
- en: "Male",
- },
- divers: {
- de: "divers",
- en: "Diverse",
- },
- "nicht festgelegt": {
- de: "nicht festgelegt",
- en: "Not Specified",
- },
+ // weiblich: {
+ // de: "weiblich",
+ // en: "Female",
+ // },
+ // männlich: {
+ // de: "männlich",
+ // en: "Male",
+ // },
+ // divers: {
+ // de: "divers",
+ // en: "Diverse",
+ // },
+ // "nicht festgelegt": {
+ // de: "nicht festgelegt",
+ // en: "Not Specified",
+ // },
};
export function sectorIndex(alter: Alter): number | null {
@@ -103,13 +101,13 @@ export function sectorIndex(alter: Alter): number | null {
}
}
-function horizonIndex(alter: Alter): number {
- if (alter.distance <= 0) return 100;
- else if (alter.distance < 33.33) return 0;
- else if (alter.distance < 66.67) return 1;
- else if (alter.distance < 100) return 2;
- else return 100;
-}
+// function horizonIndex(alter: Alter): number {
+// if (alter.distance <= 0) return 100;
+// else if (alter.distance < 33.33) return 0;
+// else if (alter.distance < 66.67) return 1;
+// else if (alter.distance < 100) return 2;
+// else return 100;
+// }
const SECTOR: AlterCategorization = {
label: "Sektor",
@@ -132,6 +130,7 @@ const PROFI: AlterCategorization = {
categories: ["prof. Hilfe", "Netzwerk ohne prof. Hilfe", "gesamtes Netzwerk"],
};
+/* obsolete categorizations (since Jun 2024)
const HORIZON_CUM: AlterCategorization = {
label: "Horizont (kumulativ)",
inCategory: (catIndex: number, a: Alter): boolean =>
@@ -152,6 +151,7 @@ const GENDER: AlterCategorization = {
a.currentGender === Gender[catIndex],
categories: ["weiblich", "männlich", "divers", "nicht festgelegt,"],
};
+*/
// const AGE: AlterCategorization = {
// label: "Alter",
@@ -173,17 +173,13 @@ const ALL: AlterCategorization = {
};
export function getAlterCategorization(key = ""): AlterCategorization {
- return key === "sector"
- ? SECTOR
- : key === "profi"
- ? PROFI
- : key === "horizon"
- ? HORIZON
- : key === "horizon_cum"
- ? HORIZON_CUM
- : key === "gender"
- ? GENDER
- : ALL;
+ return key === "sector" ? SECTOR : key === "profi" ? PROFI : ALL;
+ // : key === "horizon"
+ // ? HORIZON
+ // : key === "horizon_cum"
+ // ? HORIZON_CUM
+ // : key === "gender"
+ // ? GENDER
// : key === "age"
// ? AGE
}
@@ -192,8 +188,8 @@ export const allAlterCategorizationKeys = [
"",
"sector",
"profi",
- "horizon",
- "horizon_cum",
- "gender",
+ // "horizon",
+ // "horizon_cum",
+ // "gender",
// "age",
];
diff --git a/src/data/Horizon.ts b/src/data/Horizon.ts
new file mode 100644
index 0000000..2aa89b6
--- /dev/null
+++ b/src/data/Horizon.ts
@@ -0,0 +1,20 @@
+import { Alter } from "./Alter";
+
+export const HORIZON_KEYS = ["horizon_close", "horizon_middle", "horizon_far"];
+
+export function horizonKey(alter: Alter): string {
+ if (alter.distance < 33.33) return HORIZON_KEYS[0];
+ else if (alter.distance < 66.67) return HORIZON_KEYS[1];
+ else return HORIZON_KEYS[2];
+}
+
+/**
+ * get the "closeness" of an alter in 9 concentric rings around the ego.
+ * 9 = very close, ..., 0 = on or beyond the outer horizon.
+ * Based on Java class Position by Nikolaus Kelis (v. 1.4.2)
+ * @param alter
+ * @returns integer between 9 (close) and 0 (distant)
+ */
+export function naehenScore(alter: Alter): number {
+ return Math.max(9 - Math.floor((alter.distance * 9) / 100), 0);
+}
diff --git a/src/data/NWKRecord.ts b/src/data/NWKRecord.ts
index c46b7a7..60d2690 100644
--- a/src/data/NWKRecord.ts
+++ b/src/data/NWKRecord.ts
@@ -114,7 +114,7 @@ function parseNWKFile(nwkText: string): any {
edgeType: 0,
edgeTypeByUser: 0,
angle: 0,
- distance: 0
+ distance: 0,
});
}
break;
@@ -144,6 +144,9 @@ function parseNWKFile(nwkText: string): any {
break;
}
});
+ //alteri ohne position werden verworfen
+ //weil easyNWK 1.5 so gelöschte alteri gespeichert hat
+ nwkData.alteri = nwkData.alteri.filter((a: {distance: number}) => a.distance > 0);
nwkData.version.nwk = {
ego: nwkData.ego,
@@ -189,4 +192,4 @@ function cartesianToPolar(x: number, y: number) {
const angle = Math.atan2(centeredY, centeredX) * (180 / Math.PI);
return { distance: distance, angle: angle };
-}
+}
\ No newline at end of file
diff --git a/src/data/NetworkAnalysis.ts b/src/data/NetworkAnalysis.ts
index 60e9116..ae8af28 100644
--- a/src/data/NetworkAnalysis.ts
+++ b/src/data/NetworkAnalysis.ts
@@ -1,21 +1,26 @@
-import { Alter, isConnectable, naehenScore } from "./Alter";
-import { AlterCategorization, sectorIndex } from "./AlterCategories";
-import { Connection } from "./Connection";
-import { NWK } from "./NWK";
+import { type Alter, isConnectable } from "./Alter";
+import { HORIZON_KEYS, horizonKey, naehenScore } from "./Horizon";
+import { type AlterCategorization, sectorIndex } from "./AlterCategories";
+import { Gender } from "./Gender";
+import type { NWK } from "./NWK";
export interface NetworkAnalysis {
alterConnected: number;
alterConnectable: number;
intConnCount: number;
- extConnCount: number;
- naehenSum: number;
+ degreeAvg: number;
+ degreeDev: number;
+ naehenAvg: number;
+ naehenDev: number;
stars: Array;
maxDegree: number;
isolated: Array;
- bridgePersons: Array;
- bridges: Array;
alterZeroEdge: Array;
+ genderConnected: Array;
+ genderConnectable: Array;
+ horizonConnected: Array;
+ horizonConnectable: Array;
}
function initNetworkAnalysis(): NetworkAnalysis {
@@ -23,15 +28,19 @@ function initNetworkAnalysis(): NetworkAnalysis {
alterConnected: 0,
alterConnectable: 0,
intConnCount: 0,
- extConnCount: 0,
- naehenSum: 0,
+ degreeAvg: 0,
+ degreeDev: 0,
+ naehenAvg: 0,
+ naehenDev: 0,
stars: [],
maxDegree: 0,
isolated: [],
- bridgePersons: [],
- bridges: [],
alterZeroEdge: [],
+ genderConnected: [],
+ genderConnectable: [],
+ horizonConnected: [],
+ horizonConnectable: [],
};
}
@@ -50,8 +59,9 @@ export function getOrInit(
interface AlterMetrics {
alter: Alter;
degree: number;
- sector: number;
- bridgePerson: boolean;
+ // sector: number;
+ naehe: number;
+ isolated: boolean;
}
/**
@@ -72,43 +82,46 @@ export function analyseNWKbyCategory(
alterMetrics.set(alter.id, {
alter,
degree: 0,
- sector: sec,
- bridgePerson: false,
+ naehe: naehenScore(alter),
+ // sector: sec,
+ isolated: true,
});
}
const result = new Map();
- for (const conn of nwk.connections) {
- const a1 = alterMetrics.get(conn.id1);
- const a2 = alterMetrics.get(conn.id2);
- if (!(a1 && a2)) continue;
-
- // (2) increase degree of each node
- a1.degree++;
- a2.degree++;
-
- // (3) mark bridge persons
- if (a1.sector !== a2.sector) {
- a1.bridgePerson = true;
- a2.bridgePerson = true;
- }
- }
-
for (let i = 0; i < categories.categories.length; i++) {
const analysis = getOrInit(result, categories.categories[i]);
- // count alterZeroEdgeCount in this category
- for (const alter of nwk.alteri) {
+ for (const conn of nwk.connections) {
+ const a1 = alterMetrics.get(conn.id1);
+ const a2 = alterMetrics.get(conn.id2);
+ if (!(a1 && a2)) continue;
+
+ // they are not isolated (category irrelevant)
+ a1.isolated = false;
+ a2.isolated = false;
+
+ // (9) count connections for density
if (
- alter.edgeType == 0 &&
- categories.inCategory(i, alter) &&
- isConnectable(alter)
+ categories.inCategory(i, a1.alter) &&
+ categories.inCategory(i, a2.alter)
) {
- analysis.alterZeroEdge.push(alter);
+ // both sides of connection are in category
+ analysis.intConnCount++;
+
+ // (2) increase degree of each node (only if both alters in same sector/category)
+ a1.degree++;
+ a2.degree++;
}
}
- // TODO reconsider whether a zero edge alter can be star or bridgeperson
+
+ let degreeSum = 0;
+ let naehenSum = 0;
+ const genderConnected = new Map();
+ const genderConnectable = new Map();
+ const horizonConnected = new Map();
+ const horizonConnectable = new Map();
for (const [, am] of alterMetrics) {
if (categories.inCategory(i, am.alter)) {
@@ -124,57 +137,73 @@ export function analyseNWKbyCategory(
analysis.stars.push(am.alter);
}
- // (6) collect isolated (must have edge to ego!)
- if (am.degree == 0 && am.alter.edgeType >= 1) {
- analysis.isolated.push(am.alter);
+ // count alterZeroEdgeCount in this category
+ if (am.alter.edgeType == 0) {
+ analysis.alterZeroEdge.push(am.alter);
}
- // (7) collect bridge persons
- // to exclude connectable alteri #46 --> && am.alter.edgeType >= 1
- if (am.bridgePerson) {
- analysis.bridgePersons.push(am.alter);
+ // (6) collect isolated (must have edge to ego!)
+ // degree cannot be used because it is only within category
+ if (am.isolated && am.alter.edgeType >= 1) {
+ analysis.isolated.push(am.alter);
}
- // (8) increase networkSize & naehenSum
+ // (8) increase networkSize & naehenSum & size-by-arrays
analysis.alterConnectable++;
+ degreeSum += am.degree;
+ countByKey(genderConnectable, am.alter.currentGender);
+ countByKey(horizonConnectable, horizonKey(am.alter));
if (am.alter.edgeType >= 1) {
analysis.alterConnected++;
- analysis.naehenSum += naehenScore(am.alter);
+ countByKey(genderConnected, am.alter.currentGender);
+ countByKey(horizonConnected, horizonKey(am.alter));
+ naehenSum += am.naehe;
}
}
}
- for (const conn of nwk.connections) {
- const a1 = alterMetrics.get(conn.id1);
- const a2 = alterMetrics.get(conn.id2);
- if (!(a1 && a2)) continue;
+ analysis.degreeAvg = degreeSum / analysis.alterConnectable;
+ analysis.naehenAvg = naehenSum / analysis.alterConnected;
+ analysis.genderConnected = mapToArray(genderConnected, Gender);
+ analysis.genderConnectable = mapToArray(genderConnectable, Gender);
+ analysis.horizonConnected = mapToArray(horizonConnected, HORIZON_KEYS);
+ analysis.horizonConnectable = mapToArray(horizonConnectable, HORIZON_KEYS);
- // (9) count connections for density
- if (
- categories.inCategory(i, a1.alter) &&
- categories.inCategory(i, a2.alter)
- ) {
- // both sides of connection are in category
- analysis.intConnCount++;
+ // another iteration to calculate standard deviation
+ degreeSum = 0;
+ naehenSum = 0;
- // (3b) bridges count only if both sides are in the same category
- // to exclude connectable alteri #46 --> && a1.edgeType >= 1 && a2.edgeType >= 1
- if (a1.sector !== a2.sector) {
- analysis.bridges.push(conn);
+ for (const [, am] of alterMetrics) {
+ if (categories.inCategory(i, am.alter)) {
+ degreeSum += (am.degree - analysis.degreeAvg) ** 2;
+ if (am.alter.edgeType >= 1) {
+ naehenSum += (am.naehe - analysis.naehenAvg) ** 2;
}
- } else if (
- categories.inCategory(i, a1.alter) ||
- categories.inCategory(i, a2.alter)
- ) {
- // exactly one side of connection is in category
- analysis.extConnCount++;
}
}
+ analysis.degreeDev = Math.sqrt(degreeSum / analysis.alterConnectable);
+ analysis.naehenDev = Math.sqrt(naehenSum / analysis.alterConnected);
}
return result;
}
+function countByKey(map: Map, key: string) {
+ const prev = map.get(key);
+ if (prev) {
+ map.set(key, prev + 1);
+ } else {
+ map.set(key, 1);
+ }
+}
+
+function mapToArray(map: Map, keys: string[]) {
+ return keys.map((k) => {
+ const value = map.get(k);
+ return value ? value : 0;
+ });
+}
+
/**
*
* Based on Java class NetworkAnalysis by Nikolaus Kelis (v. 1.4.2)
diff --git a/src/data/statisticsCSV.ts b/src/data/statisticsCSV.ts
index 11825ab..e76c6e0 100644
--- a/src/data/statisticsCSV.ts
+++ b/src/data/statisticsCSV.ts
@@ -5,124 +5,137 @@ import {
import {
analyseNWKbyCategory,
calculateDensity,
- getOrInit,
NetworkAnalysis,
} from "@/data/NetworkAnalysis";
-import { NWK } from "@/data/NWK";
import { Alter } from "./Alter";
+import { store } from "@/store";
+import { NWKVersion } from "./NWKVersion";
const SEP = ";";
+let output = "";
export function statisticsCSV(
- nwk: NWK,
- displayName: (a: Alter) => string
+ versions: NWKVersion[]
): string {
- let output = "Auswertung" + SEP + nwk.ego.name;
+ output = "";
+
+ output += "Name des Egos" + SEP;
+ output += "Name der Netzwerkkarte" + SEP;
+ output += "Datum" + SEP;
+ output += "ID" + SEP;
+ output += "Netzwerksektor" + SEP;
+ output += "Netzwerkgröße" + SEP;
+ output += "Netzwerkgröße (+aktivierbare)" + SEP;
+ output += "nach Geschlecht weiblich" + SEP;
+ output += "nach Geschlecht weiblich (+aktivierbare)" + SEP;
+ output += "nach Geschlecht männlich" + SEP;
+ output += "nach Geschlecht männlich (+aktivierbare)" + SEP;
+ output += "nach Geschlecht divers" + SEP;
+ output += "nach Geschlecht divers (+aktivierbare)" + SEP;
+ output += "nach Geschlecht nicht festgelegt" + SEP;
+ output += "nach Geschlecht nicht festgelegt (+aktivierbare)" + SEP;
+ output += "nach Horizont nah" + SEP;
+ output += "nach Horizont nah (+aktivierbare)" + SEP;
+ output += "nach Horizont mittel" + SEP;
+ output += "nach Horizont mittel (+aktivierbare)" + SEP;
+ output += "nach Horizont entfernt" + SEP;
+ output += "nach Horizont entfernt (+aktivierbare)" + SEP;
+ output += "Durschschn. Nähe" + SEP;
+ output += "Durschschn. Nähe (SD)" + SEP;
+ output += "Dichte" + SEP;
+ output += "Durchschn. Degree" + SEP;
+ output += "Durchschn. Degree (SD)" + SEP;
+ output += "Star(s)" + SEP;
+ output += "Isolierte" + SEP;
+ output += "Personen ohne Kante zum Ego" + SEP;
+ output += "\n";
- for (const cat of allAlterCategorizationKeys) {
- // loop each tab of the statistics panel (below each other on single sheet)
- const categorization = getAlterCategorization(cat);
- const networkAnalysis = analyseNWKbyCategory(nwk, categorization);
-
- output += "\n\n" + categorization.label + "\n\n";
-
- output += "Kennzahl";
- for (const label of categorization.categories) {
- output += SEP + label;
- }
-
- output += "\nNetzwerkgröße";
- for (const label of categorization.categories) {
- output +=
- SEP + getOrInit(networkAnalysis, label).alterConnected.toFixed(0);
- }
-
- output += "\nBeziehungsgewicht";
- for (const label of categorization.categories) {
- output += SEP + getOrInit(networkAnalysis, label).naehenSum.toFixed(0);
- }
-
- output += "\nDichte der Kategorie";
- for (const label of categorization.categories) {
- const { alterConnectable, intConnCount } = getOrInit(
- networkAnalysis,
- label
- );
- output +=
- SEP +
- calculateDensity(alterConnectable, intConnCount).toLocaleString(
- undefined,
- {
- minimumFractionDigits: 3,
- maximumFractionDigits: 3,
+ for (const version of versions) {
+ for (const cat of allAlterCategorizationKeys) {
+ const categorization = getAlterCategorization(cat);
+ const networkAnalysisMap = analyseNWKbyCategory(version.nwk, categorization);
+
+ for (const label of categorization.categories) {
+ const networkAnalysis = networkAnalysisMap.get(label);
+ if (networkAnalysis) {
+ getDataForKeyFigures(networkAnalysis, version.nwk.ego.name, version.title, version.date, version.id, categorization.label, label);
}
- );
- }
-
- output += "\nStar(s)";
- output += categorization.categories
- .map((label) => {
- const { stars, maxDegree } = getOrInit(networkAnalysis, label);
- if (stars.length > 0 && maxDegree > 0) {
- return stars.map((a) => displayName(a)).join(", ");
- // + " (" + maxDegree + " Beziehungen)"
- } else {
- return "-";
+ output += "\n";
}
- })
- .reduce((prev, curr) => prev + SEP + curr, "");
-
- output += "\nBrücken";
- for (const label of categorization.categories) {
- output +=
- SEP + getOrInit(networkAnalysis, label).bridges.length.toFixed(0);
- }
-
- output += "\nBrückenperson(en)";
- output += makeComputedAlterGroup(
- networkAnalysis,
- categorization.categories,
- displayName,
- "bridgePersons"
- ).reduce((prev, curr) => prev + SEP + curr, "");
-
- output += "\nIsolierte";
- output += makeComputedAlterGroup(
- networkAnalysis,
- categorization.categories,
- displayName,
- "isolated"
- ).reduce((prev, curr) => prev + SEP + curr, "");
+ }
+ }
+
+ output += "\n";
+ return output;
+}
- output += "\nPersonen ohne Kante zur Ankerperson";
- output += makeComputedAlterGroup(
- networkAnalysis,
- categorization.categories,
- displayName,
- "alterZeroEdge"
- ).reduce((prev, curr) => prev + SEP + curr, "");
+function getDataForKeyFigures(networkAnalysis: NetworkAnalysis, ego: string, title: string, date: string, id: number, categoryLabel: string, label: string) {
+ output += ego + SEP;
+ output += title + SEP;
+ output += date + SEP;
+ output += id + SEP;
+ output += categoryLabel + (label ? " " + label : "") + SEP;
+ output += networkAnalysis.alterConnectable + SEP;
+ output += networkAnalysis.alterConnected + SEP;
+
+ for (const [i, g] of networkAnalysis.genderConnected.entries()) {
+ output += g + SEP;
+ output += networkAnalysis.genderConnectable[i] + SEP;
+ }
+ for (const [i, g] of networkAnalysis.horizonConnected.entries()) {
+ output += g + SEP;
+ output += networkAnalysis.horizonConnectable[i] + SEP;
}
+ output += networkAnalysis.naehenAvg.toString().replace('.', ',') + SEP;
+ output += networkAnalysis.naehenDev.toString().replace('.', ',') + SEP;
+ const density = calculateDensity(networkAnalysis.alterConnectable, networkAnalysis.intConnCount);
+ output += density.toString().replace('.', ',') + SEP;
+ output += networkAnalysis.degreeAvg.toString().replace(".", ",") + SEP;
+ output += networkAnalysis.degreeDev.toString().replace('.', ',') + SEP;
+ output += formatStars(networkAnalysis) + SEP;
+ output += formatIsolated(networkAnalysis.isolated) + SEP;
+ output += formatZeroEdge(networkAnalysis.alterZeroEdge) + SEP;
+}
- return output;
+function formatStars(networkAnalysis: NetworkAnalysis): string {
+ const alteri = networkAnalysis.stars;
+ if (alteri.length > 0 && networkAnalysis.maxDegree > 0) {
+ return document.documentElement.lang == "de"
+ ? alteri.map((a) => store.getters["displayName"](a)).join(", ") +
+ " (" +
+ networkAnalysis.maxDegree +
+ " Beziehungen)"
+ : alteri.map((a) => store.getters["displayName"](a)).join(", ") +
+ " (" +
+ networkAnalysis.maxDegree +
+ " relations)";
+ } else {
+ return document.documentElement.lang == "de" ? "keine" : "none";
+ }
}
-function makeComputedAlterGroup(
- networkAnalysis: Map,
- categoryLabels: string[],
- displayName: (a: Alter) => string,
- group: "stars" | "isolated" | "bridgePersons" | "alterZeroEdge"
-) {
- return categoryLabels.map((cat) => {
- const analysis = getOrInit(networkAnalysis, cat);
- if (analysis[group].length > 0) {
- return (
- analysis[group].length +
- " (" +
- analysis[group].map((a) => displayName(a)).join(", ") +
- ")"
- );
- } else {
- return "0";
- }
- });
+function formatIsolated(alteri: Alter[]): string {
+ if (alteri.length > 0) {
+ return (
+ alteri.length +
+ " (" +
+ alteri.map((a) => store.getters["displayName"](a)).join(", ") +
+ ")"
+ );
+ } else {
+ return "0";
+ }
}
+
+function formatZeroEdge(alteri: Alter[]): string {
+ if (alteri.length > 0) {
+ return (
+ alteri.length +
+ " (" +
+ alteri.map((a) => store.getters["displayName"](a)).join(", ") +
+ ")"
+ );
+ } else {
+ return "0";
+ }
+}
\ No newline at end of file
diff --git a/src/de.ts b/src/de.ts
index 0d54973..e6cabf0 100644
--- a/src/de.ts
+++ b/src/de.ts
@@ -34,31 +34,42 @@ export default {
horizon: "Horizont",
horizoncumulative: "Horizont (kumulativ)",
gender: "Geschlecht",
- networksize: "Netzwerkgröße",
+ networksize: "Netzwerkgröße (+aktivierbare)",
+ sizebygender: "nach Geschlecht",
+ sizebyhorizon: "nach Horizont",
+ horizon_close: "nah",
+ horizon_middle: "mittel",
+ horizon_far: "entfernt",
+ closeness: "Durchschn. Nähe (SD)",
relationshipweight: "Beziehungsgewicht",
- totaldensity: "Dichte gesamt",
+ totaldensity: "Dichte",
categorydensity: "Dichte der Kategorie",
+ degree: "Durchschn. Degree (SD)",
stars: "Star(s)",
categorystar: "Star(s) (pro Kategorie)",
- bridges: "Brücken",
- bridgepersons: "Brückenperson(en)",
+ // bridges: "Brücken",
+ // bridgepersons: "Brückenperson(en)",
isolatedpersons: "Isolierte",
- personswithoutedgetotheego: "Personen ohne Kante zur Ankerperson",
+ personswithoutedgetotheego: "Personen ohne Kante zum Ego",
networkmsg:
- "Anzahl der Kontakte im Netzwerk exklusive Ankerperson und exklusive Personen ohne Kante zur Ankerperson",
+ "Anzahl der Kontakte im Netzwerk exklusive des Egos und exklusive Personen ohne Kante zum Ego (bzw. inklusive aktivierbarer Personen; d.h. Menschen, nicht verstorben)",
+ closenessmsg:
+ "arithmetisches Mittel der Nähe der Kontakte zum Ego in 9 konzentrischen Ringen (9=nah … 1=entfernt)",
relationshipmsg:
"Summierte Nähe bzw. Distanz der Kontakte zur Ankerperson. Je höher die Kennzahl, umso näher stehen die Personen der Ankerperson.",
densitymsg:
- "Verhältnis der tatsächlich vorhandenen zu den theoretisch möglichen Verbindungen (exklusive der Verbindungen zwischen Anker- und Kontaktpersonen, inklusive Personen ohne Kante zur Ankerperson). Optional: Maßzahl liegt zwischen 0 (nur isolierte Kontakte) und 1 (jede Person im Netzwerk ist mit jeder anderen verbunden).",
+ "Verhältnis der tatsächlich vorhandenen zu den theoretisch möglichen Verbindungen (exklusive der Verbindungen zwischen Ego und Kontaktpersonen, inklusive Personen ohne Kante zum Ego). Kennzahl liegt zwischen 0 (nur isolierte Kontakte) und 1 (jede Person im Netzwerk ist mit jeder anderen verbunden).",
+ degreemsg:
+ "arithmetisches Mittel der Verbindungen von Kontaktpersonen (exklusive der Verbindungen zwischen Ego und Kontaktpersonen, inklusive Personen ohne Kante zum Ego)",
starsmsg:
- "Kontakt(e) mit den meisten Verbindungen im Netzwerk (neben der Ankerperson)",
- bridgemsg: "Anzahl der Verbindungen zwischen den Sektoren im Netzwerk",
- bridgesmsg2:
- "Kontakt(e), die einzelne Sektoren im Netzwerk miteinander verbinden",
+ "Kontakt(e) mit den meisten Verbindungen im Netzwerk (exklusive Ego)",
+ // bridgemsg: "Anzahl der Verbindungen zwischen den Sektoren im Netzwerk",
+ // bridgesmsg2:
+ // "Kontakt(e), die einzelne Sektoren im Netzwerk miteinander verbinden",
isolatedmsg:
- "Kontakt(e), die ausschließlich mit der Ankerperson verbunden sind",
+ "Kontakt(e), die ausschließlich mit dem Ego verbunden sind",
noedgemsg:
- "Lebende Personen ohne aktualisierte Verbindung zur Ankerperson. Verbindungen mit anderen Personen im Netzwerk und damit indirekte Verbindung zur Ankerperson sind möglich.",
+ "Lebende Personen ohne aktualisierte Verbindung zum Ego. Verbindungen mit anderen Personen im Netzwerk und damit indirekte Verbindung zum Ego sind möglich.",
//},
//viewOptions: {
diff --git a/src/en.ts b/src/en.ts
index a13ec9d..67c4802 100644
--- a/src/en.ts
+++ b/src/en.ts
@@ -35,9 +35,16 @@ export default {
horizoncumulative: "Horizon (cumulative)",
gender: "Gender",
networksize: "Network size",
+ sizebygender: "by Gender",
+ sizebyhorizon: "by Horizont",
+ horizon_close: "close",
+ horizon_middle: "middle",
+ horizon_far: "distant",
+ closeness: "Avg. Closeness (SD)",
relationshipweight: "Relationship weight",
totaldensity: "Total density",
categorydensity: "Category density",
+ degree: "Avg. Degree (SD)",
categorystar: "Star (per category)",
stars: "Star(s)",
bridges: "Bridges",
@@ -46,10 +53,14 @@ export default {
personswithoutedgetotheego: "Person(s) without edge to the ego",
networkmsg:
"Number of contacts in the network without ego and without contacts that do not have an edge to the ego",
+ closenessmsg:
+ "arithmetic average of closeness of contacts to the ego in 9 contric rings (9=close … 1=distant)",
relationshipmsg:
"Summed proximity or distance of the contacts to the ego. The higher the indicator, the closer the contacts are to the ego.",
densitymsg:
"Ratio of the actually existing connections to the theoretically possible connections (excluding connections between ego and contacts, including contacts without edge to ego). Optional: Measurement is between 0 (isolated contacts only) and 1 (every person in the network is connected to everyone else).",
+ degreemsg:
+ "arithmetic average of connections of contact persons (eckluding connections to the ego, inclusive persons without edge to the ego)",
starsmsg:
"Contact(s) with most connections in the network (besides the ego)",
bridgesmsg2: "Contact(s) connecting individual sectors in the network",
diff --git a/src/store/sessionModule.ts b/src/store/sessionModule.ts
index 475e614..aa777fd 100644
--- a/src/store/sessionModule.ts
+++ b/src/store/sessionModule.ts
@@ -1,13 +1,11 @@
export const TAB_BASE = "base";
export const TAB_CONNECTIONS = "connections";
-export interface SessionFlags {
- statistics: boolean;
- nwkchange: boolean;
- nwkcomparison: boolean;
-}
+// export interface SessionFlags {
+// versionComparison: boolean;
+// }
-export interface SessionState extends SessionFlags {
+export interface SessionState {
selected: Set;
editIndex: number | null;
editTab: string;
@@ -15,10 +13,7 @@ export interface SessionState extends SessionFlags {
export function initSessionState(): SessionState {
return {
- statistics: false,
- nwkcomparison: false,
- nwkchange: false,
-
+ // versionComparison: false,
selected: new Set(),
editIndex: null,
editTab: "",
@@ -35,7 +30,7 @@ const getters = {
};
const mutations = {
- updateFlag(
+ /* updateFlag(
state: SessionState,
payload: { flag: keyof SessionFlags; value: boolean }
) {
@@ -52,7 +47,7 @@ const mutations = {
toggle(state: SessionState, flag: keyof SessionFlags): void {
state[flag] = !state[flag];
- },
+ }, */
toggleAlterSelected(state: SessionState, alterId: number): void {
if (state.selected.has(alterId)) {
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index 01cc853..e0c5401 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -43,7 +43,7 @@
/>
-
+
@@ -128,7 +128,6 @@ export default defineComponent({
egoEditMode,
editEgoFinished,
mapclick,
- showStatistics: computed(() => store.state.session.statistics),
};
},
});
diff --git a/src/views/PdfView.vue b/src/views/PdfView.vue
index cbc0cff..2516217 100644
--- a/src/views/PdfView.vue
+++ b/src/views/PdfView.vue
@@ -157,11 +157,7 @@ export default defineComponent({
" " +
visibleNWKVersion.value?.title +
" " +
- visibleNWKVersion.value?.date?.substring(8, 10) +
- "." +
- visibleNWKVersion.value?.date?.substring(5, 7) +
- "." +
- visibleNWKVersion.value?.date?.substring(0, 4) +
+ new Date(visibleNWKVersion.value!.date).toLocaleDateString("en-CA") +
".pdf"),
window.print();
};
|