EnVisageOnline/Main/Source/EnVisage/Views/Scenarios/_finInfoChart.cshtml

286 lines
9.0 KiB
Plaintext

<div id="finInfoGraphPlaceholder">
<div class="panel panel-white panel-compact otherside collapsible-vertical">
<div class='panel-heading'>
<span class='panel-title ui-expander'>
<a data-target="#graph-container">
<i class="panel-title-icon fa fa-bar-chart-o"></i><span>Financial Information</span>
</a>
</span>
</div>
<div class='panel-body table-light' id="graph-container">
<div class="row padding-sm">
<div class="graph-container form-group-margin" id="fin-info-graph-container" style="min-height: 260px; min-width: 400px;">
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
// 10 days
var BAR_WIDTH = 10 * 24 * 60 * 60 * 1000,
BAR_ALIGN = 'center';
var _internalData = null;
function initFinInfoGraph() {
$("#finInfoGraphPlaceholder .panel.collapsible-vertical a").on('click', function () {
toggleGraphPanel(this, false);
});
restoreUserFinInfoGraphPreferences();
}
function refreshFinInfoGraphData(data) {
_internalData = data;
buildFinInfoGraph();
}
function updateProjectedRevenueOnFinGraph(value) {
_internalData = _internalData || {};
_internalData.ProjectedRevenue = value || 0;
buildFinInfoGraph();
}
function updateProjectedExpenseOnFinGraph(value) {
_internalData = _internalData || {};
_internalData.TDDirectCosts = value || 0;
buildFinInfoGraph();
}
function updateRevenueAndExpenseOnFinGraph(revenue, expense) {
_internalData = _internalData || {};
_internalData.ProjectedRevenue = revenue || 0;
_internalData.TDDirectCosts = expense || 0;
buildFinInfoGraph();
}
function updateCostSavingsOnFinGraph(value) {
_internalData = _internalData || {};
_internalData.CostSavings = value || 0;
buildFinInfoGraph();
}
function buildFinInfoGraph() {
// we should recreate plot container each time when we refresh it, because pixel plot create wrapper around div
// and push into it some additional information; so if we use original container few times we will have few containers with plot information
$('#fin-info-graph-container').html('<div id="fin-info-graph"></div>');
$('#fin-info-graph').pixelPlot(getGraphSeries(), {
xaxis: {
mode: "time",
timeformat: "%b %Y",
tickSize: [1, "month"],
tickLength: 0,
rotateTicks: 90
},
yaxes: [
{
axisLabel: "SPEND OVER TIME",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 11,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 10
}, {
axisLabel: "EXPENDITURE COST",
axisLabelUseCanvas: true,
axisLabelFontSizePixels: 11,
axisLabelFontFamily: 'Verdana, Arial',
axisLabelPadding: 10,
position: "right"
}
],
grid: {
hoverable: true,
borderWidth: 3,
backgroundColor: { colors: ["#878787", "#444444"] }
}
}, {
height: 350,
tooltipText: 'getToolTip(x, y)'
});
}
function getToolTip(x, y) {
var date = (new Date(x)).toString().split(' ');
return '$' + y.toFixed(2) + ' at ' + date[1] + ' ' + date[3];
}
function prepareGraphData() {
var data = _internalData || {};
var graphData = {
ECExpense: [],
TotalExpense: [],
ProjectedRevenue: [],
TDDIrectCost: [],
CostSavings: []
};
var total = 0;
for (var key in data.ECExpense || {}) {
total += (data.ECExpense[key] || 0);
graphData.ECExpense.push([key, data.ECExpense[key]]);
graphData.TotalExpense.push([key, total]);
}
if (graphData.ECExpense.length > 0) {
var tenDays = (10 * 24 * 60 * 60 * 1000),
endDate = parseInt(graphData.ECExpense[graphData.ECExpense.length - 1][0]) + tenDays;
var expense = parseFloat(data.TDDirectCosts || 0);
if (expense > 0)
graphData.TDDIrectCost.push([endDate, expense]);
// if expense exists we should show revenue and/or cost savings right after it
if (graphData.TDDIrectCost.length > 0)
endDate += tenDays;
if (data.IsRevenueGenerating === true) {
var revenue = parseFloat(data.ProjectedRevenue || 0);
if (revenue > 0)
graphData.ProjectedRevenue.push([endDate, revenue]);
}
var costSavings = parseFloat(data.CostSavings || 0);
if (costSavings > 0)
graphData.CostSavings.push([endDate, costSavings]);
}
return graphData;
}
function getGraphSeries() {
var graphData = prepareGraphData();
if (!graphData)
return;
var colors = {
ECExpenseColor: '#9d9d9d',
TotalExpenseColor: '#3156be',
CostSavingsColor: '#e8e64e',
RevenueColor: '#71c73e',
ExpenseColor: '#d54848',
};
var headers = [{
label: "Expenditure Cost",
data: graphData.ECExpense,
type: "Cost",
stack: false,
color: colors.ECExpenseColor,
lines: {
show: true,
fill: true
},
yaxis: 2
}, {
label: "Total Cost",
data: graphData.TotalExpense,
type: "Cost",
stack: false,
color: colors.TotalExpenseColor,
bars: {
show: true,
align: BAR_ALIGN,
barWidth: BAR_WIDTH,
lineWidth: 1,
fill: true
}
}];
if (graphData.TDDIrectCost.length > 0) {
headers.push({
label: "Projected Expense",
data: graphData.TDDIrectCost,
type: "Cost",
stack: false,
color: colors.ExpenseColor,
bars: {
show: true,
align: BAR_ALIGN,
barWidth: BAR_WIDTH,
lineWidth: 1,
fill: true
}
});
}
if (graphData.CostSavings.length > 0) {
headers.push({
label: "Cost Savings",
data: graphData.CostSavings,
type: "Cost",
stack: true,
color: colors.CostSavingsColor,
bars: {
show: true,
align: BAR_ALIGN,
barWidth: BAR_WIDTH,
lineWidth: 1,
fill: true
}
});
}
if (graphData.ProjectedRevenue.length > 0) {
headers.push({
label: "Projected Revenue",
data: graphData.ProjectedRevenue,
type: "Cost",
stack: true,
color: colors.RevenueColor,
bars: {
show: true,
align: BAR_ALIGN,
barWidth: BAR_WIDTH,
lineWidth: 1,
fill: true
}
});
}
return headers;
}
function toggleGraphPanel(chevron) {
var isCollapsed = $(chevron).hasClass("collapsed");
$(chevron).toggleClass("collapsed");
if (!isCollapsed) {
var panelBody = $(chevron).closest(".panel-compact").find(".panel-body");
$(chevron).parents('.panel').find(".row.padding-sm").slideUp();
}
else {
$(chevron).parents('.panel').find(".row.padding-sm").slideDown();
}
var prefs = [{
Key: "graph-panel-collapsed",
Value: !isCollapsed
}];
saveUserPagePreferences(prefs, getDataSection($("#finInfoGraphPlaceholder")), '/Scenarios/Details');
if (isCollapsed)
buildFinInfoGraph();
}
function restoreUserFinInfoGraphPreferences() {
var prefs = loadUserPagePreferences(getDataSection($("#finInfoGraphPlaceholder")), '/Scenarios/Details');
if (!!prefs && prefs.length > 0) {
for (var i = 0; i < prefs.length; i++) {
switch (prefs[i].Key) {
case "graph-panel-collapsed":
if (prefs[i].Value == true) {
$("#finInfoGraphPlaceholder .panel.collapsible-vertical a").trigger('click');
}
break;
}
}
}
}
</script>