Sales Chart

This commit is contained in:
HojouFotytu 2024-01-21 15:59:24 +09:00
parent 44610b4d6e
commit e474033d9c
7 changed files with 101 additions and 82 deletions

View File

@ -32,7 +32,18 @@ namespace Monitor.Pages
HttpContext.Session.SetString("LoggedIn" + PTMagicConfiguration.GeneralSettings.Monitor.Port.ToString(), DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'")); HttpContext.Session.SetString("LoggedIn" + PTMagicConfiguration.GeneralSettings.Monitor.Port.ToString(), DateTime.UtcNow.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fff'Z'"));
PTMagicConfiguration.GeneralSettings.Monitor.IsPasswordProtected = true; PTMagicConfiguration.GeneralSettings.Monitor.IsPasswordProtected = true;
//PTMagicConfiguration.WriteGeneralSettings(); //PTMagicConfiguration.WriteGeneralSettings();
if (cbRememberMe != null)
{
if (cbRememberMe.Equals("on", StringComparison.InvariantCultureIgnoreCase))
{
CookieOptions cookieOption = new CookieOptions();
cookieOption.Expires = DateTime.UtcNow.AddYears(1);
string cookieValue = EncryptionHelper.Encrypt(encryptedPassword);
Response.Cookies.Append("PTMRememberMeKey", cookieValue, cookieOption);
}
}
Response.Redirect(PTMagicConfiguration.GeneralSettings.Monitor.RootUrl); Response.Redirect(PTMagicConfiguration.GeneralSettings.Monitor.RootUrl);
} }

View File

@ -155,7 +155,7 @@ else
<div class="row"> <div class="row">
<div class="col-sm-12"> <div class="col-sm-12">
<div class="card-box"> <div class="card-box">
<h4 class="m-t-0 m-b-20 header-title"><b>Live Trends at @Model.PTMagicConfiguration.GeneralSettings.Application.Exchange</b></h4> <h4 class="m-t-0 m-b-20 header-title"><b>Market Trends at @Model.PTMagicConfiguration.GeneralSettings.Application.Exchange </b><i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="@Math.Round(Model.DataHours, 1) hours of data available. Currently set to show @Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours hours at @Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes intervals, in general settings."></i></h4>
<table class="table table-sm"> <table class="table table-sm">
<thead> <thead>
<tr> <tr>

View File

