wiki-grav/plugins/admin/themes/grav/app/dashboard/chart.js
2022-04-24 14:32:58 +02:00

139 lines
4.2 KiB
JavaScript

import $ from 'jquery';
import chartist from 'chartist';
import { translations } from 'grav-config';
import { Instance as gpm } from '../utils/gpm';
import { Instance as updates } from '../updates';
// let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
export const defaults = {
data: {
series: [100, 0]
},
options: {
Pie: {
donut: true,
donutWidth: 10,
startAngle: 0,
total: 100,
showLabel: false,
height: 150,
// chartPadding: !isFirefox ? 10 : 25 // workaround for older versions of firefox
chartPadding: 5
},
Bar: {
height: 164,
chartPadding: 20, // workaround for older versions of firefox
axisX: {
showGrid: false,
labelOffset: {
x: 0,
y: 0
}
},
axisY: {
offset: 15,
showLabel: true,
showGrid: true,
labelOffset: {
x: 5,
y: 5
},
scaleMinSpace: 25
}
}
}
};
export default class Chart {
constructor(element, options = {}, data = {}) {
this.element = $(element) || [];
if (!this.element[0]) { return; }
let type = (this.element.data('chart-type') || 'pie').toLowerCase();
this.type = type.charAt(0).toUpperCase() + type.substr(1).toLowerCase();
options = Object.assign({}, defaults.options[this.type], options);
data = Object.assign({}, defaults.data, data);
Object.assign(this, {
options,
data
});
this.chart = chartist[this.type](this.element.find('.ct-chart').empty()[0], this.data, this.options);
this.chart.on('created', () => {
this.element.find('.hidden').removeClass('hidden');
// FIX: workaround for chartist issue not allowing HTML in labels anymore
// https://github.com/gionkunz/chartist-js/issues/937
this.element.find('.ct-label').each((index, label) => {
label = $(label);
const text = label.html().replace('&lt;', '<').replace('&gt;', '>');
label.html(text);
});
});
}
updateData(data) {
Object.assign(this.data, data);
this.chart.update(this.data);
}
};
export class UpdatesChart extends Chart {
constructor(element, options = {}, data = {}) {
super(element, options, data);
this.chart.on('draw', (data) => this.draw(data));
gpm.on('fetched', (response) => {
if (!response.payload) { return; }
let payload = response.payload.grav;
let missing = (response.payload.resources.total + (payload.isUpdatable ? 1 : 0)) * 100 / (response.payload.installed + (payload.isUpdatable ? 1 : 0));
let updated = 100 - missing;
this.updateData({ series: [updated, missing] });
if (response.payload.resources.total) {
updates.maintenance('show');
}
});
}
draw(data) {
if (data.index) { return; }
let notice = translations.PLUGIN_ADMIN[data.value === 100 ? 'FULLY_UPDATED' : 'UPDATES_AVAILABLE'];
this.element.find('.numeric span').text(`${Math.round(data.value)}%`);
this.element.find('.js__updates-available-description').html(notice);
this.element.find('.hidden').removeClass('hidden');
}
updateData(data) {
super.updateData(data);
// missing updates
if (this.data.series[0] < 100) {
this.element.closest('#updates').find('[data-update-packages]').fadeIn();
}
}
}
let charts = {};
$('[data-chart-name]').each(function() {
let element = $(this);
let name = element.data('chart-name') || '';
let options = element.data('chart-options') || {};
let data = element.data('chart-data') || {};
if (name === 'updates') {
charts[name] = new UpdatesChart(element, options, data);
} else {
charts[name] = new Chart(element, options, data);
}
});
export let Instances = charts;