mirror of https://github.com/abpframework/abp.git
21 changed files with 34356 additions and 6 deletions
@ -0,0 +1,9 @@ |
|||
namespace DashboardDemo |
|||
{ |
|||
public class NewUserStatistiWidgetResultDto |
|||
{ |
|||
public string[] Labels { get; set; } |
|||
|
|||
public int[] Data { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
namespace DashboardDemo |
|||
{ |
|||
public enum NewUserStatisticFrequency |
|||
{ |
|||
Daily, |
|||
Monthly |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
using System; |
|||
|
|||
namespace DashboardDemo |
|||
{ |
|||
public class NewUserStatisticWidgetInputDto |
|||
{ |
|||
public DateTime StartDate { get; set; } |
|||
|
|||
public DateTime EndDate { get; set; } |
|||
|
|||
public NewUserStatisticFrequency Frequency { get; set; } = NewUserStatisticFrequency.Daily; |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace DashboardDemo.Web.Bundles |
|||
{ |
|||
public class ChartjsScriptContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.Add("/libs/chart.js/Chart.js"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
|
|||
namespace DashboardDemo.Web.Bundles |
|||
{ |
|||
public class ChartjsStyleContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.Add("/libs/chart.js/Chart.css"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
<div class="newUserStatistic-widget"> |
|||
<abp-card background="Light"> |
|||
<abp-card-header background="Secondary" class="text-white"> |
|||
User Statistics |
|||
</abp-card-header> |
|||
<abp-card-body> |
|||
<div> |
|||
<div class="form-group" id="FrequencyFilter"> |
|||
<select class="form-control"> |
|||
<option value="Daily">Daily</option> |
|||
<option value="Monthly">Monthly</option> |
|||
</select> |
|||
</div> |
|||
</div |
|||
<div class="row mt-5"> |
|||
<canvas id="NewUserStatisticChart" class="NewUserStatisticChart"></canvas> |
|||
</div> |
|||
</abp-card-body> |
|||
</abp-card> |
|||
</div> |
|||
@ -0,0 +1,93 @@ |
|||
(function () { |
|||
var chart; |
|||
var serviceMethod = dashboardDemo.dashboard.getNewUserStatisticWidget; |
|||
var latestEndDate; |
|||
var latestStartDate; |
|||
|
|||
var getFrequencyVal = function() { |
|||
return $("#FrequencyFilter option:selected").val(); |
|||
}; |
|||
|
|||
var createChart = function (statistic) { |
|||
chart = new Chart($('#NewUserStatisticChart'), |
|||
{ |
|||
type: 'bar', |
|||
data: { |
|||
labels: statistic.labels, |
|||
datasets: [ |
|||
{ |
|||
label: 'User count', |
|||
data: statistic.data, |
|||
backgroundColor: 'rgba(255, 132, 132, 1)' |
|||
} |
|||
] |
|||
}, |
|||
options: { |
|||
scales: { |
|||
yAxes: [{ |
|||
ticks: { |
|||
beginAtZero: true |
|||
} |
|||
}] |
|||
} |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
var refreshChart = function (statistic) { |
|||
chart.data = { |
|||
labels: statistic.labels, |
|||
datasets: [ |
|||
{ |
|||
label: 'User count', |
|||
data: statistic.data, |
|||
backgroundColor: 'rgba(255, 132, 132, 1)' |
|||
} |
|||
] |
|||
}; |
|||
chart.update(); |
|||
}; |
|||
|
|||
var init = function (args) { |
|||
serviceMethod({ |
|||
startDate: args.filters.startDate, |
|||
endDate: args.filters.endDate, |
|||
frequency: getFrequencyVal() |
|||
}) |
|||
.then(function (result) { |
|||
createChart(result); |
|||
}); |
|||
|
|||
latestStartDate = args.filters.startDate; |
|||
latestEndDate = args.filters.endDate; |
|||
}; |
|||
|
|||
var refresh = function (args) { |
|||
|
|||
serviceMethod({ |
|||
startDate: args.filters.startDate, |
|||
endDate: args.filters.endDate, |
|||
frequency: getFrequencyVal() |
|||
}) |
|||
.then(function (result) { |
|||
refreshChart(result); |
|||
}); |
|||
|
|||
latestStartDate = args.filters.startDate; |
|||
latestEndDate = args.filters.endDate; |
|||
}; |
|||
|
|||
$('#FrequencyFilter').on('change', |
|||
function () { |
|||
refresh({ |
|||
filters: { |
|||
startDate: latestStartDate, |
|||
endDate: latestEndDate |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
abp.event.on('refresh-widgets', refresh); |
|||
|
|||
abp.event.on('init-widgets', init); |
|||
})(); |
|||
@ -0,0 +1,19 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using DashboardDemo.Web.Bundles; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bundling; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace DashboardDemo.Web.Pages.Components.NewUserStatisticWidget |
|||
{ |
|||
[DependsOn(typeof(ChartjsScriptContributor))] |
|||
public class NewUserStatisticWidgetScriptContributor : BundleContributor |
|||
{ |
|||
public override void ConfigureBundle(BundleConfigurationContext context) |
|||
{ |
|||
context.Files.Add("/Pages/Components/NewUserStatisticWidget/Default.js"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using DashboardDemo.Web.Bundles; |
|||
using DashboardDemo.Web.Pages.Components.NewUserStatisticWidget; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Widgets; |
|||
|
|||
namespace DashboardDemo.Web.Pages.Components.CountersWidget |
|||
{ |
|||
[Widget( |
|||
StyleTypes = new[] { typeof(ChartjsStyleContributor) }, |
|||
ScriptTypes = new[] { typeof(NewUserStatisticWidgetScriptContributor)} |
|||
)] |
|||
public class NewUserStatisticWidgetViewComponent : AbpViewComponent |
|||
{ |
|||
public async Task<IViewComponentResult> InvokeAsync() |
|||
{ |
|||
return View(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,8 +1,5 @@ |
|||
module.exports = { |
|||
aliases: { |
|||
|
|||
}, |
|||
mappings: { |
|||
|
|||
"@node_modules/chart.js/dist/*.*": "@libs/chart.js/" |
|||
} |
|||
}; |
|||
}; |
|||
File diff suppressed because it is too large
File diff suppressed because one or more lines are too long
@ -0,0 +1,47 @@ |
|||
/* |
|||
* DOM element rendering detection |
|||
* https://davidwalsh.name/detect-node-insertion |
|||
*/ |
|||
@keyframes chartjs-render-animation { |
|||
from { opacity: 0.99; } |
|||
to { opacity: 1; } |
|||
} |
|||
|
|||
.chartjs-render-monitor { |
|||
animation: chartjs-render-animation 0.001s; |
|||
} |
|||
|
|||
/* |
|||
* DOM element resizing detection |
|||
* https://github.com/marcj/css-element-queries |
|||
*/ |
|||
.chartjs-size-monitor, |
|||
.chartjs-size-monitor-expand, |
|||
.chartjs-size-monitor-shrink { |
|||
position: absolute; |
|||
direction: ltr; |
|||
left: 0; |
|||
top: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
overflow: hidden; |
|||
pointer-events: none; |
|||
visibility: hidden; |
|||
z-index: -1; |
|||
} |
|||
|
|||
.chartjs-size-monitor-expand > div { |
|||
position: absolute; |
|||
width: 1000000px; |
|||
height: 1000000px; |
|||
left: 0; |
|||
top: 0; |
|||
} |
|||
|
|||
.chartjs-size-monitor-shrink > div { |
|||
position: absolute; |
|||
width: 200%; |
|||
height: 200%; |
|||
left: 0; |
|||
top: 0; |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1 @@ |
|||
@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0} |
|||
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue