forked from PinSpace-Org/GistPin
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnetwork-metrics.ts
More file actions
90 lines (73 loc) 路 2.59 KB
/
Copy pathnetwork-metrics.ts
File metadata and controls
90 lines (73 loc) 路 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
export interface UserActivity {
users: number[];
activity: number[];
timestamps: string[];
}
export interface GeographicData {
locations: Array<{
region: string;
userCount: number;
activityLevel: number;
}>;
}
export interface NetworkMetrics {
valuePerUser: number[];
metcalfeValues: number[];
criticalMassIndex: number | null;
geographicDensity: Record<string, number>;
networkStrength: number;
}
export function calculateValuePerUser(users: number[], activity: number[]): number[] {
if (users.length !== activity.length) {
throw new Error('Users and activity arrays must have the same length');
}
return users.map((userCount, index) => {
if (userCount === 0) return 0;
return activity[index] / userCount;
});
}
export function metcalfeLawCurve(users: number[]): number[] {
return users.map(userCount => {
return (userCount * (userCount - 1)) / 2;
});
}
export function detectCriticalMass(data: number[]): number | null {
if (data.length < 3) return null;
let maxGrowthRate = 0;
let criticalIndex = null;
for (let i = 1; i < data.length - 1; i++) {
const growthRate = (data[i] - data[i - 1]) / data[i - 1];
const secondDerivative = (data[i + 1] - 2 * data[i] + data[i - 1]);
if (growthRate > maxGrowthRate && secondDerivative < 0) {
maxGrowthRate = growthRate;
criticalIndex = i;
}
}
return criticalIndex;
}
export function calculateGeographicDensity(data: GeographicData): Record<string, number> {
const density: Record<string, number> = {};
const totalUsers = data.locations.reduce((sum, loc) => sum + loc.userCount, 0);
data.locations.forEach(loc => {
if (totalUsers > 0) {
density[loc.region] = (loc.userCount / totalUsers) * 100;
}
});
return density;
}
export function calculateNetworkStrength(metrics: {
valuePerUser: number[];
metcalfeValues: number[];
criticalMassIndex: number | null;
geographicDensity: Record<string, number>;
}): number {
const latestValuePerUser = metrics.valuePerUser[metrics.valuePerUser.length - 1] || 0;
const latestMetcalfe = metrics.metcalfeValues[metrics.metcalfeValues.length - 1] || 1;
const valueRatio = Math.min(latestValuePerUser / (latestMetcalfe / 1000), 1);
const criticalMassBonus = metrics.criticalMassIndex !== null ? 0.2 : 0;
const densityValues = Object.values(metrics.geographicDensity);
const geographicScore = densityValues.length > 0
? densityValues.reduce((sum, val) => sum + val, 0) / densityValues.length / 100
: 0;
return Math.min((valueRatio + criticalMassBonus + geographicScore) / 2.2, 1);
}