chart.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import $ from 'jquery';
  2. import chartist from 'chartist';
  3. import { translations } from 'grav-config';
  4. import { Instance as gpm } from '../utils/gpm';
  5. import { Instance as updates } from '../updates';
  6. let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1;
  7. export const defaults = {
  8. data: {
  9. series: [100, 0]
  10. },
  11. options: {
  12. Pie: {
  13. donut: true,
  14. donutWidth: 10,
  15. startAngle: 0,
  16. total: 100,
  17. showLabel: false,
  18. height: 150,
  19. // chartPadding: !isFirefox ? 10 : 25 // workaround for older versions of firefox
  20. chartPadding: 5
  21. },
  22. Bar: {
  23. height: 164,
  24. chartPadding: !isFirefox ? 5 : 10, // workaround for older versions of firefox
  25. axisX: {
  26. showGrid: false,
  27. labelOffset: {
  28. x: 0,
  29. y: 0
  30. }
  31. },
  32. axisY: {
  33. offset: 15,
  34. showLabel: true,
  35. showGrid: true,
  36. labelOffset: {
  37. x: 5,
  38. y: 5
  39. },
  40. scaleMinSpace: !isFirefox ? 20 : 10
  41. }
  42. }
  43. }
  44. };
  45. export default class Chart {
  46. constructor(element, options = {}, data = {}) {
  47. this.element = $(element) || [];
  48. if (!this.element[0]) { return; }
  49. let type = (this.element.data('chart-type') || 'pie').toLowerCase();
  50. this.type = type.charAt(0).toUpperCase() + type.substr(1).toLowerCase();
  51. options = Object.assign({}, defaults.options[this.type], options);
  52. data = Object.assign({}, defaults.data, data);
  53. Object.assign(this, {
  54. options,
  55. data
  56. });
  57. this.chart = chartist[this.type](this.element.find('.ct-chart').empty()[0], this.data, this.options);
  58. this.chart.on('created', () => {
  59. this.element.find('.hidden').removeClass('hidden');
  60. // FIX: workaround for chartist issue not allowing HTML in labels anymore
  61. // https://github.com/gionkunz/chartist-js/issues/937
  62. this.element.find('.ct-label').each((index, label) => {
  63. label = $(label);
  64. const text = label.html().replace('&lt;', '<').replace('&gt;', '>');
  65. label.html(text);
  66. });
  67. });
  68. }
  69. updateData(data) {
  70. Object.assign(this.data, data);
  71. this.chart.update(this.data);
  72. }
  73. };
  74. export class UpdatesChart extends Chart {
  75. constructor(element, options = {}, data = {}) {
  76. super(element, options, data);
  77. this.chart.on('draw', (data) => this.draw(data));
  78. gpm.on('fetched', (response) => {
  79. if (!response.payload) { return; }
  80. let payload = response.payload.grav;
  81. let missing = (response.payload.resources.total + (payload.isUpdatable ? 1 : 0)) * 100 / (response.payload.installed + (payload.isUpdatable ? 1 : 0));
  82. let updated = 100 - missing;
  83. this.updateData({ series: [updated, missing] });
  84. if (response.payload.resources.total) {
  85. updates.maintenance('show');
  86. }
  87. });
  88. }
  89. draw(data) {
  90. if (data.index) { return; }
  91. let notice = translations.PLUGIN_ADMIN[data.value === 100 ? 'FULLY_UPDATED' : 'UPDATES_AVAILABLE'];
  92. this.element.find('.numeric span').text(`${Math.round(data.value)}%`);
  93. this.element.find('.js__updates-available-description').html(notice);
  94. this.element.find('.hidden').removeClass('hidden');
  95. }
  96. updateData(data) {
  97. super.updateData(data);
  98. // missing updates
  99. if (this.data.series[0] < 100) {
  100. this.element.closest('#updates').find('[data-update-packages]').fadeIn();
  101. }
  102. }
  103. }
  104. let charts = {};
  105. $('[data-chart-name]').each(function() {
  106. let element = $(this);
  107. let name = element.data('chart-name') || '';
  108. let options = element.data('chart-options') || {};
  109. let data = element.data('chart-data') || {};
  110. if (name === 'updates') {
  111. charts[name] = new UpdatesChart(element, options, data);
  112. } else {
  113. charts[name] = new Chart(element, options, data);
  114. }
  115. });
  116. export let Instances = charts;