@ -4,6 +4,7 @@ using System.Linq;
using Core.Main; using Core.Main;
using Core.Helper; using Core.Helper;
using Core.Main.DataObjects.PTMagicData; using Core.Main.DataObjects.PTMagicData;
using System.Globalization;
namespace Monitor.Pages namespace Monitor.Pages
{ {
@ -11,6 +12,7 @@ namespace Monitor.Pages
{ {
public List<MarketTrend> MarketTrends { get; set; } = new List<MarketTrend>(); public List<MarketTrend> MarketTrends { get; set; } = new List<MarketTrend>();
public string TrendChartDataJSON = ""; public string TrendChartDataJSON = "";
public double DataHours { get; set; }
public void OnGet() public void OnGet()
{ {
@ -28,77 +30,85 @@ namespace Monitor.Pages
private void BuildMarketTrendChartData() private void BuildMarketTrendChartData()
{ {
if (MarketTrends.Count > 0) List<string> trendChartData = new List<string>();
{ if (MarketTrends.Count > 0)
TrendChartDataJSON = "[";
int mtIndex = 0;
foreach (MarketTrend mt in MarketTrends)
{ {
if (mt.DisplayGraph)
{ int mtIndex = 0;
string lineColor = ""; foreach (MarketTrend mt in MarketTrends)
if (mtIndex < Constants.ChartLineColors.Length)
{ {
lineColor = Constants.ChartLineColors[mtIndex]; if (mt.DisplayGraph)
}
else
{
lineColor = Constants.ChartLineColors[mtIndex - 20];
}
if (Summary.MarketTrendChanges.ContainsKey(mt.Name))
{
List<MarketTrendChange> marketTrendChangeSummaries = Summary.MarketTrendChanges[mt.Name];
if (marketTrendChangeSummaries.Count > 0)
{
if (!TrendChartDataJSON.Equals("[")) TrendChartDataJSON += ",";
TrendChartDataJSON += "{";
TrendChartDataJSON += "key: '" + SystemHelper.SplitCamelCase(mt.Name) + "',";
TrendChartDataJSON += "color: '" + lineColor + "',";
TrendChartDataJSON += "values: [";
// Get trend ticks for chart
DateTime currentDateTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, DateTime.UtcNow.Hour, 0, 0);
DateTime startDateTime = currentDateTime.AddHours(-PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours);
DateTime endDateTime = currentDateTime;
int trendChartTicks = 0;
for (DateTime tickTime = startDateTime; tickTime <= endDateTime; tickTime = tickTime.AddMinutes(PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes))
{ {
List<MarketTrendChange> tickRange = marketTrendChangeSummaries.FindAll(m => m.TrendDateTime >= tickTime).OrderBy(m => m.TrendDateTime).ToList(); string lineColor = mtIndex < Constants.ChartLineColors.Length
if (tickRange.Count > 0) ? Constants.ChartLineColors[mtIndex]
{ : Constants.ChartLineColors[mtIndex - 20];
MarketTrendChange mtc = tickRange.First();
if (tickTime != startDateTime) TrendChartDataJSON += ",\n";
if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0;
TrendChartDataJSON += "{ x: new Date('" + tickTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}"; if (Summary.MarketTrendChanges.ContainsKey(mt.Name))
trendChartTicks++; {
} List<MarketTrendChange> marketTrendChangeSummaries = Summary.MarketTrendChanges[mt.Name];
if (marketTrendChangeSummaries.Count > 0)
{
List<string> trendValues = new List<string>();
// Sort marketTrendChangeSummaries by TrendDateTime
marketTrendChangeSummaries = marketTrendChangeSummaries.OrderBy(m => m.TrendDateTime).ToList();
// Get trend ticks for chart
TimeSpan offset;
bool isNegative = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.StartsWith("-");
string offsetWithoutSign = PTMagicConfiguration.GeneralSettings.Application.TimezoneOffset.TrimStart('+', '-');
if (!TimeSpan.TryParse(offsetWithoutSign, out offset))
{
offset = TimeSpan.Zero; // If offset is invalid, set it to zero
}
DateTime currentDateTime = DateTime.UtcNow;
DateTime startDateTime = currentDateTime.AddHours(-PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours);
DateTime endDateTime = currentDateTime;
// Ensure startDateTime doesn't exceed the available data
DateTime earliestTrendDateTime = marketTrendChangeSummaries.Min(mtc => mtc.TrendDateTime);
startDateTime = startDateTime > earliestTrendDateTime ? startDateTime : earliestTrendDateTime;
DataHours = (currentDateTime - earliestTrendDateTime).TotalHours;
// Cache the result of SplitCamelCase(mt.Name)
string splitCamelCaseName = SystemHelper.SplitCamelCase(mt.Name);
for (DateTime tickTime = startDateTime; tickTime <= endDateTime; tickTime = tickTime.AddMinutes(PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes))
{
// Use binary search to find the range of items that match the condition
int index = marketTrendChangeSummaries.BinarySearch(new MarketTrendChange { TrendDateTime = tickTime }, Comparer<MarketTrendChange>.Create((x, y) => x.TrendDateTime.CompareTo(y.TrendDateTime)));
if (index < 0) index = ~index;
if (index < marketTrendChangeSummaries.Count)
{
MarketTrendChange mtc = marketTrendChangeSummaries[index];
if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0;
// Adjust tickTime to the desired timezone before converting to string
DateTime adjustedTickTime = tickTime.Add(isNegative ? -offset : offset);
trendValues.Add("{ x: new Date('" + adjustedTickTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", CultureInfo.InvariantCulture) + "}");
}
}
// Add most recent tick
MarketTrendChange latestMtc = marketTrendChangeSummaries.Last();
if (Double.IsInfinity(latestMtc.TrendChange)) latestMtc.TrendChange = 0;
// Adjust latestMtc.TrendDateTime to the desired timezone before converting to string
DateTime adjustedLatestTrendDateTime = latestMtc.TrendDateTime.Add(isNegative ? -offset : offset);
trendValues.Add("{ x: new Date('" + adjustedLatestTrendDateTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + latestMtc.TrendChange.ToString("0.00", CultureInfo.InvariantCulture) + "}");
// Use cached splitCamelCaseName
trendChartData.Add("{ key: '" + splitCamelCaseName + "', color: '" + lineColor + "', values: [" + string.Join(",\n", trendValues) + "] }");
mtIndex++;
}
}
} }
// Add most recent tick
List<MarketTrendChange> latestTickRange = marketTrendChangeSummaries.OrderByDescending(m => m.TrendDateTime).ToList();
if (latestTickRange.Count > 0)
{
MarketTrendChange mtc = latestTickRange.First();
if (trendChartTicks > 0) TrendChartDataJSON += ",\n";
if (Double.IsInfinity(mtc.TrendChange)) mtc.TrendChange = 0;
TrendChartDataJSON += "{ x: new Date('" + mtc.TrendDateTime.ToString("yyyy-MM-ddTHH:mm:ss").Replace(".", ":") + "'), y: " + mtc.TrendChange.ToString("0.00", new System.Globalization.CultureInfo("en-US")) + "}";
}
TrendChartDataJSON += "]";
TrendChartDataJSON += "}";
mtIndex++;
}
} }
}
} }
TrendChartDataJSON += "]"; TrendChartDataJSON = "[" + string.Join(",", trendChartData) + "]";
}
} }
} }
} }

