diff --git a/Plan/common/src/main/resources/assets/plan/web/js/graphs.js b/Plan/common/src/main/resources/assets/plan/web/js/graphs.js index 3f3eda04d..225900a42 100644 --- a/Plan/common/src/main/resources/assets/plan/web/js/graphs.js +++ b/Plan/common/src/main/resources/assets/plan/web/js/graphs.js @@ -290,6 +290,80 @@ function performanceChart(id, playersOnlineSeries, tpsSeries, cpuSeries, ramSeri } function playersChart(id, playersOnlineSeries, sel) { + function groupByIntervalStartingFrom(startDate, interval) { + let previousGroupStart = startDate; + const groupByInterval = [[]]; + + for (let point of playersOnlineSeries.data) { + const date = point[0]; + if (date < startDate) { + continue; + } + + if (previousGroupStart + interval < date) { + previousGroupStart = date; + groupByInterval.push([]); + } + + const currentGroup = groupByInterval[groupByInterval.length - 1]; + currentGroup.push(point); + } + return groupByInterval; + } + + function averageGroupPoints(groupByInterval, minDate) { + const averages = []; + for (let group of groupByInterval) { + let totalDate = 0; + let total = 0; + let count = group.length; + for (let point of group) { + totalDate += (point[0] - minDate); // Remove the minDate from dates to calculate a smaller total + total += point[1]; + } + + if (count !== 0) { + const middleDate = Math.trunc((totalDate / count) + minDate); + const average = Math.trunc(total / count); + averages.push([middleDate, average]); + } + } + return averages; + } + + function getAveragePlayersSeries(minDate, twentyPointInterval) { + const groupByInterval = groupByIntervalStartingFrom(minDate, twentyPointInterval); + + return { + name: s.name.averagePlayersOnline, + type: s.type.spline, + tooltip: s.tooltip.zeroDecimals, + data: averageGroupPoints(groupByInterval, minDate), + color: "#1E90FF", + yAxis: 0 + }; + } + + function updateAveragePlayers(event) { + const minDate = event.min; + const maxDate = event.max; + const twentyPointInterval = (maxDate - minDate) / 20; + + const averagePlayersSeries = getAveragePlayersSeries(minDate, twentyPointInterval); + + const playersOnlineGraph = graphs.find(graph => graph && graph.renderTo && graph.renderTo.id === id); + playersOnlineGraph.series[1].update(averagePlayersSeries); + } + + const emptyAveragePlayersSeries = { + name: s.name.averagePlayersOnline, + type: s.type.spline, + tooltip: s.tooltip.zeroDecimals, + data: [], + color: "#1E90FF", + yAxis: 0 + }; + graphs.push(Highcharts.stockChart(id, { rangeSelector: { selected: sel, @@ -299,13 +373,18 @@ function playersChart(id, playersOnlineSeries, sel) { softMax: 2, softMin: 0 }, + xAxis: { + events: { + afterSetExtremes: updateAveragePlayers + } + }, title: {text: ''}, plotOptions: { areaspline: { fillOpacity: 0.4 } }, - series: [playersOnlineSeries] + series: [playersOnlineSeries, emptyAveragePlayersSeries] })); } diff --git a/Plan/common/src/main/resources/assets/plan/web/network.html b/Plan/common/src/main/resources/assets/plan/web/network.html index 2d144daa7..bf257dcb9 100644 --- a/Plan/common/src/main/resources/assets/plan/web/network.html +++ b/Plan/common/src/main/resources/assets/plan/web/network.html @@ -1081,6 +1081,7 @@ const s = { name: { playersOnline: 'Players Online', + averagePlayersOnline: 'Players Online (Average)', uniquePlayers: 'Unique Players', newPlayers: 'New Players', maxPing: 'Worst Ping', diff --git a/Plan/common/src/main/resources/assets/plan/web/server.html b/Plan/common/src/main/resources/assets/plan/web/server.html index 5ed42deff..2308c9344 100644 --- a/Plan/common/src/main/resources/assets/plan/web/server.html +++ b/Plan/common/src/main/resources/assets/plan/web/server.html @@ -1364,6 +1364,7 @@ const s = { name: { playersOnline: 'Players Online', + averagePlayersOnline: 'Players Online (Average)', uniquePlayers: 'Unique Players', newPlayers: 'New Players', tps: 'TPS',