diff --git a/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoLayout.razor b/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoLayout.razor
index 46bfa0b..81356f6 100644
--- a/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoLayout.razor
+++ b/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoLayout.razor
@@ -26,7 +26,7 @@
-
+
diff --git a/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatistics.razor b/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatistics.razor
index daf1538..4ef6793 100644
--- a/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatistics.razor
+++ b/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatistics.razor
@@ -1,3 +1,8 @@
@inherits PlayerInfoStatisticsBase
-
\ No newline at end of file
+
+ @**@
\ No newline at end of file
diff --git a/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatistics.razor.css b/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatistics.razor.css
new file mode 100644
index 0000000..eb47927
--- /dev/null
+++ b/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatistics.razor.css
@@ -0,0 +1,6 @@
+.chartsRow {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ justify-content: space-around;
+}
diff --git a/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatisticsBase.cs b/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatisticsBase.cs
index 74ad5f2..46efe38 100644
--- a/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatisticsBase.cs
+++ b/WotBlitzStatisticsPro.Blazor/Pages/PlayerInfoStatisticsBase.cs
@@ -1,5 +1,7 @@
-using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
+using WotBlitzStatisticsPro.Blazor.GraphQl;
using WotBlitzStatisticsPro.Blazor.Services;
namespace WotBlitzStatisticsPro.Blazor.Pages
@@ -9,11 +11,19 @@ namespace WotBlitzStatisticsPro.Blazor.Pages
[Inject]
public IChartsService ChartsService { get; set; }
+
+ [Parameter]
+ public IEnumerable TanksList { get; set; }
+
+
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
- await ChartsService.BuildBarChart("main");
+ await ChartsService.BuildBarChartBattlesByTankType("battlesByTankType", TanksList);
+ await ChartsService.BuildBarChartWinRatesByTankType("winRateByTankType", TanksList);
+ await ChartsService.BuildBarChartAvgDmgByTankType("avgDmgByTankType", TanksList);
+ //await ChartsService.BuildStackedBarChart("stacked");
}
}
}
diff --git a/WotBlitzStatisticsPro.Blazor/Resources/App.de.resx b/WotBlitzStatisticsPro.Blazor/Resources/App.de.resx
index e57f177..f8a4425 100644
--- a/WotBlitzStatisticsPro.Blazor/Resources/App.de.resx
+++ b/WotBlitzStatisticsPro.Blazor/Resources/App.de.resx
@@ -123,9 +123,15 @@
Mittlere EP
+
+ Mittlerer Schaden dem Panzertype
+
Gefechte
+
+ Gefechte dem Panzertype
+
Abbrechen
@@ -216,6 +222,9 @@
Sieg
+
+ Panzertypensieg
+
vor Jahren
diff --git a/WotBlitzStatisticsPro.Blazor/Resources/App.ru.resx b/WotBlitzStatisticsPro.Blazor/Resources/App.ru.resx
index a2c451a..d35deb5 100644
--- a/WotBlitzStatisticsPro.Blazor/Resources/App.ru.resx
+++ b/WotBlitzStatisticsPro.Blazor/Resources/App.ru.resx
@@ -123,9 +123,15 @@
Средний опыт
+
+ Средний урон по типу танка
+
Количество боёв
+
+ Количество боёв по типу танка
+
Отмена
@@ -216,6 +222,9 @@
Процент побед
+
+ Процент побед по типу танка
+
лет назад
diff --git a/WotBlitzStatisticsPro.Blazor/Services/ChartService.cs b/WotBlitzStatisticsPro.Blazor/Services/ChartService.cs
index 844362c..3022639 100644
--- a/WotBlitzStatisticsPro.Blazor/Services/ChartService.cs
+++ b/WotBlitzStatisticsPro.Blazor/Services/ChartService.cs
@@ -1,20 +1,209 @@
-using System.Threading.Tasks;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Localization;
using Microsoft.JSInterop;
+using WotBlitzStatisticsPro.Blazor.GraphQl;
+using WotBlitzStatisticsPro.Blazor.Helpers;
namespace WotBlitzStatisticsPro.Blazor.Services
{
public class ChartService: IChartsService
{
private readonly IJSRuntime _jsRuntime;
+ private readonly IStringLocalizer _localize;
- public ChartService(IJSRuntime jsRuntime)
+ public ChartService(IJSRuntime jsRuntime, IStringLocalizer localize)
{
_jsRuntime = jsRuntime;
+ _localize = localize;
}
- public async Task BuildBarChart(string elementId)
+ public async Task BuildBarChartBattlesByTankType(string elementId, IEnumerable tanks)
{
- await _jsRuntime.InvokeVoidAsync("eChartsInterop.BuildBarChart", elementId);
+ var battlesCountByTankType = new Dictionary();
+
+ foreach (var tank in tanks)
+ {
+ if (tank.TankTypeId == null)
+ {
+ continue;
+ }
+ if (battlesCountByTankType.ContainsKey(tank.TankTypeId))
+ {
+ battlesCountByTankType[tank.TankTypeId] += tank.Battles;
+ }
+ else
+ {
+ battlesCountByTankType.Add(tank.TankTypeId, tank.Battles);
+ }
+ }
+
+ int mediumValue = 0;
+ int lightValue = 0;
+ int heavyValue = 0;
+ int atValue = 0;
+ if (battlesCountByTankType.ContainsKey(Constants.MediumTank))
+ {
+ mediumValue = Convert.ToInt32(battlesCountByTankType[Constants.MediumTank]);
+ }
+ if (battlesCountByTankType.ContainsKey(Constants.LightTank))
+ {
+ lightValue = Convert.ToInt32(battlesCountByTankType[Constants.LightTank]);
+ }
+ if (battlesCountByTankType.ContainsKey(Constants.HeavyTank))
+ {
+ heavyValue = Convert.ToInt32(battlesCountByTankType[Constants.HeavyTank]);
+ }
+ if (battlesCountByTankType.ContainsKey(Constants.AtSpg))
+ {
+ atValue = Convert.ToInt32(battlesCountByTankType[Constants.AtSpg]);
+ }
+
+ var chartData = new[]
+ {
+ new {tankType = Constants.MediumTank, value = mediumValue, color = "#9FE3CE"},
+ new {tankType = Constants.LightTank, value = lightValue, color = "#9FE3CE"},
+ new {tankType = Constants.HeavyTank, value = heavyValue, color = "#9FE3CE"},
+ new {tankType = Constants.AtSpg, value = atValue, color = "#9FE3CE"},
+ };
+
+ await _jsRuntime.InvokeVoidAsync("eChartsInterop.BuildBarChartByTankType", elementId, _localize.GetString("Battles by tank types").Value, chartData);
+ }
+
+ public async Task BuildBarChartWinRatesByTankType(string elementId, IEnumerable tanks)
+ {
+ var battlesCountByTankType = new Dictionary();
+ var winsCountByTankType = new Dictionary();
+
+ foreach (var tank in tanks)
+ {
+ if(tank.TankTypeId == null)
+ {
+ continue;
+ }
+ if(battlesCountByTankType.ContainsKey(tank.TankTypeId))
+ {
+ battlesCountByTankType[tank.TankTypeId] += tank.Battles;
+ }
+ else
+ {
+ battlesCountByTankType.Add(tank.TankTypeId, tank.Battles);
+ }
+ if(winsCountByTankType.ContainsKey(tank.TankTypeId))
+ {
+ winsCountByTankType[tank.TankTypeId] += tank.Wins;
+ }
+ else
+ {
+ winsCountByTankType.Add(tank.TankTypeId, tank.Wins);
+ }
+ }
+
+ int mediumValue = 0;
+ int lightValue = 0;
+ int heavyValue = 0;
+ int atValue = 0;
+ if (battlesCountByTankType.ContainsKey(Constants.MediumTank))
+ {
+ mediumValue = Convert.ToInt32(100 * winsCountByTankType[Constants.MediumTank] /
+ battlesCountByTankType[Constants.MediumTank]);
+ }
+ if (battlesCountByTankType.ContainsKey(Constants.LightTank))
+ {
+ lightValue = Convert.ToInt32(100 * winsCountByTankType[Constants.LightTank] /
+ battlesCountByTankType[Constants.LightTank]);
+ }
+ if (battlesCountByTankType.ContainsKey(Constants.HeavyTank))
+ {
+ heavyValue = Convert.ToInt32(100 * winsCountByTankType[Constants.HeavyTank] /
+ battlesCountByTankType[Constants.HeavyTank]);
+ }
+ if (battlesCountByTankType.ContainsKey(Constants.AtSpg))
+ {
+ atValue = Convert.ToInt32(100 * winsCountByTankType[Constants.AtSpg] /
+ battlesCountByTankType[Constants.AtSpg]);
+ }
+
+ var chartData = new[]
+ {
+ new {tankType = Constants.MediumTank, value = mediumValue, color = mediumValue.ScaleColor()},
+ new {tankType = Constants.LightTank, value = lightValue, color = lightValue.ScaleColor()},
+ new {tankType = Constants.HeavyTank, value = heavyValue, color = heavyValue.ScaleColor()},
+ new {tankType = Constants.AtSpg, value = atValue, color = atValue.ScaleColor()},
+ };
+
+ await _jsRuntime.InvokeVoidAsync("eChartsInterop.BuildBarChartByTankType", elementId, _localize.GetString("Win rate by tank types").Value, chartData);
+ }
+
+ public async Task BuildBarChartAvgDmgByTankType(string elementId, IEnumerable tanks)
+ {
+ var battlesCountByTankType = new Dictionary();
+ var damageSumByTankType = new Dictionary();
+
+ foreach (var tank in tanks)
+ {
+ if (tank.TankTypeId == null)
+ {
+ continue;
+ }
+ if (battlesCountByTankType.ContainsKey(tank.TankTypeId))
+ {
+ battlesCountByTankType[tank.TankTypeId] += tank.Battles;
+ }
+ else
+ {
+ battlesCountByTankType.Add(tank.TankTypeId, tank.Battles);
+ }
+ if (damageSumByTankType.ContainsKey(tank.TankTypeId))
+ {
+ damageSumByTankType[tank.TankTypeId] += tank.DamageDealt;
+ }
+ else
+ {
+ damageSumByTankType.Add(tank.TankTypeId, tank.DamageDealt);
+ }
+ }
+
+ int mediumValue = 0;
+ int lightValue = 0;
+ int heavyValue = 0;
+ int atValue = 0;
+ if (battlesCountByTankType.ContainsKey(Constants.MediumTank))
+ {
+ mediumValue = Convert.ToInt32(damageSumByTankType[Constants.MediumTank] /
+ battlesCountByTankType[Constants.MediumTank]);
+ }
+ if (battlesCountByTankType.ContainsKey(Constants.LightTank))
+ {
+ lightValue = Convert.ToInt32(damageSumByTankType[Constants.LightTank] /
+ battlesCountByTankType[Constants.LightTank]);
+ }
+ if (battlesCountByTankType.ContainsKey(Constants.HeavyTank))
+ {
+ heavyValue = Convert.ToInt32(damageSumByTankType[Constants.HeavyTank] /
+ battlesCountByTankType[Constants.HeavyTank]);
+ }
+ if (battlesCountByTankType.ContainsKey(Constants.AtSpg))
+ {
+ atValue = Convert.ToInt32(damageSumByTankType[Constants.AtSpg] /
+ battlesCountByTankType[Constants.AtSpg]);
+ }
+
+ var chartData = new[]
+ {
+ new {tankType = Constants.MediumTank, value = mediumValue, color = "#D98D8B"},
+ new {tankType = Constants.LightTank, value = lightValue, color = "#D98D8B"},
+ new {tankType = Constants.HeavyTank, value = heavyValue, color = "#D98D8B"},
+ new {tankType = Constants.AtSpg, value = atValue, color = "#D98D8B"},
+ };
+
+ await _jsRuntime.InvokeVoidAsync("eChartsInterop.BuildBarChartByTankType", elementId, _localize.GetString("Avg damage by tank types").Value, chartData);
+ }
+
+ public async Task BuildStackedBarChart(string elementId)
+ {
+ await _jsRuntime.InvokeVoidAsync("eChartsInterop.BuildStackedBarChart", elementId);
}
}
}
\ No newline at end of file
diff --git a/WotBlitzStatisticsPro.Blazor/Services/IChartsService.cs b/WotBlitzStatisticsPro.Blazor/Services/IChartsService.cs
index 927f753..7687285 100644
--- a/WotBlitzStatisticsPro.Blazor/Services/IChartsService.cs
+++ b/WotBlitzStatisticsPro.Blazor/Services/IChartsService.cs
@@ -1,9 +1,14 @@
-using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using WotBlitzStatisticsPro.Blazor.GraphQl;
namespace WotBlitzStatisticsPro.Blazor.Services
{
public interface IChartsService
{
- Task BuildBarChart(string elementId);
+ Task BuildBarChartBattlesByTankType(string elementId, IEnumerable tanks);
+ Task BuildBarChartWinRatesByTankType(string elementId, IEnumerable tanks);
+ Task BuildBarChartAvgDmgByTankType(string elementId, IEnumerable tanks);
+ Task BuildStackedBarChart(string elementId);
}
}
\ No newline at end of file
diff --git a/WotBlitzStatisticsPro.Blazor/wwwroot/echarts/echarts-interop.js b/WotBlitzStatisticsPro.Blazor/wwwroot/echarts/echarts-interop.js
index a847152..6686831 100644
--- a/WotBlitzStatisticsPro.Blazor/wwwroot/echarts/echarts-interop.js
+++ b/WotBlitzStatisticsPro.Blazor/wwwroot/echarts/echarts-interop.js
@@ -1,29 +1,272 @@
var eChartsInterop = eChartsInterop || {};
-eChartsInterop.BuildBarChart = function (elementId) {
+eChartsInterop.BuildBarChartByTankType = function (elementId, chartTitle, chartData) {
+ var tankTypes = {
+ 'HeavyTank': '/tank-type/vehicle.class.heavy.small.scale-200.png',
+ 'AtSpg': '/tank-type/vehicle.class.atspg.small.scale-200.png',
+ 'MediumTank': '/tank-type/vehicle.class.medium.small.scale-200.png',
+ 'LightTank': '/tank-type/vehicle.class.light.small.scale-200.png'
+ };
+
+ var seriesLabel = {
+ show: true
+ }
+
// based on prepared DOM, initialize echarts instance
- var myChart = echarts.init(document.getElementById(elementId));
+ var myChart = echarts.init(document.getElementById(elementId), 'dark');
+
+ var lightData = chartData.find(d => d.tankType === 'lightTank');
+ var mediumData = chartData.find(d => d.tankType === 'mediumTank');
+ var heavyData = chartData.find(d => d.tankType === 'heavyTank');
+ var atData = chartData.find(d => d.tankType === 'AT-SPG');
// specify chart configuration item and data
var option = {
title: {
- text: 'ECharts entry example'
+ text: chartTitle
},
- tooltip: {},
- legend: {
- data: ['Sales']
+ toolbox: {
+ show: true,
+ feature: {
+ saveAsImage: {}
+ }
},
xAxis: {
- data: ["shirt", "cardign", "chiffon shirt", "pants", "heels", "socks"]
+ type: 'value',
+ name: '',
+ axisLabel: {
+ formatter: '{value}'
+ }
},
- yAxis: {},
- series: [{
- name: 'Sales',
- type: 'bar',
- data: [5, 20, 36, 10, 10, 20]
- }]
+ yAxis: {
+ type: 'category',
+ data: ['HeavyTank', 'AtSpg', 'MediumTank', 'LightTank'],
+ axisTick: {
+ alignWithLabel: true
+ },
+ axisLabel: {
+ formatter: function (value) {
+ return '{' + value + '| }';
+ },
+ rich: {
+ value: {
+ lineHeight: 10,
+ align: 'center'
+ },
+ HeavyTank: {
+ height: 20,
+ width: 20,
+ align: 'center',
+ backgroundColor: {
+ image: tankTypes.HeavyTank
+ }
+ },
+ AtSpg: {
+ height: 20,
+ width: 20,
+ align: 'center',
+ backgroundColor: {
+ image: tankTypes.AtSpg
+ }
+ },
+ MediumTank: {
+ height: 20,
+ width: 20,
+ align: 'center',
+ backgroundColor: {
+ image: tankTypes.MediumTank
+ }
+ },
+ LightTank: {
+ height: 20,
+ width: 20,
+ align: 'center',
+ backgroundColor: {
+ image: tankTypes.LightTank
+ }
+ }
+ }
+ }
+ },
+ series: [
+ {
+ type: 'bar',
+ label: seriesLabel,
+ barWidth: '30px',
+ data: [
+ {
+ value: heavyData.value,
+ itemStyle: {
+ color: heavyData.color
+ }
+ },
+ {
+ value: atData.value,
+ itemStyle: {
+ color: atData.color
+ }
+ },
+ {
+ value: mediumData.value,
+ itemStyle: {
+ color: mediumData.color
+ }
+ },
+ {
+ value: lightData.value,
+ itemStyle: {
+ color: lightData.color
+ }
+ }]
+ }]
};
// use configuration item and data specified to show chart
myChart.setOption(option);
+ window.addEventListener('resize',
+ function() {
+ myChart.resize();
+ });
+};
+
+eChartsInterop.BuildStackedBarChart = function (elementId) {
+ var tankTypes = {
+ 'HeavyTank': '/tank-type/vehicle.class.heavy.small.scale-200.png',
+ 'AtSpg': '/tank-type/vehicle.class.atspg.small.scale-200.png',
+ 'MediumTank': '/tank-type/vehicle.class.medium.small.scale-200.png',
+ 'LightTank': '/tank-type/vehicle.class.light.small.scale-200.png'
+ };
+
+ var seriesLabel = {
+ show: true
+ }
+
+ // based on prepared DOM, initialize echarts instance
+ var myChart = echarts.init(document.getElementById(elementId), 'dark');
+
+ // specify chart configuration item and data
+ var option = {
+
+ title: {
+ text: 'Statistics by tank types'
+ },
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: { // Use axis to trigger tooltip
+ type: 'shadow' // 'shadow' as default; can also be 'line' or 'shadow'
+ }
+ },
+ legend: {
+ data: ['Battles', '% Побед', 'Avg Dmg']
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ containLabel: true
+ },
+ xAxis: {
+ type: 'value'
+ },
+ toolbox: {
+ show: true,
+ feature: {
+ saveAsImage: {}
+ }
+ },
+ yAxis: {
+ type: 'category',
+ data: ['HeavyTank', 'AtSpg', 'MediumTank', 'LightTank'],
+ axisTick: {
+ alignWithLabel: true
+ },
+ axisLabel: {
+ formatter: function (value) {
+ return '{' + value + '| }';
+ },
+ rich: {
+ value: {
+ lineHeight: 10,
+ align: 'center'
+ },
+ HeavyTank: {
+ height: 20,
+ width: 20,
+ align: 'center',
+ backgroundColor: {
+ image: tankTypes.HeavyTank
+ }
+ },
+ AtSpg: {
+ height: 20,
+ width: 20,
+ align: 'center',
+ backgroundColor: {
+ image: tankTypes.AtSpg
+ }
+ },
+ MediumTank: {
+ height: 20,
+ width: 20,
+ align: 'center',
+ backgroundColor: {
+ image: tankTypes.MediumTank
+ }
+ },
+ LightTank: {
+ height: 20,
+ width: 20,
+ align: 'center',
+ backgroundColor: {
+ image: tankTypes.LightTank
+ }
+ }
+ }
+ }
+ },
+ series: [
+ {
+ name: 'Battles',
+ type: 'bar',
+ stack: 'total',
+ label: {
+ show: true
+ },
+ emphasis: {
+ focus: 'series'
+ },
+ data: [830, 1300, 50, 5000]
+ },
+ {
+ name: '% Побед',
+ type: 'bar',
+ stack: 'total',
+ label: {
+ show: true
+ },
+ emphasis: {
+ focus: 'series'
+ },
+ data: [35, 56, 48, 60]
+ },
+ {
+ name: 'Avg Dmg',
+ type: 'bar',
+ stack: 'total',
+ label: {
+ show: true
+ },
+ emphasis: {
+ focus: 'series'
+ },
+ data: [600, 2500, 1700, 1300]
+ }
+ ]
+ };
+
+ // use configuration item and data specified to show chart
+ myChart.setOption(option);
+ window.onresize = function () {
+ myChart.resize();
+ };
};
\ No newline at end of file