From 6d0f859a93f1d9ce93b72be123da6e046c3464d9 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Fri, 1 Jun 2018 19:55:26 -0500 Subject: [PATCH] more updates to top stats page --- Plugins/Stats/Helpers/StatManager.cs | 25 +- Plugins/Stats/Models/EFRating.cs | 2 + .../Stats/Web/Controllers/StatsController.cs | 2 +- Plugins/Stats/Web/Dtos/TopStatsInfo.cs | 1 + Plugins/Stats/Web/Views/Stats/_List.cshtml | 23 +- ...180601172317_AddActivityAmount.Designer.cs | 504 ++++++++++++++++++ .../20180601172317_AddActivityAmount.cs | 25 + .../DatabaseContextModelSnapshot.cs | 2 + WebfrontCore/WebfrontCore.csproj | 1 + .../wwwroot/css/bootstrap-custom.scss | 9 +- WebfrontCore/wwwroot/js/loader.js | 8 +- WebfrontCore/wwwroot/js/stats.js | 48 +- 12 files changed, 617 insertions(+), 33 deletions(-) create mode 100644 SharedLibraryCore/Migrations/20180601172317_AddActivityAmount.Designer.cs create mode 100644 SharedLibraryCore/Migrations/20180601172317_AddActivityAmount.cs diff --git a/Plugins/Stats/Helpers/StatManager.cs b/Plugins/Stats/Helpers/StatManager.cs index 05c046488..2bef137ce 100644 --- a/Plugins/Stats/Helpers/StatManager.cs +++ b/Plugins/Stats/Helpers/StatManager.cs @@ -53,7 +53,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers var thirtyDaysAgo = DateTime.UtcNow.AddMonths(-1); var iqClientRatings = (from rating in context.Set() #if !DEBUG - where rating.RatingHistory.Client.TotalConnectionTime > 3600 + where rating.ActivityAmount > 3600 #endif where rating.RatingHistory.Client.Level != Player.Permission.Banned where rating.RatingHistory.Client.LastConnection > thirtyDaysAgo @@ -106,6 +106,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers LastSeen = Utilities.GetTimePassed(clientRatingsDict[s.ClientId].LastConnection, false), Name = clientRatingsDict[s.ClientId].Name, Performance = Math.Round(clientRatingsDict[s.ClientId].Performance, 2), + RatingChange = clientRatingsDict[s.ClientId].Ratings.First().Ranking - clientRatingsDict[s.ClientId].Ratings.Last().Ranking, PerformanceHistory = clientRatingsDict[s.ClientId].Ratings.Count() > 1 ? clientRatingsDict[s.ClientId].Ratings.Select(r => r.Performance).ToList() : new List() { clientRatingsDict[s.ClientId].Performance, clientRatingsDict[s.ClientId].Performance }, @@ -559,7 +560,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers // update their performance #if !DEBUG - if ((DateTime.UtcNow - attackerStats.LastStatHistoryUpdate).TotalMinutes >= 10) + if ((DateTime.UtcNow - attackerStats.LastStatHistoryUpdate).TotalMinutes >= 2.5) #endif { await UpdateStatHistory(attacker, attackerStats); @@ -620,16 +621,20 @@ namespace IW4MAdmin.Plugins.Stats.Helpers ctx.Update(clientHistory); } + var thirtyDaysAgo = DateTime.UtcNow.AddMonths(-1); // get the client ranking for the current server int individualClientRanking = await ctx.Set() .Where(c => c.ServerId == clientStats.ServerId) + .Where(r => r.RatingHistory.Client.Level != Player.Permission.Banned) + .Where(r => r.ActivityAmount > 3600) + .Where(r => r.RatingHistory.Client.LastConnection > thirtyDaysAgo) .Where(c => c.RatingHistory.ClientId != client.ClientId) .Where(r => r.Newest) .Where(c => c.Performance > clientStats.Performance) .CountAsync() + 1; - // limit max history per server to 30 - if (clientHistory.Ratings.Count(r => r.ServerId == clientStats.ServerId) >= 30) + // limit max history per server to 40 + if (clientHistory.Ratings.Count(r => r.ServerId == clientStats.ServerId) >= 40) { var ratingToRemove = clientHistory.Ratings.First(r => r.ServerId == clientStats.ServerId); ctx.Entry(ratingToRemove).State = EntityState.Deleted; @@ -653,6 +658,7 @@ namespace IW4MAdmin.Plugins.Stats.Helpers Newest = true, ServerId = clientStats.ServerId, RatingHistoryId = clientHistory.RatingHistoryId, + ActivityAmount = currentServerTotalPlaytime }); // get other server stats @@ -667,18 +673,18 @@ namespace IW4MAdmin.Plugins.Stats.Helpers // weight the overall performance based on play time var performanceAverage = clientStatsList.Sum(p => (p.Performance * p.TimePlayed)) / clientStatsList.Sum(p => p.TimePlayed); - var thirtyDaysAgo = DateTime.UtcNow.AddMonths(-1); int overallClientRanking = await ctx.Set() .Where(r => r.RatingHistory.Client.Level != Player.Permission.Banned) - .Where(r => r.RatingHistory.Client.TotalConnectionTime > 3600) + .Where(r => r.ActivityAmount > 3600) .Where(r => r.RatingHistory.Client.LastConnection > thirtyDaysAgo) .Where(r => r.RatingHistory.ClientId != client.ClientId) .Where(r => r.ServerId == null) .Where(r => r.Newest) + .Where(r => r.Performance > performanceAverage) .CountAsync() + 1; - // limit max average history to 30 - if (clientHistory.Ratings.Count(r => r.ServerId == null) >= 30) + // limit max average history to 40 + if (clientHistory.Ratings.Count(r => r.ServerId == null) >= 40) { var ratingToRemove = clientHistory.Ratings.First(r => r.ServerId == null); ctx.Entry(ratingToRemove).State = EntityState.Deleted; @@ -701,7 +707,8 @@ namespace IW4MAdmin.Plugins.Stats.Helpers Performance = performanceAverage, Ranking = overallClientRanking, ServerId = null, - RatingHistoryId = clientHistory.RatingHistoryId + RatingHistoryId = clientHistory.RatingHistoryId, + ActivityAmount = clientStatsList.Sum(s => s.TimePlayed) }); await ctx.SaveChangesAsync(); diff --git a/Plugins/Stats/Models/EFRating.cs b/Plugins/Stats/Models/EFRating.cs index 96efb9dc1..cc0fd9dae 100644 --- a/Plugins/Stats/Models/EFRating.cs +++ b/Plugins/Stats/Models/EFRating.cs @@ -25,5 +25,7 @@ namespace IW4MAdmin.Plugins.Stats.Models [Required] // indicates if the rating is the latest public bool Newest { get; set; } + [Required] + public int ActivityAmount { get; set; } } } diff --git a/Plugins/Stats/Web/Controllers/StatsController.cs b/Plugins/Stats/Web/Controllers/StatsController.cs index 3d9256a3a..a1d7d8022 100644 --- a/Plugins/Stats/Web/Controllers/StatsController.cs +++ b/Plugins/Stats/Web/Controllers/StatsController.cs @@ -16,7 +16,7 @@ namespace IW4MAdmin.Plugins.Stats.Web.Controllers ViewBag.Title = Utilities.CurrentLocalization.LocalizationIndex.Set["WEBFRONT_STATS_INDEX_TITLE"]; ViewBag.Description = Utilities.CurrentLocalization.LocalizationIndex.Set["WEBFRONT_STATS_INDEX_DESC"]; - return View("Index", await Plugin.Manager.GetTopStats(0, 25)); + return View("Index", await Plugin.Manager.GetTopStats(0, 10)); } [HttpGet] diff --git a/Plugins/Stats/Web/Dtos/TopStatsInfo.cs b/Plugins/Stats/Web/Dtos/TopStatsInfo.cs index 0ae0ef90d..22fa8a8f0 100644 --- a/Plugins/Stats/Web/Dtos/TopStatsInfo.cs +++ b/Plugins/Stats/Web/Dtos/TopStatsInfo.cs @@ -16,6 +16,7 @@ namespace IW4MAdmin.Plugins.Stats.Web.Dtos public string LastSeen { get; set; } public int Kills { get; set; } public int Deaths { get; set; } + public int RatingChange { get; set; } public List PerformanceHistory { get; set; } } } diff --git a/Plugins/Stats/Web/Views/Stats/_List.cshtml b/Plugins/Stats/Web/Views/Stats/_List.cshtml index c4f83ceed..d5d8f329f 100644 --- a/Plugins/Stats/Web/Views/Stats/_List.cshtml +++ b/Plugins/Stats/Web/Views/Stats/_List.cshtml @@ -29,7 +29,26 @@ {
-

#@stat.Ranking — @Html.ActionLink(stat.Name, "ProfileAsync", "Client", new { id = stat.ClientId })

+
+
#@stat.Ranking
+ @if (stat.RatingChange > 0) + { +
+
+
@stat.RatingChange
+
+ } + @if (stat.RatingChange < 0) + { +
+
@Math.Abs(stat.RatingChange)
+
+
+ } + + @Html.ActionLink(stat.Name, "ProfileAsync", "Client", new { id = stat.ClientId }) +
+ @stat.Performance @loc["PLUGINS_STATS_COMMANDS_PERFORMANCE"]
@stat.KDR @loc["PLUGINS_STATS_TEXT_KDR"] @stat.Kills @loc["PLUGINS_STATS_TEXT_KILLS"] @@ -46,4 +65,4 @@
-} \ No newline at end of file +} diff --git a/SharedLibraryCore/Migrations/20180601172317_AddActivityAmount.Designer.cs b/SharedLibraryCore/Migrations/20180601172317_AddActivityAmount.Designer.cs new file mode 100644 index 000000000..82341aef5 --- /dev/null +++ b/SharedLibraryCore/Migrations/20180601172317_AddActivityAmount.Designer.cs @@ -0,0 +1,504 @@ +// +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.EntityFrameworkCore.Storage.Internal; +using SharedLibraryCore.Database; +using SharedLibraryCore.Objects; +using System; + +namespace SharedLibraryCore.Migrations +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20180601172317_AddActivityAmount")] + partial class AddActivityAmount + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "2.0.2-rtm-10011"); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b => + { + b.Property("KillId") + .ValueGeneratedOnAdd(); + + b.Property("Active"); + + b.Property("AttackerId"); + + b.Property("Damage"); + + b.Property("DeathOriginVector3Id"); + + b.Property("DeathType"); + + b.Property("HitLoc"); + + b.Property("KillOriginVector3Id"); + + b.Property("Map"); + + b.Property("ServerId"); + + b.Property("VictimId"); + + b.Property("ViewAnglesVector3Id"); + + b.Property("Weapon"); + + b.Property("When"); + + b.HasKey("KillId"); + + b.HasIndex("AttackerId"); + + b.HasIndex("DeathOriginVector3Id"); + + b.HasIndex("KillOriginVector3Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("VictimId"); + + b.HasIndex("ViewAnglesVector3Id"); + + b.ToTable("EFClientKills"); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b => + { + b.Property("MessageId") + .ValueGeneratedOnAdd(); + + b.Property("Active"); + + b.Property("ClientId"); + + b.Property("Message"); + + b.Property("ServerId"); + + b.Property("TimeSent"); + + b.HasKey("MessageId"); + + b.HasIndex("ClientId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFClientMessages"); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b => + { + b.Property("RatingHistoryId") + .ValueGeneratedOnAdd(); + + b.Property("Active"); + + b.Property("ClientId"); + + b.HasKey("RatingHistoryId"); + + b.HasIndex("ClientId"); + + b.ToTable("EFClientRatingHistory"); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b => + { + b.Property("ClientId"); + + b.Property("ServerId"); + + b.Property("Active"); + + b.Property("Deaths"); + + b.Property("EloRating"); + + b.Property("Kills"); + + b.Property("MaxStrain"); + + b.Property("RollingWeightedKDR"); + + b.Property("SPM"); + + b.Property("Skill"); + + b.Property("TimePlayed"); + + b.HasKey("ClientId", "ServerId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFClientStatistics"); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b => + { + b.Property("HitLocationCountId") + .ValueGeneratedOnAdd(); + + b.Property("Active"); + + b.Property("ClientId") + .HasColumnName("EFClientStatistics_ClientId"); + + b.Property("HitCount"); + + b.Property("HitOffsetAverage"); + + b.Property("Location"); + + b.Property("MaxAngleDistance"); + + b.Property("ServerId") + .HasColumnName("EFClientStatistics_ServerId"); + + b.HasKey("HitLocationCountId"); + + b.HasIndex("ServerId"); + + b.HasIndex("ClientId", "ServerId"); + + b.ToTable("EFHitLocationCounts"); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b => + { + b.Property("RatingId") + .ValueGeneratedOnAdd(); + + b.Property("Active"); + + b.Property("ActivityAmount"); + + b.Property("Newest"); + + b.Property("Performance"); + + b.Property("Ranking"); + + b.Property("RatingHistoryId"); + + b.Property("ServerId"); + + b.HasKey("RatingId"); + + b.HasIndex("RatingHistoryId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFRating"); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServer", b => + { + b.Property("ServerId"); + + b.Property("Active"); + + b.Property("Port"); + + b.HasKey("ServerId"); + + b.ToTable("EFServers"); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b => + { + b.Property("StatisticId") + .ValueGeneratedOnAdd(); + + b.Property("Active"); + + b.Property("ServerId"); + + b.Property("TotalKills"); + + b.Property("TotalPlayTime"); + + b.HasKey("StatisticId"); + + b.HasIndex("ServerId"); + + b.ToTable("EFServerStatistics"); + }); + + modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b => + { + b.Property("AliasId") + .ValueGeneratedOnAdd(); + + b.Property("Active"); + + b.Property("DateAdded"); + + b.Property("IPAddress"); + + b.Property("LinkId"); + + b.Property("Name") + .IsRequired(); + + b.HasKey("AliasId"); + + b.HasIndex("LinkId"); + + b.ToTable("EFAlias"); + }); + + modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAliasLink", b => + { + b.Property("AliasLinkId") + .ValueGeneratedOnAdd(); + + b.Property("Active"); + + b.HasKey("AliasLinkId"); + + b.ToTable("EFAliasLinks"); + }); + + modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b => + { + b.Property("ClientId") + .ValueGeneratedOnAdd(); + + b.Property("Active"); + + b.Property("AliasLinkId"); + + b.Property("Connections"); + + b.Property("CurrentAliasId"); + + b.Property("FirstConnection"); + + b.Property("LastConnection"); + + b.Property("Level"); + + b.Property("Masked"); + + b.Property("NetworkId"); + + b.Property("Password"); + + b.Property("PasswordSalt"); + + b.Property("TotalConnectionTime"); + + b.HasKey("ClientId"); + + b.HasIndex("AliasLinkId"); + + b.HasIndex("CurrentAliasId"); + + b.HasIndex("NetworkId") + .IsUnique(); + + b.ToTable("EFClients"); + }); + + modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b => + { + b.Property("PenaltyId") + .ValueGeneratedOnAdd(); + + b.Property("Active"); + + b.Property("AutomatedOffense"); + + b.Property("Expires"); + + b.Property("LinkId"); + + b.Property("OffenderId"); + + b.Property("Offense") + .IsRequired(); + + b.Property("PunisherId"); + + b.Property("Type"); + + b.Property("When"); + + b.HasKey("PenaltyId"); + + b.HasIndex("LinkId"); + + b.HasIndex("OffenderId"); + + b.HasIndex("PunisherId"); + + b.ToTable("EFPenalties"); + }); + + modelBuilder.Entity("SharedLibraryCore.Helpers.Vector3", b => + { + b.Property("Vector3Id") + .ValueGeneratedOnAdd(); + + b.Property("X"); + + b.Property("Y"); + + b.Property("Z"); + + b.HasKey("Vector3Id"); + + b.ToTable("Vector3"); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientKill", b => + { + b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Attacker") + .WithMany() + .HasForeignKey("AttackerId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("SharedLibraryCore.Helpers.Vector3", "DeathOrigin") + .WithMany() + .HasForeignKey("DeathOriginVector3Id"); + + b.HasOne("SharedLibraryCore.Helpers.Vector3", "KillOrigin") + .WithMany() + .HasForeignKey("KillOriginVector3Id"); + + b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Victim") + .WithMany() + .HasForeignKey("VictimId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("SharedLibraryCore.Helpers.Vector3", "ViewAngles") + .WithMany() + .HasForeignKey("ViewAnglesVector3Id"); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientMessage", b => + { + b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", b => + { + b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics", b => + { + b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFHitLocationCount", b => + { + b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Client") + .WithMany() + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientStatistics") + .WithMany("HitLocations") + .HasForeignKey("ClientId", "ServerId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFRating", b => + { + b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFClientRatingHistory", "RatingHistory") + .WithMany("Ratings") + .HasForeignKey("RatingHistoryId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("IW4MAdmin.Plugins.Stats.Models.EFServerStatistics", b => + { + b.HasOne("IW4MAdmin.Plugins.Stats.Models.EFServer", "Server") + .WithMany() + .HasForeignKey("ServerId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("SharedLibraryCore.Database.Models.EFAlias", b => + { + b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link") + .WithMany("Children") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Restrict); + }); + + modelBuilder.Entity("SharedLibraryCore.Database.Models.EFClient", b => + { + b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "AliasLink") + .WithMany() + .HasForeignKey("AliasLinkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("SharedLibraryCore.Database.Models.EFAlias", "CurrentAlias") + .WithMany() + .HasForeignKey("CurrentAliasId") + .OnDelete(DeleteBehavior.Cascade); + }); + + modelBuilder.Entity("SharedLibraryCore.Database.Models.EFPenalty", b => + { + b.HasOne("SharedLibraryCore.Database.Models.EFAliasLink", "Link") + .WithMany("ReceivedPenalties") + .HasForeignKey("LinkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Offender") + .WithMany("ReceivedPenalties") + .HasForeignKey("OffenderId") + .OnDelete(DeleteBehavior.Restrict); + + b.HasOne("SharedLibraryCore.Database.Models.EFClient", "Punisher") + .WithMany("AdministeredPenalties") + .HasForeignKey("PunisherId") + .OnDelete(DeleteBehavior.Restrict); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/SharedLibraryCore/Migrations/20180601172317_AddActivityAmount.cs b/SharedLibraryCore/Migrations/20180601172317_AddActivityAmount.cs new file mode 100644 index 000000000..fc82d29a6 --- /dev/null +++ b/SharedLibraryCore/Migrations/20180601172317_AddActivityAmount.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; +using System.Collections.Generic; + +namespace SharedLibraryCore.Migrations +{ + public partial class AddActivityAmount : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ActivityAmount", + table: "EFRating", + nullable: false, + defaultValue: 0); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ActivityAmount", + table: "EFRating"); + } + } +} diff --git a/SharedLibraryCore/Migrations/DatabaseContextModelSnapshot.cs b/SharedLibraryCore/Migrations/DatabaseContextModelSnapshot.cs index 54323dc99..065d690cb 100644 --- a/SharedLibraryCore/Migrations/DatabaseContextModelSnapshot.cs +++ b/SharedLibraryCore/Migrations/DatabaseContextModelSnapshot.cs @@ -176,6 +176,8 @@ namespace SharedLibraryCore.Migrations b.Property("Active"); + b.Property("ActivityAmount"); + b.Property("Newest"); b.Property("Performance"); diff --git a/WebfrontCore/WebfrontCore.csproj b/WebfrontCore/WebfrontCore.csproj index 1960e294e..6968c90a3 100644 --- a/WebfrontCore/WebfrontCore.csproj +++ b/WebfrontCore/WebfrontCore.csproj @@ -30,6 +30,7 @@ + diff --git a/WebfrontCore/wwwroot/css/bootstrap-custom.scss b/WebfrontCore/wwwroot/css/bootstrap-custom.scss index e2d297199..a05fbeb0c 100644 --- a/WebfrontCore/wwwroot/css/bootstrap-custom.scss +++ b/WebfrontCore/wwwroot/css/bootstrap-custom.scss @@ -192,5 +192,12 @@ select { } .client-rating-icon { +} -} \ No newline at end of file +.client-rating-change-up, .client-rating-change-down { + font-size: 0.75rem; +} + +.client-rating-change-amount { + font-size: 1rem; +} diff --git a/WebfrontCore/wwwroot/js/loader.js b/WebfrontCore/wwwroot/js/loader.js index b7f2df254..d54c15a76 100644 --- a/WebfrontCore/wwwroot/js/loader.js +++ b/WebfrontCore/wwwroot/js/loader.js @@ -1,12 +1,14 @@ -let loaderOffset = 25; -let loadCount = 25; +let loaderOffset = 10; +let loadCount = 10; let isLoaderLoading = false; let loadUri = ''; let loaderResponseId = ''; -function initLoader(location, loaderId) { +function initLoader(location, loaderId, count = 10) { loadUri = location; loaderResponseId = loaderId; + loadCount = count; + loaderOffset = count; setupListeners(); } diff --git a/WebfrontCore/wwwroot/js/stats.js b/WebfrontCore/wwwroot/js/stats.js index e5433e334..3d31e2147 100644 --- a/WebfrontCore/wwwroot/js/stats.js +++ b/WebfrontCore/wwwroot/js/stats.js @@ -2,9 +2,24 @@ const data = $('#' + id).data('history'); let fixedData = []; data.forEach(function (item, i) { - fixedData[i] = { x: i, y: item }; + fixedData[i] = { x: i, y: Math.floor(item) }; }); + let dataMin = Math.min(...data); + const dataMax = Math.max(...data); + + if (dataMax - dataMin === 0) { + dataMin = 0; + } + + const padding = (dataMax - dataMin) * 0.075; + const min = Math.max(0, dataMin - padding); + const max = dataMax + padding; + let interval = Math.floor((max - min) / 2); + + if (interval < 1) + interval = 1; + return new CanvasJS.Chart(id, { backgroundColor: 'transparent', height: height, @@ -12,37 +27,36 @@ animationEnabled: false, toolTip: { contentFormatter: function (e) { - return e.entries[0].dataPoint.y; + return Math.round(e.entries[0].dataPoint.y, 1); } }, - axisX: { - interval: 1, - gridThickness: 0, - lineThickness: 0, - tickThickness: 0, - margin: 0, - valueFormatString: " " + title: { + text: "Performance History", + fontSize: 14 }, - axisY: { + axisX: { gridThickness: 0, lineThickness: 0, tickThickness: 0, - minimum: Math.min(...data) - Math.min(...data) * 0.075, - maximum: Math.max(...data) + Math.max(...data) * 0.075, margin: 0, valueFormatString: " ", - labelMaxWidth: 0 + }, + axisY: { + labelFontSize: 12, + interval: interval, + gridThickness: 0, + lineThickness: 0.5, + valueFormatString: "#,##0", + minimum: min, + maximum: max }, legend: { - maxWidth: 0, - maxHeight: 0, dockInsidePlotArea: true }, data: [{ - showInLegend: false, type: "splineArea", color: 'rgba(0, 122, 204, 0.25)', - markerSize: 0, + markerSize: 3.5, dataPoints: fixedData }] });