add dynamic loading for charts

This commit is contained in:
jejolare 2024-09-25 21:25:02 +07:00
parent 9bb0c0ef03
commit af5dc3876e
5 changed files with 208 additions and 245 deletions

View file

@ -388,244 +388,207 @@ const requestsLimiter = rateLimit({
app.get(
'/api/get_chart/:chart/:period',
'/api/get_chart/:chart/:offset',
async (req, res) => {
const { chart } = req.params;
if (!chart) {
return res.status(400).json({ error: 'Invalid parameters' });
}
const currentTime = Math.round(Date.now() / 1000);
const period = currentTime - 24 * 3600; // 24 hours ago
const period2 = currentTime - 48 * 3600; // 48 hours ago
if (chart === 'all') {
// First query
const arrayAll = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from "actual_timestamp")::BIGINT'
),
'at',
],
[literal('"block_cumulative_size"::REAL'), 'bcs'],
[literal('"tr_count"::REAL'), 'trc'],
[literal('"difficulty"::REAL'), 'd'],
[col('type'), 't'],
],
where: {
actual_timestamp: {
[Op.gt]: new Date(period * 1000), // Convert to milliseconds
},
},
order: [[literal('"at"'), 'ASC']],
});
// Second query
const rows0 = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'day\', "actual_timestamp"))::BIGINT'
),
'at',
],
[literal('SUM("tr_count"::REAL)'), 'sum_trc'],
],
group: ['at'],
order: [[literal('"at"'), 'ASC']],
});
// Third query
const rows1 = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from "actual_timestamp")::BIGINT'
),
'at',
],
[literal('"difficulty120"::REAL'), 'd120'],
[literal('"hashrate100"::REAL'), 'h100'],
[literal('"hashrate400"::REAL'), 'h400'],
],
where: {
type: '1',
actual_timestamp: {
[Op.gt]: new Date(period2 * 1000),
},
},
order: [[literal('"at"'), 'ASC']],
});
const arrayAllJson = arrayAll.map((record) => record.toJSON());
const rows0Json = rows0.map((record) => record.toJSON());
const rows1Json = rows1.map((record) => record.toJSON());
const resultArray = [...arrayAllJson];
resultArray[0] = rows0Json;
resultArray[1] = rows1Json;
res.json(resultArray);
} else if (chart === 'AvgBlockSize') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'hour\', "actual_timestamp"))::BIGINT'
),
'at',
],
[fn('avg', literal('"block_cumulative_size"::REAL')), 'bcs'],
],
group: ['at'],
order: [[literal('"at"'), 'ASC']],
});
res.json(result.map((record) => record.toJSON()));
} else if (chart === 'AvgTransPerBlock') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'hour\', "actual_timestamp"))::BIGINT'
),
'at',
],
[fn('avg', literal('"tr_count"::REAL')), 'trc'],
],
group: ['at'],
order: [[literal('"at"'), 'ASC']],
});
res.json(result.map((record) => record.toJSON()));
} else if (chart === 'hashRate') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'hour\', "actual_timestamp"))::BIGINT'
),
'at',
],
[fn('avg', literal('"difficulty120"::REAL')), 'd120'],
[fn('avg', literal('"hashrate100"::REAL')), 'h100'],
[fn('avg', literal('"hashrate400"::REAL')), 'h400'],
],
where: {
type: '1',
},
group: ['at'],
order: [[literal('"at"'), 'ASC']],
});
res.json(result.map((record) => record.toJSON()));
} else if (chart === 'pos-difficulty') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'hour\', "actual_timestamp"))::BIGINT'
),
'at',
],
[
literal(
`CASE WHEN (MAX("difficulty"::NUMERIC) - AVG("difficulty"::NUMERIC)) > (AVG("difficulty"::NUMERIC) - MIN("difficulty"::NUMERIC)) THEN MAX("difficulty"::NUMERIC) ELSE MIN("difficulty"::NUMERIC) END`
),
'd',
],
],
where: {
type: '0',
},
group: ['at'],
order: [[literal('"at"'), 'ASC']],
});
const result1 = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from "actual_timestamp")::BIGINT'
),
'at',
],
[literal('"difficulty"::REAL'), 'd'],
],
where: {
type: '0',
},
order: [[literal('"at"'), 'ASC']],
});
res.json({
aggregated: result.map((record) => record.toJSON()),
detailed: result1.map((record) => record.toJSON()),
});
} else if (chart === 'pow-difficulty') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'hour\', "actual_timestamp"))::BIGINT'
),
'at',
],
[
literal(
`CASE WHEN (MAX("difficulty"::NUMERIC) - AVG("difficulty"::NUMERIC)) > (AVG("difficulty"::NUMERIC) - MIN("difficulty"::NUMERIC)) THEN MAX("difficulty"::NUMERIC) ELSE MIN("difficulty"::NUMERIC) END`
),
'd',
],
],
where: {
type: '1',
},
group: ['at'],
order: [[literal('"at"'), 'ASC']],
});
const result1 = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from "actual_timestamp")::BIGINT'
),
'at',
],
[literal('"difficulty"::REAL'), 'd'],
],
where: {
type: '1',
},
order: [[literal('"at"'), 'ASC']],
});
res.json({
aggregated: result.map((record) => record.toJSON()),
detailed: result1.map((record) => record.toJSON()),
});
} else if (chart === 'ConfirmTransactPerDay') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'day\', "actual_timestamp"))::BIGINT'
),
'at',
],
[literal('SUM("tr_count"::REAL)'), 'sum_trc'],
],
group: ['at'],
order: [[literal('"at"'), 'ASC']],
});
res.json(result.map((record) => record.toJSON()));
} else {
res.status(400).json({ error: 'Invalid chart type' });
}
const { chart, offset } = req.params;
const offsetDate = new Date(parseInt(offset, 10));
if (!chart) {
return res.status(400).json({ error: 'Invalid parameters' });
}
// const currentTime = Math.round(Date.now() / 1000);
// const period = currentTime - 24 * 3600; // 24 hours ago
// const period2 = currentTime - 48 * 3600; // 48 hours ago
if (chart === 'AvgBlockSize') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'hour\', "actual_timestamp"))::BIGINT'
),
'at',
],
[fn('avg', literal('"block_cumulative_size"::REAL')), 'bcs'],
],
group: ['at'],
order: [[literal('"at"'), 'ASC']],
where: {
actual_timestamp: {
[Op.gt]: offsetDate,
},
}
});
res.json(result.map((record) => record.toJSON()));
} else if (chart === 'AvgTransPerBlock') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'hour\', "actual_timestamp"))::BIGINT'
),
'at',
],
[fn('avg', literal('"tr_count"::REAL')), 'trc'],
],
group: ['at'],
order: [[literal('"at"'), 'ASC']],
where: {
actual_timestamp: {
[Op.gt]: offsetDate,
},
}
});
res.json(result.map((record) => record.toJSON()));
} else if (chart === 'hashRate') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'hour\', "actual_timestamp"))::BIGINT'
),
'at',
],
[fn('avg', literal('"difficulty120"::REAL')), 'd120'],
[fn('avg', literal('"hashrate100"::REAL')), 'h100'],
[fn('avg', literal('"hashrate400"::REAL')), 'h400'],
],
where: {
type: '1',
actual_timestamp: {
[Op.gt]: offsetDate,
},
},
group: ['at'],
order: [[literal('"at"'), 'ASC']],
});
res.json(result.map((record) => record.toJSON()));
} else if (chart === 'pos-difficulty') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'hour\', "actual_timestamp"))::BIGINT'
),
'at',
],
[
literal(
`CASE WHEN (MAX("difficulty"::NUMERIC) - AVG("difficulty"::NUMERIC)) > (AVG("difficulty"::NUMERIC) - MIN("difficulty"::NUMERIC)) THEN MAX("difficulty"::NUMERIC) ELSE MIN("difficulty"::NUMERIC) END`
),
'd',
],
],
where: {
type: '0',
actual_timestamp: {
[Op.gt]: offsetDate,
},
},
group: ['at'],
order: [[literal('"at"'), 'ASC']],
});
const result1 = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from "actual_timestamp")::BIGINT'
),
'at',
],
[literal('"difficulty"::REAL'), 'd'],
],
where: {
type: '0',
actual_timestamp: {
[Op.gt]: offsetDate,
},
},
order: [[literal('"at"'), 'ASC']],
});
res.json({
aggregated: result.map((record) => record.toJSON()),
detailed: result1.map((record) => record.toJSON()),
});
} else if (chart === 'pow-difficulty') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'hour\', "actual_timestamp"))::BIGINT'
),
'at',
],
[
literal(
`CASE WHEN (MAX("difficulty"::NUMERIC) - AVG("difficulty"::NUMERIC)) > (AVG("difficulty"::NUMERIC) - MIN("difficulty"::NUMERIC)) THEN MAX("difficulty"::NUMERIC) ELSE MIN("difficulty"::NUMERIC) END`
),
'd',
],
],
where: {
type: '1',
actual_timestamp: {
[Op.gt]: offsetDate,
},
},
group: ['at'],
order: [[literal('"at"'), 'ASC']],
});
const result1 = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from "actual_timestamp")::BIGINT'
),
'at',
],
[literal('"difficulty"::REAL'), 'd'],
],
where: {
type: '1',
actual_timestamp: {
[Op.gt]: offsetDate,
},
},
order: [[literal('"at"'), 'ASC']],
});
res.json({
aggregated: result.map((record) => record.toJSON()),
detailed: result1.map((record) => record.toJSON()),
});
} else if (chart === 'ConfirmTransactPerDay') {
const result = await Chart.findAll({
attributes: [
[
literal(
'extract(epoch from date_trunc(\'day\', "actual_timestamp"))::BIGINT'
),
'at',
],
[literal('SUM("tr_count"::REAL)'), 'sum_trc'],
],
group: ['at'],
order: [[literal('"at"'), 'ASC']],
where: {
actual_timestamp: {
[Op.gt]: offsetDate,
},
}
});
res.json(result.map((record) => record.toJSON()));
} else {
res.status(400).json({ error: 'Invalid chart type' });
}
}
);
);
app.get(
"/api/get_tx_by_keyimage/:id",

View file

@ -72,7 +72,7 @@ function ChartPage() {
async function fetchChart() {
if (!chartId) return;
setLoading(true);
const result = await Utils.fetchChartInfo(chartId);
const result = await Utils.fetchChartInfo(chartId, 0);
setLoading(false);
if (!result) return;
setChartSeries(result);

View file

@ -41,10 +41,10 @@ function Charts() {
];
const chartPeriod = 7 * 24 * 60 * 60 * 1e3;
const now = +new Date();
const offset = +new Date(1680695278000) - chartPeriod;
await Promise.all(titles.map(async title => {
const result = await Utils.fetchChartInfo(title);
const result = await Utils.fetchChartInfo(title, offset);
if (title === "hash-rate") {
console.log("hash-rate", result);
}
@ -55,7 +55,7 @@ function Charts() {
setChartsSeries(prev => ({
...prev,
[title]: result.map(
series => series.filter(e => e.x > now - chartPeriod)
series => series.filter(e => e.x > offset - chartPeriod)
)
}))
}));
@ -73,7 +73,7 @@ function Charts() {
} = props;
return (
<Link href={"/charts/" + requestTitle} className={styles["charts__chart__wrapper"]}>
<Link href={"/chart/" + requestTitle} className={styles["charts__chart__wrapper"]}>
<div className={styles["charts__chart__title"]}>
<p>{title}</p>
</div>

View file

@ -59,10 +59,10 @@ class Fetch {
return await fetch(this.proxyPath + `/search_by_id/${id}`).then(res => res.json());
}
static async getChartData(chartId: string) {
static async getChartData(chartId: string, offset: number) {
const chartRequestName = chartRequestNames[chartId];
if (!chartRequestName) return undefined;
return await fetch(this.proxyPath + `/get_chart/${chartRequestName}/all`).then(res => res.json());
return await fetch(this.proxyPath + `/get_chart/${chartRequestName}/${offset}`).then(res => res.json());
}
static async getWhitelistedAssets(offset: number, count: number, searchText: string) {

View file

@ -112,9 +112,9 @@ class Utils {
}
}
static async fetchChartInfo(chartId: string): Promise<ChartSeriesElem[][] | undefined> {
static async fetchChartInfo(chartId: string, offset: number): Promise<ChartSeriesElem[][] | undefined> {
if (!(chartId && chartRequestNames[chartId])) return;
const result = await Fetch.getChartData(chartId);
const result = await Fetch.getChartData(chartId, offset);
if (!result) return;
if (result.success === false) return;