gsd 10 hours ago
parent
commit
8ad0557d71
  1. 203
      chartGenerator.js

203
chartGenerator.js

@ -1,10 +1,9 @@
const { createCanvas, registerFont } = require('canvas');
const { createCanvas } = require('canvas');
const Chart = require('chart.js/auto');
const {testData} = require("./trash/testData");
const {formatSeconds} = require("./utils");
const { testData } = require("./trash/testData");
const { formatSeconds } = require("./utils");
const moment = require('moment');
const fs = require("fs");
function prepareData(data) {
const result = [];
@ -15,7 +14,7 @@ function prepareData(data) {
return container[mapName];
}
return 0;
}
};
const grabMapName = (container) => {
if (!container) return "";
@ -23,103 +22,178 @@ function prepareData(data) {
return mapName;
}
return "";
}
//console.log(data)
};
for (const srvId of Object.keys(data.lastplay)) {
const obj = {}
obj["srv_id"] = srvId;
obj["server_name"] = data.servers[srvId].name;
obj["lastplay"] = grabFirstValue(data.lastplay[srvId])
obj["lastplay_moment"] = moment.unix(obj["lastplay"]).format("DD-MM-YYYY HH:mm")
obj["gametime"] = grabFirstValue(data.gametime[srvId])
obj["map_name"] = grabMapName(data.lastplay[srvId])
const obj = {};
obj.srv_id = srvId;
obj.server_name = data.servers[srvId].name;
obj.lastplay = grabFirstValue(data.lastplay[srvId]);
obj.lastplay_moment = moment.unix(obj.lastplay).format("DD-MM-YYYY HH:mm");
obj.gametime = grabFirstValue(data.gametime[srvId]);
obj.map_name = grabMapName(data.lastplay[srvId]);
result.push(obj);
}
return result;
}
function generateChartData(d) {
const maxGametime = d.sort((a, b) => a.gametime - b.gametime).at(d.length - 1)["gametime"]
console.log(maxGametime)
function getTextAlignByPoint(p, r) {
const dx = p.x - r.xCenter;
const dy = p.y - r.yCenter;
if (Math.abs(dx) < Math.abs(dy) * 0.1) {
return 'center';
}
let gametimeDelimiter = 1;
for (const delimiter of [60, 3600, 3600 * 24]) {
if (maxGametime > delimiter)
gametimeDelimiter = delimiter;
if (dx > 0) {
return 'left';
}
console.log(gametimeDelimiter)
return 'right';
}
function getAlignedRectX(textAlign, x, width, padX) {
if (textAlign === 'left') {
return x - padX;
}
if (textAlign === 'right') {
return x - width - padX;
}
return x - width / 2 - padX;
}
const customLabelsPlugin = {
id: 'customLabelsPlugin',
afterDraw(chart) {
const { ctx, scales: { r } } = chart;
const labels = chart.data.labels;
ctx.save();
labels.forEach((label, i) => {
const p = r.getPointPosition(i, r.drawingArea + 50);
const align = getTextAlignByPoint(p, r);
const lines = Array.isArray(label) ? label : [label];
const [mapName, serverName, playTime] = lines;
ctx.textAlign = align;
ctx.textBaseline = 'middle';
// 1 строка
ctx.font = 'bold 16px Arial';
let w = ctx.measureText(mapName).width;
let rx = getAlignedRectX(align, p.x, w, 6);
ctx.fillStyle = '#395c78';
ctx.fillRect(rx, p.y - 28, w + 12, 22);
ctx.fillStyle = '#ffffff';
ctx.fillText(mapName, p.x, p.y - 17);
// 2 строка
ctx.font = '14px Arial';
w = ctx.measureText(serverName).width;
rx = getAlignedRectX(align, p.x, w, 6);
ctx.fillStyle = '#0e0d0d';
ctx.fillText(serverName, p.x, p.y + 4);
// 3 строка
ctx.font = '14px Arial';
ctx.fillStyle = '#0e0d0d';
ctx.fillText(playTime, p.x, p.y + 24);
});
ctx.restore();
}
};
function generateChartData(d) {
const chartData = {
labels: [],
datasets: []
}
const data = []
d.sort((a, b) => b.gametime - a.gametime).forEach(
(val) => {
chartData.labels.push(`${val['server_name']}\n${val['lastplay_moment']}\nНаиграно: ${formatSeconds(val['gametime'])}`)
data.push(val['gametime'] / gametimeDelimiter)
}
)
};
const data = [];
d
.sort((a, b) => a.server_name.localeCompare(b.server_name, 'ru'))
.forEach((val) => {
chartData.labels.push(
[
`${val.server_name}`,
`${val.lastplay_moment}`,
`Наиграно: ${formatSeconds(val.gametime)}`
]
);
data.push(Math.pow(val.gametime || 0, 0.3));
});
chartData.datasets.push({
label: "Наиграно времени",
data: data,
})
const chartConfig = {
data,
borderColor: '#ff853e',
backgroundColor: '#ff853e94',
pointBackgroundColor: '#ff853e',
pointBorderColor: '#ff853e'
});
return {
type: 'radar',
data: chartData,
plugins: [
{
id: 'customCanvasBackgroundColor',
beforeDraw: (chart) => {
const { ctx, width, height } = chart;
ctx.save();
ctx.globalCompositeOperation = 'destination-over';
ctx.fillStyle = '#f7f3f1';
ctx.fillRect(0, 0, width, height);
ctx.restore();
}
},
customLabelsPlugin
],
options: {
responsive: false,
maintainAspectRatio: false,
borderColor: '#bd3b3b',
//backgroundColor: '#FFFFFF',
layout: {
padding: 20
padding: 110
},
plugins: {
legend: {
position: 'top',
display: false
},
title: {
display: false,
text: 'Chart.js Polar Area Chart With Centered Point Labels'
display: false
}
},
scales: {
r: {
beginAtZero: true,
grid: {
color: '#ef9849'
color: '#6d6d6d'
},
angleLines: {
color: '#f08149'
color: '#6d6d6d'
},
pointLabels: {
display: true,
//centerPointLabels: true,
padding: 44,
font: {
size: 16
},
backdropColor: "#395c78",
backdropPadding: "1",
color: "#f5e7de"
ticks: {
display: false
},
pointLabels: {
display: false,
}
}
}
},
}
};
return chartConfig;
}
function createChartOnData(testData) {
// Create a canvas and chart
const width = process.env.W || 900;
const height = process.env.H || 700;
const width = Number(process.env.W) || 900;
const height = Number(process.env.H) || 700;
const canvas = createCanvas(width, height);
const ctx = canvas.getContext('2d');
@ -129,10 +203,10 @@ function createChartOnData(testData) {
new Chart(ctx, chartConfig);
return canvas.createPNGStream();
return canvas.createPNGStream();
}
module.exports = {createChartOnData}
module.exports = { createChartOnData };
function test() {
const stream = createChartOnData(testData);
@ -143,5 +217,4 @@ function test() {
out.on('finish', () => console.log('The chart image was saved.'));
}
//test()
test()

Loading…
Cancel
Save