import { getCountry } from "src/countries";
import type { ItemList } from "src/types";
import { sidebarLimit } from "utils/chart";
import { type ChartDataPoint } from "utils/filters";
import { computed, type Ref } from "vue";
export function useChartStats(
chartData: Ref<ChartDataPoint[]>,
xRange: Ref<string[] | undefined>,
yRange: Ref<string[] | undefined>,
latRange?: Ref<string[] | undefined>,
lonRange?: Ref<string[] | undefined>,
) {
const effectiveData = computed(() => {
let data = chartData.value;
if (xRange.value && xRange.value.length === 2) {
const minX = new Date(xRange.value[0]!).getTime();
const maxX = new Date(xRange.value[1]!).getTime();
data = data.filter((d) => {
const t = d.time.getTime();
return t >= minX && t <= maxX;
});
}
if (yRange.value && yRange.value.length === 2) {
const minY = parseFloat(yRange.value[0]!);
const maxY = parseFloat(yRange.value[1]!);
data = data.filter((d) => {
return d.dst_port >= minY && d.dst_port <= maxY;
});
}
if (latRange?.value && latRange.value.length === 2) {
const minLat = Math.min(
parseFloat(latRange.value[0]!),
parseFloat(latRange.value[1]!),
);
const maxLat = Math.max(
parseFloat(latRange.value[0]!),
parseFloat(latRange.value[1]!),
);
data = data.filter((d) => {
if (d.latitude === undefined) return false;
return d.latitude >= minLat && d.latitude <= maxLat;
});
}
if (lonRange?.value && lonRange.value.length === 2) {
const minLon = Math.min(
parseFloat(lonRange.value[0]!),
parseFloat(lonRange.value[1]!),
);
const maxLon = Math.max(
parseFloat(lonRange.value[0]!),
parseFloat(lonRange.value[1]!),
);
data = data.filter((d) => {
if (d.longitude === undefined) return false;
return d.longitude >= minLon && d.longitude <= maxLon;
});
}
return data;
});
const ipCounts = computed(() => {
const counts: Record<string, number> = {};
effectiveData.value.forEach((point: ChartDataPoint) => {
counts[point.remote_addr] = (counts[point.remote_addr] || 0) + 1;
});
return Object.entries(counts)
.map(([value, count]) => ({ value, count }))
.sort((a, b) => b.count - a.count)
.slice(0, sidebarLimit);
});
const portCounts = computed<ItemList[]>(() => {
const counts: Record<number, number> = {};
effectiveData.value.forEach((point: ChartDataPoint) => {
counts[point.dst_port] = (counts[point.dst_port] || 0) + 1;
});
delete counts[-1];
return Object.entries(counts)
.map(([value, count]) => ({ value: Number(value), count }))
.sort((a, b) => b.count - a.count)
.slice(0, sidebarLimit);
});
const countryCounts = computed<ItemList[]>(() => {
const counts: Record<string, number> = {};
effectiveData.value.forEach((point: ChartDataPoint) => {
const country = point.country || "Unknown";
counts[country] = (counts[country] || 0) + 1;
});
return Object.entries(counts)
.map(([value, count]) => {
const country = getCountry(value);
return {
value,
count,
label: `${country.flag} ${country.name}`,
};
})
.sort((a, b) => b.count - a.count)
.slice(0, sidebarLimit);
});
return {
ipCounts,
portCounts,
countryCounts,
};
}