Browse Source

Fix traffic charts. Add chart vars

Add UI_TRAFFIC_STATS, UI_CHART_TYPE
pull/915/head
Sergei Birukov 1 year ago
committed by Philip H
parent
commit
aedb691b2b
  1. 3
      src/.env
  2. 1
      src/config.js
  3. 4
      src/lib/Server.js
  4. 8
      src/www/index.html
  5. 7
      src/www/js/api.js
  6. 111
      src/www/js/app.js

3
src/.env

@ -0,0 +1,3 @@
WG_HOST=127.0.0.1
UI_TRAFFIC_STATS=true
UI_CHART_TYPE=2

1
src/config.js

@ -35,3 +35,4 @@ iptables -D FORWARD -o wg0 -j ACCEPT;
`.split('\n').join(' ');
module.exports.LANG = process.env.LANG || 'en';
module.exports.UI_TRAFFIC_STATS = process.env.UI_TRAFFIC_STATS || 'false';
module.exports.UI_CHART_TYPE = process.env.UI_CHART_TYPE || 0;

4
src/lib/Server.js

@ -19,6 +19,7 @@ const {
PASSWORD,
LANG,
UI_TRAFFIC_STATS,
UI_CHART_TYPE,
} = require('../config');
module.exports = class Server {
@ -45,6 +46,9 @@ module.exports = class Server {
.get('/api/ui-traffic-stats', (Util.promisify(async () => {
return UI_TRAFFIC_STATS === 'true';
})))
.get('/api/ui-chart-type', (Util.promisify(async () => {
return UI_CHART_TYPE || 0;
})))
// Authentication
.get('/api/session', Util.promisify(async (req) => {

8
src/www/index.html

@ -77,12 +77,12 @@
class="relative overflow-hidden border-b last:border-b-0 border-gray-100 dark:border-neutral-600 border-solid">
<!-- Chart -->
<div class="absolute z-0 bottom-0 left-0 right-0" style="top: 60%;">
<apexchart width="100%" height="100%" :options="client.chartOptions" :series="client.transferTxSeries">
<div v-if="uiChartType" class="absolute z-0 bottom-0 left-0 right-0" style="top: 60%;">
<apexchart width="100%" height="100%" :options="chartOptionsTX" :series="client.transferTxSeries">
</apexchart>
</div>
<div class="absolute z-0 top-0 left-0 right-0" style="bottom: 60%;">
<apexchart width="100%" height="100%" :options="client.chartOptions" :series="client.transferRxSeries"
<div v-if="uiChartType" class="absolute z-0 top-0 left-0 right-0" style="bottom: 60%;">
<apexchart width="100%" height="100%" :options="chartOptionsRX" :series="client.transferRxSeries"
style="transform: scaleY(-1);">
</apexchart>
</div>

7
src/www/js/api.js

@ -50,6 +50,13 @@ class API {
});
}
async getChartType() {
return this.call({
method: 'get',
path: '/ui-chart-type',
});
}
async getSession() {
return this.call({
method: 'get',

111
src/www/js/app.js

@ -23,14 +23,33 @@ function bytes(bytes, decimals, kib, maxunit) {
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({
locale: localStorage.getItem('lang') || 'en',
fallbackLocale: 'en',
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({
el: '#app',
components: {
apexchart: VueApexCharts,
},
i18n,
data: {
authenticated: null,
@ -55,10 +74,11 @@ new Vue({
isDark: null,
uiTrafficStats: false,
uiChartType: 0,
chartOptions: {
chart: {
background: 'transparent',
type: 'bar',
stacked: false,
toolbar: {
show: false,
@ -67,10 +87,23 @@ new Vue({
enabled: false,
},
},
colors: [
'#DDDDDD', // rx
'#EEEEEE', // tx
],
colors: [],
stroke: {
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: {
enabled: false,
},
@ -135,7 +168,7 @@ new Vue({
updateCharts = false,
} = {}) {
if (!this.authenticated) return;
const clients = await this.api.getClients();
this.clients = clients.map((client) => {
if (client.name.includes('@') && client.name.includes('.')) {
@ -154,26 +187,40 @@ new Vue({
// client.transferRx = this.clientsPersist[client.id].transferRxPrevious + 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) {
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.shift();
this.clientsPersist[client.id].transferTxHistory.push(this.clientsPersist[client.id].transferTxCurrent);
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.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.hoverRx = this.clientsPersist[client.id].hoverRx;
@ -278,7 +325,7 @@ new Vue({
this.authenticated = session.authenticated;
this.requiresPassword = session.requiresPassword;
this.refresh({
updateCharts: true,
updateCharts: this.updateCharts,
}).catch((err) => {
alert(err.message || err.toString());
});
@ -289,7 +336,7 @@ new Vue({
setInterval(() => {
this.refresh({
updateCharts: true,
updateCharts: this.updateCharts,
}).catch(console.error);
}, 1000);
@ -298,9 +345,16 @@ new Vue({
this.uiTrafficStats = res;
})
.catch(() => {
console.log('Failed to get ui-traffic-stats');
this.uiTrafficStats = false;
});
this.api.getChartType()
.then((res) => {
this.uiChartType = parseInt(res);
})
.catch(() => {
this.uiChartType = 0;
});
Promise.resolve().then(async () => {
const lang = await this.api.getLang();
@ -333,4 +387,27 @@ new Vue({
this.latestRelease = latestRelease;
}).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…
Cancel
Save