Sales Chart
This commit is contained in:
parent
44610b4d6e
commit
e474033d9c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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) + "]";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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'));
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue