1/** 2 * @file plugins/generic/usageStats/js/UsageStatsFrontendHandler.js 3 * 4 * Copyright (c) 2013-2020 Simon Fraser University 5 * Copyright (c) 2003-2020 John Willinsky 6 * Distributed under the GNU GPL v3. For full terms see the file docs/COPYING. 7 * 8 * @package plugins.generic.usageStats 9 * 10 * @brief A small handler to initialize Chart.js graphs on the frontend 11 */ 12(function() { 13 14 if (typeof pkpUsageStats === 'undefined' || typeof pkpUsageStats.data === 'undefined') { 15 return; 16 } 17 18 var graphs, noStatsNotice; 19 20 // Check for .querySelectorAll in browser support 21 try { 22 graphs = document.querySelectorAll('.usageStatsGraph'); 23 noStatsNotice = document.querySelectorAll('.usageStatsUnavailable'); 24 } catch (e) { 25 console.log('Usage stats graph could not be loaded because your browser is too old. Please update your browser.'); 26 return; 27 } 28 29 // Hide the unavailable stats notice when a chart is loaded 30 document.addEventListener('usageStatsChartLoaded.pkp', function(e) { 31 for (var i = 0; i < noStatsNotice.length; i++) { 32 if (typeof noStatsNotice[i].dataset.objectType !== 'undefined' && typeof noStatsNotice[i].dataset.objectId !== 'undefined' && noStatsNotice[i].dataset.objectType === e.target.dataset.objectType && noStatsNotice[i].dataset.objectId === e.target.dataset.objectId ) { 33 noStatsNotice[i].parentNode.removeChild(noStatsNotice[i]); 34 } 35 } 36 }); 37 38 // Define default chart options 39 var chartOptions = { 40 legend: { 41 display: false, 42 }, 43 tooltips: { 44 titleColor: '#333', 45 bodyColor: '#333', 46 footerColor: '#333', 47 backgroundColor: '#ddd', 48 cornerRadius: 2, 49 }, 50 elements: { 51 line: { 52 borderColor: 'rgba(0,0,0,0.3)', 53 borderWidth: 1, 54 borderJoinStyle: 'round', 55 backgroundColor: 'rgba(0,0,0,0.3)', 56 }, 57 rectangle: { 58 backgroundColor: 'rgba(0,0,0,0.3)', 59 }, 60 point: { 61 radius: 2, 62 hoverRadius: 6, 63 borderWidth: 0, 64 hitRadius: 5, 65 }, 66 }, 67 scales: { 68 xAxes: [{ 69 gridLines: { 70 color: 'rgba(0,0,0,0.05)', 71 drawTicks: false, 72 }, 73 }], 74 yAxes: [{ 75 gridLines: { 76 color: 'rgba(0,0,0,0.05)', 77 drawTicks: false, 78 }, 79 }], 80 }, 81 }; 82 83 if (pkpUsageStats.config.chartType === 'bar') { 84 chartOptions.scales.xAxes = [{ 85 gridLines: { 86 color: 'transparent', 87 } 88 }]; 89 } 90 91 // Fire an event to allow third-party customization of the options 92 var optionsEvent = document.createEvent('Event'); 93 optionsEvent.initEvent('usageStatsChartOptions.pkp', true, true); 94 optionsEvent.chartOptions = chartOptions; 95 document.dispatchEvent(optionsEvent); 96 97 var graph, objectType, objectId, graphData, initializedEvent; 98 pkpUsageStats.charts = {}; 99 for (var g = 0; g < graphs.length; g++) { 100 graph = graphs[g]; 101 102 // Check for markup we can use 103 if (typeof graph.dataset.objectType === 'undefined' || typeof graph.dataset.objectId === 'undefined' ) { 104 console.log('Usage stats graph is missing data-object-type and data-object-id attributes', graph); 105 continue; 106 } 107 108 objectType = graph.dataset.objectType; 109 objectId = graph.dataset.objectId; 110 111 // Check that data exists for this graph 112 if (typeof pkpUsageStats.data[objectType] === 'undefined' || pkpUsageStats.data[objectType][objectId] === 'undefined' ) { 113 console.log('Could not find data for this usage stats graph.', objectType, objectId); 114 continue; 115 } 116 117 // Do nothing if there's no data for this chart 118 if (typeof pkpUsageStats.data[objectType][objectId].data === 'undefined') { 119 graph.parentNode.removeChild(graph); 120 continue; 121 } 122 123 graphData = pkpUsageStats.data[objectType][objectId]; 124 125 // Turn the data set into an array 126 var dataArray = [], labelsArray = [], currentDate = new Date(), 127 currentYear = currentDate.getFullYear(), currentMonth = currentDate.getMonth(); 128 // Get the data from the last year 129 for (month = currentMonth + 1; month <= 11; month++) { 130 if (!(currentYear - 1 in graphData.data)) { 131 dataArray.push(0); 132 } else { 133 dataArray.push(graphData.data[currentYear - 1][month+1]); 134 } 135 labelsArray.push(pkpUsageStats.locale.months[month]); 136 } 137 // Get the data from the current year 138 for (month = 0; month <= currentMonth; month++) { 139 if (!(currentYear in graphData.data)) { 140 dataArray.push(0); 141 } else { 142 dataArray.push(graphData.data[currentYear][month+1]); 143 } 144 labelsArray.push(pkpUsageStats.locale.months[month]); 145 } 146 147 pkpUsageStats.charts[objectType + '_' + objectId] = new Chart(graph, { 148 type: pkpUsageStats.config.chartType, 149 data: { 150 labels: labelsArray, 151 datasets: [{ 152 label: graphData.label, 153 data: dataArray, 154 }] 155 }, 156 options: chartOptions, 157 }); 158 159 // Fire an event when the chart is initialized 160 var initializedEvent = document.createEvent('Event'); 161 initializedEvent.initEvent('usageStatsChartLoaded.pkp', true, true); 162 graph.dispatchEvent(initializedEvent); 163 } 164})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.