mirror of
https://github.com/louislam/uptime-kuma.git
synced 2025-06-19 18:56:48 +02:00
bug fix, made beats bars smaller
This commit is contained in:
parent
bf7d6deb73
commit
76b9680445
2 changed files with 74 additions and 42 deletions
|
@ -266,40 +266,41 @@ async function getAggregatedHeartbeats(uptimeCalculator, days) {
|
|||
const now = dayjs.utc();
|
||||
const result = [];
|
||||
|
||||
// Calculate the actual time range we have
|
||||
const startTime = now.subtract(days, "day").startOf("minute");
|
||||
// Force exact time range: exactly N days ago to exactly now
|
||||
const endTime = now;
|
||||
const startTime = now.subtract(days, "day");
|
||||
const totalMinutes = endTime.diff(startTime, "minute");
|
||||
|
||||
// Calculate how many buckets we can actually show (max 100)
|
||||
const targetBuckets = Math.min(100, totalMinutes);
|
||||
const bucketSizeMinutes = Math.max(1, Math.floor(totalMinutes / targetBuckets));
|
||||
// Always create exactly 100 buckets spanning the full time range
|
||||
const numBuckets = 100;
|
||||
const bucketSizeMinutes = totalMinutes / numBuckets;
|
||||
|
||||
// Determine data granularity based on days
|
||||
let dataPoints;
|
||||
let granularity;
|
||||
// Get available data from UptimeCalculator for lookup
|
||||
const availableData = {};
|
||||
let rawDataPoints;
|
||||
|
||||
if (days <= 1) {
|
||||
// For 1 day or less, use minutely data
|
||||
granularity = "minute";
|
||||
dataPoints = uptimeCalculator.getDataArray(days * 24 * 60, granularity);
|
||||
const exactMinutes = Math.ceil(days * 24 * 60);
|
||||
rawDataPoints = uptimeCalculator.getDataArray(exactMinutes, "minute");
|
||||
} else if (days <= 30) {
|
||||
// For 2-30 days, use hourly data
|
||||
granularity = "hour";
|
||||
dataPoints = uptimeCalculator.getDataArray(days * 24, granularity);
|
||||
const exactHours = Math.ceil(days * 24);
|
||||
rawDataPoints = uptimeCalculator.getDataArray(exactHours, "hour");
|
||||
} else {
|
||||
// For 31+ days, use daily data
|
||||
granularity = "day";
|
||||
dataPoints = uptimeCalculator.getDataArray(days, granularity);
|
||||
rawDataPoints = uptimeCalculator.getDataArray(days, "day");
|
||||
}
|
||||
|
||||
// Create time buckets
|
||||
const buckets = [];
|
||||
const actualBuckets = Math.floor(totalMinutes / bucketSizeMinutes);
|
||||
// Create lookup map for available data
|
||||
for (const point of rawDataPoints) {
|
||||
if (point && point.timestamp) {
|
||||
availableData[point.timestamp] = point;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < actualBuckets; i++) {
|
||||
// Create exactly numBuckets buckets spanning the full requested time range
|
||||
const buckets = [];
|
||||
for (let i = 0; i < numBuckets; i++) {
|
||||
const bucketStart = startTime.add(i * bucketSizeMinutes, "minute");
|
||||
const bucketEnd = bucketStart.add(bucketSizeMinutes, "minute");
|
||||
const bucketEnd = startTime.add((i + 1) * bucketSizeMinutes, "minute");
|
||||
|
||||
buckets.push({
|
||||
start: bucketStart.unix(),
|
||||
|
@ -312,22 +313,20 @@ async function getAggregatedHeartbeats(uptimeCalculator, days) {
|
|||
});
|
||||
}
|
||||
|
||||
// Aggregate data points into buckets
|
||||
for (const dataPoint of dataPoints) {
|
||||
if (!dataPoint || !dataPoint.timestamp) {
|
||||
continue;
|
||||
}
|
||||
// Aggregate available data into buckets
|
||||
for (const [ timestamp, dataPoint ] of Object.entries(availableData)) {
|
||||
const timestampNum = parseInt(timestamp);
|
||||
|
||||
// Find the appropriate bucket for this data point
|
||||
const bucket = buckets.find(b =>
|
||||
dataPoint.timestamp >= b.start && dataPoint.timestamp < b.end
|
||||
timestampNum >= b.start && timestampNum < b.end
|
||||
);
|
||||
|
||||
if (bucket) {
|
||||
if (bucket && dataPoint) {
|
||||
bucket.up += dataPoint.up || 0;
|
||||
bucket.down += dataPoint.down || 0;
|
||||
bucket.maintenance += dataPoint.maintenance || 0;
|
||||
bucket.pending += dataPoint.pending || 0;
|
||||
bucket.maintenance += 0; // UptimeCalculator treats maintenance as up
|
||||
bucket.pending += 0; // UptimeCalculator doesn't track pending separately
|
||||
bucket.hasData = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,6 +94,12 @@ export default {
|
|||
if (!this.beatList) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// For configured ranges, no padding needed since we show all beats
|
||||
if (this.normalizedHeartbeatBarDays > 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let num = this.beatList.length - this.maxBeat;
|
||||
|
||||
if (this.move) {
|
||||
|
@ -114,17 +120,19 @@ export default {
|
|||
|
||||
// If heartbeat days is configured (not auto), data should be aggregated from server
|
||||
if (this.normalizedHeartbeatBarDays > 0 && this.beatList.length > 0) {
|
||||
// Data is already aggregated from server, use it directly
|
||||
// But still limit to maxBeat for display
|
||||
if (this.beatList.length > this.maxBeat) {
|
||||
return this.beatList.slice(this.beatList.length - this.maxBeat);
|
||||
}
|
||||
// Data is already aggregated from server covering exact time range requested
|
||||
// Show all beats to display the full requested time period
|
||||
return this.beatList;
|
||||
}
|
||||
|
||||
// Original logic for auto mode (heartbeatBarDays = 0)
|
||||
let placeholders = [];
|
||||
|
||||
// Handle case where maxBeat is -1 (no limit)
|
||||
if (this.maxBeat <= 0) {
|
||||
return this.beatList;
|
||||
}
|
||||
|
||||
let start = this.beatList.length - this.maxBeat;
|
||||
|
||||
if (this.move) {
|
||||
|
@ -144,7 +152,7 @@ export default {
|
|||
|
||||
wrapStyle() {
|
||||
let topBottom = (((this.beatHeight * this.hoverScale) - this.beatHeight) / 2);
|
||||
let leftRight = (((this.beatWidth * this.hoverScale) - this.beatWidth) / 2);
|
||||
let leftRight = (((this.dynamicBeatWidth * this.hoverScale) - this.dynamicBeatWidth) / 2);
|
||||
|
||||
return {
|
||||
padding: `${topBottom}px ${leftRight}px`,
|
||||
|
@ -153,8 +161,8 @@ export default {
|
|||
},
|
||||
|
||||
barStyle() {
|
||||
if (this.move && this.shortBeatList.length > this.maxBeat) {
|
||||
let width = -(this.beatWidth + this.beatHoverAreaPadding * 2);
|
||||
if (this.move && this.maxBeat > 0 && this.shortBeatList.length > this.maxBeat) {
|
||||
let width = -(this.dynamicBeatWidth + this.beatHoverAreaPadding * 2);
|
||||
|
||||
return {
|
||||
transition: "all ease-in-out 0.25s",
|
||||
|
@ -175,9 +183,28 @@ export default {
|
|||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculate dynamic beat width for configured ranges
|
||||
* @returns {number} Beat width in pixels
|
||||
*/
|
||||
dynamicBeatWidth() {
|
||||
// For configured ranges, fit all beats to available width
|
||||
if (this.normalizedHeartbeatBarDays > 0 && this.shortBeatList.length > 0) {
|
||||
if (this.$refs.wrap) {
|
||||
const availableWidth = this.$refs.wrap.clientWidth;
|
||||
const totalBeats = this.shortBeatList.length;
|
||||
const totalPadding = totalBeats * (this.beatHoverAreaPadding * 2);
|
||||
const availableForBeats = availableWidth - totalPadding;
|
||||
const calculatedWidth = Math.max(1, Math.floor(availableForBeats / totalBeats));
|
||||
return Math.min(calculatedWidth, this.beatWidth); // Don't exceed original width
|
||||
}
|
||||
}
|
||||
return this.beatWidth;
|
||||
},
|
||||
|
||||
beatStyle() {
|
||||
return {
|
||||
width: this.beatWidth + "px",
|
||||
width: this.dynamicBeatWidth + "px",
|
||||
height: this.beatHeight + "px",
|
||||
};
|
||||
},
|
||||
|
@ -188,7 +215,7 @@ export default {
|
|||
*/
|
||||
timeStyle() {
|
||||
return {
|
||||
"margin-left": this.numPadding * (this.beatWidth + this.beatHoverAreaPadding * 2) + "px",
|
||||
"margin-left": this.numPadding * (this.dynamicBeatWidth + this.beatHoverAreaPadding * 2) + "px",
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -285,8 +312,14 @@ export default {
|
|||
*/
|
||||
resize() {
|
||||
if (this.$refs.wrap) {
|
||||
// For configured ranges, don't limit maxBeat - show all beats
|
||||
if (this.normalizedHeartbeatBarDays > 0) {
|
||||
this.maxBeat = -1; // No limit
|
||||
} else {
|
||||
// For auto mode, calculate based on screen width
|
||||
this.maxBeat = Math.floor(this.$refs.wrap.clientWidth / (this.beatWidth + this.beatHoverAreaPadding * 2));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue