feat: added charts by tank type

This commit is contained in:
Mikhail Shabanov committed 2021-08-05 13:03:56 +02:00
1 parent d75fff58c7
commit 73bbe3cd14
9 files changed
+497 -21

No files matched your search

@@ -26,7 +26,7 @@
<PlayerInfoOverview AccountInfo="@AccountInfo"></PlayerInfoOverview>
</RadzenTabsItem>
<RadzenTabsItem Icon="insights">
<PlayerInfoStatistics></PlayerInfoStatistics>
<PlayerInfoStatistics TanksList="@AccountInfo.Tanks"></PlayerInfoStatistics>
</RadzenTabsItem>
<RadzenTabsItem Icon="agriculture">
<PlayerInfoTanksList TanksList="@AccountInfo.Tanks"></PlayerInfoTanksList>
@@ -1,3 +1,8 @@
@inherits PlayerInfoStatisticsBase
<div id="main" style="width:600px; height:400px;"></div>
<div class="chartsRow">
<div id="battlesByTankType" style="width: 33%; min-width: 300px; height:300px; margin-top: 10px;"></div>
<div id="winRateByTankType" style="width: 33%; min-width: 300px; height: 300px; margin-top: 10px; "></div>
<div id="avgDmgByTankType" style="width: 33%; min-width: 300px; height: 300px; margin-top: 10px; "></div>
</div>
@*<div id="stacked" style="width:300px; height:500px; margin-top: 20px"></div>*@
@@ -0,0 +1,6 @@
.chartsRow {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
}
@@ -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<ITank> 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");
}
}
}
@@ -123,9 +123,15 @@
<data name="Average XP" xml:space="preserve">
<value>Mittlere EP</value>
</data>
<data name="Avg damage by tank types" xml:space="preserve">
<value>Mittlerer Schaden dem Panzertype</value>
</data>
<data name="Battles" xml:space="preserve">
<value>Gefechte</value>
</data>
<data name="Battles by tank types" xml:space="preserve">
<value>Gefechte dem Panzertype</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Abbrechen</value>
</data>
@@ -216,6 +222,9 @@
<data name="Win rate" xml:space="preserve">
<value>Sieg</value>
</data>
<data name="Win rate by tank types" xml:space="preserve">
<value>Panzertypensieg</value>
</data>
<data name="years ago" xml:space="preserve">
<value>vor Jahren</value>
</data>
@@ -123,9 +123,15 @@
<data name="Average XP" xml:space="preserve">
<value>Средний опыт</value>
</data>
<data name="Avg damage by tank types" xml:space="preserve">
<value>Средний урон по типу танка</value>
</data>
<data name="Battles" xml:space="preserve">
<value>Количество боёв</value>
</data>
<data name="Battles by tank types" xml:space="preserve">
<value>Количество боёв по типу танка</value>
</data>
<data name="Cancel" xml:space="preserve">
<value>Отмена</value>
</data>
@@ -216,6 +222,9 @@
<data name="Win rate" xml:space="preserve">
<value>Процент побед</value>
</data>
<data name="Win rate by tank types" xml:space="preserve">
<value>Процент побед по типу танка</value>
</data>
<data name="years ago" xml:space="preserve">
<value>лет назад</value>
</data>
@@ -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<App> _localize;
public ChartService(IJSRuntime jsRuntime)
public ChartService(IJSRuntime jsRuntime, IStringLocalizer<App> localize)
{
_jsRuntime = jsRuntime;
_localize = localize;
}
public async Task BuildBarChart(string elementId)
public async Task BuildBarChartBattlesByTankType(string elementId, IEnumerable<ITank> tanks)
{
await _jsRuntime.InvokeVoidAsync("eChartsInterop.BuildBarChart", elementId);
var battlesCountByTankType = new Dictionary<string, long>();
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<ITank> tanks)
{
var battlesCountByTankType = new Dictionary<string, long>();
var winsCountByTankType = new Dictionary<string, long>();
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<ITank> tanks)
{
var battlesCountByTankType = new Dictionary<string, long>();
var damageSumByTankType = new Dictionary<string, long>();
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);
}
}
}
@@ -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<ITank> tanks);
Task BuildBarChartWinRatesByTankType(string elementId, IEnumerable<ITank> tanks);
Task BuildBarChartAvgDmgByTankType(string elementId, IEnumerable<ITank> tanks);
Task BuildStackedBarChart(string elementId);
}
}
@@ -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',
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',
data: [5, 20, 36, 10, 10, 20]
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();
};
};