Fix traffic charts. Add chart vars
Add UI_TRAFFIC_STATS, UI_CHART_TYPE
This commit is contained in:
parent
ed0e46788a
commit
aedb691b2b
|
@ -0,0 +1,3 @@
|
||||||
|
WG_HOST=127.0.0.1
|
||||||
|
UI_TRAFFIC_STATS=true
|
||||||
|
UI_CHART_TYPE=2
|
|
@ -35,3 +35,4 @@ iptables -D FORWARD -o wg0 -j ACCEPT;
|
||||||
`.split('\n').join(' ');
|
`.split('\n').join(' ');
|
||||||
module.exports.LANG = process.env.LANG || 'en';
|
module.exports.LANG = process.env.LANG || 'en';
|
||||||
module.exports.UI_TRAFFIC_STATS = process.env.UI_TRAFFIC_STATS || 'false';
|
module.exports.UI_TRAFFIC_STATS = process.env.UI_TRAFFIC_STATS || 'false';
|
||||||
|
module.exports.UI_CHART_TYPE = process.env.UI_CHART_TYPE || 0;
|
||||||
|
|
|
@ -19,6 +19,7 @@ const {
|
||||||
PASSWORD,
|
PASSWORD,
|
||||||
LANG,
|
LANG,
|
||||||
UI_TRAFFIC_STATS,
|
UI_TRAFFIC_STATS,
|
||||||
|
UI_CHART_TYPE,
|
||||||
} = require('../config');
|
} = require('../config');
|
||||||
|
|
||||||
module.exports = class Server {
|
module.exports = class Server {
|
||||||
|
@ -45,6 +46,9 @@ module.exports = class Server {
|
||||||
.get('/api/ui-traffic-stats', (Util.promisify(async () => {
|
.get('/api/ui-traffic-stats', (Util.promisify(async () => {
|
||||||
return UI_TRAFFIC_STATS === 'true';
|
return UI_TRAFFIC_STATS === 'true';
|
||||||
})))
|
})))
|
||||||
|
.get('/api/ui-chart-type', (Util.promisify(async () => {
|
||||||
|
return UI_CHART_TYPE || 0;
|
||||||
|
})))
|
||||||
|
|
||||||
// Authentication
|
// Authentication
|
||||||
.get('/api/session', Util.promisify(async (req) => {
|
.get('/api/session', Util.promisify(async (req) => {
|
||||||
|
|
|
@ -77,12 +77,12 @@
|
||||||
class="relative overflow-hidden border-b last:border-b-0 border-gray-100 dark:border-neutral-600 border-solid">
|
class="relative overflow-hidden border-b last:border-b-0 border-gray-100 dark:border-neutral-600 border-solid">
|
||||||
|
|
||||||
<!-- Chart -->
|
<!-- Chart -->
|
||||||
<div class="absolute z-0 bottom-0 left-0 right-0" style="top: 60%;">
|
<div v-if="uiChartType" class="absolute z-0 bottom-0 left-0 right-0" style="top: 60%;">
|
||||||
<apexchart width="100%" height="100%" :options="client.chartOptions" :series="client.transferTxSeries">
|
<apexchart width="100%" height="100%" :options="chartOptionsTX" :series="client.transferTxSeries">
|
||||||
</apexchart>
|
</apexchart>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute z-0 top-0 left-0 right-0" style="bottom: 60%;">
|
<div v-if="uiChartType" class="absolute z-0 top-0 left-0 right-0" style="bottom: 60%;">
|
||||||
<apexchart width="100%" height="100%" :options="client.chartOptions" :series="client.transferRxSeries"
|
<apexchart width="100%" height="100%" :options="chartOptionsRX" :series="client.transferRxSeries"
|
||||||
style="transform: scaleY(-1);">
|
style="transform: scaleY(-1);">
|
||||||
</apexchart>
|
</apexchart>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -50,6 +50,13 @@ class API {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getChartType() {
|
||||||
|
return this.call({
|
||||||
|
method: 'get',
|
||||||
|
path: '/ui-chart-type',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async getSession() {
|
async getSession() {
|
||||||
return this.call({
|
return this.call({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
|
|
@ -23,14 +23,33 @@ function bytes(bytes, decimals, kib, maxunit) {
|
||||||
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
const theme = darkModeMediaQuery.matches ? 'dark' : 'light';
|
||||||
|
|
||||||
const i18n = new VueI18n({
|
const i18n = new VueI18n({
|
||||||
locale: localStorage.getItem('lang') || 'en',
|
locale: localStorage.getItem('lang') || 'en',
|
||||||
fallbackLocale: 'en',
|
fallbackLocale: 'en',
|
||||||
messages,
|
messages,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const UI_CHART_TYPES = [
|
||||||
|
{ type: false, strokeWidth: 0 },
|
||||||
|
{ type: 'line', strokeWidth: 3 },
|
||||||
|
{ type: 'area', strokeWidth: 0 },
|
||||||
|
{ type: 'bar', strokeWidth: 0 },
|
||||||
|
]
|
||||||
|
|
||||||
|
const CHART_COLORS = {
|
||||||
|
rx: { light: 'rgba(0,0,0,0.2)', dark: 'rgba(255,255,255,0.3)' },
|
||||||
|
tx: { light: 'rgba(0,0,0,0.3)', dark: 'rgba(255,255,255,0.5)' },
|
||||||
|
gradient: {light: ['rgba(0,0,0,0.1)', 'rgba(0,0,0,0)'], dark: ['rgba(255,255,255,0.1)', 'rgba(255,255,255,0)']},
|
||||||
|
}
|
||||||
|
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
|
components: {
|
||||||
|
apexchart: VueApexCharts,
|
||||||
|
},
|
||||||
i18n,
|
i18n,
|
||||||
data: {
|
data: {
|
||||||
authenticated: null,
|
authenticated: null,
|
||||||
|
@ -55,10 +74,11 @@ new Vue({
|
||||||
isDark: null,
|
isDark: null,
|
||||||
uiTrafficStats: false,
|
uiTrafficStats: false,
|
||||||
|
|
||||||
|
uiChartType: 0,
|
||||||
|
|
||||||
chartOptions: {
|
chartOptions: {
|
||||||
chart: {
|
chart: {
|
||||||
background: 'transparent',
|
background: 'transparent',
|
||||||
type: 'bar',
|
|
||||||
stacked: false,
|
stacked: false,
|
||||||
toolbar: {
|
toolbar: {
|
||||||
show: false,
|
show: false,
|
||||||
|
@ -67,10 +87,23 @@ new Vue({
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
colors: [
|
colors: [],
|
||||||
'#DDDDDD', // rx
|
stroke: {
|
||||||
'#EEEEEE', // tx
|
curve: 'smooth',
|
||||||
],
|
},
|
||||||
|
fill: {
|
||||||
|
type: 'gradient',
|
||||||
|
gradient: {
|
||||||
|
shade: 'dark',
|
||||||
|
type: 'vertical',
|
||||||
|
shadeIntensity: 1,
|
||||||
|
gradientToColors: CHART_COLORS.gradient[theme],
|
||||||
|
inverseColors: true,
|
||||||
|
opacityFrom: 1,
|
||||||
|
opacityTo: 1,
|
||||||
|
stops: [0, 100],
|
||||||
|
},
|
||||||
|
},
|
||||||
dataLabels: {
|
dataLabels: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
|
@ -154,26 +187,40 @@ new Vue({
|
||||||
// client.transferRx = this.clientsPersist[client.id].transferRxPrevious + Math.random() * 1000;
|
// client.transferRx = this.clientsPersist[client.id].transferRxPrevious + Math.random() * 1000;
|
||||||
// client.transferTx = this.clientsPersist[client.id].transferTxPrevious + Math.random() * 1000;
|
// client.transferTx = this.clientsPersist[client.id].transferTxPrevious + Math.random() * 1000;
|
||||||
|
|
||||||
|
this.clientsPersist[client.id].transferRxCurrent = client.transferRx - this.clientsPersist[client.id].transferRxPrevious;
|
||||||
|
this.clientsPersist[client.id].transferRxPrevious = client.transferRx;
|
||||||
|
this.clientsPersist[client.id].transferTxCurrent = client.transferTx - this.clientsPersist[client.id].transferTxPrevious;
|
||||||
|
this.clientsPersist[client.id].transferTxPrevious = client.transferTx;
|
||||||
|
|
||||||
if (updateCharts) {
|
if (updateCharts) {
|
||||||
this.clientsPersist[client.id].transferRxCurrent = client.transferRx - this.clientsPersist[client.id].transferRxPrevious;
|
|
||||||
this.clientsPersist[client.id].transferRxPrevious = client.transferRx;
|
|
||||||
this.clientsPersist[client.id].transferTxCurrent = client.transferTx - this.clientsPersist[client.id].transferTxPrevious;
|
|
||||||
this.clientsPersist[client.id].transferTxPrevious = client.transferTx;
|
|
||||||
|
|
||||||
this.clientsPersist[client.id].transferRxHistory.push(this.clientsPersist[client.id].transferRxCurrent);
|
this.clientsPersist[client.id].transferRxHistory.push(this.clientsPersist[client.id].transferRxCurrent);
|
||||||
this.clientsPersist[client.id].transferRxHistory.shift();
|
this.clientsPersist[client.id].transferRxHistory.shift();
|
||||||
|
|
||||||
this.clientsPersist[client.id].transferTxHistory.push(this.clientsPersist[client.id].transferTxCurrent);
|
this.clientsPersist[client.id].transferTxHistory.push(this.clientsPersist[client.id].transferTxCurrent);
|
||||||
this.clientsPersist[client.id].transferTxHistory.shift();
|
this.clientsPersist[client.id].transferTxHistory.shift();
|
||||||
|
|
||||||
|
this.clientsPersist[client.id].transferTxSeries = [{
|
||||||
|
name: 'Tx',
|
||||||
|
data: this.clientsPersist[client.id].transferTxHistory,
|
||||||
|
}];
|
||||||
|
|
||||||
|
this.clientsPersist[client.id].transferRxSeries = [{
|
||||||
|
name: 'Rx',
|
||||||
|
data: this.clientsPersist[client.id].transferRxHistory,
|
||||||
|
}];
|
||||||
|
|
||||||
|
client.transferTxHistory = this.clientsPersist[client.id].transferTxHistory;
|
||||||
|
client.transferRxHistory = this.clientsPersist[client.id].transferRxHistory;
|
||||||
|
client.transferMax = Math.max(...client.transferTxHistory, ...client.transferRxHistory);
|
||||||
|
|
||||||
|
client.transferTxSeries = this.clientsPersist[client.id].transferTxSeries;
|
||||||
|
client.transferRxSeries = this.clientsPersist[client.id].transferRxSeries;
|
||||||
}
|
}
|
||||||
|
|
||||||
client.transferTxCurrent = this.clientsPersist[client.id].transferTxCurrent;
|
client.transferTxCurrent = this.clientsPersist[client.id].transferTxCurrent;
|
||||||
client.transferRxCurrent = this.clientsPersist[client.id].transferRxCurrent;
|
client.transferRxCurrent = this.clientsPersist[client.id].transferRxCurrent;
|
||||||
|
|
||||||
client.transferTxHistory = this.clientsPersist[client.id].transferTxHistory;
|
|
||||||
client.transferRxHistory = this.clientsPersist[client.id].transferRxHistory;
|
|
||||||
client.transferMax = Math.max(...client.transferTxHistory, ...client.transferRxHistory);
|
|
||||||
|
|
||||||
client.hoverTx = this.clientsPersist[client.id].hoverTx;
|
client.hoverTx = this.clientsPersist[client.id].hoverTx;
|
||||||
client.hoverRx = this.clientsPersist[client.id].hoverRx;
|
client.hoverRx = this.clientsPersist[client.id].hoverRx;
|
||||||
|
|
||||||
|
@ -278,7 +325,7 @@ new Vue({
|
||||||
this.authenticated = session.authenticated;
|
this.authenticated = session.authenticated;
|
||||||
this.requiresPassword = session.requiresPassword;
|
this.requiresPassword = session.requiresPassword;
|
||||||
this.refresh({
|
this.refresh({
|
||||||
updateCharts: true,
|
updateCharts: this.updateCharts,
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
alert(err.message || err.toString());
|
alert(err.message || err.toString());
|
||||||
});
|
});
|
||||||
|
@ -289,7 +336,7 @@ new Vue({
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
this.refresh({
|
this.refresh({
|
||||||
updateCharts: true,
|
updateCharts: this.updateCharts,
|
||||||
}).catch(console.error);
|
}).catch(console.error);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
|
@ -298,10 +345,17 @@ new Vue({
|
||||||
this.uiTrafficStats = res;
|
this.uiTrafficStats = res;
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
console.log('Failed to get ui-traffic-stats');
|
|
||||||
this.uiTrafficStats = false;
|
this.uiTrafficStats = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.api.getChartType()
|
||||||
|
.then((res) => {
|
||||||
|
this.uiChartType = parseInt(res);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.uiChartType = 0;
|
||||||
|
});
|
||||||
|
|
||||||
Promise.resolve().then(async () => {
|
Promise.resolve().then(async () => {
|
||||||
const lang = await this.api.getLang();
|
const lang = await this.api.getLang();
|
||||||
if (lang !== localStorage.getItem('lang') && i18n.availableLocales.includes(lang)) {
|
if (lang !== localStorage.getItem('lang') && i18n.availableLocales.includes(lang)) {
|
||||||
|
@ -333,4 +387,27 @@ new Vue({
|
||||||
this.latestRelease = latestRelease;
|
this.latestRelease = latestRelease;
|
||||||
}).catch((err) => console.error(err));
|
}).catch((err) => console.error(err));
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
chartOptionsTX() {
|
||||||
|
const opts = {
|
||||||
|
...this.chartOptions,
|
||||||
|
colors: [CHART_COLORS.tx[theme]],
|
||||||
|
};
|
||||||
|
opts.chart.type = UI_CHART_TYPES[this.uiChartType].type || false;
|
||||||
|
opts.stroke.width = UI_CHART_TYPES[this.uiChartType].strokeWidth;
|
||||||
|
return opts;
|
||||||
|
},
|
||||||
|
chartOptionsRX() {
|
||||||
|
const opts = {
|
||||||
|
...this.chartOptions,
|
||||||
|
colors: [CHART_COLORS.rx[theme]],
|
||||||
|
};
|
||||||
|
opts.chart.type = UI_CHART_TYPES[this.uiChartType].type || false;
|
||||||
|
opts.stroke.width = UI_CHART_TYPES[this.uiChartType].strokeWidth;
|
||||||
|
return opts;
|
||||||
|
},
|
||||||
|
updateCharts() {
|
||||||
|
return this.uiChartType > 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue