c5375b661b
broke data out into its own library. may be breaking changes with existing plugins
406 lines
9.3 KiB
JavaScript
406 lines
9.3 KiB
JavaScript
window.onresize = function () {
|
|
drawPlayerModel();
|
|
}
|
|
|
|
$(document).ready(function () {
|
|
$('.table-slide').click(function () {
|
|
$(this).siblings().children().children('.hidden-row').slideToggle(0);
|
|
$(this).children('span').toggleClass('oi-chevron-top oi-chevron-bottom');
|
|
});
|
|
setupPerformanceGraph();
|
|
drawPlayerModel();
|
|
})
|
|
|
|
function setupPerformanceGraph() {
|
|
const summary = $('#client_stats_summary');
|
|
if (summary === undefined) {
|
|
return;
|
|
}
|
|
const chart = $('#client_performance_history');
|
|
const container = $('#client_performance_history_container');
|
|
chart.attr('height', summary.height());
|
|
chart.attr('width', container.width());
|
|
renderPerformanceChart();
|
|
}
|
|
|
|
function drawPlayerModel() {
|
|
const canvas = document.getElementById('hitlocation_model');
|
|
if (canvas === null) {
|
|
return;
|
|
}
|
|
const context = canvas.getContext('2d');
|
|
const container = $('#hitlocation_container');
|
|
const background = new Image();
|
|
background.onload = () => {
|
|
const backgroundRatioX = background.width / background.height;
|
|
|
|
canvas.height = container.height() - 28;
|
|
canvas.width = (canvas.height * backgroundRatioX);
|
|
|
|
const scalar = canvas.height / background.height;
|
|
|
|
drawHitLocationChart(context, background, scalar, canvas.width, canvas.height);
|
|
}
|
|
background.src = '/images/stats/hit_location_model.png';
|
|
}
|
|
|
|
function buildHitLocationPosition() {
|
|
let hitLocations = {}
|
|
hitLocations['head'] = {
|
|
x: 454.5,
|
|
y: 108.5,
|
|
width: 157,
|
|
height: 217
|
|
}
|
|
|
|
hitLocations['torso_upper'] = {
|
|
x: 457,
|
|
y: 318,
|
|
width: 254,
|
|
height: 202
|
|
}
|
|
|
|
hitLocations['torso_lower'] = {
|
|
x: 456.50,
|
|
y: 581,
|
|
width: 315,
|
|
height: 324
|
|
}
|
|
|
|
hitLocations['right_leg_upper'] = {
|
|
x: 527.5,
|
|
y: 856.7,
|
|
width: 149,
|
|
height: 228
|
|
}
|
|
|
|
hitLocations['right_leg_lower'] = {
|
|
x: 542,
|
|
y: 1077.6,
|
|
width: 120,
|
|
height: 214
|
|
}
|
|
|
|
hitLocations['right_foot'] = {
|
|
x: 558.5,
|
|
y: 1253.5,
|
|
width: 93,
|
|
height: 138
|
|
}
|
|
|
|
hitLocations['left_leg_upper'] = {
|
|
x: 382.5,
|
|
y: 857,
|
|
width: 141,
|
|
height: 228
|
|
}
|
|
|
|
hitLocations['left_leg_lower'] = {
|
|
x: 371.5,
|
|
y: 1078,
|
|
width: 119,
|
|
height: 214
|
|
}
|
|
|
|
hitLocations['left_foot'] = {
|
|
x: 353,
|
|
y: 1254,
|
|
width: 90,
|
|
height: 138
|
|
}
|
|
|
|
hitLocations['left_arm_upper'] = {
|
|
p1: {
|
|
x: 330,
|
|
y: 218
|
|
},
|
|
p2: {
|
|
x: 330,
|
|
y: 400
|
|
},
|
|
p3: {
|
|
x: 255,
|
|
y: 475
|
|
},
|
|
p4: {
|
|
x: 165,
|
|
y: 375
|
|
},
|
|
type: 'polygon'
|
|
}
|
|
|
|
hitLocations['right_arm_upper'] = {
|
|
p1: {
|
|
x: 584,
|
|
y: 218
|
|
},
|
|
p2: {
|
|
x: 584,
|
|
y: 400
|
|
},
|
|
p3: {
|
|
x: 659,
|
|
y: 475
|
|
},
|
|
p4: {
|
|
x: 749,
|
|
y: 375
|
|
},
|
|
type: 'polygon'
|
|
}
|
|
|
|
hitLocations['left_arm_lower'] = {
|
|
p1: {
|
|
x: 165,
|
|
y: 375
|
|
},
|
|
p2: {
|
|
x: 255,
|
|
y: 475
|
|
},
|
|
p3: {
|
|
x: 121,
|
|
y: 584
|
|
},
|
|
p4: {
|
|
x: 30,
|
|
y: 512
|
|
},
|
|
type: 'polygon'
|
|
}
|
|
|
|
hitLocations['right_arm_lower'] = {
|
|
p1: {
|
|
x: 749,
|
|
y: 375
|
|
},
|
|
p2: {
|
|
x: 659,
|
|
y: 475
|
|
},
|
|
p3: {
|
|
x: 789,
|
|
y: 587
|
|
},
|
|
p4: {
|
|
x: 876,
|
|
y: 497
|
|
},
|
|
type: 'polygon'
|
|
}
|
|
|
|
hitLocations['left_hand'] = {
|
|
p1: {
|
|
x: 30,
|
|
y: 512
|
|
},
|
|
p2: {
|
|
x: 121,
|
|
y: 584
|
|
},
|
|
p3: {
|
|
x: 0,
|
|
y: 669
|
|
},
|
|
p4: {
|
|
x: 0,
|
|
y: 582
|
|
},
|
|
type: 'polygon'
|
|
}
|
|
|
|
hitLocations['right_hand'] = {
|
|
p1: {
|
|
x: 789,
|
|
y: 587
|
|
},
|
|
p2: {
|
|
x: 876,
|
|
y: 497
|
|
},
|
|
p3: {
|
|
x: 905,
|
|
y: 534
|
|
},
|
|
p4: {
|
|
x: 905,
|
|
y: 666
|
|
},
|
|
type: 'polygon'
|
|
}
|
|
return hitLocations;
|
|
}
|
|
|
|
function drawHitLocationChart(context, background, scalar, width, height) {
|
|
context.drawImage(background, 0, 0, background.width, background.height, 0, 0, width, height);
|
|
|
|
const hitLocations = buildHitLocationPosition();
|
|
|
|
$.each(hitLocationData, (index, hit) => {
|
|
let scaledPercentage = hit.percentage / maxPercentage;
|
|
let red;
|
|
let green = 255;
|
|
|
|
if (scaledPercentage < 0.5) {
|
|
red = Math.round(scaledPercentage * 255 * 2);
|
|
} else {
|
|
red = 255;
|
|
green = Math.round((1 - scaledPercentage) * 255 * 2);
|
|
}
|
|
|
|
red = red.toString(16).padStart(2, '0');
|
|
green = green.toString(16).padStart(2, '0');
|
|
|
|
const color = '#' + red + green + '0077';
|
|
const location = hitLocations[hit.name];
|
|
|
|
if (location.type === 'polygon') {
|
|
drawPolygon(context, scalar, location.p1, location.p2, location.p3, location.p4, color);
|
|
} else {
|
|
drawRectangle(context, scalar, location.x, location.y, location.width, location.height, color);
|
|
}
|
|
});
|
|
}
|
|
|
|
function drawRectangle(context, scalar, x, y, width, height, color) {
|
|
const scaledRectWidth = width * scalar;
|
|
const scaledRectHeight = height * scalar;
|
|
const rectX = x * scalar - (scaledRectWidth / 2);
|
|
const rectY = y * scalar - (scaledRectHeight / 2);
|
|
context.beginPath();
|
|
context.fillStyle = color
|
|
context.fillRect(rectX, rectY, scaledRectWidth, scaledRectHeight);
|
|
context.closePath();
|
|
}
|
|
|
|
function drawPolygon(context, scalar, p1, p2, p3, p4, color) {
|
|
|
|
const points = [p1, p2, p3, p4];
|
|
|
|
$.each(points, (index, point) => {
|
|
point.x = point.x * scalar;
|
|
point.y = point.y * scalar;
|
|
});
|
|
|
|
context.beginPath();
|
|
context.fillStyle = color;
|
|
context.moveTo(p1.x, p1.y);
|
|
context.lineTo(p2.x, p2.y);
|
|
context.lineTo(p3.x, p3.y);
|
|
context.lineTo(p4.x, p4.y);
|
|
context.fill();
|
|
context.closePath();
|
|
}
|
|
|
|
function getClosestMultiple(baseValue, value) {
|
|
return Math.round(value / baseValue) * baseValue;
|
|
}
|
|
|
|
function renderPerformanceChart() {
|
|
const id = 'client_performance_history';
|
|
const data = $('#' + id).data('history');
|
|
|
|
if (data === undefined) {
|
|
return;
|
|
}
|
|
if (data.length <= 1) {
|
|
// only 0 perf
|
|
return;
|
|
}
|
|
|
|
const labels = [];
|
|
data.forEach(function (item, i) {
|
|
labels.push(i);
|
|
});
|
|
|
|
const padding = 4;
|
|
let dataMin = Math.min(...data);
|
|
const dataMax = Math.max(...data);
|
|
|
|
if (dataMax - dataMin === 0) {
|
|
dataMin = 0;
|
|
}
|
|
|
|
dataMin = Math.max(0, dataMin);
|
|
|
|
const min = getClosestMultiple(padding, dataMin - padding);
|
|
const max = getClosestMultiple(padding, dataMax + padding);
|
|
|
|
const chartData = {
|
|
labels: labels,
|
|
datasets: [{
|
|
data: data,
|
|
pointBackgroundColor: 'rgba(255, 255, 255, 0)',
|
|
pointBorderColor: 'rgba(255, 255, 255, 0)',
|
|
pointHoverRadius: 5,
|
|
pointHoverBackgroundColor: 'rgba(255, 255, 255, 1)',
|
|
}]
|
|
};
|
|
|
|
const options = {
|
|
defaultFontFamily: '-apple-system, BlinkMacSystemFont, "Open Sans", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"',
|
|
responsive: true,
|
|
maintainAspectRatio: false,
|
|
legend: false,
|
|
tooltips: {
|
|
callbacks: {
|
|
label: (tooltipItem) => Math.round(tooltipItem.yLabel) + ' ' + _localization["PLUGINS_STATS_COMMANDS_PERFORMANCE"],
|
|
title: () => ''
|
|
},
|
|
mode: 'nearest',
|
|
intersect: false,
|
|
animationDuration: 0,
|
|
cornerRadius: 0,
|
|
displayColors: false
|
|
},
|
|
hover: {
|
|
mode: 'nearest',
|
|
intersect: false
|
|
},
|
|
elements: {
|
|
line: {
|
|
fill: false,
|
|
borderColor: 'rgba(255, 255, 255, 0.75)',
|
|
borderWidth: 2
|
|
},
|
|
point: {
|
|
radius: 5
|
|
}
|
|
},
|
|
scales: {
|
|
xAxes: [{
|
|
display: false,
|
|
}],
|
|
yAxes: [{
|
|
gridLines: {
|
|
display: false
|
|
},
|
|
|
|
position: 'right',
|
|
ticks: {
|
|
callback: function (value, index, values) {
|
|
if (index === values.length - 1) {
|
|
return min;
|
|
} else if (index === 0) {
|
|
return max;
|
|
} else {
|
|
return '';
|
|
}
|
|
},
|
|
fontColor: 'rgba(255, 255, 255, 0.25)'
|
|
}
|
|
}]
|
|
},
|
|
layout: {
|
|
padding: {
|
|
left: 15
|
|
}
|
|
},
|
|
};
|
|
|
|
new Chart(id, {
|
|
type: 'line',
|
|
data: chartData,
|
|
options: options
|
|
});
|
|
} |