test chart drawing
This commit is contained in:
parent
6c9dad52df
commit
36c6d87cd3
27
package-lock.json
generated
27
package-lock.json
generated
|
@ -9,6 +9,7 @@
|
|||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"bcrypt": "^5.0.1",
|
||||
"chart.js": "^3.9.1",
|
||||
"compression": "^1.7.3",
|
||||
"cookie": "^0.5.0",
|
||||
"core-js": "^3.23.4",
|
||||
|
@ -30,6 +31,7 @@
|
|||
"passport-vkontakte": "^0.5.0",
|
||||
"ppfun-captcha": "^1.6.6",
|
||||
"react": "^18.2.0",
|
||||
"react-chartjs-2": "^4.3.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^4.3.1",
|
||||
"react-redux": "^8.0.2",
|
||||
|
@ -3655,6 +3657,11 @@
|
|||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/chart.js": {
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz",
|
||||
"integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w=="
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
|
@ -8759,6 +8766,15 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-chartjs-2": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz",
|
||||
"integrity": "sha512-5i3mjP6tU7QSn0jvb8I4hudTzHJqS8l00ORJnVwI2sYu0ihpj83Lv2YzfxunfxTZkscKvZu2F2w9LkwNBhj6xA==",
|
||||
"peerDependencies": {
|
||||
"chart.js": "^3.5.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-dom": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||
|
@ -13780,6 +13796,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"chart.js": {
|
||||
"version": "3.9.1",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz",
|
||||
"integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w=="
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
|
@ -17619,6 +17640,12 @@
|
|||
"loose-envify": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"react-chartjs-2": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz",
|
||||
"integrity": "sha512-5i3mjP6tU7QSn0jvb8I4hudTzHJqS8l00ORJnVwI2sYu0ihpj83Lv2YzfxunfxTZkscKvZu2F2w9LkwNBhj6xA==",
|
||||
"requires": {}
|
||||
},
|
||||
"react-dom": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"bcrypt": "^5.0.1",
|
||||
"chart.js": "^3.9.1",
|
||||
"compression": "^1.7.3",
|
||||
"cookie": "^0.5.0",
|
||||
"core-js": "^3.23.4",
|
||||
|
@ -44,6 +45,7 @@
|
|||
"passport-vkontakte": "^0.5.0",
|
||||
"ppfun-captcha": "^1.6.6",
|
||||
"react": "^18.2.0",
|
||||
"react-chartjs-2": "^4.3.1",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^4.3.1",
|
||||
"react-redux": "^8.0.2",
|
||||
|
|
|
@ -4,11 +4,114 @@
|
|||
|
||||
/* eslint-disable max-len */
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { shallowEqual, useSelector } from 'react-redux';
|
||||
import { t } from 'ttag';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineController,
|
||||
} from 'chart.js';
|
||||
import { Line } from 'react-chartjs-2';
|
||||
|
||||
import { selectStats } from '../store/selectors/ranks';
|
||||
import { colorFromText } from '../core/utils';
|
||||
|
||||
ChartJS.register(
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
LineElement,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineController,
|
||||
);
|
||||
|
||||
const options = {
|
||||
responsive: true,
|
||||
aspectRatio: 1.2,
|
||||
color: '#e6e6e6',
|
||||
scales: {
|
||||
x: {
|
||||
grid: {
|
||||
drawBorder: false,
|
||||
color: '#656565',
|
||||
},
|
||||
ticks: {
|
||||
color: '#e6e6e6',
|
||||
},
|
||||
},
|
||||
y: {
|
||||
grid: {
|
||||
drawBorder: false,
|
||||
color: '#656565',
|
||||
},
|
||||
ticks: {
|
||||
color: '#e6e6e6',
|
||||
},
|
||||
},
|
||||
},
|
||||
interaction: {
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'top',
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
color: '#e6e6e6',
|
||||
text: 'Top 10 Countries [pxls / day]',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const onlineStatsOptions = {
|
||||
responsive: true,
|
||||
color: '#e6e6e6',
|
||||
scales: {
|
||||
x: {
|
||||
grid: {
|
||||
drawBorder: false,
|
||||
color: '#656565',
|
||||
},
|
||||
ticks: {
|
||||
color: '#e6e6e6',
|
||||
},
|
||||
},
|
||||
y: {
|
||||
grid: {
|
||||
drawBorder: false,
|
||||
color: '#656565',
|
||||
},
|
||||
ticks: {
|
||||
color: '#e6e6e6',
|
||||
},
|
||||
},
|
||||
},
|
||||
interaction: {
|
||||
mode: 'index',
|
||||
intersect: false,
|
||||
},
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
title: {
|
||||
display: true,
|
||||
color: '#e6e6e6',
|
||||
text: 'Players Online per full hour',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
const Rankings = () => {
|
||||
|
@ -23,6 +126,80 @@ const Rankings = () => {
|
|||
histStats,
|
||||
] = useSelector(selectStats, shallowEqual);
|
||||
|
||||
const cHistData = useMemo(() => {
|
||||
if (area !== 'charts') {
|
||||
return null;
|
||||
}
|
||||
const dataPerCountry = {};
|
||||
const labels = [];
|
||||
let ts = Date.now();
|
||||
let c = cHistStats.length;
|
||||
while (c) {
|
||||
const dAmount = cHistStats.length - c;
|
||||
c -= 1;
|
||||
// x label
|
||||
const date = new Date(ts);
|
||||
labels.unshift(`${date.getUTCMonth() + 1} / ${date.getUTCDate()}`);
|
||||
ts -= 1000 * 3600 * 24;
|
||||
// y data per country
|
||||
const dailyRanks = cHistStats[c];
|
||||
for (let i = 0; i < dailyRanks.length; i += 1) {
|
||||
const { cc, px } = dailyRanks[i];
|
||||
if (!dataPerCountry[cc]) {
|
||||
dataPerCountry[cc] = [];
|
||||
}
|
||||
const countryDat = dataPerCountry[cc];
|
||||
while (countryDat.length < dAmount) {
|
||||
countryDat.push(null);
|
||||
}
|
||||
countryDat.push(px);
|
||||
}
|
||||
}
|
||||
console.log(dataPerCountry);
|
||||
const countries = Object.keys(dataPerCountry);
|
||||
const datasets = countries.map((cc) => {
|
||||
const color = colorFromText(`${cc}${cc}${cc}${cc}${cc}`);
|
||||
return {
|
||||
label: cc,
|
||||
data: dataPerCountry[cc],
|
||||
borderColor: color,
|
||||
backgroundColor: color,
|
||||
};
|
||||
});
|
||||
return {
|
||||
labels,
|
||||
datasets,
|
||||
};
|
||||
}, [area, cHistStats]);
|
||||
|
||||
const onlineData = useMemo(() => {
|
||||
if (area !== 'charts') {
|
||||
return null;
|
||||
}
|
||||
const labels = [];
|
||||
const data = [];
|
||||
let ts = Date.now();
|
||||
let c = onlineStats.length;
|
||||
while (c) {
|
||||
c -= 1;
|
||||
const date = new Date(ts);
|
||||
const hours = date.getHours();
|
||||
const key = hours || `${date.getMonth() + 1} / ${date.getDate()}`;
|
||||
labels.unshift(String(key));
|
||||
ts -= 1000 * 3600;
|
||||
data.push(onlineStats[c]);
|
||||
}
|
||||
return {
|
||||
labels,
|
||||
datasets: [{
|
||||
label: 'Players',
|
||||
data,
|
||||
borderColor: '#3fadda',
|
||||
backgroundColor: '#3fadda',
|
||||
}],
|
||||
};
|
||||
}, [area, onlineStats]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="content">
|
||||
|
@ -61,6 +238,15 @@ const Rankings = () => {
|
|||
}
|
||||
onClick={() => setArea('countries')}
|
||||
>{t`Countries Today`}</span>
|
||||
<span className="hdivider" />
|
||||
<span
|
||||
role="button"
|
||||
tabIndex={-1}
|
||||
className={
|
||||
(area === 'charts') ? 'modallink selected' : 'modallink'
|
||||
}
|
||||
onClick={() => setArea('charts')}
|
||||
>{t`Chart`}</span>
|
||||
</div>
|
||||
{(['total', 'today', 'yesterday', 'countries'].includes(area)) && (
|
||||
<table style={{
|
||||
|
@ -148,6 +334,12 @@ const Rankings = () => {
|
|||
</tbody>
|
||||
</table>
|
||||
)}
|
||||
{(area === 'charts') && (
|
||||
<>
|
||||
<Line options={options} data={cHistData} />
|
||||
<Line options={onlineStatsOptions} data={onlineData} />
|
||||
</>
|
||||
)}
|
||||
<p>
|
||||
{t`Ranking updates every 5 min. Daily rankings get reset at midnight UTC.`}
|
||||
</p>
|
||||
|
|
|
@ -324,7 +324,7 @@ export function requestDeleteAccount(password) {
|
|||
|
||||
export function requestRankings() {
|
||||
return makeAPIGETRequest(
|
||||
'/ranking',
|
||||
'https://pixelplanet.fun/ranking',
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user