544 lines
25 KiB
Plaintext
544 lines
25 KiB
Plaintext
@page
|
|
@model DashboardBottomModel
|
|
@{
|
|
Layout = null;
|
|
}
|
|
|
|
@section Styles {
|
|
<link href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/nvd3/nv.d3.min.css" rel="stylesheet" type="text/css" />
|
|
<link href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/tablesaw/css/tablesaw.css" rel="stylesheet" type="text/css" />
|
|
}
|
|
|
|
<div class="row">
|
|
|
|
<div class="col-md-3 px-1">
|
|
<div class="card-box px-1" style="height:240px;">
|
|
<div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds * 1000)" data-color="#aaa,#414d59"
|
|
title="All charts set to refresh every @Model.PTMagicConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds seconds in your general settings."></div>
|
|
@{
|
|
string totalCurrentValueString = Model.totalCurrentValue.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"));
|
|
if (Model.totalCurrentValue > 100) {
|
|
totalCurrentValueString = Math.Round(Model.totalCurrentValue, 2).ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"));
|
|
}
|
|
}
|
|
<div class="asset-distribution container" style="height: 100%; width: 100%;">
|
|
<div class="text-center">
|
|
<span data-toggle="tooltip" data-placement="top" title="Total current account value">TCV: <text class="text-autocolor">@totalCurrentValueString @Model.Summary.MainMarket </text> </span>
|
|
</div>
|
|
<div class="text-center">
|
|
<small>
|
|
<span data-toggle="tooltip" data-placement="top" title="Starting balance from PTM settings">Start: <text class="text-autocolor">@Model.MiscData.StartBalance </text></span>
|
|
<span data-toggle="tooltip" data-placement="top" title="TCV gain on starting balance">  Gain: <text class="text-autocolor">@Math.Round(((Model.totalCurrentValue - Model.MiscData.StartBalance) / Model.MiscData.StartBalance) * 100, 2)%</text></span>
|
|
</small>
|
|
</div>
|
|
<svg style="height:100%;width:100%"></svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-9">
|
|
<div class="card-box px-2" style="height:240px;">
|
|
<h4 class="m-t-0 header-title"><b>Live TCV Trend </b><i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="Data is added while the monitor is running. Currently set to show the past @Model.PTMagicConfiguration.GeneralSettings.Monitor.LiveTCVTimeframeMinutes minutes in your monitor settings."></i>
|
|
@if (!Model.TotalCurrentValueLiveChartDataJSON.Equals("")) {
|
|
<div class="TCVLive-chart">
|
|
<svg style="height:220px;width:100%"></svg>
|
|
</div>
|
|
} else {
|
|
<p>Unable to load graph, no sales data found.</p>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6 px-1">
|
|
<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 at @Model.PTMagicConfiguration.GeneralSettings.Monitor.GraphIntervalMinutes intervals, in general settings."></i></h4>
|
|
@if (!Model.TrendChartDataJSON.Equals("")) {
|
|
<div class="trend-chart">
|
|
<svg style="height: 300px;width: 100%;"></svg>
|
|
</div>
|
|
} else {
|
|
<p>Unable to load graph, no market trend data found.</p>
|
|
}
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div class="col-md-6 px-1">
|
|
@*<div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeconds * 1000)" data-color="#aaa,#414d59"></div>*@
|
|
<div class="card-box px-2" style="height:340px;">
|
|
<h4 class="m-t-0 m-b-20 header-title" style="display: inline;">Daily Profit <i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="@Model.PTData.DailyPNL.Count days of data available. Currently Set to @Model.PTMagicConfiguration.GeneralSettings.Monitor.ProfitsMaxTimeframeDays days in general settings."></i>
|
|
@if (!Model.ProfitChartDataJSON.Equals("")) {
|
|
<div class="profit-chart">
|
|
<svg style="height:300px;width:100%"></svg>
|
|
</div>
|
|
} else {
|
|
<p>Unable to load graph, no sales data found.</p>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-5 px-1">
|
|
<div class="card-box px-3">
|
|
@* <div class="cdev" data-percent="100" data-duration="@Html.Raw(@Model.PTMagicConfiguration.GeneralSettings.Monitor.RefreshSeco;nds * 1000)" data-color="#aaa,#414d59"></div>
|
|
<br> *@
|
|
<h4 class="m-t-0 m-b-20 header-title">Live Market Trends
|
|
<i class="fa fa-info-circle text-muted" style="font-size small" data-toggle="tooltip" data-placement="top" title="Set to refresh every @Model.PTMagicConfiguration.GeneralSettings.Monitor.DashboardChartsRefreshSeconds seconds in general settings."></i>
|
|
<small class="pull-right" style="font-size: small"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)MarketAnalyzer">ANALYZER</a></small>
|
|
</h4>
|
|
<table class="table table-sm">
|
|
<thead>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th class="text-right">Markets</th>
|
|
<th class="text-right">Timeframe</th>
|
|
<th class="text-right">Threshold <i class="fa fa-info-circle text-muted" data-toggle="tooltip" data-placement="top" title="Pairs exceeding this threshold are considered outliers that are excluded from the trend average."></i>
|
|
</th>
|
|
<th class="text-right">Change</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach (var marketTrend in Model.MarketTrends.OrderBy(mt => mt.TrendMinutes)) {
|
|
if (Model.Summary.MarketTrendChanges.ContainsKey(marketTrend.Name)) {
|
|
double trendChange = Model.Summary.MarketTrendChanges[marketTrend.Name].Last().TrendChange;
|
|
string trendChangeOutput = trendChange.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US"));
|
|
|
|
int marketCount = marketTrend.MaxMarkets;
|
|
string marketCountString = marketCount.ToString();
|
|
|
|
if (marketCount == 0) {
|
|
marketCountString = "All";
|
|
} else if (marketCount > Model.Summary.MarketSummary.Keys.Count && marketTrend.Platform.Equals("Exchange", StringComparison.InvariantCultureIgnoreCase)) {
|
|
marketCountString = Model.Summary.MarketSummary.Keys.Count.ToString();
|
|
}
|
|
|
|
// Cache the result of SplitCamelCase(marketTrend.Name)
|
|
string splitCamelCaseName = Core.Helper.SystemHelper.SplitCamelCase(marketTrend.Name);
|
|
|
|
<tr>
|
|
<td>@splitCamelCaseName</td> <!-- Use the cached value here -->
|
|
<td class="text-right">@marketCountString</td>
|
|
<td class="text-right">@Core.Helper.SystemHelper.GetProperDurationTime(marketTrend.TrendMinutes * 60, false)</td>
|
|
@if (marketTrend.TrendThreshold == 0)
|
|
{
|
|
<td class="text-right">--</td>
|
|
}
|
|
else
|
|
{
|
|
<td class="text-right">@marketTrend.TrendThreshold %</td>
|
|
}
|
|
<td class="text-right text-autocolor" style="font-weight:bold;">@trendChangeOutput %</td>
|
|
</tr>
|
|
}
|
|
}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-7 px-1">
|
|
<div class="card-box px-3">
|
|
<h4 class="m-t-0 m-b-20 header-title">Sales Overview
|
|
<i class="fa fa-info-circle text-muted" style="font-size x-small" data-toggle="tooltip" data-placement="top" title="All data acquired via Profit Trailer API."></i>
|
|
<small class="pull-right" style="font-size: small"><a href="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)SalesAnalyzer">ANALYZER</a></small>
|
|
</h4>
|
|
@{
|
|
|
|
double avgGrowthThisMonth = Model.PTData.MonthlyStats.FirstOrDefault(data => data.Order == 1)?.AvgGrowth ?? 0.0;
|
|
double avgGrowthLastMonth = Model.PTData.MonthlyStats.FirstOrDefault(data => data.Order == 2)?.AvgGrowth ?? 0.0;
|
|
|
|
//var startingBalance = Model.MiscData.StartBalance;
|
|
var totalCurrentValue = Model.totalCurrentValue;
|
|
var overviewStats = Model.StatsData;
|
|
|
|
var todaysSales = overviewStats.SalesToday;
|
|
var todaysProfit = overviewStats.ProfitToday;
|
|
var todaysFunding = overviewStats.FundingToday;
|
|
var todaysPercentGain = overviewStats.ProfitPercToday + Model.PTData.Stats.TotalFundingPercToday;
|
|
|
|
var yesterdaysSales = overviewStats.SalesYesterday;
|
|
var yesterdaysProfit = overviewStats.ProfitYesterday;
|
|
var yesterdaysFunding = overviewStats.FundingYesterday;
|
|
var yesterdaysPercentGain = overviewStats.ProfitPercYesterday + Model.PTData.Stats.TotalFundingPercYesterday;
|
|
|
|
var last7DaysSales = overviewStats.SalesWeek;
|
|
var last7DaysProfit = overviewStats.ProfitWeek;
|
|
var last7DaysFunding = overviewStats.FundingWeek;
|
|
var last7DaysPercentGain = overviewStats.ProfitPercWeek + Model.PTData.Stats.TotalFundingPercWeek;
|
|
|
|
var thisMonthSales = overviewStats.SalesThisMonth;
|
|
var thisMonthProfit = overviewStats.ProfitThisMonth;
|
|
var thisMonthFunding = overviewStats.FundingThisMonth;
|
|
var thisMonthPercentGain = avgGrowthThisMonth;
|
|
|
|
var lastMonthSales = overviewStats.SalesLastMonth;
|
|
var lastMonthProfit = overviewStats.ProfitLastMonth;
|
|
var lastMonthFunding = overviewStats.FundingLastMonth;
|
|
var lastMonthPercentGain = avgGrowthLastMonth;
|
|
|
|
var totalSales = overviewStats.TotalSales;
|
|
var totalProfit = overviewStats.TotalProfit;
|
|
var totalFunding = overviewStats.FundingTotal;
|
|
var totalPercentGain = overviewStats.TotalProfitPerc + Model.PTData.Stats.TotalFundingPerc;
|
|
|
|
double todaysProfitFiat = Math.Round((todaysProfit + todaysFunding) * Model.PTData.Misc.FiatConversionRate, 2);
|
|
double yesterdaysProfitFiat = Math.Round((yesterdaysProfit + yesterdaysFunding) * Model.PTData.Misc.FiatConversionRate, 2);
|
|
double last7DaysProfitFiat = Math.Round((last7DaysProfit + last7DaysFunding) * Model.PTData.Misc.FiatConversionRate, 2);
|
|
double thisMonthProfitFiat = Math.Round((thisMonthProfit + thisMonthFunding) * Model.PTData.Misc.FiatConversionRate, 2);
|
|
double lastMonthProfitFiat = Math.Round((lastMonthProfit + lastMonthFunding) * Model.PTData.Misc.FiatConversionRate, 2);
|
|
double totalProfitFiat = Math.Round((totalProfit + totalFunding) * Model.PTData.Misc.FiatConversionRate, 2);
|
|
|
|
bool futuresFunding = Model.PropertiesData.IsLeverageExchange;
|
|
|
|
}
|
|
<table class="table table-sm">
|
|
<thead>
|
|
<tr>
|
|
<th></th>
|
|
<th class="text-right">Sales</th>
|
|
<th class="text-right">Profit @Model.PTData.Misc.Market</th>
|
|
@if (futuresFunding)
|
|
{
|
|
<th class="text-right">Funding</th>
|
|
}
|
|
<th class="text-right">@Model.PTData.Properties.Currency</th>
|
|
<th class="text-right">Gain</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<th>Today</th>
|
|
<td class="text-right">@overviewStats.SalesToday</td>
|
|
<td class="text-right text-autocolor">@todaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
@if (futuresFunding)
|
|
{
|
|
<td class="text-right text-autocolor">@todaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
}
|
|
<td class="text-right text-autocolor">@Html.Raw(todaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
|
|
<td class="text-right text-autocolor">@todaysPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) %</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Yesterday</th>
|
|
<td class="text-right">@yesterdaysSales</td>
|
|
<td class="text-right text-autocolor">@yesterdaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
@if (futuresFunding)
|
|
{
|
|
<td class="text-right text-autocolor">@yesterdaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
}
|
|
<td class="text-right text-autocolor">@Html.Raw(yesterdaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
|
|
<td class="text-right text-autocolor">@yesterdaysPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) %</td>
|
|
</tr>
|
|
<tr>
|
|
<th>7 Days</th>
|
|
<td class="text-right">@last7DaysSales</td>
|
|
<td class="text-right text-autocolor">@last7DaysProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
@if (futuresFunding)
|
|
{
|
|
<td class="text-right text-autocolor">@last7DaysFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
}
|
|
<td class="text-right text-autocolor">@Html.Raw(last7DaysProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
|
|
<td class="text-right text-autocolor">@last7DaysPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) %</td>
|
|
</tr>
|
|
<tr>
|
|
@{
|
|
var timeParts = @Model.MiscData.TimeZoneOffset.Split(':');
|
|
var timeZoneOffsetHours = int.Parse(timeParts[0]);
|
|
var timeZoneOffset = TimeSpan.FromHours(timeZoneOffsetHours);
|
|
var timeZoneInfo = TimeZoneInfo.CreateCustomTimeZone("Custom", timeZoneOffset, "Custom", "Custom");
|
|
var currentDateTime = TimeZoneInfo.ConvertTime(DateTime.UtcNow, timeZoneInfo);
|
|
var currentMonthName = currentDateTime.ToString("MMMM");
|
|
}
|
|
<th>@currentMonthName</th>
|
|
<td class="text-right">@thisMonthSales</td>
|
|
<td class="text-right text-autocolor">@thisMonthProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
@if (futuresFunding)
|
|
{
|
|
<td class="text-right text-autocolor">@thisMonthFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
}
|
|
<td class="text-right text-autocolor">@Html.Raw(thisMonthProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
|
|
<td class="text-right text-autocolor">@thisMonthPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) %</td>
|
|
</tr>
|
|
<tr>
|
|
@{
|
|
var previousMonthDateTime = currentDateTime.AddMonths(-1);
|
|
var previousMonthName = previousMonthDateTime.ToString("MMMM");
|
|
}
|
|
<th>@previousMonthName</th>
|
|
<td class="text-right">@lastMonthSales</td>
|
|
<td class="text-right text-autocolor">@lastMonthProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
@if (futuresFunding)
|
|
{
|
|
<td class="text-right text-autocolor">@lastMonthFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
}
|
|
<td class="text-right text-autocolor">@Html.Raw(lastMonthProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
|
|
<td class="text-right text-autocolor">@lastMonthPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) %</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Total</th>
|
|
<td class="text-right">@totalSales</td>
|
|
<td class="text-right text-autocolor">@totalProfit.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
@if (futuresFunding)
|
|
{
|
|
<td class="text-right text-autocolor">@totalFunding.ToString("#,#0.00000000", new System.Globalization.CultureInfo("en-US"))</td>
|
|
}
|
|
<td class="text-right text-autocolor">@Html.Raw(totalProfitFiat.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")))</td>
|
|
<td class="text-right text-autocolor">@totalPercentGain.ToString("#,#0.00", new System.Globalization.CultureInfo("en-US")) %</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script src="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/d3/d3.min.js"></script>
|
|
<script src="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/nvd3/nv.d3.min.js"></script>
|
|
<script src="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/tablesaw/js/tablesaw.js"></script>
|
|
<script src="@Html.Raw(Model.PTMagicConfiguration.GeneralSettings.Monitor.RootUrl)assets/plugins/tablesaw/js/tablesaw-init.js"></script>
|
|
|
|
<script type="text/javascript">
|
|
$(document).ready(function(){
|
|
$('[data-toggle="tooltip"]').tooltip();
|
|
});
|
|
</script>
|
|
|
|
|
|
|
|
<script type="text/javascript">
|
|
$(document).ready(function () {
|
|
$(".cdev").circlos();
|
|
$('[data-toggle="tooltip"]').tooltip();
|
|
$('.text-autocolor').autocolor(false);
|
|
|
|
var assetDistributionData; // Keep a reference to the data
|
|
|
|
@if (!Model.AssetDistributionData.Equals("")) {
|
|
<text>
|
|
nv.addGraph(function() {
|
|
assetDistributionChart = nv.models.pieChart()
|
|
.x(function(d) { return d.label })
|
|
.y(function(d) { return d.value })
|
|
.showLabels(true)
|
|
.labelThreshold(.1)
|
|
.labelType("percent")
|
|
.donut(true)
|
|
.donutRatio(0.3)
|
|
.margin({top: 10, bottom: 10})
|
|
.showLegend(false); // Hide the legend
|
|
|
|
assetDistributionData = @Html.Raw(Model.AssetDistributionData);
|
|
|
|
d3.select(".asset-distribution svg") // Change this line
|
|
.style('height', '90%')
|
|
.style('width', '100%')
|
|
.datum(assetDistributionData)
|
|
.transition().duration(0)
|
|
.call(assetDistributionChart);
|
|
|
|
nv.utils.windowResize(assetDistributionChart.update);
|
|
return assetDistributionChart;
|
|
});
|
|
</text>
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
(function ($) {
|
|
'use strict';
|
|
$('[role="tooltip"]').remove();
|
|
$('[data-toggle="tooltip"]').tooltip();
|
|
$('.text-autocolor').autocolor(false);
|
|
|
|
var trendChart; // Keep a reference to the chart
|
|
var trendData; // Keep a reference to the data
|
|
|
|
@if (!Model.TrendChartDataJSON.Equals("")) {
|
|
<text>
|
|
nv.addGraph(function () {
|
|
trendChart = nv.models.lineChart();
|
|
var height = 300;
|
|
trendChart.useInteractiveGuideline(true);
|
|
trendChart.xAxis.tickFormat(function (d) { return d3.time.format('%H:%M')(new Date(d)); });
|
|
trendChart.yAxis.axisLabel('Trend %').tickFormat(d3.format(',.2f'));
|
|
|
|
trendData = @Html.Raw(Model.TrendChartDataJSON);
|
|
|
|
var svg = d3.select('.trend-chart svg').node();
|
|
d3.select(svg)
|
|
.datum(trendData)
|
|
.transition().duration(0)
|
|
.call(trendChart);
|
|
|
|
trendChart.dispatch.on('renderEnd', function() {
|
|
// Get the chart's container
|
|
var container = d3.select('.trend-chart .nv-wrap.nv-lineChart .nv-linesWrap');
|
|
|
|
// Remove any existing y=0 line
|
|
container.selectAll('.zero-line').remove();
|
|
|
|
// Get the x-values of the first and last data points
|
|
var xRange = trendChart.xAxis.scale().range();
|
|
var xMin = xRange[0];
|
|
var xMax = xRange[1];
|
|
|
|
// Add a line at y=0
|
|
container.insert('line', ':first-child')
|
|
.attr('class', 'zero-line') // Add a class to the line for easy selection
|
|
.attr('x1', xMin) // x position of the first end of the line
|
|
.attr('y1', trendChart.yAxis.scale()(0)) // y position of the first end of the line
|
|
.attr('x2', xMax) // x position of the second end of the line
|
|
.attr('y2', trendChart.yAxis.scale()(0)) // y position of the second end of the line
|
|
.attr('stroke', 'gray') // color of the line
|
|
.attr('stroke-width', 2); // width of the line
|
|
});
|
|
nv.utils.windowResize(trendChart.update);
|
|
return trendChart;
|
|
});
|
|
</text>
|
|
}
|
|
})(jQuery);
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
(function ($) {
|
|
'use strict';
|
|
$('[role="tooltip"]').remove();
|
|
$('[data-toggle="tooltip"]').tooltip();
|
|
$('.text-autocolor').autocolor(false);
|
|
|
|
var profitChart; // Keep a reference to the chart
|
|
var profitData; // Keep a reference to the data
|
|
|
|
|
|
@if (!Model.ProfitChartDataJSON.Equals("")) {
|
|
<text>
|
|
nv.addGraph(function () {
|
|
profitChart = nv.models.lineChart();
|
|
var height = 300;
|
|
profitChart.useInteractiveGuideline(true);
|
|
profitChart.xAxis.tickFormat(function (d) { return d3.time.format('%m/%d')(new Date(d)); });
|
|
profitChart.yAxis.axisLabel('Daily Profit').tickFormat(d3.format(',.2f'));
|
|
|
|
profitData = @Html.Raw(Model.ProfitChartDataJSON);
|
|
|
|
d3.select('.profit-chart svg')
|
|
.datum(profitData)
|
|
.transition().duration(0)
|
|
.call(profitChart);
|
|
|
|
profitChart.dispatch.on('renderEnd', function() {
|
|
// Get the chart's container
|
|
var container = d3.select('.profit-chart .nv-wrap.nv-lineChart .nv-linesWrap');
|
|
|
|
// Remove any existing y=0 line
|
|
container.selectAll('.zero-line').remove();
|
|
|
|
// Check if profitData[0].values is not empty
|
|
if (profitData[0].values.length > 0) {
|
|
// Get the x-values of the first and last data points
|
|
var xMin = profitChart.xAxis.scale()(profitData[0].values[0].x);
|
|
var xMax = profitChart.xAxis.scale()(profitData[0].values[profitData[0].values.length - 1].x);
|
|
|
|
// Add a line at y=0
|
|
container.insert('line', ':first-child')
|
|
.attr('class', 'zero-line') // Add a class to the line for easy selection
|
|
.attr('x1', xMin) // x position of the first end of the line
|
|
.attr('y1', profitChart.yAxis.scale()(0)) // y position of the first end of the line
|
|
.attr('x2', xMax) // x position of the second end of the line
|
|
.attr('y2', profitChart.yAxis.scale()(0)) // y position of the second end of the line
|
|
.attr('stroke', 'gray') // color of the line
|
|
.attr('stroke-width', 2); // width of the line
|
|
|
|
window.profitChartUpdate = nv.utils.windowResize(function() { profitChart.update(); });
|
|
}
|
|
});
|
|
|
|
nv.utils.windowResize(profitChart.update);
|
|
return profitChart;
|
|
});
|
|
</text>
|
|
}
|
|
})(jQuery);
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
(function ($) {
|
|
'use strict';
|
|
$('[role="tooltip"]').remove();
|
|
$('[data-toggle="tooltip"]').tooltip();
|
|
$('.text-autocolor').autocolor(false);
|
|
|
|
var TCVLiveChart; // Keep a reference to the chart
|
|
var TCVLiveData; // Keep a reference to the data
|
|
|
|
@if (!Model.TotalCurrentValueLiveChartDataJSON.Equals("")) {
|
|
<text>
|
|
nv.addGraph(function () {
|
|
TCVLiveChart = nv.models.lineChart();
|
|
TCVLiveChart.useInteractiveGuideline(true);
|
|
TCVLiveChart.xAxis.tickFormat(function (d) { return d3.time.format('%H:%M:%S')(new Date(d)); });
|
|
TCVLiveChart.yAxis.axisLabel('').tickFormat(d3.format(',.2f'));
|
|
|
|
TCVLiveData = @Html.Raw(Model.TotalCurrentValueLiveChartDataJSON);
|
|
|
|
d3.select('.TCVLive-chart svg')
|
|
.style('width', '100%')
|
|
.datum(TCVLiveData)
|
|
.transition().duration(0)
|
|
.call(TCVLiveChart);
|
|
|
|
|
|
nv.utils.windowResize(TCVLiveChart.update);
|
|
return TCVLiveChart;
|
|
});
|
|
</text>
|
|
}
|
|
})(jQuery);
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
function attachTooltipRemoval(chartClass) {
|
|
d3.selectAll(chartClass).on('mouseleave', function() {
|
|
var tooltip = d3.select(this).select('.nvtooltip');
|
|
if (!tooltip.empty()) {
|
|
tooltip.style('opacity', 0);
|
|
}
|
|
});
|
|
|
|
d3.selectAll(chartClass).on('mouseenter', function() {
|
|
var tooltip = d3.select(this).select('.nvtooltip');
|
|
if (!tooltip.empty()) {
|
|
tooltip.style('opacity', 1);
|
|
}
|
|
});
|
|
}
|
|
$(document).ready(function () {
|
|
// Hide all tooltips when the page is loaded
|
|
d3.selectAll('.nvtooltip').style('opacity', 0);
|
|
|
|
// Call the function for each chart
|
|
attachTooltipRemoval('.asset-distribution svg');
|
|
attachTooltipRemoval('.trend-chart svg');
|
|
attachTooltipRemoval('.profit-chart svg');
|
|
attachTooltipRemoval('.TCVLive-chart svg');
|
|
// Add other charts as needed
|
|
});
|
|
</script>
|
|
|
|
<script type="text/javascript">
|
|
window.cleanupData = function() {
|
|
TCVLiveChart = null;
|
|
TCVLiveData = null;
|
|
assetDistributionChart = null;
|
|
assetDistributionData = null;
|
|
trendChart = null;
|
|
trendData = null;
|
|
profitChart = null;
|
|
profitData = null;
|
|
};
|
|
</script>
|