View File

@ -379,9 +379,11 @@
@if (!Model.SalesChartDataJSON.Equals("")) { @if (!Model.SalesChartDataJSON.Equals("")) {
<text> <text>
nv.addGraph(function () { nv.addGraph(function () {
salesChart = nv.models.lineChart(); salesChart = nv.models.multiBarChart();
var height = 300; var height = 300;
salesChart.useInteractiveGuideline(true); salesChart.groupSpacing(0.5);
salesChart.showControls(false);
//salesChart.useInteractiveGuideline(true);
salesChart.xAxis.tickFormat(function (d) { return d3.time.format('%m/%d')(new Date(d)); }); salesChart.xAxis.tickFormat(function (d) { return d3.time.format('%m/%d')(new Date(d)); });
salesChart.yAxis.axisLabel('').tickFormat(d3.format(',.2f')); salesChart.yAxis.axisLabel('').tickFormat(d3.format(',.2f'));

View File

@ -10,7 +10,7 @@ using Core.Main.DataObjects.PTMagicData;
namespace Monitor.Pages namespace Monitor.Pages
{ {
public class SalesAnalyzer : _Internal.BasePageModelSecure public class SalesAnalyzer : _Internal.BasePageModelSecure
{ {
public ProfitTrailerData PTData = null; public ProfitTrailerData PTData = null;
public MiscData MiscData { get; set; } public MiscData MiscData { get; set; }
public PropertiesData PropertiesData { get; set; } public PropertiesData PropertiesData { get; set; }
@ -328,25 +328,22 @@ namespace Monitor.Pages
{ {
if (salesCountByDate.TryGetValue(date, out DailyStatsData dailyStatsData)) if (salesCountByDate.TryGetValue(date, out DailyStatsData dailyStatsData))
{ {
// Use the totalSales value directly buysPerDayList.Add(new { x = new DateTimeOffset(date).ToUnixTimeMilliseconds(), y = Convert.ToInt32(dailyStatsData.TotalBuys) });
salesPerDayList.Add(new { x = new DateTimeOffset(date).ToUnixTimeMilliseconds(), y = dailyStatsData.TotalSales }); salesPerDayList.Add(new { x = new DateTimeOffset(date).ToUnixTimeMilliseconds(), y = Convert.ToInt32(dailyStatsData.TotalSales) });
// Add daily buys to the list
buysPerDayList.Add(new { x = new DateTimeOffset(date).ToUnixTimeMilliseconds(), y = dailyStatsData.TotalBuys });
} }
} }
// Convert the lists to a JSON string using Newtonsoft.Json // Convert the lists to a JSON string using Newtonsoft.Json
SalesChartDataJSON = Newtonsoft.Json.JsonConvert.SerializeObject(new[] { SalesChartDataJSON = Newtonsoft.Json.JsonConvert.SerializeObject(new[] {
new { // New JSON object for daily buys
key = "Buys",
color = Constants.ChartLineColors[19], // Use a different color for buys
values = buysPerDayList
},
new { new {
key = "Sales", key = "Sales",
color = Constants.ChartLineColors[1], color = Constants.ChartLineColors[1],
values = salesPerDayList values = salesPerDayList
},
new { // New JSON object for daily buys
key = "Buys",
color = Constants.ChartLineColors[0], // Use a different color for buys
values = buysPerDayList
} }
}); });
} }

View File

@ -12,7 +12,7 @@
<div class="row"> <div class="row">
<div class="col-md-5 px-1"> <div class="col-md-5 px-1">
<div class="card-box px-2" style="height:340px;"> <div class="card-box px-2" style="height:340px;">
<h4 class="m-t-0 m-b-20 header-title" style="display: inline;"><b>Market Trend History </b><i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="@Math.Round(Model.DataHours, 1) hours of data available. Currently set to show @Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours hours in general settings."></i></h4> <h4 class="m-t-0 m-b-20 header-title" style="display: inline;"><b>Market Trend History </b><i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="@Math.Round(Model.DataHours, 1) hours of data available. Currently set to show @Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphMaxTimeframeHours hours at @Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes intervals, in general settings."></i></h4>
@if (!Model.TrendChartDataJSON.Equals("")) { @if (!Model.TrendChartDataJSON.Equals("")) {
<div class="trend-chart"> <div class="trend-chart">
<svg style="height: 300px;width: 100%;"></svg> <svg style="height: 300px;width: 100%;"></svg>

View File

@ -8,7 +8,6 @@ using Core.Main.DataObjects;
using Core.Main.DataObjects.PTMagicData; using Core.Main.DataObjects.PTMagicData;
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
using System.Diagnostics;
namespace Monitor.Pages namespace Monitor.Pages
{ {